mirror of
https://github.com/DOI-DO/j40-cejst-2.git
synced 2025-02-23 01:54:18 -08:00
1 line
No EOL
4 MiB
1 line
No EOL
4 MiB
(self.webpackChunkjustice40_tool=self.webpackChunkjustice40_tool||[]).push([[281],{7757:function(module,__unused_webpack_exports,__webpack_require__){eval("module.exports = __webpack_require__(5666);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9yZWdlbmVyYXRvci9pbmRleC5qcz9hMzRhIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBDQUErQyIsImZpbGUiOiI3NzU3LmpzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVnZW5lcmF0b3ItcnVudGltZVwiKTtcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7757\n")},2846:function(__unused_webpack_module,exports){eval("/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m;\n var eLen = nBytes * 8 - mLen - 1;\n var eMax = (1 << eLen) - 1;\n var eBias = eMax >> 1;\n var nBits = -7;\n var i = isLE ? nBytes - 1 : 0;\n var d = isLE ? -1 : 1;\n var s = buffer[offset + i];\n i += d;\n e = s & (1 << -nBits) - 1;\n s >>= -nBits;\n nBits += eLen;\n\n for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & (1 << -nBits) - 1;\n e >>= -nBits;\n nBits += mLen;\n\n for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias;\n } else if (e === eMax) {\n return m ? NaN : (s ? -1 : 1) * Infinity;\n } else {\n m = m + Math.pow(2, mLen);\n e = e - eBias;\n }\n\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen);\n};\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c;\n var eLen = nBytes * 8 - mLen - 1;\n var eMax = (1 << eLen) - 1;\n var eBias = eMax >> 1;\n var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0;\n var i = isLE ? 0 : nBytes - 1;\n var d = isLE ? 1 : -1;\n var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;\n value = Math.abs(value);\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0;\n e = eMax;\n } else {\n e = Math.floor(Math.log(value) / Math.LN2);\n\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--;\n c *= 2;\n }\n\n if (e + eBias >= 1) {\n value += rt / c;\n } else {\n value += rt * Math.pow(2, 1 - eBias);\n }\n\n if (value * c >= 2) {\n e++;\n c /= 2;\n }\n\n if (e + eBias >= eMax) {\n m = 0;\n e = eMax;\n } else if (e + eBias >= 1) {\n m = (value * c - 1) * Math.pow(2, mLen);\n e = e + eBias;\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);\n e = 0;\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = e << mLen | m;\n eLen += mLen;\n\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzPzBiNzkiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFFBQVEsV0FBVzs7QUFFbkI7QUFDQTtBQUNBOztBQUVBLFFBQVEsV0FBVzs7QUFFbkI7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsUUFBUSxXQUFXOztBQUVuQjtBQUNBOztBQUVBLFFBQVEsVUFBVTs7QUFFbEI7QUFDQSIsImZpbGUiOiIyODQ2LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyohIGllZWU3NTQuIEJTRC0zLUNsYXVzZSBMaWNlbnNlLiBGZXJvc3MgQWJvdWtoYWRpamVoIDxodHRwczovL2Zlcm9zcy5vcmcvb3BlbnNvdXJjZT4gKi9cbmV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtO1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMTtcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDE7XG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMTtcbiAgdmFyIG5CaXRzID0gLTc7XG4gIHZhciBpID0gaXNMRSA/IG5CeXRlcyAtIDEgOiAwO1xuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDE7XG4gIHZhciBzID0gYnVmZmVyW29mZnNldCArIGldO1xuICBpICs9IGQ7XG4gIGUgPSBzICYgKDEgPDwgLW5CaXRzKSAtIDE7XG4gIHMgPj49IC1uQml0cztcbiAgbkJpdHMgKz0gZUxlbjtcblxuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gZSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKDEgPDwgLW5CaXRzKSAtIDE7XG4gIGUgPj49IC1uQml0cztcbiAgbkJpdHMgKz0gbUxlbjtcblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhcztcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAocyA/IC0xIDogMSkgKiBJbmZpbml0eTtcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pO1xuICAgIGUgPSBlIC0gZUJpYXM7XG4gIH1cblxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKTtcbn07XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGM7XG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxO1xuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMTtcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxO1xuICB2YXIgcnQgPSBtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMDtcbiAgdmFyIGkgPSBpc0xFID8gMCA6IG5CeXRlcyAtIDE7XG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMTtcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgdmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCA/IDEgOiAwO1xuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKTtcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMDtcbiAgICBlID0gZU1heDtcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMik7XG5cbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS07XG4gICAgICBjICo9IDI7XG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICB2YWx1ZSArPSBydCAvIGM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKTtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrKztcbiAgICAgIGMgLz0gMjtcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwO1xuICAgICAgZSA9IGVNYXg7XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IGUgKyBlQmlhcztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IDA7XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gZSA8PCBtTGVuIHwgbTtcbiAgZUxlbiArPSBtTGVuO1xuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjg7XG59OyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2846\n")},4362:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = Pbf;\n\nvar ieee754 = __webpack_require__(2846);\n\nfunction Pbf(buf) {\n this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf || 0);\n this.pos = 0;\n this.type = 0;\n this.length = this.buf.length;\n}\n\nPbf.Varint = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum\n\nPbf.Fixed64 = 1; // 64-bit: double, fixed64, sfixed64\n\nPbf.Bytes = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields\n\nPbf.Fixed32 = 5; // 32-bit: float, fixed32, sfixed32\n\nvar SHIFT_LEFT_32 = (1 << 16) * (1 << 16),\n SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32; // Threshold chosen based on both benchmarking and knowledge about browser string\n// data structures (which currently switch structure types at 12 bytes or more)\n\nvar TEXT_DECODER_MIN_LENGTH = 12;\nvar utf8TextDecoder = typeof TextDecoder === 'undefined' ? null : new TextDecoder('utf8');\nPbf.prototype = {\n destroy: function destroy() {\n this.buf = null;\n },\n // === READING =================================================================\n readFields: function readFields(readField, result, end) {\n end = end || this.length;\n\n while (this.pos < end) {\n var val = this.readVarint(),\n tag = val >> 3,\n startPos = this.pos;\n this.type = val & 0x7;\n readField(tag, result, this);\n if (this.pos === startPos) this.skip(val);\n }\n\n return result;\n },\n readMessage: function readMessage(readField, result) {\n return this.readFields(readField, result, this.readVarint() + this.pos);\n },\n readFixed32: function readFixed32() {\n var val = readUInt32(this.buf, this.pos);\n this.pos += 4;\n return val;\n },\n readSFixed32: function readSFixed32() {\n var val = readInt32(this.buf, this.pos);\n this.pos += 4;\n return val;\n },\n // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed)\n readFixed64: function readFixed64() {\n var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;\n this.pos += 8;\n return val;\n },\n readSFixed64: function readSFixed64() {\n var val = readUInt32(this.buf, this.pos) + readInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;\n this.pos += 8;\n return val;\n },\n readFloat: function readFloat() {\n var val = ieee754.read(this.buf, this.pos, true, 23, 4);\n this.pos += 4;\n return val;\n },\n readDouble: function readDouble() {\n var val = ieee754.read(this.buf, this.pos, true, 52, 8);\n this.pos += 8;\n return val;\n },\n readVarint: function readVarint(isSigned) {\n var buf = this.buf,\n val,\n b;\n b = buf[this.pos++];\n val = b & 0x7f;\n if (b < 0x80) return val;\n b = buf[this.pos++];\n val |= (b & 0x7f) << 7;\n if (b < 0x80) return val;\n b = buf[this.pos++];\n val |= (b & 0x7f) << 14;\n if (b < 0x80) return val;\n b = buf[this.pos++];\n val |= (b & 0x7f) << 21;\n if (b < 0x80) return val;\n b = buf[this.pos];\n val |= (b & 0x0f) << 28;\n return readVarintRemainder(val, isSigned, this);\n },\n readVarint64: function readVarint64() {\n // for compatibility with v2.0.1\n return this.readVarint(true);\n },\n readSVarint: function readSVarint() {\n var num = this.readVarint();\n return num % 2 === 1 ? (num + 1) / -2 : num / 2; // zigzag encoding\n },\n readBoolean: function readBoolean() {\n return Boolean(this.readVarint());\n },\n readString: function readString() {\n var end = this.readVarint() + this.pos;\n var pos = this.pos;\n this.pos = end;\n\n if (end - pos >= TEXT_DECODER_MIN_LENGTH && utf8TextDecoder) {\n // longer strings are fast with the built-in browser TextDecoder API\n return readUtf8TextDecoder(this.buf, pos, end);\n } // short strings are fast with our custom implementation\n\n\n return readUtf8(this.buf, pos, end);\n },\n readBytes: function readBytes() {\n var end = this.readVarint() + this.pos,\n buffer = this.buf.subarray(this.pos, end);\n this.pos = end;\n return buffer;\n },\n // verbose for performance reasons; doesn't affect gzipped size\n readPackedVarint: function readPackedVarint(arr, isSigned) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readVarint(isSigned));\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readVarint(isSigned));\n }\n\n return arr;\n },\n readPackedSVarint: function readPackedSVarint(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readSVarint());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readSVarint());\n }\n\n return arr;\n },\n readPackedBoolean: function readPackedBoolean(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readBoolean());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readBoolean());\n }\n\n return arr;\n },\n readPackedFloat: function readPackedFloat(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readFloat());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readFloat());\n }\n\n return arr;\n },\n readPackedDouble: function readPackedDouble(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readDouble());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readDouble());\n }\n\n return arr;\n },\n readPackedFixed32: function readPackedFixed32(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readFixed32());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readFixed32());\n }\n\n return arr;\n },\n readPackedSFixed32: function readPackedSFixed32(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readSFixed32());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readSFixed32());\n }\n\n return arr;\n },\n readPackedFixed64: function readPackedFixed64(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readFixed64());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readFixed64());\n }\n\n return arr;\n },\n readPackedSFixed64: function readPackedSFixed64(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readSFixed64());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readSFixed64());\n }\n\n return arr;\n },\n skip: function skip(val) {\n var type = val & 0x7;\n if (type === Pbf.Varint) while (this.buf[this.pos++] > 0x7f) {} else if (type === Pbf.Bytes) this.pos = this.readVarint() + this.pos;else if (type === Pbf.Fixed32) this.pos += 4;else if (type === Pbf.Fixed64) this.pos += 8;else throw new Error('Unimplemented type: ' + type);\n },\n // === WRITING =================================================================\n writeTag: function writeTag(tag, type) {\n this.writeVarint(tag << 3 | type);\n },\n realloc: function realloc(min) {\n var length = this.length || 16;\n\n while (length < this.pos + min) {\n length *= 2;\n }\n\n if (length !== this.length) {\n var buf = new Uint8Array(length);\n buf.set(this.buf);\n this.buf = buf;\n this.length = length;\n }\n },\n finish: function finish() {\n this.length = this.pos;\n this.pos = 0;\n return this.buf.subarray(0, this.length);\n },\n writeFixed32: function writeFixed32(val) {\n this.realloc(4);\n writeInt32(this.buf, val, this.pos);\n this.pos += 4;\n },\n writeSFixed32: function writeSFixed32(val) {\n this.realloc(4);\n writeInt32(this.buf, val, this.pos);\n this.pos += 4;\n },\n writeFixed64: function writeFixed64(val) {\n this.realloc(8);\n writeInt32(this.buf, val & -1, this.pos);\n writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);\n this.pos += 8;\n },\n writeSFixed64: function writeSFixed64(val) {\n this.realloc(8);\n writeInt32(this.buf, val & -1, this.pos);\n writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);\n this.pos += 8;\n },\n writeVarint: function writeVarint(val) {\n val = +val || 0;\n\n if (val > 0xfffffff || val < 0) {\n writeBigVarint(val, this);\n return;\n }\n\n this.realloc(4);\n this.buf[this.pos++] = val & 0x7f | (val > 0x7f ? 0x80 : 0);\n if (val <= 0x7f) return;\n this.buf[this.pos++] = (val >>>= 7) & 0x7f | (val > 0x7f ? 0x80 : 0);\n if (val <= 0x7f) return;\n this.buf[this.pos++] = (val >>>= 7) & 0x7f | (val > 0x7f ? 0x80 : 0);\n if (val <= 0x7f) return;\n this.buf[this.pos++] = val >>> 7 & 0x7f;\n },\n writeSVarint: function writeSVarint(val) {\n this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2);\n },\n writeBoolean: function writeBoolean(val) {\n this.writeVarint(Boolean(val));\n },\n writeString: function writeString(str) {\n str = String(str);\n this.realloc(str.length * 4);\n this.pos++; // reserve 1 byte for short string length\n\n var startPos = this.pos; // write the string directly to the buffer and see how much was written\n\n this.pos = writeUtf8(this.buf, str, this.pos);\n var len = this.pos - startPos;\n if (len >= 0x80) makeRoomForExtraLength(startPos, len, this); // finally, write the message length in the reserved place and restore the position\n\n this.pos = startPos - 1;\n this.writeVarint(len);\n this.pos += len;\n },\n writeFloat: function writeFloat(val) {\n this.realloc(4);\n ieee754.write(this.buf, val, this.pos, true, 23, 4);\n this.pos += 4;\n },\n writeDouble: function writeDouble(val) {\n this.realloc(8);\n ieee754.write(this.buf, val, this.pos, true, 52, 8);\n this.pos += 8;\n },\n writeBytes: function writeBytes(buffer) {\n var len = buffer.length;\n this.writeVarint(len);\n this.realloc(len);\n\n for (var i = 0; i < len; i++) {\n this.buf[this.pos++] = buffer[i];\n }\n },\n writeRawMessage: function writeRawMessage(fn, obj) {\n this.pos++; // reserve 1 byte for short message length\n // write the message directly to the buffer and see how much was written\n\n var startPos = this.pos;\n fn(obj, this);\n var len = this.pos - startPos;\n if (len >= 0x80) makeRoomForExtraLength(startPos, len, this); // finally, write the message length in the reserved place and restore the position\n\n this.pos = startPos - 1;\n this.writeVarint(len);\n this.pos += len;\n },\n writeMessage: function writeMessage(tag, fn, obj) {\n this.writeTag(tag, Pbf.Bytes);\n this.writeRawMessage(fn, obj);\n },\n writePackedVarint: function writePackedVarint(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedVarint, arr);\n },\n writePackedSVarint: function writePackedSVarint(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedSVarint, arr);\n },\n writePackedBoolean: function writePackedBoolean(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedBoolean, arr);\n },\n writePackedFloat: function writePackedFloat(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedFloat, arr);\n },\n writePackedDouble: function writePackedDouble(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedDouble, arr);\n },\n writePackedFixed32: function writePackedFixed32(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedFixed, arr);\n },\n writePackedSFixed32: function writePackedSFixed32(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedSFixed, arr);\n },\n writePackedFixed64: function writePackedFixed64(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedFixed2, arr);\n },\n writePackedSFixed64: function writePackedSFixed64(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedSFixed2, arr);\n },\n writeBytesField: function writeBytesField(tag, buffer) {\n this.writeTag(tag, Pbf.Bytes);\n this.writeBytes(buffer);\n },\n writeFixed32Field: function writeFixed32Field(tag, val) {\n this.writeTag(tag, Pbf.Fixed32);\n this.writeFixed32(val);\n },\n writeSFixed32Field: function writeSFixed32Field(tag, val) {\n this.writeTag(tag, Pbf.Fixed32);\n this.writeSFixed32(val);\n },\n writeFixed64Field: function writeFixed64Field(tag, val) {\n this.writeTag(tag, Pbf.Fixed64);\n this.writeFixed64(val);\n },\n writeSFixed64Field: function writeSFixed64Field(tag, val) {\n this.writeTag(tag, Pbf.Fixed64);\n this.writeSFixed64(val);\n },\n writeVarintField: function writeVarintField(tag, val) {\n this.writeTag(tag, Pbf.Varint);\n this.writeVarint(val);\n },\n writeSVarintField: function writeSVarintField(tag, val) {\n this.writeTag(tag, Pbf.Varint);\n this.writeSVarint(val);\n },\n writeStringField: function writeStringField(tag, str) {\n this.writeTag(tag, Pbf.Bytes);\n this.writeString(str);\n },\n writeFloatField: function writeFloatField(tag, val) {\n this.writeTag(tag, Pbf.Fixed32);\n this.writeFloat(val);\n },\n writeDoubleField: function writeDoubleField(tag, val) {\n this.writeTag(tag, Pbf.Fixed64);\n this.writeDouble(val);\n },\n writeBooleanField: function writeBooleanField(tag, val) {\n this.writeVarintField(tag, Boolean(val));\n }\n};\n\nfunction readVarintRemainder(l, s, p) {\n var buf = p.buf,\n h,\n b;\n b = buf[p.pos++];\n h = (b & 0x70) >> 4;\n if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++];\n h |= (b & 0x7f) << 3;\n if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++];\n h |= (b & 0x7f) << 10;\n if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++];\n h |= (b & 0x7f) << 17;\n if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++];\n h |= (b & 0x7f) << 24;\n if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++];\n h |= (b & 0x01) << 31;\n if (b < 0x80) return toNum(l, h, s);\n throw new Error('Expected varint not more than 10 bytes');\n}\n\nfunction readPackedEnd(pbf) {\n return pbf.type === Pbf.Bytes ? pbf.readVarint() + pbf.pos : pbf.pos + 1;\n}\n\nfunction toNum(low, high, isSigned) {\n if (isSigned) {\n return high * 0x100000000 + (low >>> 0);\n }\n\n return (high >>> 0) * 0x100000000 + (low >>> 0);\n}\n\nfunction writeBigVarint(val, pbf) {\n var low, high;\n\n if (val >= 0) {\n low = val % 0x100000000 | 0;\n high = val / 0x100000000 | 0;\n } else {\n low = ~(-val % 0x100000000);\n high = ~(-val / 0x100000000);\n\n if (low ^ 0xffffffff) {\n low = low + 1 | 0;\n } else {\n low = 0;\n high = high + 1 | 0;\n }\n }\n\n if (val >= 0x10000000000000000 || val < -0x10000000000000000) {\n throw new Error('Given varint doesn\\'t fit into 10 bytes');\n }\n\n pbf.realloc(10);\n writeBigVarintLow(low, high, pbf);\n writeBigVarintHigh(high, pbf);\n}\n\nfunction writeBigVarintLow(low, high, pbf) {\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80;\n low >>>= 7;\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80;\n low >>>= 7;\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80;\n low >>>= 7;\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80;\n low >>>= 7;\n pbf.buf[pbf.pos] = low & 0x7f;\n}\n\nfunction writeBigVarintHigh(high, pbf) {\n var lsb = (high & 0x07) << 4;\n pbf.buf[pbf.pos++] |= lsb | ((high >>>= 3) ? 0x80 : 0);\n if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0);\n if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0);\n if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0);\n if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0);\n if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f;\n}\n\nfunction makeRoomForExtraLength(startPos, len, pbf) {\n var extraLen = len <= 0x3fff ? 1 : len <= 0x1fffff ? 2 : len <= 0xfffffff ? 3 : Math.floor(Math.log(len) / (Math.LN2 * 7)); // if 1 byte isn't enough for encoding message length, shift the data to the right\n\n pbf.realloc(extraLen);\n\n for (var i = pbf.pos - 1; i >= startPos; i--) {\n pbf.buf[i + extraLen] = pbf.buf[i];\n }\n}\n\nfunction _writePackedVarint(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeVarint(arr[i]);\n }\n}\n\nfunction _writePackedSVarint(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeSVarint(arr[i]);\n }\n}\n\nfunction _writePackedFloat(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeFloat(arr[i]);\n }\n}\n\nfunction _writePackedDouble(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeDouble(arr[i]);\n }\n}\n\nfunction _writePackedBoolean(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeBoolean(arr[i]);\n }\n}\n\nfunction _writePackedFixed(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeFixed32(arr[i]);\n }\n}\n\nfunction _writePackedSFixed(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeSFixed32(arr[i]);\n }\n}\n\nfunction _writePackedFixed2(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeFixed64(arr[i]);\n }\n}\n\nfunction _writePackedSFixed2(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeSFixed64(arr[i]);\n }\n} // Buffer code below from https://github.com/feross/buffer, MIT-licensed\n\n\nfunction readUInt32(buf, pos) {\n return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16) + buf[pos + 3] * 0x1000000;\n}\n\nfunction writeInt32(buf, val, pos) {\n buf[pos] = val;\n buf[pos + 1] = val >>> 8;\n buf[pos + 2] = val >>> 16;\n buf[pos + 3] = val >>> 24;\n}\n\nfunction readInt32(buf, pos) {\n return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16) + (buf[pos + 3] << 24);\n}\n\nfunction readUtf8(buf, pos, end) {\n var str = '';\n var i = pos;\n\n while (i < end) {\n var b0 = buf[i];\n var c = null; // codepoint\n\n var bytesPerSequence = b0 > 0xEF ? 4 : b0 > 0xDF ? 3 : b0 > 0xBF ? 2 : 1;\n if (i + bytesPerSequence > end) break;\n var b1, b2, b3;\n\n if (bytesPerSequence === 1) {\n if (b0 < 0x80) {\n c = b0;\n }\n } else if (bytesPerSequence === 2) {\n b1 = buf[i + 1];\n\n if ((b1 & 0xC0) === 0x80) {\n c = (b0 & 0x1F) << 0x6 | b1 & 0x3F;\n\n if (c <= 0x7F) {\n c = null;\n }\n }\n } else if (bytesPerSequence === 3) {\n b1 = buf[i + 1];\n b2 = buf[i + 2];\n\n if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80) {\n c = (b0 & 0xF) << 0xC | (b1 & 0x3F) << 0x6 | b2 & 0x3F;\n\n if (c <= 0x7FF || c >= 0xD800 && c <= 0xDFFF) {\n c = null;\n }\n }\n } else if (bytesPerSequence === 4) {\n b1 = buf[i + 1];\n b2 = buf[i + 2];\n b3 = buf[i + 3];\n\n if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) {\n c = (b0 & 0xF) << 0x12 | (b1 & 0x3F) << 0xC | (b2 & 0x3F) << 0x6 | b3 & 0x3F;\n\n if (c <= 0xFFFF || c >= 0x110000) {\n c = null;\n }\n }\n }\n\n if (c === null) {\n c = 0xFFFD;\n bytesPerSequence = 1;\n } else if (c > 0xFFFF) {\n c -= 0x10000;\n str += String.fromCharCode(c >>> 10 & 0x3FF | 0xD800);\n c = 0xDC00 | c & 0x3FF;\n }\n\n str += String.fromCharCode(c);\n i += bytesPerSequence;\n }\n\n return str;\n}\n\nfunction readUtf8TextDecoder(buf, pos, end) {\n return utf8TextDecoder.decode(buf.subarray(pos, end));\n}\n\nfunction writeUtf8(buf, str, pos) {\n for (var i = 0, c, lead; i < str.length; i++) {\n c = str.charCodeAt(i); // code point\n\n if (c > 0xD7FF && c < 0xE000) {\n if (lead) {\n if (c < 0xDC00) {\n buf[pos++] = 0xEF;\n buf[pos++] = 0xBF;\n buf[pos++] = 0xBD;\n lead = c;\n continue;\n } else {\n c = lead - 0xD800 << 10 | c - 0xDC00 | 0x10000;\n lead = null;\n }\n } else {\n if (c > 0xDBFF || i + 1 === str.length) {\n buf[pos++] = 0xEF;\n buf[pos++] = 0xBF;\n buf[pos++] = 0xBD;\n } else {\n lead = c;\n }\n\n continue;\n }\n } else if (lead) {\n buf[pos++] = 0xEF;\n buf[pos++] = 0xBF;\n buf[pos++] = 0xBD;\n lead = null;\n }\n\n if (c < 0x80) {\n buf[pos++] = c;\n } else {\n if (c < 0x800) {\n buf[pos++] = c >> 0x6 | 0xC0;\n } else {\n if (c < 0x10000) {\n buf[pos++] = c >> 0xC | 0xE0;\n } else {\n buf[pos++] = c >> 0x12 | 0xF0;\n buf[pos++] = c >> 0xC & 0x3F | 0x80;\n }\n\n buf[pos++] = c >> 0x6 & 0x3F | 0x80;\n }\n\n buf[pos++] = c & 0x3F | 0x80;\n }\n }\n\n return pos;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9wYmYvaW5kZXguanM/NmVmZCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxjQUFjLG1CQUFPLENBQUMsSUFBUzs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGVBQWU7O0FBRWYsZ0JBQWdCOztBQUVoQixjQUFjOztBQUVkLGdCQUFnQjs7QUFFaEI7QUFDQSx1Q0FBdUM7QUFDdkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxvREFBb0Q7QUFDcEQsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7O0FBR0w7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLG1FQUFtRSxzRUFBc0UsNkNBQTZDLDZDQUE2QztBQUNuTyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBLGlFQUFpRTs7QUFFakU7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxlQUFlO0FBQ2Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUVBQWlFOztBQUVqRTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2SEFBNkg7O0FBRTdIOztBQUVBLDJCQUEyQixlQUFlO0FBQzFDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLGdCQUFnQjtBQUNqQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLGdCQUFnQjtBQUNqQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLGdCQUFnQjtBQUNqQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDO0FBQ0E7QUFDQSxDQUFDOzs7QUFHRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBCQUEwQixnQkFBZ0I7QUFDMUMsMEJBQTBCOztBQUUxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsImZpbGUiOiI0MzYyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBiZjtcblxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0Jyk7XG5cbmZ1bmN0aW9uIFBiZihidWYpIHtcbiAgdGhpcy5idWYgPSBBcnJheUJ1ZmZlci5pc1ZpZXcgJiYgQXJyYXlCdWZmZXIuaXNWaWV3KGJ1ZikgPyBidWYgOiBuZXcgVWludDhBcnJheShidWYgfHwgMCk7XG4gIHRoaXMucG9zID0gMDtcbiAgdGhpcy50eXBlID0gMDtcbiAgdGhpcy5sZW5ndGggPSB0aGlzLmJ1Zi5sZW5ndGg7XG59XG5cblBiZi5WYXJpbnQgPSAwOyAvLyB2YXJpbnQ6IGludDMyLCBpbnQ2NCwgdWludDMyLCB1aW50NjQsIHNpbnQzMiwgc2ludDY0LCBib29sLCBlbnVtXG5cblBiZi5GaXhlZDY0ID0gMTsgLy8gNjQtYml0OiBkb3VibGUsIGZpeGVkNjQsIHNmaXhlZDY0XG5cblBiZi5CeXRlcyA9IDI7IC8vIGxlbmd0aC1kZWxpbWl0ZWQ6IHN0cmluZywgYnl0ZXMsIGVtYmVkZGVkIG1lc3NhZ2VzLCBwYWNrZWQgcmVwZWF0ZWQgZmllbGRzXG5cblBiZi5GaXhlZDMyID0gNTsgLy8gMzItYml0OiBmbG9hdCwgZml4ZWQzMiwgc2ZpeGVkMzJcblxudmFyIFNISUZUX0xFRlRfMzIgPSAoMSA8PCAxNikgKiAoMSA8PCAxNiksXG4gICAgU0hJRlRfUklHSFRfMzIgPSAxIC8gU0hJRlRfTEVGVF8zMjsgLy8gVGhyZXNob2xkIGNob3NlbiBiYXNlZCBvbiBib3RoIGJlbmNobWFya2luZyBhbmQga25vd2xlZGdlIGFib3V0IGJyb3dzZXIgc3RyaW5nXG4vLyBkYXRhIHN0cnVjdHVyZXMgKHdoaWNoIGN1cnJlbnRseSBzd2l0Y2ggc3RydWN0dXJlIHR5cGVzIGF0IDEyIGJ5dGVzIG9yIG1vcmUpXG5cbnZhciBURVhUX0RFQ09ERVJfTUlOX0xFTkdUSCA9IDEyO1xudmFyIHV0ZjhUZXh0RGVjb2RlciA9IHR5cGVvZiBUZXh0RGVjb2RlciA9PT0gJ3VuZGVmaW5lZCcgPyBudWxsIDogbmV3IFRleHREZWNvZGVyKCd1dGY4Jyk7XG5QYmYucHJvdG90eXBlID0ge1xuICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgIHRoaXMuYnVmID0gbnVsbDtcbiAgfSxcbiAgLy8gPT09IFJFQURJTkcgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgcmVhZEZpZWxkczogZnVuY3Rpb24gcmVhZEZpZWxkcyhyZWFkRmllbGQsIHJlc3VsdCwgZW5kKSB7XG4gICAgZW5kID0gZW5kIHx8IHRoaXMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICB2YXIgdmFsID0gdGhpcy5yZWFkVmFyaW50KCksXG4gICAgICAgICAgdGFnID0gdmFsID4+IDMsXG4gICAgICAgICAgc3RhcnRQb3MgPSB0aGlzLnBvcztcbiAgICAgIHRoaXMudHlwZSA9IHZhbCAmIDB4NztcbiAgICAgIHJlYWRGaWVsZCh0YWcsIHJlc3VsdCwgdGhpcyk7XG4gICAgICBpZiAodGhpcy5wb3MgPT09IHN0YXJ0UG9zKSB0aGlzLnNraXAodmFsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LFxuICByZWFkTWVzc2FnZTogZnVuY3Rpb24gcmVhZE1lc3NhZ2UocmVhZEZpZWxkLCByZXN1bHQpIHtcbiAgICByZXR1cm4gdGhpcy5yZWFkRmllbGRzKHJlYWRGaWVsZCwgcmVzdWx0LCB0aGlzLnJlYWRWYXJpbnQoKSArIHRoaXMucG9zKTtcbiAgfSxcbiAgcmVhZEZpeGVkMzI6IGZ1bmN0aW9uIHJlYWRGaXhlZDMyKCkge1xuICAgIHZhciB2YWwgPSByZWFkVUludDMyKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgdGhpcy5wb3MgKz0gNDtcbiAgICByZXR1cm4gdmFsO1xuICB9LFxuICByZWFkU0ZpeGVkMzI6IGZ1bmN0aW9uIHJlYWRTRml4ZWQzMigpIHtcbiAgICB2YXIgdmFsID0gcmVhZEludDMyKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgdGhpcy5wb3MgKz0gNDtcbiAgICByZXR1cm4gdmFsO1xuICB9LFxuICAvLyA2NC1iaXQgaW50IGhhbmRsaW5nIGlzIGJhc2VkIG9uIGdpdGh1Yi5jb20vZHB3L25vZGUtYnVmZmVyLW1vcmUtaW50cyAoTUlULWxpY2Vuc2VkKVxuICByZWFkRml4ZWQ2NDogZnVuY3Rpb24gcmVhZEZpeGVkNjQoKSB7XG4gICAgdmFyIHZhbCA9IHJlYWRVSW50MzIodGhpcy5idWYsIHRoaXMucG9zKSArIHJlYWRVSW50MzIodGhpcy5idWYsIHRoaXMucG9zICsgNCkgKiBTSElGVF9MRUZUXzMyO1xuICAgIHRoaXMucG9zICs9IDg7XG4gICAgcmV0dXJuIHZhbDtcbiAgfSxcbiAgcmVhZFNGaXhlZDY0OiBmdW5jdGlvbiByZWFkU0ZpeGVkNjQoKSB7XG4gICAgdmFyIHZhbCA9IHJlYWRVSW50MzIodGhpcy5idWYsIHRoaXMucG9zKSArIHJlYWRJbnQzMih0aGlzLmJ1ZiwgdGhpcy5wb3MgKyA0KSAqIFNISUZUX0xFRlRfMzI7XG4gICAgdGhpcy5wb3MgKz0gODtcbiAgICByZXR1cm4gdmFsO1xuICB9LFxuICByZWFkRmxvYXQ6IGZ1bmN0aW9uIHJlYWRGbG9hdCgpIHtcbiAgICB2YXIgdmFsID0gaWVlZTc1NC5yZWFkKHRoaXMuYnVmLCB0aGlzLnBvcywgdHJ1ZSwgMjMsIDQpO1xuICAgIHRoaXMucG9zICs9IDQ7XG4gICAgcmV0dXJuIHZhbDtcbiAgfSxcbiAgcmVhZERvdWJsZTogZnVuY3Rpb24gcmVhZERvdWJsZSgpIHtcbiAgICB2YXIgdmFsID0gaWVlZTc1NC5yZWFkKHRoaXMuYnVmLCB0aGlzLnBvcywgdHJ1ZSwgNTIsIDgpO1xuICAgIHRoaXMucG9zICs9IDg7XG4gICAgcmV0dXJuIHZhbDtcbiAgfSxcbiAgcmVhZFZhcmludDogZnVuY3Rpb24gcmVhZFZhcmludChpc1NpZ25lZCkge1xuICAgIHZhciBidWYgPSB0aGlzLmJ1ZixcbiAgICAgICAgdmFsLFxuICAgICAgICBiO1xuICAgIGIgPSBidWZbdGhpcy5wb3MrK107XG4gICAgdmFsID0gYiAmIDB4N2Y7XG4gICAgaWYgKGIgPCAweDgwKSByZXR1cm4gdmFsO1xuICAgIGIgPSBidWZbdGhpcy5wb3MrK107XG4gICAgdmFsIHw9IChiICYgMHg3ZikgPDwgNztcbiAgICBpZiAoYiA8IDB4ODApIHJldHVybiB2YWw7XG4gICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTtcbiAgICB2YWwgfD0gKGIgJiAweDdmKSA8PCAxNDtcbiAgICBpZiAoYiA8IDB4ODApIHJldHVybiB2YWw7XG4gICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTtcbiAgICB2YWwgfD0gKGIgJiAweDdmKSA8PCAyMTtcbiAgICBpZiAoYiA8IDB4ODApIHJldHVybiB2YWw7XG4gICAgYiA9IGJ1Zlt0aGlzLnBvc107XG4gICAgdmFsIHw9IChiICYgMHgwZikgPDwgMjg7XG4gICAgcmV0dXJuIHJlYWRWYXJpbnRSZW1haW5kZXIodmFsLCBpc1NpZ25lZCwgdGhpcyk7XG4gIH0sXG4gIHJlYWRWYXJpbnQ2NDogZnVuY3Rpb24gcmVhZFZhcmludDY0KCkge1xuICAgIC8vIGZvciBjb21wYXRpYmlsaXR5IHdpdGggdjIuMC4xXG4gICAgcmV0dXJuIHRoaXMucmVhZFZhcmludCh0cnVlKTtcbiAgfSxcbiAgcmVhZFNWYXJpbnQ6IGZ1bmN0aW9uIHJlYWRTVmFyaW50KCkge1xuICAgIHZhciBudW0gPSB0aGlzLnJlYWRWYXJpbnQoKTtcbiAgICByZXR1cm4gbnVtICUgMiA9PT0gMSA/IChudW0gKyAxKSAvIC0yIDogbnVtIC8gMjsgLy8gemlnemFnIGVuY29kaW5nXG4gIH0sXG4gIHJlYWRCb29sZWFuOiBmdW5jdGlvbiByZWFkQm9vbGVhbigpIHtcbiAgICByZXR1cm4gQm9vbGVhbih0aGlzLnJlYWRWYXJpbnQoKSk7XG4gIH0sXG4gIHJlYWRTdHJpbmc6IGZ1bmN0aW9uIHJlYWRTdHJpbmcoKSB7XG4gICAgdmFyIGVuZCA9IHRoaXMucmVhZFZhcmludCgpICsgdGhpcy5wb3M7XG4gICAgdmFyIHBvcyA9IHRoaXMucG9zO1xuICAgIHRoaXMucG9zID0gZW5kO1xuXG4gICAgaWYgKGVuZCAtIHBvcyA+PSBURVhUX0RFQ09ERVJfTUlOX0xFTkdUSCAmJiB1dGY4VGV4dERlY29kZXIpIHtcbiAgICAgIC8vIGxvbmdlciBzdHJpbmdzIGFyZSBmYXN0IHdpdGggdGhlIGJ1aWx0LWluIGJyb3dzZXIgVGV4dERlY29kZXIgQVBJXG4gICAgICByZXR1cm4gcmVhZFV0ZjhUZXh0RGVjb2Rlcih0aGlzLmJ1ZiwgcG9zLCBlbmQpO1xuICAgIH0gLy8gc2hvcnQgc3RyaW5ncyBhcmUgZmFzdCB3aXRoIG91ciBjdXN0b20gaW1wbGVtZW50YXRpb25cblxuXG4gICAgcmV0dXJuIHJlYWRVdGY4KHRoaXMuYnVmLCBwb3MsIGVuZCk7XG4gIH0sXG4gIHJlYWRCeXRlczogZnVuY3Rpb24gcmVhZEJ5dGVzKCkge1xuICAgIHZhciBlbmQgPSB0aGlzLnJlYWRWYXJpbnQoKSArIHRoaXMucG9zLFxuICAgICAgICBidWZmZXIgPSB0aGlzLmJ1Zi5zdWJhcnJheSh0aGlzLnBvcywgZW5kKTtcbiAgICB0aGlzLnBvcyA9IGVuZDtcbiAgICByZXR1cm4gYnVmZmVyO1xuICB9LFxuICAvLyB2ZXJib3NlIGZvciBwZXJmb3JtYW5jZSByZWFzb25zOyBkb2Vzbid0IGFmZmVjdCBnemlwcGVkIHNpemVcbiAgcmVhZFBhY2tlZFZhcmludDogZnVuY3Rpb24gcmVhZFBhY2tlZFZhcmludChhcnIsIGlzU2lnbmVkKSB7XG4gICAgaWYgKHRoaXMudHlwZSAhPT0gUGJmLkJ5dGVzKSByZXR1cm4gYXJyLnB1c2godGhpcy5yZWFkVmFyaW50KGlzU2lnbmVkKSk7XG4gICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgYXJyID0gYXJyIHx8IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICBhcnIucHVzaCh0aGlzLnJlYWRWYXJpbnQoaXNTaWduZWQpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXJyO1xuICB9LFxuICByZWFkUGFja2VkU1ZhcmludDogZnVuY3Rpb24gcmVhZFBhY2tlZFNWYXJpbnQoYXJyKSB7XG4gICAgaWYgKHRoaXMudHlwZSAhPT0gUGJmLkJ5dGVzKSByZXR1cm4gYXJyLnB1c2godGhpcy5yZWFkU1ZhcmludCgpKTtcbiAgICB2YXIgZW5kID0gcmVhZFBhY2tlZEVuZCh0aGlzKTtcbiAgICBhcnIgPSBhcnIgfHwgW107XG5cbiAgICB3aGlsZSAodGhpcy5wb3MgPCBlbmQpIHtcbiAgICAgIGFyci5wdXNoKHRoaXMucmVhZFNWYXJpbnQoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbiAgfSxcbiAgcmVhZFBhY2tlZEJvb2xlYW46IGZ1bmN0aW9uIHJlYWRQYWNrZWRCb29sZWFuKGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEJvb2xlYW4oKSk7XG4gICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgYXJyID0gYXJyIHx8IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICBhcnIucHVzaCh0aGlzLnJlYWRCb29sZWFuKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnI7XG4gIH0sXG4gIHJlYWRQYWNrZWRGbG9hdDogZnVuY3Rpb24gcmVhZFBhY2tlZEZsb2F0KGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEZsb2F0KCkpO1xuICAgIHZhciBlbmQgPSByZWFkUGFja2VkRW5kKHRoaXMpO1xuICAgIGFyciA9IGFyciB8fCBbXTtcblxuICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkge1xuICAgICAgYXJyLnB1c2godGhpcy5yZWFkRmxvYXQoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbiAgfSxcbiAgcmVhZFBhY2tlZERvdWJsZTogZnVuY3Rpb24gcmVhZFBhY2tlZERvdWJsZShhcnIpIHtcbiAgICBpZiAodGhpcy50eXBlICE9PSBQYmYuQnl0ZXMpIHJldHVybiBhcnIucHVzaCh0aGlzLnJlYWREb3VibGUoKSk7XG4gICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgYXJyID0gYXJyIHx8IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICBhcnIucHVzaCh0aGlzLnJlYWREb3VibGUoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbiAgfSxcbiAgcmVhZFBhY2tlZEZpeGVkMzI6IGZ1bmN0aW9uIHJlYWRQYWNrZWRGaXhlZDMyKGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEZpeGVkMzIoKSk7XG4gICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgYXJyID0gYXJyIHx8IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICBhcnIucHVzaCh0aGlzLnJlYWRGaXhlZDMyKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnI7XG4gIH0sXG4gIHJlYWRQYWNrZWRTRml4ZWQzMjogZnVuY3Rpb24gcmVhZFBhY2tlZFNGaXhlZDMyKGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZFNGaXhlZDMyKCkpO1xuICAgIHZhciBlbmQgPSByZWFkUGFja2VkRW5kKHRoaXMpO1xuICAgIGFyciA9IGFyciB8fCBbXTtcblxuICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkge1xuICAgICAgYXJyLnB1c2godGhpcy5yZWFkU0ZpeGVkMzIoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbiAgfSxcbiAgcmVhZFBhY2tlZEZpeGVkNjQ6IGZ1bmN0aW9uIHJlYWRQYWNrZWRGaXhlZDY0KGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEZpeGVkNjQoKSk7XG4gICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgYXJyID0gYXJyIHx8IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICBhcnIucHVzaCh0aGlzLnJlYWRGaXhlZDY0KCkpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnI7XG4gIH0sXG4gIHJlYWRQYWNrZWRTRml4ZWQ2NDogZnVuY3Rpb24gcmVhZFBhY2tlZFNGaXhlZDY0KGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZFNGaXhlZDY0KCkpO1xuICAgIHZhciBlbmQgPSByZWFkUGFja2VkRW5kKHRoaXMpO1xuICAgIGFyciA9IGFyciB8fCBbXTtcblxuICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkge1xuICAgICAgYXJyLnB1c2godGhpcy5yZWFkU0ZpeGVkNjQoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbiAgfSxcbiAgc2tpcDogZnVuY3Rpb24gc2tpcCh2YWwpIHtcbiAgICB2YXIgdHlwZSA9IHZhbCAmIDB4NztcbiAgICBpZiAodHlwZSA9PT0gUGJmLlZhcmludCkgd2hpbGUgKHRoaXMuYnVmW3RoaXMucG9zKytdID4gMHg3Zikge30gZWxzZSBpZiAodHlwZSA9PT0gUGJmLkJ5dGVzKSB0aGlzLnBvcyA9IHRoaXMucmVhZFZhcmludCgpICsgdGhpcy5wb3M7ZWxzZSBpZiAodHlwZSA9PT0gUGJmLkZpeGVkMzIpIHRoaXMucG9zICs9IDQ7ZWxzZSBpZiAodHlwZSA9PT0gUGJmLkZpeGVkNjQpIHRoaXMucG9zICs9IDg7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ1VuaW1wbGVtZW50ZWQgdHlwZTogJyArIHR5cGUpO1xuICB9LFxuICAvLyA9PT0gV1JJVElORyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB3cml0ZVRhZzogZnVuY3Rpb24gd3JpdGVUYWcodGFnLCB0eXBlKSB7XG4gICAgdGhpcy53cml0ZVZhcmludCh0YWcgPDwgMyB8IHR5cGUpO1xuICB9LFxuICByZWFsbG9jOiBmdW5jdGlvbiByZWFsbG9jKG1pbikge1xuICAgIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8fCAxNjtcblxuICAgIHdoaWxlIChsZW5ndGggPCB0aGlzLnBvcyArIG1pbikge1xuICAgICAgbGVuZ3RoICo9IDI7XG4gICAgfVxuXG4gICAgaWYgKGxlbmd0aCAhPT0gdGhpcy5sZW5ndGgpIHtcbiAgICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheShsZW5ndGgpO1xuICAgICAgYnVmLnNldCh0aGlzLmJ1Zik7XG4gICAgICB0aGlzLmJ1ZiA9IGJ1ZjtcbiAgICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoO1xuICAgIH1cbiAgfSxcbiAgZmluaXNoOiBmdW5jdGlvbiBmaW5pc2goKSB7XG4gICAgdGhpcy5sZW5ndGggPSB0aGlzLnBvcztcbiAgICB0aGlzLnBvcyA9IDA7XG4gICAgcmV0dXJuIHRoaXMuYnVmLnN1YmFycmF5KDAsIHRoaXMubGVuZ3RoKTtcbiAgfSxcbiAgd3JpdGVGaXhlZDMyOiBmdW5jdGlvbiB3cml0ZUZpeGVkMzIodmFsKSB7XG4gICAgdGhpcy5yZWFsbG9jKDQpO1xuICAgIHdyaXRlSW50MzIodGhpcy5idWYsIHZhbCwgdGhpcy5wb3MpO1xuICAgIHRoaXMucG9zICs9IDQ7XG4gIH0sXG4gIHdyaXRlU0ZpeGVkMzI6IGZ1bmN0aW9uIHdyaXRlU0ZpeGVkMzIodmFsKSB7XG4gICAgdGhpcy5yZWFsbG9jKDQpO1xuICAgIHdyaXRlSW50MzIodGhpcy5idWYsIHZhbCwgdGhpcy5wb3MpO1xuICAgIHRoaXMucG9zICs9IDQ7XG4gIH0sXG4gIHdyaXRlRml4ZWQ2NDogZnVuY3Rpb24gd3JpdGVGaXhlZDY0KHZhbCkge1xuICAgIHRoaXMucmVhbGxvYyg4KTtcbiAgICB3cml0ZUludDMyKHRoaXMuYnVmLCB2YWwgJiAtMSwgdGhpcy5wb3MpO1xuICAgIHdyaXRlSW50MzIodGhpcy5idWYsIE1hdGguZmxvb3IodmFsICogU0hJRlRfUklHSFRfMzIpLCB0aGlzLnBvcyArIDQpO1xuICAgIHRoaXMucG9zICs9IDg7XG4gIH0sXG4gIHdyaXRlU0ZpeGVkNjQ6IGZ1bmN0aW9uIHdyaXRlU0ZpeGVkNjQodmFsKSB7XG4gICAgdGhpcy5yZWFsbG9jKDgpO1xuICAgIHdyaXRlSW50MzIodGhpcy5idWYsIHZhbCAmIC0xLCB0aGlzLnBvcyk7XG4gICAgd3JpdGVJbnQzMih0aGlzLmJ1ZiwgTWF0aC5mbG9vcih2YWwgKiBTSElGVF9SSUdIVF8zMiksIHRoaXMucG9zICsgNCk7XG4gICAgdGhpcy5wb3MgKz0gODtcbiAgfSxcbiAgd3JpdGVWYXJpbnQ6IGZ1bmN0aW9uIHdyaXRlVmFyaW50KHZhbCkge1xuICAgIHZhbCA9ICt2YWwgfHwgMDtcblxuICAgIGlmICh2YWwgPiAweGZmZmZmZmYgfHwgdmFsIDwgMCkge1xuICAgICAgd3JpdGVCaWdWYXJpbnQodmFsLCB0aGlzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnJlYWxsb2MoNCk7XG4gICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSB2YWwgJiAweDdmIHwgKHZhbCA+IDB4N2YgPyAweDgwIDogMCk7XG4gICAgaWYgKHZhbCA8PSAweDdmKSByZXR1cm47XG4gICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSAodmFsID4+Pj0gNykgJiAweDdmIHwgKHZhbCA+IDB4N2YgPyAweDgwIDogMCk7XG4gICAgaWYgKHZhbCA8PSAweDdmKSByZXR1cm47XG4gICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSAodmFsID4+Pj0gNykgJiAweDdmIHwgKHZhbCA+IDB4N2YgPyAweDgwIDogMCk7XG4gICAgaWYgKHZhbCA8PSAweDdmKSByZXR1cm47XG4gICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSB2YWwgPj4+IDcgJiAweDdmO1xuICB9LFxuICB3cml0ZVNWYXJpbnQ6IGZ1bmN0aW9uIHdyaXRlU1ZhcmludCh2YWwpIHtcbiAgICB0aGlzLndyaXRlVmFyaW50KHZhbCA8IDAgPyAtdmFsICogMiAtIDEgOiB2YWwgKiAyKTtcbiAgfSxcbiAgd3JpdGVCb29sZWFuOiBmdW5jdGlvbiB3cml0ZUJvb2xlYW4odmFsKSB7XG4gICAgdGhpcy53cml0ZVZhcmludChCb29sZWFuKHZhbCkpO1xuICB9LFxuICB3cml0ZVN0cmluZzogZnVuY3Rpb24gd3JpdGVTdHJpbmcoc3RyKSB7XG4gICAgc3RyID0gU3RyaW5nKHN0cik7XG4gICAgdGhpcy5yZWFsbG9jKHN0ci5sZW5ndGggKiA0KTtcbiAgICB0aGlzLnBvcysrOyAvLyByZXNlcnZlIDEgYnl0ZSBmb3Igc2hvcnQgc3RyaW5nIGxlbmd0aFxuXG4gICAgdmFyIHN0YXJ0UG9zID0gdGhpcy5wb3M7IC8vIHdyaXRlIHRoZSBzdHJpbmcgZGlyZWN0bHkgdG8gdGhlIGJ1ZmZlciBhbmQgc2VlIGhvdyBtdWNoIHdhcyB3cml0dGVuXG5cbiAgICB0aGlzLnBvcyA9IHdyaXRlVXRmOCh0aGlzLmJ1Ziwgc3RyLCB0aGlzLnBvcyk7XG4gICAgdmFyIGxlbiA9IHRoaXMucG9zIC0gc3RhcnRQb3M7XG4gICAgaWYgKGxlbiA+PSAweDgwKSBtYWtlUm9vbUZvckV4dHJhTGVuZ3RoKHN0YXJ0UG9zLCBsZW4sIHRoaXMpOyAvLyBmaW5hbGx5LCB3cml0ZSB0aGUgbWVzc2FnZSBsZW5ndGggaW4gdGhlIHJlc2VydmVkIHBsYWNlIGFuZCByZXN0b3JlIHRoZSBwb3NpdGlvblxuXG4gICAgdGhpcy5wb3MgPSBzdGFydFBvcyAtIDE7XG4gICAgdGhpcy53cml0ZVZhcmludChsZW4pO1xuICAgIHRoaXMucG9zICs9IGxlbjtcbiAgfSxcbiAgd3JpdGVGbG9hdDogZnVuY3Rpb24gd3JpdGVGbG9hdCh2YWwpIHtcbiAgICB0aGlzLnJlYWxsb2MoNCk7XG4gICAgaWVlZTc1NC53cml0ZSh0aGlzLmJ1ZiwgdmFsLCB0aGlzLnBvcywgdHJ1ZSwgMjMsIDQpO1xuICAgIHRoaXMucG9zICs9IDQ7XG4gIH0sXG4gIHdyaXRlRG91YmxlOiBmdW5jdGlvbiB3cml0ZURvdWJsZSh2YWwpIHtcbiAgICB0aGlzLnJlYWxsb2MoOCk7XG4gICAgaWVlZTc1NC53cml0ZSh0aGlzLmJ1ZiwgdmFsLCB0aGlzLnBvcywgdHJ1ZSwgNTIsIDgpO1xuICAgIHRoaXMucG9zICs9IDg7XG4gIH0sXG4gIHdyaXRlQnl0ZXM6IGZ1bmN0aW9uIHdyaXRlQnl0ZXMoYnVmZmVyKSB7XG4gICAgdmFyIGxlbiA9IGJ1ZmZlci5sZW5ndGg7XG4gICAgdGhpcy53cml0ZVZhcmludChsZW4pO1xuICAgIHRoaXMucmVhbGxvYyhsZW4pO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSBidWZmZXJbaV07XG4gICAgfVxuICB9LFxuICB3cml0ZVJhd01lc3NhZ2U6IGZ1bmN0aW9uIHdyaXRlUmF3TWVzc2FnZShmbiwgb2JqKSB7XG4gICAgdGhpcy5wb3MrKzsgLy8gcmVzZXJ2ZSAxIGJ5dGUgZm9yIHNob3J0IG1lc3NhZ2UgbGVuZ3RoXG4gICAgLy8gd3JpdGUgdGhlIG1lc3NhZ2UgZGlyZWN0bHkgdG8gdGhlIGJ1ZmZlciBhbmQgc2VlIGhvdyBtdWNoIHdhcyB3cml0dGVuXG5cbiAgICB2YXIgc3RhcnRQb3MgPSB0aGlzLnBvcztcbiAgICBmbihvYmosIHRoaXMpO1xuICAgIHZhciBsZW4gPSB0aGlzLnBvcyAtIHN0YXJ0UG9zO1xuICAgIGlmIChsZW4gPj0gMHg4MCkgbWFrZVJvb21Gb3JFeHRyYUxlbmd0aChzdGFydFBvcywgbGVuLCB0aGlzKTsgLy8gZmluYWxseSwgd3JpdGUgdGhlIG1lc3NhZ2UgbGVuZ3RoIGluIHRoZSByZXNlcnZlZCBwbGFjZSBhbmQgcmVzdG9yZSB0aGUgcG9zaXRpb25cblxuICAgIHRoaXMucG9zID0gc3RhcnRQb3MgLSAxO1xuICAgIHRoaXMud3JpdGVWYXJpbnQobGVuKTtcbiAgICB0aGlzLnBvcyArPSBsZW47XG4gIH0sXG4gIHdyaXRlTWVzc2FnZTogZnVuY3Rpb24gd3JpdGVNZXNzYWdlKHRhZywgZm4sIG9iaikge1xuICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgIHRoaXMud3JpdGVSYXdNZXNzYWdlKGZuLCBvYmopO1xuICB9LFxuICB3cml0ZVBhY2tlZFZhcmludDogZnVuY3Rpb24gd3JpdGVQYWNrZWRWYXJpbnQodGFnLCBhcnIpIHtcbiAgICBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCBfd3JpdGVQYWNrZWRWYXJpbnQsIGFycik7XG4gIH0sXG4gIHdyaXRlUGFja2VkU1ZhcmludDogZnVuY3Rpb24gd3JpdGVQYWNrZWRTVmFyaW50KHRhZywgYXJyKSB7XG4gICAgaWYgKGFyci5sZW5ndGgpIHRoaXMud3JpdGVNZXNzYWdlKHRhZywgX3dyaXRlUGFja2VkU1ZhcmludCwgYXJyKTtcbiAgfSxcbiAgd3JpdGVQYWNrZWRCb29sZWFuOiBmdW5jdGlvbiB3cml0ZVBhY2tlZEJvb2xlYW4odGFnLCBhcnIpIHtcbiAgICBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCBfd3JpdGVQYWNrZWRCb29sZWFuLCBhcnIpO1xuICB9LFxuICB3cml0ZVBhY2tlZEZsb2F0OiBmdW5jdGlvbiB3cml0ZVBhY2tlZEZsb2F0KHRhZywgYXJyKSB7XG4gICAgaWYgKGFyci5sZW5ndGgpIHRoaXMud3JpdGVNZXNzYWdlKHRhZywgX3dyaXRlUGFja2VkRmxvYXQsIGFycik7XG4gIH0sXG4gIHdyaXRlUGFja2VkRG91YmxlOiBmdW5jdGlvbiB3cml0ZVBhY2tlZERvdWJsZSh0YWcsIGFycikge1xuICAgIGlmIChhcnIubGVuZ3RoKSB0aGlzLndyaXRlTWVzc2FnZSh0YWcsIF93cml0ZVBhY2tlZERvdWJsZSwgYXJyKTtcbiAgfSxcbiAgd3JpdGVQYWNrZWRGaXhlZDMyOiBmdW5jdGlvbiB3cml0ZVBhY2tlZEZpeGVkMzIodGFnLCBhcnIpIHtcbiAgICBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCBfd3JpdGVQYWNrZWRGaXhlZCwgYXJyKTtcbiAgfSxcbiAgd3JpdGVQYWNrZWRTRml4ZWQzMjogZnVuY3Rpb24gd3JpdGVQYWNrZWRTRml4ZWQzMih0YWcsIGFycikge1xuICAgIGlmIChhcnIubGVuZ3RoKSB0aGlzLndyaXRlTWVzc2FnZSh0YWcsIF93cml0ZVBhY2tlZFNGaXhlZCwgYXJyKTtcbiAgfSxcbiAgd3JpdGVQYWNrZWRGaXhlZDY0OiBmdW5jdGlvbiB3cml0ZVBhY2tlZEZpeGVkNjQodGFnLCBhcnIpIHtcbiAgICBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCBfd3JpdGVQYWNrZWRGaXhlZDIsIGFycik7XG4gIH0sXG4gIHdyaXRlUGFja2VkU0ZpeGVkNjQ6IGZ1bmN0aW9uIHdyaXRlUGFja2VkU0ZpeGVkNjQodGFnLCBhcnIpIHtcbiAgICBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCBfd3JpdGVQYWNrZWRTRml4ZWQyLCBhcnIpO1xuICB9LFxuICB3cml0ZUJ5dGVzRmllbGQ6IGZ1bmN0aW9uIHdyaXRlQnl0ZXNGaWVsZCh0YWcsIGJ1ZmZlcikge1xuICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgIHRoaXMud3JpdGVCeXRlcyhidWZmZXIpO1xuICB9LFxuICB3cml0ZUZpeGVkMzJGaWVsZDogZnVuY3Rpb24gd3JpdGVGaXhlZDMyRmllbGQodGFnLCB2YWwpIHtcbiAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkMzIpO1xuICAgIHRoaXMud3JpdGVGaXhlZDMyKHZhbCk7XG4gIH0sXG4gIHdyaXRlU0ZpeGVkMzJGaWVsZDogZnVuY3Rpb24gd3JpdGVTRml4ZWQzMkZpZWxkKHRhZywgdmFsKSB7XG4gICAgdGhpcy53cml0ZVRhZyh0YWcsIFBiZi5GaXhlZDMyKTtcbiAgICB0aGlzLndyaXRlU0ZpeGVkMzIodmFsKTtcbiAgfSxcbiAgd3JpdGVGaXhlZDY0RmllbGQ6IGZ1bmN0aW9uIHdyaXRlRml4ZWQ2NEZpZWxkKHRhZywgdmFsKSB7XG4gICAgdGhpcy53cml0ZVRhZyh0YWcsIFBiZi5GaXhlZDY0KTtcbiAgICB0aGlzLndyaXRlRml4ZWQ2NCh2YWwpO1xuICB9LFxuICB3cml0ZVNGaXhlZDY0RmllbGQ6IGZ1bmN0aW9uIHdyaXRlU0ZpeGVkNjRGaWVsZCh0YWcsIHZhbCkge1xuICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuRml4ZWQ2NCk7XG4gICAgdGhpcy53cml0ZVNGaXhlZDY0KHZhbCk7XG4gIH0sXG4gIHdyaXRlVmFyaW50RmllbGQ6IGZ1bmN0aW9uIHdyaXRlVmFyaW50RmllbGQodGFnLCB2YWwpIHtcbiAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLlZhcmludCk7XG4gICAgdGhpcy53cml0ZVZhcmludCh2YWwpO1xuICB9LFxuICB3cml0ZVNWYXJpbnRGaWVsZDogZnVuY3Rpb24gd3JpdGVTVmFyaW50RmllbGQodGFnLCB2YWwpIHtcbiAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLlZhcmludCk7XG4gICAgdGhpcy53cml0ZVNWYXJpbnQodmFsKTtcbiAgfSxcbiAgd3JpdGVTdHJpbmdGaWVsZDogZnVuY3Rpb24gd3JpdGVTdHJpbmdGaWVsZCh0YWcsIHN0cikge1xuICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgIHRoaXMud3JpdGVTdHJpbmcoc3RyKTtcbiAgfSxcbiAgd3JpdGVGbG9hdEZpZWxkOiBmdW5jdGlvbiB3cml0ZUZsb2F0RmllbGQodGFnLCB2YWwpIHtcbiAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkMzIpO1xuICAgIHRoaXMud3JpdGVGbG9hdCh2YWwpO1xuICB9LFxuICB3cml0ZURvdWJsZUZpZWxkOiBmdW5jdGlvbiB3cml0ZURvdWJsZUZpZWxkKHRhZywgdmFsKSB7XG4gICAgdGhpcy53cml0ZVRhZyh0YWcsIFBiZi5GaXhlZDY0KTtcbiAgICB0aGlzLndyaXRlRG91YmxlKHZhbCk7XG4gIH0sXG4gIHdyaXRlQm9vbGVhbkZpZWxkOiBmdW5jdGlvbiB3cml0ZUJvb2xlYW5GaWVsZCh0YWcsIHZhbCkge1xuICAgIHRoaXMud3JpdGVWYXJpbnRGaWVsZCh0YWcsIEJvb2xlYW4odmFsKSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHJlYWRWYXJpbnRSZW1haW5kZXIobCwgcywgcCkge1xuICB2YXIgYnVmID0gcC5idWYsXG4gICAgICBoLFxuICAgICAgYjtcbiAgYiA9IGJ1ZltwLnBvcysrXTtcbiAgaCA9IChiICYgMHg3MCkgPj4gNDtcbiAgaWYgKGIgPCAweDgwKSByZXR1cm4gdG9OdW0obCwgaCwgcyk7XG4gIGIgPSBidWZbcC5wb3MrK107XG4gIGggfD0gKGIgJiAweDdmKSA8PCAzO1xuICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgYiA9IGJ1ZltwLnBvcysrXTtcbiAgaCB8PSAoYiAmIDB4N2YpIDw8IDEwO1xuICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgYiA9IGJ1ZltwLnBvcysrXTtcbiAgaCB8PSAoYiAmIDB4N2YpIDw8IDE3O1xuICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgYiA9IGJ1ZltwLnBvcysrXTtcbiAgaCB8PSAoYiAmIDB4N2YpIDw8IDI0O1xuICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgYiA9IGJ1ZltwLnBvcysrXTtcbiAgaCB8PSAoYiAmIDB4MDEpIDw8IDMxO1xuICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCB2YXJpbnQgbm90IG1vcmUgdGhhbiAxMCBieXRlcycpO1xufVxuXG5mdW5jdGlvbiByZWFkUGFja2VkRW5kKHBiZikge1xuICByZXR1cm4gcGJmLnR5cGUgPT09IFBiZi5CeXRlcyA/IHBiZi5yZWFkVmFyaW50KCkgKyBwYmYucG9zIDogcGJmLnBvcyArIDE7XG59XG5cbmZ1bmN0aW9uIHRvTnVtKGxvdywgaGlnaCwgaXNTaWduZWQpIHtcbiAgaWYgKGlzU2lnbmVkKSB7XG4gICAgcmV0dXJuIGhpZ2ggKiAweDEwMDAwMDAwMCArIChsb3cgPj4+IDApO1xuICB9XG5cbiAgcmV0dXJuIChoaWdoID4+PiAwKSAqIDB4MTAwMDAwMDAwICsgKGxvdyA+Pj4gMCk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmlnVmFyaW50KHZhbCwgcGJmKSB7XG4gIHZhciBsb3csIGhpZ2g7XG5cbiAgaWYgKHZhbCA+PSAwKSB7XG4gICAgbG93ID0gdmFsICUgMHgxMDAwMDAwMDAgfCAwO1xuICAgIGhpZ2ggPSB2YWwgLyAweDEwMDAwMDAwMCB8IDA7XG4gIH0gZWxzZSB7XG4gICAgbG93ID0gfigtdmFsICUgMHgxMDAwMDAwMDApO1xuICAgIGhpZ2ggPSB+KC12YWwgLyAweDEwMDAwMDAwMCk7XG5cbiAgICBpZiAobG93IF4gMHhmZmZmZmZmZikge1xuICAgICAgbG93ID0gbG93ICsgMSB8IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvdyA9IDA7XG4gICAgICBoaWdoID0gaGlnaCArIDEgfCAwO1xuICAgIH1cbiAgfVxuXG4gIGlmICh2YWwgPj0gMHgxMDAwMDAwMDAwMDAwMDAwMCB8fCB2YWwgPCAtMHgxMDAwMDAwMDAwMDAwMDAwMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignR2l2ZW4gdmFyaW50IGRvZXNuXFwndCBmaXQgaW50byAxMCBieXRlcycpO1xuICB9XG5cbiAgcGJmLnJlYWxsb2MoMTApO1xuICB3cml0ZUJpZ1ZhcmludExvdyhsb3csIGhpZ2gsIHBiZik7XG4gIHdyaXRlQmlnVmFyaW50SGlnaChoaWdoLCBwYmYpO1xufVxuXG5mdW5jdGlvbiB3cml0ZUJpZ1ZhcmludExvdyhsb3csIGhpZ2gsIHBiZikge1xuICBwYmYuYnVmW3BiZi5wb3MrK10gPSBsb3cgJiAweDdmIHwgMHg4MDtcbiAgbG93ID4+Pj0gNztcbiAgcGJmLmJ1ZltwYmYucG9zKytdID0gbG93ICYgMHg3ZiB8IDB4ODA7XG4gIGxvdyA+Pj49IDc7XG4gIHBiZi5idWZbcGJmLnBvcysrXSA9IGxvdyAmIDB4N2YgfCAweDgwO1xuICBsb3cgPj4+PSA3O1xuICBwYmYuYnVmW3BiZi5wb3MrK10gPSBsb3cgJiAweDdmIHwgMHg4MDtcbiAgbG93ID4+Pj0gNztcbiAgcGJmLmJ1ZltwYmYucG9zXSA9IGxvdyAmIDB4N2Y7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmlnVmFyaW50SGlnaChoaWdoLCBwYmYpIHtcbiAgdmFyIGxzYiA9IChoaWdoICYgMHgwNykgPDwgNDtcbiAgcGJmLmJ1ZltwYmYucG9zKytdIHw9IGxzYiB8ICgoaGlnaCA+Pj49IDMpID8gMHg4MCA6IDApO1xuICBpZiAoIWhpZ2gpIHJldHVybjtcbiAgcGJmLmJ1ZltwYmYucG9zKytdID0gaGlnaCAmIDB4N2YgfCAoKGhpZ2ggPj4+PSA3KSA/IDB4ODAgOiAwKTtcbiAgaWYgKCFoaWdoKSByZXR1cm47XG4gIHBiZi5idWZbcGJmLnBvcysrXSA9IGhpZ2ggJiAweDdmIHwgKChoaWdoID4+Pj0gNykgPyAweDgwIDogMCk7XG4gIGlmICghaGlnaCkgcmV0dXJuO1xuICBwYmYuYnVmW3BiZi5wb3MrK10gPSBoaWdoICYgMHg3ZiB8ICgoaGlnaCA+Pj49IDcpID8gMHg4MCA6IDApO1xuICBpZiAoIWhpZ2gpIHJldHVybjtcbiAgcGJmLmJ1ZltwYmYucG9zKytdID0gaGlnaCAmIDB4N2YgfCAoKGhpZ2ggPj4+PSA3KSA/IDB4ODAgOiAwKTtcbiAgaWYgKCFoaWdoKSByZXR1cm47XG4gIHBiZi5idWZbcGJmLnBvcysrXSA9IGhpZ2ggJiAweDdmO1xufVxuXG5mdW5jdGlvbiBtYWtlUm9vbUZvckV4dHJhTGVuZ3RoKHN0YXJ0UG9zLCBsZW4sIHBiZikge1xuICB2YXIgZXh0cmFMZW4gPSBsZW4gPD0gMHgzZmZmID8gMSA6IGxlbiA8PSAweDFmZmZmZiA/IDIgOiBsZW4gPD0gMHhmZmZmZmZmID8gMyA6IE1hdGguZmxvb3IoTWF0aC5sb2cobGVuKSAvIChNYXRoLkxOMiAqIDcpKTsgLy8gaWYgMSBieXRlIGlzbid0IGVub3VnaCBmb3IgZW5jb2RpbmcgbWVzc2FnZSBsZW5ndGgsIHNoaWZ0IHRoZSBkYXRhIHRvIHRoZSByaWdodFxuXG4gIHBiZi5yZWFsbG9jKGV4dHJhTGVuKTtcblxuICBmb3IgKHZhciBpID0gcGJmLnBvcyAtIDE7IGkgPj0gc3RhcnRQb3M7IGktLSkge1xuICAgIHBiZi5idWZbaSArIGV4dHJhTGVuXSA9IHBiZi5idWZbaV07XG4gIH1cbn1cblxuZnVuY3Rpb24gX3dyaXRlUGFja2VkVmFyaW50KGFyciwgcGJmKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgcGJmLndyaXRlVmFyaW50KGFycltpXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX3dyaXRlUGFja2VkU1ZhcmludChhcnIsIHBiZikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZVNWYXJpbnQoYXJyW2ldKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfd3JpdGVQYWNrZWRGbG9hdChhcnIsIHBiZikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZUZsb2F0KGFycltpXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX3dyaXRlUGFja2VkRG91YmxlKGFyciwgcGJmKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgcGJmLndyaXRlRG91YmxlKGFycltpXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX3dyaXRlUGFja2VkQm9vbGVhbihhcnIsIHBiZikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZUJvb2xlYW4oYXJyW2ldKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfd3JpdGVQYWNrZWRGaXhlZChhcnIsIHBiZikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZUZpeGVkMzIoYXJyW2ldKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfd3JpdGVQYWNrZWRTRml4ZWQoYXJyLCBwYmYpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICBwYmYud3JpdGVTRml4ZWQzMihhcnJbaV0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIF93cml0ZVBhY2tlZEZpeGVkMihhcnIsIHBiZikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZUZpeGVkNjQoYXJyW2ldKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfd3JpdGVQYWNrZWRTRml4ZWQyKGFyciwgcGJmKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgcGJmLndyaXRlU0ZpeGVkNjQoYXJyW2ldKTtcbiAgfVxufSAvLyBCdWZmZXIgY29kZSBiZWxvdyBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyLCBNSVQtbGljZW5zZWRcblxuXG5mdW5jdGlvbiByZWFkVUludDMyKGJ1ZiwgcG9zKSB7XG4gIHJldHVybiAoYnVmW3Bvc10gfCBidWZbcG9zICsgMV0gPDwgOCB8IGJ1Zltwb3MgKyAyXSA8PCAxNikgKyBidWZbcG9zICsgM10gKiAweDEwMDAwMDA7XG59XG5cbmZ1bmN0aW9uIHdyaXRlSW50MzIoYnVmLCB2YWwsIHBvcykge1xuICBidWZbcG9zXSA9IHZhbDtcbiAgYnVmW3BvcyArIDFdID0gdmFsID4+PiA4O1xuICBidWZbcG9zICsgMl0gPSB2YWwgPj4+IDE2O1xuICBidWZbcG9zICsgM10gPSB2YWwgPj4+IDI0O1xufVxuXG5mdW5jdGlvbiByZWFkSW50MzIoYnVmLCBwb3MpIHtcbiAgcmV0dXJuIChidWZbcG9zXSB8IGJ1Zltwb3MgKyAxXSA8PCA4IHwgYnVmW3BvcyArIDJdIDw8IDE2KSArIChidWZbcG9zICsgM10gPDwgMjQpO1xufVxuXG5mdW5jdGlvbiByZWFkVXRmOChidWYsIHBvcywgZW5kKSB7XG4gIHZhciBzdHIgPSAnJztcbiAgdmFyIGkgPSBwb3M7XG5cbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgYjAgPSBidWZbaV07XG4gICAgdmFyIGMgPSBudWxsOyAvLyBjb2RlcG9pbnRcblxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gYjAgPiAweEVGID8gNCA6IGIwID4gMHhERiA/IDMgOiBiMCA+IDB4QkYgPyAyIDogMTtcbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPiBlbmQpIGJyZWFrO1xuICAgIHZhciBiMSwgYjIsIGIzO1xuXG4gICAgaWYgKGJ5dGVzUGVyU2VxdWVuY2UgPT09IDEpIHtcbiAgICAgIGlmIChiMCA8IDB4ODApIHtcbiAgICAgICAgYyA9IGIwO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYnl0ZXNQZXJTZXF1ZW5jZSA9PT0gMikge1xuICAgICAgYjEgPSBidWZbaSArIDFdO1xuXG4gICAgICBpZiAoKGIxICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgYyA9IChiMCAmIDB4MUYpIDw8IDB4NiB8IGIxICYgMHgzRjtcblxuICAgICAgICBpZiAoYyA8PSAweDdGKSB7XG4gICAgICAgICAgYyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGJ5dGVzUGVyU2VxdWVuY2UgPT09IDMpIHtcbiAgICAgIGIxID0gYnVmW2kgKyAxXTtcbiAgICAgIGIyID0gYnVmW2kgKyAyXTtcblxuICAgICAgaWYgKChiMSAmIDB4QzApID09PSAweDgwICYmIChiMiAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgIGMgPSAoYjAgJiAweEYpIDw8IDB4QyB8IChiMSAmIDB4M0YpIDw8IDB4NiB8IGIyICYgMHgzRjtcblxuICAgICAgICBpZiAoYyA8PSAweDdGRiB8fCBjID49IDB4RDgwMCAmJiBjIDw9IDB4REZGRikge1xuICAgICAgICAgIGMgPSBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChieXRlc1BlclNlcXVlbmNlID09PSA0KSB7XG4gICAgICBiMSA9IGJ1ZltpICsgMV07XG4gICAgICBiMiA9IGJ1ZltpICsgMl07XG4gICAgICBiMyA9IGJ1ZltpICsgM107XG5cbiAgICAgIGlmICgoYjEgJiAweEMwKSA9PT0gMHg4MCAmJiAoYjIgJiAweEMwKSA9PT0gMHg4MCAmJiAoYjMgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICBjID0gKGIwICYgMHhGKSA8PCAweDEyIHwgKGIxICYgMHgzRikgPDwgMHhDIHwgKGIyICYgMHgzRikgPDwgMHg2IHwgYjMgJiAweDNGO1xuXG4gICAgICAgIGlmIChjIDw9IDB4RkZGRiB8fCBjID49IDB4MTEwMDAwKSB7XG4gICAgICAgICAgYyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYyA9PT0gbnVsbCkge1xuICAgICAgYyA9IDB4RkZGRDtcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxO1xuICAgIH0gZWxzZSBpZiAoYyA+IDB4RkZGRikge1xuICAgICAgYyAtPSAweDEwMDAwO1xuICAgICAgc3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMCk7XG4gICAgICBjID0gMHhEQzAwIHwgYyAmIDB4M0ZGO1xuICAgIH1cblxuICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZTtcbiAgfVxuXG4gIHJldHVybiBzdHI7XG59XG5cbmZ1bmN0aW9uIHJlYWRVdGY4VGV4dERlY29kZXIoYnVmLCBwb3MsIGVuZCkge1xuICByZXR1cm4gdXRmOFRleHREZWNvZGVyLmRlY29kZShidWYuc3ViYXJyYXkocG9zLCBlbmQpKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVVdGY4KGJ1Ziwgc3RyLCBwb3MpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGMsIGxlYWQ7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSk7IC8vIGNvZGUgcG9pbnRcblxuICAgIGlmIChjID4gMHhEN0ZGICYmIGMgPCAweEUwMDApIHtcbiAgICAgIGlmIChsZWFkKSB7XG4gICAgICAgIGlmIChjIDwgMHhEQzAwKSB7XG4gICAgICAgICAgYnVmW3BvcysrXSA9IDB4RUY7XG4gICAgICAgICAgYnVmW3BvcysrXSA9IDB4QkY7XG4gICAgICAgICAgYnVmW3BvcysrXSA9IDB4QkQ7XG4gICAgICAgICAgbGVhZCA9IGM7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYyA9IGxlYWQgLSAweEQ4MDAgPDwgMTAgfCBjIC0gMHhEQzAwIHwgMHgxMDAwMDtcbiAgICAgICAgICBsZWFkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGMgPiAweERCRkYgfHwgaSArIDEgPT09IHN0ci5sZW5ndGgpIHtcbiAgICAgICAgICBidWZbcG9zKytdID0gMHhFRjtcbiAgICAgICAgICBidWZbcG9zKytdID0gMHhCRjtcbiAgICAgICAgICBidWZbcG9zKytdID0gMHhCRDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsZWFkID0gYztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobGVhZCkge1xuICAgICAgYnVmW3BvcysrXSA9IDB4RUY7XG4gICAgICBidWZbcG9zKytdID0gMHhCRjtcbiAgICAgIGJ1Zltwb3MrK10gPSAweEJEO1xuICAgICAgbGVhZCA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGMgPCAweDgwKSB7XG4gICAgICBidWZbcG9zKytdID0gYztcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGMgPCAweDgwMCkge1xuICAgICAgICBidWZbcG9zKytdID0gYyA+PiAweDYgfCAweEMwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGMgPCAweDEwMDAwKSB7XG4gICAgICAgICAgYnVmW3BvcysrXSA9IGMgPj4gMHhDIHwgMHhFMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBidWZbcG9zKytdID0gYyA+PiAweDEyIHwgMHhGMDtcbiAgICAgICAgICBidWZbcG9zKytdID0gYyA+PiAweEMgJiAweDNGIHwgMHg4MDtcbiAgICAgICAgfVxuXG4gICAgICAgIGJ1Zltwb3MrK10gPSBjID4+IDB4NiAmIDB4M0YgfCAweDgwO1xuICAgICAgfVxuXG4gICAgICBidWZbcG9zKytdID0gYyAmIDB4M0YgfCAweDgwO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwb3M7XG59Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4362\n")},5792:function(module){eval('!function (t, i) {\n true ? module.exports = i() : 0;\n}(this, function () {\n "use strict";\n\n function t(t, r, e, a, h) {\n !function t(n, r, e, a, h) {\n for (; a > e;) {\n if (a - e > 600) {\n var o = a - e + 1,\n s = r - e + 1,\n l = Math.log(o),\n f = .5 * Math.exp(2 * l / 3),\n u = .5 * Math.sqrt(l * f * (o - f) / o) * (s - o / 2 < 0 ? -1 : 1),\n m = Math.max(e, Math.floor(r - s * f / o + u)),\n c = Math.min(a, Math.floor(r + (o - s) * f / o + u));\n t(n, r, m, c, h);\n }\n\n var p = n[r],\n d = e,\n x = a;\n\n for (i(n, e, r), h(n[a], p) > 0 && i(n, e, a); d < x;) {\n for (i(n, d, x), d++, x--; h(n[d], p) < 0;) {\n d++;\n }\n\n for (; h(n[x], p) > 0;) {\n x--;\n }\n }\n\n 0 === h(n[e], p) ? i(n, e, x) : i(n, ++x, a), x <= r && (e = x + 1), r <= x && (a = x - 1);\n }\n }(t, r, e || 0, a || t.length - 1, h || n);\n }\n\n function i(t, i, n) {\n var r = t[i];\n t[i] = t[n], t[n] = r;\n }\n\n function n(t, i) {\n return t < i ? -1 : t > i ? 1 : 0;\n }\n\n var r = function r(t) {\n void 0 === t && (t = 9), this._maxEntries = Math.max(4, t), this._minEntries = Math.max(2, Math.ceil(.4 * this._maxEntries)), this.clear();\n };\n\n function e(t, i, n) {\n if (!n) return i.indexOf(t);\n\n for (var r = 0; r < i.length; r++) {\n if (n(t, i[r])) return r;\n }\n\n return -1;\n }\n\n function a(t, i) {\n h(t, 0, t.children.length, i, t);\n }\n\n function h(t, i, n, r, e) {\n e || (e = p(null)), e.minX = 1 / 0, e.minY = 1 / 0, e.maxX = -1 / 0, e.maxY = -1 / 0;\n\n for (var a = i; a < n; a++) {\n var h = t.children[a];\n o(e, t.leaf ? r(h) : h);\n }\n\n return e;\n }\n\n function o(t, i) {\n return t.minX = Math.min(t.minX, i.minX), t.minY = Math.min(t.minY, i.minY), t.maxX = Math.max(t.maxX, i.maxX), t.maxY = Math.max(t.maxY, i.maxY), t;\n }\n\n function s(t, i) {\n return t.minX - i.minX;\n }\n\n function l(t, i) {\n return t.minY - i.minY;\n }\n\n function f(t) {\n return (t.maxX - t.minX) * (t.maxY - t.minY);\n }\n\n function u(t) {\n return t.maxX - t.minX + (t.maxY - t.minY);\n }\n\n function m(t, i) {\n return t.minX <= i.minX && t.minY <= i.minY && i.maxX <= t.maxX && i.maxY <= t.maxY;\n }\n\n function c(t, i) {\n return i.minX <= t.maxX && i.minY <= t.maxY && i.maxX >= t.minX && i.maxY >= t.minY;\n }\n\n function p(t) {\n return {\n children: t,\n height: 1,\n leaf: !0,\n minX: 1 / 0,\n minY: 1 / 0,\n maxX: -1 / 0,\n maxY: -1 / 0\n };\n }\n\n function d(i, n, r, e, a) {\n for (var h = [n, r]; h.length;) {\n if (!((r = h.pop()) - (n = h.pop()) <= e)) {\n var o = n + Math.ceil((r - n) / e / 2) * e;\n t(i, o, n, r, a), h.push(n, o, o, r);\n }\n }\n }\n\n return r.prototype.all = function () {\n return this._all(this.data, []);\n }, r.prototype.search = function (t) {\n var i = this.data,\n n = [];\n if (!c(t, i)) return n;\n\n for (var r = this.toBBox, e = []; i;) {\n for (var a = 0; a < i.children.length; a++) {\n var h = i.children[a],\n o = i.leaf ? r(h) : h;\n c(t, o) && (i.leaf ? n.push(h) : m(t, o) ? this._all(h, n) : e.push(h));\n }\n\n i = e.pop();\n }\n\n return n;\n }, r.prototype.collides = function (t) {\n var i = this.data;\n if (!c(t, i)) return !1;\n\n for (var n = []; i;) {\n for (var r = 0; r < i.children.length; r++) {\n var e = i.children[r],\n a = i.leaf ? this.toBBox(e) : e;\n\n if (c(t, a)) {\n if (i.leaf || m(t, a)) return !0;\n n.push(e);\n }\n }\n\n i = n.pop();\n }\n\n return !1;\n }, r.prototype.load = function (t) {\n if (!t || !t.length) return this;\n\n if (t.length < this._minEntries) {\n for (var i = 0; i < t.length; i++) {\n this.insert(t[i]);\n }\n\n return this;\n }\n\n var n = this._build(t.slice(), 0, t.length - 1, 0);\n\n if (this.data.children.length) {\n if (this.data.height === n.height) this._splitRoot(this.data, n);else {\n if (this.data.height < n.height) {\n var r = this.data;\n this.data = n, n = r;\n }\n\n this._insert(n, this.data.height - n.height - 1, !0);\n }\n } else this.data = n;\n return this;\n }, r.prototype.insert = function (t) {\n return t && this._insert(t, this.data.height - 1), this;\n }, r.prototype.clear = function () {\n return this.data = p([]), this;\n }, r.prototype.remove = function (t, i) {\n if (!t) return this;\n\n for (var n, r, a, h = this.data, o = this.toBBox(t), s = [], l = []; h || s.length;) {\n if (h || (h = s.pop(), r = s[s.length - 1], n = l.pop(), a = !0), h.leaf) {\n var f = e(t, h.children, i);\n if (-1 !== f) return h.children.splice(f, 1), s.push(h), this._condense(s), this;\n }\n\n a || h.leaf || !m(h, o) ? r ? (n++, h = r.children[n], a = !1) : h = null : (s.push(h), l.push(n), n = 0, r = h, h = h.children[0]);\n }\n\n return this;\n }, r.prototype.toBBox = function (t) {\n return t;\n }, r.prototype.compareMinX = function (t, i) {\n return t.minX - i.minX;\n }, r.prototype.compareMinY = function (t, i) {\n return t.minY - i.minY;\n }, r.prototype.toJSON = function () {\n return this.data;\n }, r.prototype.fromJSON = function (t) {\n return this.data = t, this;\n }, r.prototype._all = function (t, i) {\n for (var n = []; t;) {\n t.leaf ? i.push.apply(i, t.children) : n.push.apply(n, t.children), t = n.pop();\n }\n\n return i;\n }, r.prototype._build = function (t, i, n, r) {\n var e,\n h = n - i + 1,\n o = this._maxEntries;\n if (h <= o) return a(e = p(t.slice(i, n + 1)), this.toBBox), e;\n r || (r = Math.ceil(Math.log(h) / Math.log(o)), o = Math.ceil(h / Math.pow(o, r - 1))), (e = p([])).leaf = !1, e.height = r;\n var s = Math.ceil(h / o),\n l = s * Math.ceil(Math.sqrt(o));\n d(t, i, n, l, this.compareMinX);\n\n for (var f = i; f <= n; f += l) {\n var u = Math.min(f + l - 1, n);\n d(t, f, u, s, this.compareMinY);\n\n for (var m = f; m <= u; m += s) {\n var c = Math.min(m + s - 1, u);\n e.children.push(this._build(t, m, c, r - 1));\n }\n }\n\n return a(e, this.toBBox), e;\n }, r.prototype._chooseSubtree = function (t, i, n, r) {\n for (; r.push(i), !i.leaf && r.length - 1 !== n;) {\n for (var e = 1 / 0, a = 1 / 0, h = void 0, o = 0; o < i.children.length; o++) {\n var s = i.children[o],\n l = f(s),\n u = (m = t, c = s, (Math.max(c.maxX, m.maxX) - Math.min(c.minX, m.minX)) * (Math.max(c.maxY, m.maxY) - Math.min(c.minY, m.minY)) - l);\n u < a ? (a = u, e = l < e ? l : e, h = s) : u === a && l < e && (e = l, h = s);\n }\n\n i = h || i.children[0];\n }\n\n var m, c;\n return i;\n }, r.prototype._insert = function (t, i, n) {\n var r = n ? t : this.toBBox(t),\n e = [],\n a = this._chooseSubtree(r, this.data, i, e);\n\n for (a.children.push(t), o(a, r); i >= 0 && e[i].children.length > this._maxEntries;) {\n this._split(e, i), i--;\n }\n\n this._adjustParentBBoxes(r, e, i);\n }, r.prototype._split = function (t, i) {\n var n = t[i],\n r = n.children.length,\n e = this._minEntries;\n\n this._chooseSplitAxis(n, e, r);\n\n var h = this._chooseSplitIndex(n, e, r),\n o = p(n.children.splice(h, n.children.length - h));\n\n o.height = n.height, o.leaf = n.leaf, a(n, this.toBBox), a(o, this.toBBox), i ? t[i - 1].children.push(o) : this._splitRoot(n, o);\n }, r.prototype._splitRoot = function (t, i) {\n this.data = p([t, i]), this.data.height = t.height + 1, this.data.leaf = !1, a(this.data, this.toBBox);\n }, r.prototype._chooseSplitIndex = function (t, i, n) {\n for (var r, e, a, o, s, l, u, m = 1 / 0, c = 1 / 0, p = i; p <= n - i; p++) {\n var d = h(t, 0, p, this.toBBox),\n x = h(t, p, n, this.toBBox),\n v = (e = d, a = x, o = void 0, s = void 0, l = void 0, u = void 0, o = Math.max(e.minX, a.minX), s = Math.max(e.minY, a.minY), l = Math.min(e.maxX, a.maxX), u = Math.min(e.maxY, a.maxY), Math.max(0, l - o) * Math.max(0, u - s)),\n M = f(d) + f(x);\n v < m ? (m = v, r = p, c = M < c ? M : c) : v === m && M < c && (c = M, r = p);\n }\n\n return r || n - i;\n }, r.prototype._chooseSplitAxis = function (t, i, n) {\n var r = t.leaf ? this.compareMinX : s,\n e = t.leaf ? this.compareMinY : l;\n this._allDistMargin(t, i, n, r) < this._allDistMargin(t, i, n, e) && t.children.sort(r);\n }, r.prototype._allDistMargin = function (t, i, n, r) {\n t.children.sort(r);\n\n for (var e = this.toBBox, a = h(t, 0, i, e), s = h(t, n - i, n, e), l = u(a) + u(s), f = i; f < n - i; f++) {\n var m = t.children[f];\n o(a, t.leaf ? e(m) : m), l += u(a);\n }\n\n for (var c = n - i - 1; c >= i; c--) {\n var p = t.children[c];\n o(s, t.leaf ? e(p) : p), l += u(s);\n }\n\n return l;\n }, r.prototype._adjustParentBBoxes = function (t, i, n) {\n for (var r = n; r >= 0; r--) {\n o(i[r], t);\n }\n }, r.prototype._condense = function (t) {\n for (var i = t.length - 1, n = void 0; i >= 0; i--) {\n 0 === t[i].children.length ? i > 0 ? (n = t[i - 1].children).splice(n.indexOf(t[i]), 1) : this.clear() : a(t[i], this.toBBox);\n }\n }, r;\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9yYnVzaC9yYnVzaC5taW4uanM/NzliYyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBLEVBQUUsS0FBMEQsMEJBQTBCLENBQW1GO0FBQ3pLLENBQUM7QUFDRDs7QUFFQTtBQUNBO0FBQ0EsWUFBWSxPQUFPO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxzREFBc0QsT0FBTztBQUM3RCxvQ0FBb0MsZ0JBQWdCO0FBQ3BEO0FBQ0E7O0FBRUEsZ0JBQWdCLGdCQUFnQjtBQUNoQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLG1CQUFtQixPQUFPO0FBQzFCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esd0JBQXdCLFVBQVU7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBLHFDQUFxQyxHQUFHO0FBQ3hDLHFCQUFxQix1QkFBdUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBLG9CQUFvQixHQUFHO0FBQ3ZCLHFCQUFxQix1QkFBdUI7QUFDNUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQSxxQkFBcUIsY0FBYztBQUNuQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSx1RUFBdUU7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDs7QUFFQSx3RUFBd0UsZUFBZTtBQUN2RjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNILG9CQUFvQixHQUFHO0FBQ3ZCO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsUUFBUTtBQUMzQjtBQUNBOztBQUVBLHFCQUFxQixRQUFRO0FBQzdCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNILFVBQVUsMENBQTBDO0FBQ3BELHVEQUF1RCx1QkFBdUI7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBLHFDQUFxQyxtREFBbUQ7QUFDeEY7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSCw4REFBOEQsWUFBWTtBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLCtGQUErRixXQUFXO0FBQzFHO0FBQ0E7QUFDQTs7QUFFQSwyQkFBMkIsUUFBUTtBQUNuQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0gsbUJBQW1CLFFBQVE7QUFDM0I7QUFDQTtBQUNBLEdBQUc7QUFDSCwwQ0FBMEMsUUFBUTtBQUNsRDtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUMiLCJmaWxlIjoiNTc5Mi5qcyIsInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbiAodCwgaSkge1xuICBcIm9iamVjdFwiID09IHR5cGVvZiBleHBvcnRzICYmIFwidW5kZWZpbmVkXCIgIT0gdHlwZW9mIG1vZHVsZSA/IG1vZHVsZS5leHBvcnRzID0gaSgpIDogXCJmdW5jdGlvblwiID09IHR5cGVvZiBkZWZpbmUgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShpKSA6ICh0ID0gdCB8fCBzZWxmKS5SQnVzaCA9IGkoKTtcbn0odGhpcywgZnVuY3Rpb24gKCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBmdW5jdGlvbiB0KHQsIHIsIGUsIGEsIGgpIHtcbiAgICAhZnVuY3Rpb24gdChuLCByLCBlLCBhLCBoKSB7XG4gICAgICBmb3IgKDsgYSA+IGU7KSB7XG4gICAgICAgIGlmIChhIC0gZSA+IDYwMCkge1xuICAgICAgICAgIHZhciBvID0gYSAtIGUgKyAxLFxuICAgICAgICAgICAgICBzID0gciAtIGUgKyAxLFxuICAgICAgICAgICAgICBsID0gTWF0aC5sb2cobyksXG4gICAgICAgICAgICAgIGYgPSAuNSAqIE1hdGguZXhwKDIgKiBsIC8gMyksXG4gICAgICAgICAgICAgIHUgPSAuNSAqIE1hdGguc3FydChsICogZiAqIChvIC0gZikgLyBvKSAqIChzIC0gbyAvIDIgPCAwID8gLTEgOiAxKSxcbiAgICAgICAgICAgICAgbSA9IE1hdGgubWF4KGUsIE1hdGguZmxvb3IociAtIHMgKiBmIC8gbyArIHUpKSxcbiAgICAgICAgICAgICAgYyA9IE1hdGgubWluKGEsIE1hdGguZmxvb3IociArIChvIC0gcykgKiBmIC8gbyArIHUpKTtcbiAgICAgICAgICB0KG4sIHIsIG0sIGMsIGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHAgPSBuW3JdLFxuICAgICAgICAgICAgZCA9IGUsXG4gICAgICAgICAgICB4ID0gYTtcblxuICAgICAgICBmb3IgKGkobiwgZSwgciksIGgoblthXSwgcCkgPiAwICYmIGkobiwgZSwgYSk7IGQgPCB4Oykge1xuICAgICAgICAgIGZvciAoaShuLCBkLCB4KSwgZCsrLCB4LS07IGgobltkXSwgcCkgPCAwOykge1xuICAgICAgICAgICAgZCsrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvciAoOyBoKG5beF0sIHApID4gMDspIHtcbiAgICAgICAgICAgIHgtLTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAwID09PSBoKG5bZV0sIHApID8gaShuLCBlLCB4KSA6IGkobiwgKyt4LCBhKSwgeCA8PSByICYmIChlID0geCArIDEpLCByIDw9IHggJiYgKGEgPSB4IC0gMSk7XG4gICAgICB9XG4gICAgfSh0LCByLCBlIHx8IDAsIGEgfHwgdC5sZW5ndGggLSAxLCBoIHx8IG4pO1xuICB9XG5cbiAgZnVuY3Rpb24gaSh0LCBpLCBuKSB7XG4gICAgdmFyIHIgPSB0W2ldO1xuICAgIHRbaV0gPSB0W25dLCB0W25dID0gcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIG4odCwgaSkge1xuICAgIHJldHVybiB0IDwgaSA/IC0xIDogdCA+IGkgPyAxIDogMDtcbiAgfVxuXG4gIHZhciByID0gZnVuY3Rpb24gcih0KSB7XG4gICAgdm9pZCAwID09PSB0ICYmICh0ID0gOSksIHRoaXMuX21heEVudHJpZXMgPSBNYXRoLm1heCg0LCB0KSwgdGhpcy5fbWluRW50cmllcyA9IE1hdGgubWF4KDIsIE1hdGguY2VpbCguNCAqIHRoaXMuX21heEVudHJpZXMpKSwgdGhpcy5jbGVhcigpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIGUodCwgaSwgbikge1xuICAgIGlmICghbikgcmV0dXJuIGkuaW5kZXhPZih0KTtcblxuICAgIGZvciAodmFyIHIgPSAwOyByIDwgaS5sZW5ndGg7IHIrKykge1xuICAgICAgaWYgKG4odCwgaVtyXSkpIHJldHVybiByO1xuICAgIH1cblxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGEodCwgaSkge1xuICAgIGgodCwgMCwgdC5jaGlsZHJlbi5sZW5ndGgsIGksIHQpO1xuICB9XG5cbiAgZnVuY3Rpb24gaCh0LCBpLCBuLCByLCBlKSB7XG4gICAgZSB8fCAoZSA9IHAobnVsbCkpLCBlLm1pblggPSAxIC8gMCwgZS5taW5ZID0gMSAvIDAsIGUubWF4WCA9IC0xIC8gMCwgZS5tYXhZID0gLTEgLyAwO1xuXG4gICAgZm9yICh2YXIgYSA9IGk7IGEgPCBuOyBhKyspIHtcbiAgICAgIHZhciBoID0gdC5jaGlsZHJlblthXTtcbiAgICAgIG8oZSwgdC5sZWFmID8gcihoKSA6IGgpO1xuICAgIH1cblxuICAgIHJldHVybiBlO1xuICB9XG5cbiAgZnVuY3Rpb24gbyh0LCBpKSB7XG4gICAgcmV0dXJuIHQubWluWCA9IE1hdGgubWluKHQubWluWCwgaS5taW5YKSwgdC5taW5ZID0gTWF0aC5taW4odC5taW5ZLCBpLm1pblkpLCB0Lm1heFggPSBNYXRoLm1heCh0Lm1heFgsIGkubWF4WCksIHQubWF4WSA9IE1hdGgubWF4KHQubWF4WSwgaS5tYXhZKSwgdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHModCwgaSkge1xuICAgIHJldHVybiB0Lm1pblggLSBpLm1pblg7XG4gIH1cblxuICBmdW5jdGlvbiBsKHQsIGkpIHtcbiAgICByZXR1cm4gdC5taW5ZIC0gaS5taW5ZO1xuICB9XG5cbiAgZnVuY3Rpb24gZih0KSB7XG4gICAgcmV0dXJuICh0Lm1heFggLSB0Lm1pblgpICogKHQubWF4WSAtIHQubWluWSk7XG4gIH1cblxuICBmdW5jdGlvbiB1KHQpIHtcbiAgICByZXR1cm4gdC5tYXhYIC0gdC5taW5YICsgKHQubWF4WSAtIHQubWluWSk7XG4gIH1cblxuICBmdW5jdGlvbiBtKHQsIGkpIHtcbiAgICByZXR1cm4gdC5taW5YIDw9IGkubWluWCAmJiB0Lm1pblkgPD0gaS5taW5ZICYmIGkubWF4WCA8PSB0Lm1heFggJiYgaS5tYXhZIDw9IHQubWF4WTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGModCwgaSkge1xuICAgIHJldHVybiBpLm1pblggPD0gdC5tYXhYICYmIGkubWluWSA8PSB0Lm1heFkgJiYgaS5tYXhYID49IHQubWluWCAmJiBpLm1heFkgPj0gdC5taW5ZO1xuICB9XG5cbiAgZnVuY3Rpb24gcCh0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNoaWxkcmVuOiB0LFxuICAgICAgaGVpZ2h0OiAxLFxuICAgICAgbGVhZjogITAsXG4gICAgICBtaW5YOiAxIC8gMCxcbiAgICAgIG1pblk6IDEgLyAwLFxuICAgICAgbWF4WDogLTEgLyAwLFxuICAgICAgbWF4WTogLTEgLyAwXG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGQoaSwgbiwgciwgZSwgYSkge1xuICAgIGZvciAodmFyIGggPSBbbiwgcl07IGgubGVuZ3RoOykge1xuICAgICAgaWYgKCEoKHIgPSBoLnBvcCgpKSAtIChuID0gaC5wb3AoKSkgPD0gZSkpIHtcbiAgICAgICAgdmFyIG8gPSBuICsgTWF0aC5jZWlsKChyIC0gbikgLyBlIC8gMikgKiBlO1xuICAgICAgICB0KGksIG8sIG4sIHIsIGEpLCBoLnB1c2gobiwgbywgbywgcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHIucHJvdG90eXBlLmFsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsKHRoaXMuZGF0YSwgW10pO1xuICB9LCByLnByb3RvdHlwZS5zZWFyY2ggPSBmdW5jdGlvbiAodCkge1xuICAgIHZhciBpID0gdGhpcy5kYXRhLFxuICAgICAgICBuID0gW107XG4gICAgaWYgKCFjKHQsIGkpKSByZXR1cm4gbjtcblxuICAgIGZvciAodmFyIHIgPSB0aGlzLnRvQkJveCwgZSA9IFtdOyBpOykge1xuICAgICAgZm9yICh2YXIgYSA9IDA7IGEgPCBpLmNoaWxkcmVuLmxlbmd0aDsgYSsrKSB7XG4gICAgICAgIHZhciBoID0gaS5jaGlsZHJlblthXSxcbiAgICAgICAgICAgIG8gPSBpLmxlYWYgPyByKGgpIDogaDtcbiAgICAgICAgYyh0LCBvKSAmJiAoaS5sZWFmID8gbi5wdXNoKGgpIDogbSh0LCBvKSA/IHRoaXMuX2FsbChoLCBuKSA6IGUucHVzaChoKSk7XG4gICAgICB9XG5cbiAgICAgIGkgPSBlLnBvcCgpO1xuICAgIH1cblxuICAgIHJldHVybiBuO1xuICB9LCByLnByb3RvdHlwZS5jb2xsaWRlcyA9IGZ1bmN0aW9uICh0KSB7XG4gICAgdmFyIGkgPSB0aGlzLmRhdGE7XG4gICAgaWYgKCFjKHQsIGkpKSByZXR1cm4gITE7XG5cbiAgICBmb3IgKHZhciBuID0gW107IGk7KSB7XG4gICAgICBmb3IgKHZhciByID0gMDsgciA8IGkuY2hpbGRyZW4ubGVuZ3RoOyByKyspIHtcbiAgICAgICAgdmFyIGUgPSBpLmNoaWxkcmVuW3JdLFxuICAgICAgICAgICAgYSA9IGkubGVhZiA/IHRoaXMudG9CQm94KGUpIDogZTtcblxuICAgICAgICBpZiAoYyh0LCBhKSkge1xuICAgICAgICAgIGlmIChpLmxlYWYgfHwgbSh0LCBhKSkgcmV0dXJuICEwO1xuICAgICAgICAgIG4ucHVzaChlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpID0gbi5wb3AoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gITE7XG4gIH0sIHIucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAodCkge1xuICAgIGlmICghdCB8fCAhdC5sZW5ndGgpIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKHQubGVuZ3RoIDwgdGhpcy5fbWluRW50cmllcykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMuaW5zZXJ0KHRbaV0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB2YXIgbiA9IHRoaXMuX2J1aWxkKHQuc2xpY2UoKSwgMCwgdC5sZW5ndGggLSAxLCAwKTtcblxuICAgIGlmICh0aGlzLmRhdGEuY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICBpZiAodGhpcy5kYXRhLmhlaWdodCA9PT0gbi5oZWlnaHQpIHRoaXMuX3NwbGl0Um9vdCh0aGlzLmRhdGEsIG4pO2Vsc2Uge1xuICAgICAgICBpZiAodGhpcy5kYXRhLmhlaWdodCA8IG4uaGVpZ2h0KSB7XG4gICAgICAgICAgdmFyIHIgPSB0aGlzLmRhdGE7XG4gICAgICAgICAgdGhpcy5kYXRhID0gbiwgbiA9IHI7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9pbnNlcnQobiwgdGhpcy5kYXRhLmhlaWdodCAtIG4uaGVpZ2h0IC0gMSwgITApO1xuICAgICAgfVxuICAgIH0gZWxzZSB0aGlzLmRhdGEgPSBuO1xuICAgIHJldHVybiB0aGlzO1xuICB9LCByLnByb3RvdHlwZS5pbnNlcnQgPSBmdW5jdGlvbiAodCkge1xuICAgIHJldHVybiB0ICYmIHRoaXMuX2luc2VydCh0LCB0aGlzLmRhdGEuaGVpZ2h0IC0gMSksIHRoaXM7XG4gIH0sIHIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGEgPSBwKFtdKSwgdGhpcztcbiAgfSwgci5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKHQsIGkpIHtcbiAgICBpZiAoIXQpIHJldHVybiB0aGlzO1xuXG4gICAgZm9yICh2YXIgbiwgciwgYSwgaCA9IHRoaXMuZGF0YSwgbyA9IHRoaXMudG9CQm94KHQpLCBzID0gW10sIGwgPSBbXTsgaCB8fCBzLmxlbmd0aDspIHtcbiAgICAgIGlmIChoIHx8IChoID0gcy5wb3AoKSwgciA9IHNbcy5sZW5ndGggLSAxXSwgbiA9IGwucG9wKCksIGEgPSAhMCksIGgubGVhZikge1xuICAgICAgICB2YXIgZiA9IGUodCwgaC5jaGlsZHJlbiwgaSk7XG4gICAgICAgIGlmICgtMSAhPT0gZikgcmV0dXJuIGguY2hpbGRyZW4uc3BsaWNlKGYsIDEpLCBzLnB1c2goaCksIHRoaXMuX2NvbmRlbnNlKHMpLCB0aGlzO1xuICAgICAgfVxuXG4gICAgICBhIHx8IGgubGVhZiB8fCAhbShoLCBvKSA/IHIgPyAobisrLCBoID0gci5jaGlsZHJlbltuXSwgYSA9ICExKSA6IGggPSBudWxsIDogKHMucHVzaChoKSwgbC5wdXNoKG4pLCBuID0gMCwgciA9IGgsIGggPSBoLmNoaWxkcmVuWzBdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSwgci5wcm90b3R5cGUudG9CQm94ID0gZnVuY3Rpb24gKHQpIHtcbiAgICByZXR1cm4gdDtcbiAgfSwgci5wcm90b3R5cGUuY29tcGFyZU1pblggPSBmdW5jdGlvbiAodCwgaSkge1xuICAgIHJldHVybiB0Lm1pblggLSBpLm1pblg7XG4gIH0sIHIucHJvdG90eXBlLmNvbXBhcmVNaW5ZID0gZnVuY3Rpb24gKHQsIGkpIHtcbiAgICByZXR1cm4gdC5taW5ZIC0gaS5taW5ZO1xuICB9LCByLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YTtcbiAgfSwgci5wcm90b3R5cGUuZnJvbUpTT04gPSBmdW5jdGlvbiAodCkge1xuICAgIHJldHVybiB0aGlzLmRhdGEgPSB0LCB0aGlzO1xuICB9LCByLnByb3RvdHlwZS5fYWxsID0gZnVuY3Rpb24gKHQsIGkpIHtcbiAgICBmb3IgKHZhciBuID0gW107IHQ7KSB7XG4gICAgICB0LmxlYWYgPyBpLnB1c2guYXBwbHkoaSwgdC5jaGlsZHJlbikgOiBuLnB1c2guYXBwbHkobiwgdC5jaGlsZHJlbiksIHQgPSBuLnBvcCgpO1xuICAgIH1cblxuICAgIHJldHVybiBpO1xuICB9LCByLnByb3RvdHlwZS5fYnVpbGQgPSBmdW5jdGlvbiAodCwgaSwgbiwgcikge1xuICAgIHZhciBlLFxuICAgICAgICBoID0gbiAtIGkgKyAxLFxuICAgICAgICBvID0gdGhpcy5fbWF4RW50cmllcztcbiAgICBpZiAoaCA8PSBvKSByZXR1cm4gYShlID0gcCh0LnNsaWNlKGksIG4gKyAxKSksIHRoaXMudG9CQm94KSwgZTtcbiAgICByIHx8IChyID0gTWF0aC5jZWlsKE1hdGgubG9nKGgpIC8gTWF0aC5sb2cobykpLCBvID0gTWF0aC5jZWlsKGggLyBNYXRoLnBvdyhvLCByIC0gMSkpKSwgKGUgPSBwKFtdKSkubGVhZiA9ICExLCBlLmhlaWdodCA9IHI7XG4gICAgdmFyIHMgPSBNYXRoLmNlaWwoaCAvIG8pLFxuICAgICAgICBsID0gcyAqIE1hdGguY2VpbChNYXRoLnNxcnQobykpO1xuICAgIGQodCwgaSwgbiwgbCwgdGhpcy5jb21wYXJlTWluWCk7XG5cbiAgICBmb3IgKHZhciBmID0gaTsgZiA8PSBuOyBmICs9IGwpIHtcbiAgICAgIHZhciB1ID0gTWF0aC5taW4oZiArIGwgLSAxLCBuKTtcbiAgICAgIGQodCwgZiwgdSwgcywgdGhpcy5jb21wYXJlTWluWSk7XG5cbiAgICAgIGZvciAodmFyIG0gPSBmOyBtIDw9IHU7IG0gKz0gcykge1xuICAgICAgICB2YXIgYyA9IE1hdGgubWluKG0gKyBzIC0gMSwgdSk7XG4gICAgICAgIGUuY2hpbGRyZW4ucHVzaCh0aGlzLl9idWlsZCh0LCBtLCBjLCByIC0gMSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhKGUsIHRoaXMudG9CQm94KSwgZTtcbiAgfSwgci5wcm90b3R5cGUuX2Nob29zZVN1YnRyZWUgPSBmdW5jdGlvbiAodCwgaSwgbiwgcikge1xuICAgIGZvciAoOyByLnB1c2goaSksICFpLmxlYWYgJiYgci5sZW5ndGggLSAxICE9PSBuOykge1xuICAgICAgZm9yICh2YXIgZSA9IDEgLyAwLCBhID0gMSAvIDAsIGggPSB2b2lkIDAsIG8gPSAwOyBvIDwgaS5jaGlsZHJlbi5sZW5ndGg7IG8rKykge1xuICAgICAgICB2YXIgcyA9IGkuY2hpbGRyZW5bb10sXG4gICAgICAgICAgICBsID0gZihzKSxcbiAgICAgICAgICAgIHUgPSAobSA9IHQsIGMgPSBzLCAoTWF0aC5tYXgoYy5tYXhYLCBtLm1heFgpIC0gTWF0aC5taW4oYy5taW5YLCBtLm1pblgpKSAqIChNYXRoLm1heChjLm1heFksIG0ubWF4WSkgLSBNYXRoLm1pbihjLm1pblksIG0ubWluWSkpIC0gbCk7XG4gICAgICAgIHUgPCBhID8gKGEgPSB1LCBlID0gbCA8IGUgPyBsIDogZSwgaCA9IHMpIDogdSA9PT0gYSAmJiBsIDwgZSAmJiAoZSA9IGwsIGggPSBzKTtcbiAgICAgIH1cblxuICAgICAgaSA9IGggfHwgaS5jaGlsZHJlblswXTtcbiAgICB9XG5cbiAgICB2YXIgbSwgYztcbiAgICByZXR1cm4gaTtcbiAgfSwgci5wcm90b3R5cGUuX2luc2VydCA9IGZ1bmN0aW9uICh0LCBpLCBuKSB7XG4gICAgdmFyIHIgPSBuID8gdCA6IHRoaXMudG9CQm94KHQpLFxuICAgICAgICBlID0gW10sXG4gICAgICAgIGEgPSB0aGlzLl9jaG9vc2VTdWJ0cmVlKHIsIHRoaXMuZGF0YSwgaSwgZSk7XG5cbiAgICBmb3IgKGEuY2hpbGRyZW4ucHVzaCh0KSwgbyhhLCByKTsgaSA+PSAwICYmIGVbaV0uY2hpbGRyZW4ubGVuZ3RoID4gdGhpcy5fbWF4RW50cmllczspIHtcbiAgICAgIHRoaXMuX3NwbGl0KGUsIGkpLCBpLS07XG4gICAgfVxuXG4gICAgdGhpcy5fYWRqdXN0UGFyZW50QkJveGVzKHIsIGUsIGkpO1xuICB9LCByLnByb3RvdHlwZS5fc3BsaXQgPSBmdW5jdGlvbiAodCwgaSkge1xuICAgIHZhciBuID0gdFtpXSxcbiAgICAgICAgciA9IG4uY2hpbGRyZW4ubGVuZ3RoLFxuICAgICAgICBlID0gdGhpcy5fbWluRW50cmllcztcblxuICAgIHRoaXMuX2Nob29zZVNwbGl0QXhpcyhuLCBlLCByKTtcblxuICAgIHZhciBoID0gdGhpcy5fY2hvb3NlU3BsaXRJbmRleChuLCBlLCByKSxcbiAgICAgICAgbyA9IHAobi5jaGlsZHJlbi5zcGxpY2UoaCwgbi5jaGlsZHJlbi5sZW5ndGggLSBoKSk7XG5cbiAgICBvLmhlaWdodCA9IG4uaGVpZ2h0LCBvLmxlYWYgPSBuLmxlYWYsIGEobiwgdGhpcy50b0JCb3gpLCBhKG8sIHRoaXMudG9CQm94KSwgaSA/IHRbaSAtIDFdLmNoaWxkcmVuLnB1c2gobykgOiB0aGlzLl9zcGxpdFJvb3Qobiwgbyk7XG4gIH0sIHIucHJvdG90eXBlLl9zcGxpdFJvb3QgPSBmdW5jdGlvbiAodCwgaSkge1xuICAgIHRoaXMuZGF0YSA9IHAoW3QsIGldKSwgdGhpcy5kYXRhLmhlaWdodCA9IHQuaGVpZ2h0ICsgMSwgdGhpcy5kYXRhLmxlYWYgPSAhMSwgYSh0aGlzLmRhdGEsIHRoaXMudG9CQm94KTtcbiAgfSwgci5wcm90b3R5cGUuX2Nob29zZVNwbGl0SW5kZXggPSBmdW5jdGlvbiAodCwgaSwgbikge1xuICAgIGZvciAodmFyIHIsIGUsIGEsIG8sIHMsIGwsIHUsIG0gPSAxIC8gMCwgYyA9IDEgLyAwLCBwID0gaTsgcCA8PSBuIC0gaTsgcCsrKSB7XG4gICAgICB2YXIgZCA9IGgodCwgMCwgcCwgdGhpcy50b0JCb3gpLFxuICAgICAgICAgIHggPSBoKHQsIHAsIG4sIHRoaXMudG9CQm94KSxcbiAgICAgICAgICB2ID0gKGUgPSBkLCBhID0geCwgbyA9IHZvaWQgMCwgcyA9IHZvaWQgMCwgbCA9IHZvaWQgMCwgdSA9IHZvaWQgMCwgbyA9IE1hdGgubWF4KGUubWluWCwgYS5taW5YKSwgcyA9IE1hdGgubWF4KGUubWluWSwgYS5taW5ZKSwgbCA9IE1hdGgubWluKGUubWF4WCwgYS5tYXhYKSwgdSA9IE1hdGgubWluKGUubWF4WSwgYS5tYXhZKSwgTWF0aC5tYXgoMCwgbCAtIG8pICogTWF0aC5tYXgoMCwgdSAtIHMpKSxcbiAgICAgICAgICBNID0gZihkKSArIGYoeCk7XG4gICAgICB2IDwgbSA/IChtID0gdiwgciA9IHAsIGMgPSBNIDwgYyA/IE0gOiBjKSA6IHYgPT09IG0gJiYgTSA8IGMgJiYgKGMgPSBNLCByID0gcCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHIgfHwgbiAtIGk7XG4gIH0sIHIucHJvdG90eXBlLl9jaG9vc2VTcGxpdEF4aXMgPSBmdW5jdGlvbiAodCwgaSwgbikge1xuICAgIHZhciByID0gdC5sZWFmID8gdGhpcy5jb21wYXJlTWluWCA6IHMsXG4gICAgICAgIGUgPSB0LmxlYWYgPyB0aGlzLmNvbXBhcmVNaW5ZIDogbDtcbiAgICB0aGlzLl9hbGxEaXN0TWFyZ2luKHQsIGksIG4sIHIpIDwgdGhpcy5fYWxsRGlzdE1hcmdpbih0LCBpLCBuLCBlKSAmJiB0LmNoaWxkcmVuLnNvcnQocik7XG4gIH0sIHIucHJvdG90eXBlLl9hbGxEaXN0TWFyZ2luID0gZnVuY3Rpb24gKHQsIGksIG4sIHIpIHtcbiAgICB0LmNoaWxkcmVuLnNvcnQocik7XG5cbiAgICBmb3IgKHZhciBlID0gdGhpcy50b0JCb3gsIGEgPSBoKHQsIDAsIGksIGUpLCBzID0gaCh0LCBuIC0gaSwgbiwgZSksIGwgPSB1KGEpICsgdShzKSwgZiA9IGk7IGYgPCBuIC0gaTsgZisrKSB7XG4gICAgICB2YXIgbSA9IHQuY2hpbGRyZW5bZl07XG4gICAgICBvKGEsIHQubGVhZiA/IGUobSkgOiBtKSwgbCArPSB1KGEpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGMgPSBuIC0gaSAtIDE7IGMgPj0gaTsgYy0tKSB7XG4gICAgICB2YXIgcCA9IHQuY2hpbGRyZW5bY107XG4gICAgICBvKHMsIHQubGVhZiA/IGUocCkgOiBwKSwgbCArPSB1KHMpO1xuICAgIH1cblxuICAgIHJldHVybiBsO1xuICB9LCByLnByb3RvdHlwZS5fYWRqdXN0UGFyZW50QkJveGVzID0gZnVuY3Rpb24gKHQsIGksIG4pIHtcbiAgICBmb3IgKHZhciByID0gbjsgciA+PSAwOyByLS0pIHtcbiAgICAgIG8oaVtyXSwgdCk7XG4gICAgfVxuICB9LCByLnByb3RvdHlwZS5fY29uZGVuc2UgPSBmdW5jdGlvbiAodCkge1xuICAgIGZvciAodmFyIGkgPSB0Lmxlbmd0aCAtIDEsIG4gPSB2b2lkIDA7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAwID09PSB0W2ldLmNoaWxkcmVuLmxlbmd0aCA/IGkgPiAwID8gKG4gPSB0W2kgLSAxXS5jaGlsZHJlbikuc3BsaWNlKG4uaW5kZXhPZih0W2ldKSwgMSkgOiB0aGlzLmNsZWFyKCkgOiBhKHRbaV0sIHRoaXMudG9CQm94KTtcbiAgICB9XG4gIH0sIHI7XG59KTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5792\n')},5438:function(__unused_webpack_module,__unused_webpack_exports,__webpack_require__){eval("var $ = __webpack_require__(2109);\n\n// eslint-disable-next-line es/no-math-hypot -- required for testing\nvar $hypot = Math.hypot;\nvar abs = Math.abs;\nvar sqrt = Math.sqrt;\n\n// Chrome 77 bug\n// https://bugs.chromium.org/p/v8/issues/detail?id=9546\nvar BUGGY = !!$hypot && $hypot(Infinity, NaN) !== Infinity;\n\n// `Math.hypot` method\n// https://tc39.es/ecma262/#sec-math.hypot\n$({ target: 'Math', stat: true, forced: BUGGY }, {\n // eslint-disable-next-line no-unused-vars -- required for `.length`\n hypot: function hypot(value1, value2) {\n var sum = 0;\n var i = 0;\n var aLen = arguments.length;\n var larg = 0;\n var arg, div;\n while (i < aLen) {\n arg = abs(arguments[i++]);\n if (larg < arg) {\n div = larg / arg;\n sum = sum * div * div + 1;\n larg = arg;\n } else if (arg > 0) {\n div = arg / larg;\n sum += div * div;\n } else sum += arg;\n }\n return larg === Infinity ? Infinity : larg * sqrt(sum);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMubWF0aC5oeXBvdC5qcz80MDU3Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFFBQVEsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHLDRDQUE0QztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLENBQUMiLCJmaWxlIjoiNTQzOC5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXMvbm8tbWF0aC1oeXBvdCAtLSByZXF1aXJlZCBmb3IgdGVzdGluZ1xudmFyICRoeXBvdCA9IE1hdGguaHlwb3Q7XG52YXIgYWJzID0gTWF0aC5hYnM7XG52YXIgc3FydCA9IE1hdGguc3FydDtcblxuLy8gQ2hyb21lIDc3IGJ1Z1xuLy8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9OTU0NlxudmFyIEJVR0dZID0gISEkaHlwb3QgJiYgJGh5cG90KEluZmluaXR5LCBOYU4pICE9PSBJbmZpbml0eTtcblxuLy8gYE1hdGguaHlwb3RgIG1ldGhvZFxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy1tYXRoLmh5cG90XG4kKHsgdGFyZ2V0OiAnTWF0aCcsIHN0YXQ6IHRydWUsIGZvcmNlZDogQlVHR1kgfSwge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMgLS0gcmVxdWlyZWQgZm9yIGAubGVuZ3RoYFxuICBoeXBvdDogZnVuY3Rpb24gaHlwb3QodmFsdWUxLCB2YWx1ZTIpIHtcbiAgICB2YXIgc3VtID0gMDtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBsYXJnID0gMDtcbiAgICB2YXIgYXJnLCBkaXY7XG4gICAgd2hpbGUgKGkgPCBhTGVuKSB7XG4gICAgICBhcmcgPSBhYnMoYXJndW1lbnRzW2krK10pO1xuICAgICAgaWYgKGxhcmcgPCBhcmcpIHtcbiAgICAgICAgZGl2ID0gbGFyZyAvIGFyZztcbiAgICAgICAgc3VtID0gc3VtICogZGl2ICogZGl2ICsgMTtcbiAgICAgICAgbGFyZyA9IGFyZztcbiAgICAgIH0gZWxzZSBpZiAoYXJnID4gMCkge1xuICAgICAgICBkaXYgPSBhcmcgLyBsYXJnO1xuICAgICAgICBzdW0gKz0gZGl2ICogZGl2O1xuICAgICAgfSBlbHNlIHN1bSArPSBhcmc7XG4gICAgfVxuICAgIHJldHVybiBsYXJnID09PSBJbmZpbml0eSA/IEluZmluaXR5IDogbGFyZyAqIHNxcnQoc3VtKTtcbiAgfVxufSk7XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5438\n")},629:function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('// ESM COMPAT FLAG\n__webpack_require__.r(__webpack_exports__);\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n "default": function() { return /* binding */ cejst; }\n});\n\n// NAMESPACE OBJECT: ./src/components/map.module.scss\nvar map_module_namespaceObject = {};\n__webpack_require__.r(map_module_namespaceObject);\n__webpack_require__.d(map_module_namespaceObject, {\n "G7": function() { return mapContainer; },\n "jt": function() { return map_module_popupCloser; },\n "a6": function() { return map_module_popupContainer; }\n});\n\n// EXTERNAL MODULE: ./node_modules/react/index.js\nvar react = __webpack_require__(7294);\n// EXTERNAL MODULE: ./src/components/layout.tsx + 8 modules\nvar layout = __webpack_require__(6515);\n;// CONCATENATED MODULE: ./node_modules/ol/Disposable.js\n/**\n * @module ol/Disposable\n */\n\n/**\n * @classdesc\n * Objects that need to clean up after themselves.\n */\nvar Disposable =\n/** @class */\nfunction () {\n function Disposable() {\n /**\n * The object has already been disposed.\n * @type {boolean}\n * @protected\n */\n this.disposed = false;\n }\n /**\n * Clean up.\n */\n\n\n Disposable.prototype.dispose = function () {\n if (!this.disposed) {\n this.disposed = true;\n this.disposeInternal();\n }\n };\n /**\n * Extension point for disposable objects.\n * @protected\n */\n\n\n Disposable.prototype.disposeInternal = function () {};\n\n return Disposable;\n}();\n\n/* harmony default export */ var ol_Disposable = (Disposable);\n;// CONCATENATED MODULE: ./node_modules/ol/array.js\n/**\n * @module ol/array\n */\n\n/**\n * Performs a binary search on the provided sorted list and returns the index of the item if found. If it can\'t be found it\'ll return -1.\n * https://github.com/darkskyapp/binary-search\n *\n * @param {Array<*>} haystack Items to search through.\n * @param {*} needle The item to look for.\n * @param {Function=} opt_comparator Comparator function.\n * @return {number} The index of the item if found, -1 if not.\n */\nfunction binarySearch(haystack, needle, opt_comparator) {\n var mid, cmp;\n var comparator = opt_comparator || numberSafeCompareFunction;\n var low = 0;\n var high = haystack.length;\n var found = false;\n\n while (low < high) {\n /* Note that "(low + high) >>> 1" may overflow, and results in a typecast\n * to double (which gives the wrong results). */\n mid = low + (high - low >> 1);\n cmp = +comparator(haystack[mid], needle);\n\n if (cmp < 0.0) {\n /* Too low. */\n low = mid + 1;\n } else {\n /* Key found or too high */\n high = mid;\n found = !cmp;\n }\n }\n /* Key not found. */\n\n\n return found ? low : ~low;\n}\n/**\n * Compare function for array sort that is safe for numbers.\n * @param {*} a The first object to be compared.\n * @param {*} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is less than, equal to, or greater than the second.\n */\n\nfunction numberSafeCompareFunction(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n}\n/**\n * Whether the array contains the given object.\n * @param {Array<*>} arr The array to test for the presence of the element.\n * @param {*} obj The object for which to test.\n * @return {boolean} The object is in the array.\n */\n\nfunction includes(arr, obj) {\n return arr.indexOf(obj) >= 0;\n}\n/**\n * @param {Array<number>} arr Array.\n * @param {number} target Target.\n * @param {number} direction 0 means return the nearest, > 0\n * means return the largest nearest, < 0 means return the\n * smallest nearest.\n * @return {number} Index.\n */\n\nfunction linearFindNearest(arr, target, direction) {\n var n = arr.length;\n\n if (arr[0] <= target) {\n return 0;\n } else if (target <= arr[n - 1]) {\n return n - 1;\n } else {\n var i = void 0;\n\n if (direction > 0) {\n for (i = 1; i < n; ++i) {\n if (arr[i] < target) {\n return i - 1;\n }\n }\n } else if (direction < 0) {\n for (i = 1; i < n; ++i) {\n if (arr[i] <= target) {\n return i;\n }\n }\n } else {\n for (i = 1; i < n; ++i) {\n if (arr[i] == target) {\n return i;\n } else if (arr[i] < target) {\n if (arr[i - 1] - target < target - arr[i]) {\n return i - 1;\n } else {\n return i;\n }\n }\n }\n }\n\n return n - 1;\n }\n}\n/**\n * @param {Array<*>} arr Array.\n * @param {number} begin Begin index.\n * @param {number} end End index.\n */\n\nfunction reverseSubArray(arr, begin, end) {\n while (begin < end) {\n var tmp = arr[begin];\n arr[begin] = arr[end];\n arr[end] = tmp;\n ++begin;\n --end;\n }\n}\n/**\n * @param {Array<VALUE>} arr The array to modify.\n * @param {!Array<VALUE>|VALUE} data The elements or arrays of elements to add to arr.\n * @template VALUE\n */\n\nfunction array_extend(arr, data) {\n var extension = Array.isArray(data) ? data : [data];\n var length = extension.length;\n\n for (var i = 0; i < length; i++) {\n arr[arr.length] = extension[i];\n }\n}\n/**\n * @param {Array<VALUE>} arr The array to modify.\n * @param {VALUE} obj The element to remove.\n * @template VALUE\n * @return {boolean} If the element was removed.\n */\n\nfunction remove(arr, obj) {\n var i = arr.indexOf(obj);\n var found = i > -1;\n\n if (found) {\n arr.splice(i, 1);\n }\n\n return found;\n}\n/**\n * @param {Array<VALUE>} arr The array to search in.\n * @param {function(VALUE, number, ?) : boolean} func The function to compare.\n * @template VALUE\n * @return {VALUE|null} The element found or null.\n */\n\nfunction find(arr, func) {\n var length = arr.length >>> 0;\n var value;\n\n for (var i = 0; i < length; i++) {\n value = arr[i];\n\n if (func(value, i, arr)) {\n return value;\n }\n }\n\n return null;\n}\n/**\n * @param {Array|Uint8ClampedArray} arr1 The first array to compare.\n * @param {Array|Uint8ClampedArray} arr2 The second array to compare.\n * @return {boolean} Whether the two arrays are equal.\n */\n\nfunction equals(arr1, arr2) {\n var len1 = arr1.length;\n\n if (len1 !== arr2.length) {\n return false;\n }\n\n for (var i = 0; i < len1; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n\n return true;\n}\n/**\n * Sort the passed array such that the relative order of equal elements is preverved.\n * See https://en.wikipedia.org/wiki/Sorting_algorithm#Stability for details.\n * @param {Array<*>} arr The array to sort (modifies original).\n * @param {!function(*, *): number} compareFnc Comparison function.\n * @api\n */\n\nfunction stableSort(arr, compareFnc) {\n var length = arr.length;\n var tmp = Array(arr.length);\n var i;\n\n for (i = 0; i < length; i++) {\n tmp[i] = {\n index: i,\n value: arr[i]\n };\n }\n\n tmp.sort(function (a, b) {\n return compareFnc(a.value, b.value) || a.index - b.index;\n });\n\n for (i = 0; i < arr.length; i++) {\n arr[i] = tmp[i].value;\n }\n}\n/**\n * @param {Array<*>} arr The array to search in.\n * @param {Function} func Comparison function.\n * @return {number} Return index.\n */\n\nfunction findIndex(arr, func) {\n var index;\n var found = !arr.every(function (el, idx) {\n index = idx;\n return !func(el, idx, arr);\n });\n return found ? index : -1;\n}\n/**\n * @param {Array<*>} arr The array to test.\n * @param {Function=} opt_func Comparison function.\n * @param {boolean=} opt_strict Strictly sorted (default false).\n * @return {boolean} Return index.\n */\n\nfunction isSorted(arr, opt_func, opt_strict) {\n var compare = opt_func || numberSafeCompareFunction;\n return arr.every(function (currentVal, index) {\n if (index === 0) {\n return true;\n }\n\n var res = compare(arr[index - 1], currentVal);\n return !(res > 0 || opt_strict && res === 0);\n });\n}\n;// CONCATENATED MODULE: ./node_modules/ol/functions.js\n/**\n * @module ol/functions\n */\n\n/**\n * Always returns true.\n * @returns {boolean} true.\n */\n\nfunction TRUE() {\n return true;\n}\n/**\n * Always returns false.\n * @returns {boolean} false.\n */\n\nfunction functions_FALSE() {\n return false;\n}\n/**\n * A reusable function, used e.g. as a default for callbacks.\n *\n * @return {void} Nothing.\n */\n\nfunction VOID() {}\n/**\n * Wrap a function in another function that remembers the last return. If the\n * returned function is called twice in a row with the same arguments and the same\n * this object, it will return the value from the first call in the second call.\n *\n * @param {function(...any): ReturnType} fn The function to memoize.\n * @return {function(...any): ReturnType} The memoized function.\n * @template ReturnType\n */\n\nfunction memoizeOne(fn) {\n var called = false;\n /** @type {ReturnType} */\n\n var lastResult;\n /** @type {Array<any>} */\n\n var lastArgs;\n var lastThis;\n return function () {\n var nextArgs = Array.prototype.slice.call(arguments);\n\n if (!called || this !== lastThis || !equals(nextArgs, lastArgs)) {\n called = true;\n lastThis = this;\n lastArgs = nextArgs;\n lastResult = fn.apply(this, arguments);\n }\n\n return lastResult;\n };\n}\n;// CONCATENATED MODULE: ./node_modules/ol/util.js\n/**\n * @module ol/util\n */\n\n/**\n * @return {?} Any return.\n */\nfunction util_abstract() {\n return (\n /** @type {?} */\n function () {\n throw new Error(\'Unimplemented abstract method.\');\n }()\n );\n}\n/**\n * Counter for getUid.\n * @type {number}\n * @private\n */\n\nvar uidCounter_ = 0;\n/**\n * Gets a unique ID for an object. This mutates the object so that further calls\n * with the same object as a parameter returns the same value. Unique IDs are generated\n * as a strictly increasing sequence. Adapted from goog.getUid.\n *\n * @param {Object} obj The object to get the unique ID for.\n * @return {string} The unique ID for the object.\n * @api\n */\n\nfunction getUid(obj) {\n return obj.ol_uid || (obj.ol_uid = String(++uidCounter_));\n}\n/**\n * OpenLayers version.\n * @type {string}\n */\n\nvar VERSION = \'6.5.0\';\n;// CONCATENATED MODULE: ./node_modules/ol/AssertionError.js\nvar __extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/AssertionError\n */\n\n\n\n/**\n * Error object thrown when an assertion failed. This is an ECMA-262 Error,\n * extended with a `code` property.\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error.\n */\n\nvar AssertionError =\n/** @class */\nfunction (_super) {\n __extends(AssertionError, _super);\n /**\n * @param {number} code Error code.\n */\n\n\n function AssertionError(code) {\n var _this = this;\n\n var path = VERSION === \'latest\' ? VERSION : \'v\' + VERSION.split(\'-\')[0];\n var message = \'Assertion failed. See https://openlayers.org/en/\' + path + \'/doc/errors/#\' + code + \' for details.\';\n _this = _super.call(this, message) || this;\n /**\n * Error code. The meaning of the code can be found on\n * https://openlayers.org/en/latest/doc/errors/ (replace `latest` with\n * the version found in the OpenLayers script\'s header comment if a version\n * other than the latest is used).\n * @type {number}\n * @api\n */\n\n _this.code = code;\n /**\n * @type {string}\n */\n\n _this.name = \'AssertionError\'; // Re-assign message, see https://github.com/Rich-Harris/buble/issues/40\n\n _this.message = message;\n return _this;\n }\n\n return AssertionError;\n}(Error);\n\n/* harmony default export */ var ol_AssertionError = (AssertionError);\n;// CONCATENATED MODULE: ./node_modules/ol/asserts.js\n/**\n * @module ol/asserts\n */\n\n/**\n * @param {*} assertion Assertion we expected to be truthy.\n * @param {number} errorCode Error code.\n */\n\nfunction asserts_assert(assertion, errorCode) {\n if (!assertion) {\n throw new ol_AssertionError(errorCode);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/transform.js\n/**\n * @module ol/transform\n */\n\n/**\n * An array representing an affine 2d transformation for use with\n * {@link module:ol/transform} functions. The array has 6 elements.\n * @typedef {!Array<number>} Transform\n * @api\n */\n\n/**\n * Collection of affine 2d transformation functions. The functions work on an\n * array of 6 elements. The element order is compatible with the [SVGMatrix\n * interface](https://developer.mozilla.org/en-US/docs/Web/API/SVGMatrix) and is\n * a subset (elements a to f) of a 3×3 matrix:\n * ```\n * [ a c e ]\n * [ b d f ]\n * [ 0 0 1 ]\n * ```\n */\n\n/**\n * @private\n * @type {Transform}\n */\n\nvar tmp_ = new Array(6);\n/**\n * Create an identity transform.\n * @return {!Transform} Identity transform.\n */\n\nfunction create() {\n return [1, 0, 0, 1, 0, 0];\n}\n/**\n * Resets the given transform to an identity transform.\n * @param {!Transform} transform Transform.\n * @return {!Transform} Transform.\n */\n\nfunction transform_reset(transform) {\n return set(transform, 1, 0, 0, 1, 0, 0);\n}\n/**\n * Multiply the underlying matrices of two transforms and return the result in\n * the first transform.\n * @param {!Transform} transform1 Transform parameters of matrix 1.\n * @param {!Transform} transform2 Transform parameters of matrix 2.\n * @return {!Transform} transform1 multiplied with transform2.\n */\n\nfunction multiply(transform1, transform2) {\n var a1 = transform1[0];\n var b1 = transform1[1];\n var c1 = transform1[2];\n var d1 = transform1[3];\n var e1 = transform1[4];\n var f1 = transform1[5];\n var a2 = transform2[0];\n var b2 = transform2[1];\n var c2 = transform2[2];\n var d2 = transform2[3];\n var e2 = transform2[4];\n var f2 = transform2[5];\n transform1[0] = a1 * a2 + c1 * b2;\n transform1[1] = b1 * a2 + d1 * b2;\n transform1[2] = a1 * c2 + c1 * d2;\n transform1[3] = b1 * c2 + d1 * d2;\n transform1[4] = a1 * e2 + c1 * f2 + e1;\n transform1[5] = b1 * e2 + d1 * f2 + f1;\n return transform1;\n}\n/**\n * Set the transform components a-f on a given transform.\n * @param {!Transform} transform Transform.\n * @param {number} a The a component of the transform.\n * @param {number} b The b component of the transform.\n * @param {number} c The c component of the transform.\n * @param {number} d The d component of the transform.\n * @param {number} e The e component of the transform.\n * @param {number} f The f component of the transform.\n * @return {!Transform} Matrix with transform applied.\n */\n\nfunction set(transform, a, b, c, d, e, f) {\n transform[0] = a;\n transform[1] = b;\n transform[2] = c;\n transform[3] = d;\n transform[4] = e;\n transform[5] = f;\n return transform;\n}\n/**\n * Set transform on one matrix from another matrix.\n * @param {!Transform} transform1 Matrix to set transform to.\n * @param {!Transform} transform2 Matrix to set transform from.\n * @return {!Transform} transform1 with transform from transform2 applied.\n */\n\nfunction setFromArray(transform1, transform2) {\n transform1[0] = transform2[0];\n transform1[1] = transform2[1];\n transform1[2] = transform2[2];\n transform1[3] = transform2[3];\n transform1[4] = transform2[4];\n transform1[5] = transform2[5];\n return transform1;\n}\n/**\n * Transforms the given coordinate with the given transform returning the\n * resulting, transformed coordinate. The coordinate will be modified in-place.\n *\n * @param {Transform} transform The transformation.\n * @param {import("./coordinate.js").Coordinate|import("./pixel.js").Pixel} coordinate The coordinate to transform.\n * @return {import("./coordinate.js").Coordinate|import("./pixel.js").Pixel} return coordinate so that operations can be\n * chained together.\n */\n\nfunction apply(transform, coordinate) {\n var x = coordinate[0];\n var y = coordinate[1];\n coordinate[0] = transform[0] * x + transform[2] * y + transform[4];\n coordinate[1] = transform[1] * x + transform[3] * y + transform[5];\n return coordinate;\n}\n/**\n * Applies rotation to the given transform.\n * @param {!Transform} transform Transform.\n * @param {number} angle Angle in radians.\n * @return {!Transform} The rotated transform.\n */\n\nfunction rotate(transform, angle) {\n var cos = Math.cos(angle);\n var sin = Math.sin(angle);\n return multiply(transform, set(tmp_, cos, sin, -sin, cos, 0, 0));\n}\n/**\n * Applies scale to a given transform.\n * @param {!Transform} transform Transform.\n * @param {number} x Scale factor x.\n * @param {number} y Scale factor y.\n * @return {!Transform} The scaled transform.\n */\n\nfunction scale(transform, x, y) {\n return multiply(transform, set(tmp_, x, 0, 0, y, 0, 0));\n}\n/**\n * Creates a scale transform.\n * @param {!Transform} target Transform to overwrite.\n * @param {number} x Scale factor x.\n * @param {number} y Scale factor y.\n * @return {!Transform} The scale transform.\n */\n\nfunction makeScale(target, x, y) {\n return set(target, x, 0, 0, y, 0, 0);\n}\n/**\n * Applies translation to the given transform.\n * @param {!Transform} transform Transform.\n * @param {number} dx Translation x.\n * @param {number} dy Translation y.\n * @return {!Transform} The translated transform.\n */\n\nfunction translate(transform, dx, dy) {\n return multiply(transform, set(tmp_, 1, 0, 0, 1, dx, dy));\n}\n/**\n * Creates a composite transform given an initial translation, scale, rotation, and\n * final translation (in that order only, not commutative).\n * @param {!Transform} transform The transform (will be modified in place).\n * @param {number} dx1 Initial translation x.\n * @param {number} dy1 Initial translation y.\n * @param {number} sx Scale factor x.\n * @param {number} sy Scale factor y.\n * @param {number} angle Rotation (in counter-clockwise radians).\n * @param {number} dx2 Final translation x.\n * @param {number} dy2 Final translation y.\n * @return {!Transform} The composite transform.\n */\n\nfunction compose(transform, dx1, dy1, sx, sy, angle, dx2, dy2) {\n var sin = Math.sin(angle);\n var cos = Math.cos(angle);\n transform[0] = sx * cos;\n transform[1] = sy * sin;\n transform[2] = -sx * sin;\n transform[3] = sy * cos;\n transform[4] = dx2 * sx * cos - dy2 * sx * sin + dx1;\n transform[5] = dx2 * sy * sin + dy2 * sy * cos + dy1;\n return transform;\n}\n/**\n * Creates a composite transform given an initial translation, scale, rotation, and\n * final translation (in that order only, not commutative). The resulting transform\n * string can be applied as `transform` porperty of an HTMLElement\'s style.\n * @param {number} dx1 Initial translation x.\n * @param {number} dy1 Initial translation y.\n * @param {number} sx Scale factor x.\n * @param {number} sy Scale factor y.\n * @param {number} angle Rotation (in counter-clockwise radians).\n * @param {number} dx2 Final translation x.\n * @param {number} dy2 Final translation y.\n * @return {string} The composite css transform.\n * @api\n */\n\nfunction composeCssTransform(dx1, dy1, sx, sy, angle, dx2, dy2) {\n return transform_toString(compose(create(), dx1, dy1, sx, sy, angle, dx2, dy2));\n}\n/**\n * Invert the given transform.\n * @param {!Transform} source The source transform to invert.\n * @return {!Transform} The inverted (source) transform.\n */\n\nfunction invert(source) {\n return makeInverse(source, source);\n}\n/**\n * Invert the given transform.\n * @param {!Transform} target Transform to be set as the inverse of\n * the source transform.\n * @param {!Transform} source The source transform to invert.\n * @return {!Transform} The inverted (target) transform.\n */\n\nfunction makeInverse(target, source) {\n var det = determinant(source);\n asserts_assert(det !== 0, 32); // Transformation matrix cannot be inverted\n\n var a = source[0];\n var b = source[1];\n var c = source[2];\n var d = source[3];\n var e = source[4];\n var f = source[5];\n target[0] = d / det;\n target[1] = -b / det;\n target[2] = -c / det;\n target[3] = a / det;\n target[4] = (c * f - d * e) / det;\n target[5] = -(a * f - b * e) / det;\n return target;\n}\n/**\n * Returns the determinant of the given matrix.\n * @param {!Transform} mat Matrix.\n * @return {number} Determinant.\n */\n\nfunction determinant(mat) {\n return mat[0] * mat[3] - mat[1] * mat[2];\n}\n/**\n * A string version of the transform. This can be used\n * for CSS transforms.\n * @param {!Transform} mat Matrix.\n * @return {string} The transform as a string.\n */\n\nfunction transform_toString(mat) {\n return \'matrix(\' + mat.join(\', \') + \')\';\n}\n;// CONCATENATED MODULE: ./node_modules/ol/extent/Corner.js\n/**\n * @module ol/extent/Corner\n */\n\n/**\n * Extent corner.\n * @enum {string}\n */\n/* harmony default export */ var Corner = ({\n BOTTOM_LEFT: \'bottom-left\',\n BOTTOM_RIGHT: \'bottom-right\',\n TOP_LEFT: \'top-left\',\n TOP_RIGHT: \'top-right\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/extent/Relationship.js\n/**\n * @module ol/extent/Relationship\n */\n\n/**\n * Relationship to an extent.\n * @enum {number}\n */\n/* harmony default export */ var Relationship = ({\n UNKNOWN: 0,\n INTERSECTING: 1,\n ABOVE: 2,\n RIGHT: 4,\n BELOW: 8,\n LEFT: 16\n});\n;// CONCATENATED MODULE: ./node_modules/ol/extent.js\n/**\n * @module ol/extent\n */\n\n\n\n/**\n * An array of numbers representing an extent: `[minx, miny, maxx, maxy]`.\n * @typedef {Array<number>} Extent\n * @api\n */\n\n/**\n * Build an extent that includes all given coordinates.\n *\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.\n * @return {Extent} Bounding extent.\n * @api\n */\n\nfunction boundingExtent(coordinates) {\n var extent = createEmpty();\n\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n extendCoordinate(extent, coordinates[i]);\n }\n\n return extent;\n}\n/**\n * @param {Array<number>} xs Xs.\n * @param {Array<number>} ys Ys.\n * @param {Extent=} opt_extent Destination extent.\n * @private\n * @return {Extent} Extent.\n */\n\nfunction _boundingExtentXYs(xs, ys, opt_extent) {\n var minX = Math.min.apply(null, xs);\n var minY = Math.min.apply(null, ys);\n var maxX = Math.max.apply(null, xs);\n var maxY = Math.max.apply(null, ys);\n return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n}\n/**\n * Return extent increased by the provided value.\n * @param {Extent} extent Extent.\n * @param {number} value The amount by which the extent should be buffered.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n * @api\n */\n\n\nfunction buffer(extent, value, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0] - value;\n opt_extent[1] = extent[1] - value;\n opt_extent[2] = extent[2] + value;\n opt_extent[3] = extent[3] + value;\n return opt_extent;\n } else {\n return [extent[0] - value, extent[1] - value, extent[2] + value, extent[3] + value];\n }\n}\n/**\n * Creates a clone of an extent.\n *\n * @param {Extent} extent Extent to clone.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} The clone.\n */\n\nfunction clone(extent, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0];\n opt_extent[1] = extent[1];\n opt_extent[2] = extent[2];\n opt_extent[3] = extent[3];\n return opt_extent;\n } else {\n return extent.slice();\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {number} Closest squared distance.\n */\n\nfunction closestSquaredDistanceXY(extent, x, y) {\n var dx, dy;\n\n if (x < extent[0]) {\n dx = extent[0] - x;\n } else if (extent[2] < x) {\n dx = x - extent[2];\n } else {\n dx = 0;\n }\n\n if (y < extent[1]) {\n dy = extent[1] - y;\n } else if (extent[3] < y) {\n dy = y - extent[3];\n } else {\n dy = 0;\n }\n\n return dx * dx + dy * dy;\n}\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {Extent} extent Extent.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @return {boolean} The coordinate is contained in the extent.\n * @api\n */\n\nfunction containsCoordinate(extent, coordinate) {\n return containsXY(extent, coordinate[0], coordinate[1]);\n}\n/**\n * Check if one extent contains another.\n *\n * An extent is deemed contained if it lies completely within the other extent,\n * including if they share one or more edges.\n *\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {boolean} The second extent is contained by or on the edge of the\n * first.\n * @api\n */\n\nfunction containsExtent(extent1, extent2) {\n return extent1[0] <= extent2[0] && extent2[2] <= extent1[2] && extent1[1] <= extent2[1] && extent2[3] <= extent1[3];\n}\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {Extent} extent Extent.\n * @param {number} x X coordinate.\n * @param {number} y Y coordinate.\n * @return {boolean} The x, y values are contained in the extent.\n * @api\n */\n\nfunction containsXY(extent, x, y) {\n return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];\n}\n/**\n * Get the relationship between a coordinate and extent.\n * @param {Extent} extent The extent.\n * @param {import("./coordinate.js").Coordinate} coordinate The coordinate.\n * @return {import("./extent/Relationship.js").default} The relationship (bitwise compare with\n * import("./extent/Relationship.js").Relationship).\n */\n\nfunction coordinateRelationship(extent, coordinate) {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var x = coordinate[0];\n var y = coordinate[1];\n var relationship = Relationship.UNKNOWN;\n\n if (x < minX) {\n relationship = relationship | Relationship.LEFT;\n } else if (x > maxX) {\n relationship = relationship | Relationship.RIGHT;\n }\n\n if (y < minY) {\n relationship = relationship | Relationship.BELOW;\n } else if (y > maxY) {\n relationship = relationship | Relationship.ABOVE;\n }\n\n if (relationship === Relationship.UNKNOWN) {\n relationship = Relationship.INTERSECTING;\n }\n\n return relationship;\n}\n/**\n * Create an empty extent.\n * @return {Extent} Empty extent.\n * @api\n */\n\nfunction createEmpty() {\n return [Infinity, Infinity, -Infinity, -Infinity];\n}\n/**\n * Create a new extent or update the provided extent.\n * @param {number} minX Minimum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxX Maximum X.\n * @param {number} maxY Maximum Y.\n * @param {Extent=} opt_extent Destination extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdate(minX, minY, maxX, maxY, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = minX;\n opt_extent[1] = minY;\n opt_extent[2] = maxX;\n opt_extent[3] = maxY;\n return opt_extent;\n } else {\n return [minX, minY, maxX, maxY];\n }\n}\n/**\n * Create a new empty extent or make the provided one empty.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdateEmpty(opt_extent) {\n return createOrUpdate(Infinity, Infinity, -Infinity, -Infinity, opt_extent);\n}\n/**\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdateFromCoordinate(coordinate, opt_extent) {\n var x = coordinate[0];\n var y = coordinate[1];\n return createOrUpdate(x, y, x, y, opt_extent);\n}\n/**\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdateFromCoordinates(coordinates, opt_extent) {\n var extent = createOrUpdateEmpty(opt_extent);\n return extendCoordinates(extent, coordinates);\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdateFromFlatCoordinates(flatCoordinates, offset, end, stride, opt_extent) {\n var extent = createOrUpdateEmpty(opt_extent);\n return extendFlatCoordinates(extent, flatCoordinates, offset, end, stride);\n}\n/**\n * @param {Array<Array<import("./coordinate.js").Coordinate>>} rings Rings.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdateFromRings(rings, opt_extent) {\n var extent = createOrUpdateEmpty(opt_extent);\n return extendRings(extent, rings);\n}\n/**\n * Determine if two extents are equivalent.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {boolean} The two extents are equivalent.\n * @api\n */\n\nfunction extent_equals(extent1, extent2) {\n return extent1[0] == extent2[0] && extent1[2] == extent2[2] && extent1[1] == extent2[1] && extent1[3] == extent2[3];\n}\n/**\n * Determine if two extents are approximately equivalent.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @param {number} tolerance Tolerance in extent coordinate units.\n * @return {boolean} The two extents differ by less than the tolerance.\n */\n\nfunction approximatelyEquals(extent1, extent2, tolerance) {\n return Math.abs(extent1[0] - extent2[0]) < tolerance && Math.abs(extent1[2] - extent2[2]) < tolerance && Math.abs(extent1[1] - extent2[1]) < tolerance && Math.abs(extent1[3] - extent2[3]) < tolerance;\n}\n/**\n * Modify an extent to include another extent.\n * @param {Extent} extent1 The extent to be modified.\n * @param {Extent} extent2 The extent that will be included in the first.\n * @return {Extent} A reference to the first (extended) extent.\n * @api\n */\n\nfunction extent_extend(extent1, extent2) {\n if (extent2[0] < extent1[0]) {\n extent1[0] = extent2[0];\n }\n\n if (extent2[2] > extent1[2]) {\n extent1[2] = extent2[2];\n }\n\n if (extent2[1] < extent1[1]) {\n extent1[1] = extent2[1];\n }\n\n if (extent2[3] > extent1[3]) {\n extent1[3] = extent2[3];\n }\n\n return extent1;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n */\n\nfunction extendCoordinate(extent, coordinate) {\n if (coordinate[0] < extent[0]) {\n extent[0] = coordinate[0];\n }\n\n if (coordinate[0] > extent[2]) {\n extent[2] = coordinate[0];\n }\n\n if (coordinate[1] < extent[1]) {\n extent[1] = coordinate[1];\n }\n\n if (coordinate[1] > extent[3]) {\n extent[3] = coordinate[1];\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.\n * @return {Extent} Extent.\n */\n\nfunction extendCoordinates(extent, coordinates) {\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n extendCoordinate(extent, coordinates[i]);\n }\n\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {Extent} Extent.\n */\n\nfunction extendFlatCoordinates(extent, flatCoordinates, offset, end, stride) {\n for (; offset < end; offset += stride) {\n extendXY(extent, flatCoordinates[offset], flatCoordinates[offset + 1]);\n }\n\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<Array<import("./coordinate.js").Coordinate>>} rings Rings.\n * @return {Extent} Extent.\n */\n\nfunction extendRings(extent, rings) {\n for (var i = 0, ii = rings.length; i < ii; ++i) {\n extendCoordinates(extent, rings[i]);\n }\n\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n */\n\nfunction extendXY(extent, x, y) {\n extent[0] = Math.min(extent[0], x);\n extent[1] = Math.min(extent[1], y);\n extent[2] = Math.max(extent[2], x);\n extent[3] = Math.max(extent[3], y);\n}\n/**\n * This function calls `callback` for each corner of the extent. If the\n * callback returns a truthy value the function returns that value\n * immediately. Otherwise the function returns `false`.\n * @param {Extent} extent Extent.\n * @param {function(import("./coordinate.js").Coordinate): S} callback Callback.\n * @return {S|boolean} Value.\n * @template S\n */\n\nfunction forEachCorner(extent, callback) {\n var val;\n val = callback(getBottomLeft(extent));\n\n if (val) {\n return val;\n }\n\n val = callback(getBottomRight(extent));\n\n if (val) {\n return val;\n }\n\n val = callback(getTopRight(extent));\n\n if (val) {\n return val;\n }\n\n val = callback(getTopLeft(extent));\n\n if (val) {\n return val;\n }\n\n return false;\n}\n/**\n * Get the size of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Area.\n * @api\n */\n\nfunction getArea(extent) {\n var area = 0;\n\n if (!extent_isEmpty(extent)) {\n area = extent_getWidth(extent) * getHeight(extent);\n }\n\n return area;\n}\n/**\n * Get the bottom left coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Bottom left coordinate.\n * @api\n */\n\nfunction getBottomLeft(extent) {\n return [extent[0], extent[1]];\n}\n/**\n * Get the bottom right coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Bottom right coordinate.\n * @api\n */\n\nfunction getBottomRight(extent) {\n return [extent[2], extent[1]];\n}\n/**\n * Get the center coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Center.\n * @api\n */\n\nfunction getCenter(extent) {\n return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];\n}\n/**\n * Get a corner coordinate of an extent.\n * @param {Extent} extent Extent.\n * @param {import("./extent/Corner.js").default} corner Corner.\n * @return {import("./coordinate.js").Coordinate} Corner coordinate.\n */\n\nfunction getCorner(extent, corner) {\n var coordinate;\n\n if (corner === Corner.BOTTOM_LEFT) {\n coordinate = getBottomLeft(extent);\n } else if (corner === Corner.BOTTOM_RIGHT) {\n coordinate = getBottomRight(extent);\n } else if (corner === Corner.TOP_LEFT) {\n coordinate = getTopLeft(extent);\n } else if (corner === Corner.TOP_RIGHT) {\n coordinate = getTopRight(extent);\n } else {\n asserts_assert(false, 13); // Invalid corner\n }\n\n return coordinate;\n}\n/**\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {number} Enlarged area.\n */\n\nfunction getEnlargedArea(extent1, extent2) {\n var minX = Math.min(extent1[0], extent2[0]);\n var minY = Math.min(extent1[1], extent2[1]);\n var maxX = Math.max(extent1[2], extent2[2]);\n var maxY = Math.max(extent1[3], extent2[3]);\n return (maxX - minX) * (maxY - minY);\n}\n/**\n * @param {import("./coordinate.js").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import("./size.js").Size} size Size.\n * @param {Extent=} opt_extent Destination extent.\n * @return {Extent} Extent.\n */\n\nfunction getForViewAndSize(center, resolution, rotation, size, opt_extent) {\n var dx = resolution * size[0] / 2;\n var dy = resolution * size[1] / 2;\n var cosRotation = Math.cos(rotation);\n var sinRotation = Math.sin(rotation);\n var xCos = dx * cosRotation;\n var xSin = dx * sinRotation;\n var yCos = dy * cosRotation;\n var ySin = dy * sinRotation;\n var x = center[0];\n var y = center[1];\n var x0 = x - xCos + ySin;\n var x1 = x - xCos - ySin;\n var x2 = x + xCos - ySin;\n var x3 = x + xCos + ySin;\n var y0 = y - xSin - yCos;\n var y1 = y - xSin + yCos;\n var y2 = y + xSin + yCos;\n var y3 = y + xSin - yCos;\n return createOrUpdate(Math.min(x0, x1, x2, x3), Math.min(y0, y1, y2, y3), Math.max(x0, x1, x2, x3), Math.max(y0, y1, y2, y3), opt_extent);\n}\n/**\n * Get the height of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Height.\n * @api\n */\n\nfunction getHeight(extent) {\n return extent[3] - extent[1];\n}\n/**\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {number} Intersection area.\n */\n\nfunction getIntersectionArea(extent1, extent2) {\n var intersection = getIntersection(extent1, extent2);\n return getArea(intersection);\n}\n/**\n * Get the intersection of two extents.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @param {Extent=} opt_extent Optional extent to populate with intersection.\n * @return {Extent} Intersecting extent.\n * @api\n */\n\nfunction getIntersection(extent1, extent2, opt_extent) {\n var intersection = opt_extent ? opt_extent : createEmpty();\n\n if (intersects(extent1, extent2)) {\n if (extent1[0] > extent2[0]) {\n intersection[0] = extent1[0];\n } else {\n intersection[0] = extent2[0];\n }\n\n if (extent1[1] > extent2[1]) {\n intersection[1] = extent1[1];\n } else {\n intersection[1] = extent2[1];\n }\n\n if (extent1[2] < extent2[2]) {\n intersection[2] = extent1[2];\n } else {\n intersection[2] = extent2[2];\n }\n\n if (extent1[3] < extent2[3]) {\n intersection[3] = extent1[3];\n } else {\n intersection[3] = extent2[3];\n }\n } else {\n createOrUpdateEmpty(intersection);\n }\n\n return intersection;\n}\n/**\n * @param {Extent} extent Extent.\n * @return {number} Margin.\n */\n\nfunction getMargin(extent) {\n return extent_getWidth(extent) + getHeight(extent);\n}\n/**\n * Get the size (width, height) of an extent.\n * @param {Extent} extent The extent.\n * @return {import("./size.js").Size} The extent size.\n * @api\n */\n\nfunction getSize(extent) {\n return [extent[2] - extent[0], extent[3] - extent[1]];\n}\n/**\n * Get the top left coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Top left coordinate.\n * @api\n */\n\nfunction getTopLeft(extent) {\n return [extent[0], extent[3]];\n}\n/**\n * Get the top right coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Top right coordinate.\n * @api\n */\n\nfunction getTopRight(extent) {\n return [extent[2], extent[3]];\n}\n/**\n * Get the width of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Width.\n * @api\n */\n\nfunction extent_getWidth(extent) {\n return extent[2] - extent[0];\n}\n/**\n * Determine if one extent intersects another.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent.\n * @return {boolean} The two extents intersect.\n * @api\n */\n\nfunction intersects(extent1, extent2) {\n return extent1[0] <= extent2[2] && extent1[2] >= extent2[0] && extent1[1] <= extent2[3] && extent1[3] >= extent2[1];\n}\n/**\n * Determine if an extent is empty.\n * @param {Extent} extent Extent.\n * @return {boolean} Is empty.\n * @api\n */\n\nfunction extent_isEmpty(extent) {\n return extent[2] < extent[0] || extent[3] < extent[1];\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction returnOrUpdate(extent, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0];\n opt_extent[1] = extent[1];\n opt_extent[2] = extent[2];\n opt_extent[3] = extent[3];\n return opt_extent;\n } else {\n return extent;\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} value Value.\n */\n\nfunction scaleFromCenter(extent, value) {\n var deltaX = (extent[2] - extent[0]) / 2 * (value - 1);\n var deltaY = (extent[3] - extent[1]) / 2 * (value - 1);\n extent[0] -= deltaX;\n extent[2] += deltaX;\n extent[1] -= deltaY;\n extent[3] += deltaY;\n}\n/**\n * Determine if the segment between two coordinates intersects (crosses,\n * touches, or is contained by) the provided extent.\n * @param {Extent} extent The extent.\n * @param {import("./coordinate.js").Coordinate} start Segment start coordinate.\n * @param {import("./coordinate.js").Coordinate} end Segment end coordinate.\n * @return {boolean} The segment intersects the extent.\n */\n\nfunction intersectsSegment(extent, start, end) {\n var intersects = false;\n var startRel = coordinateRelationship(extent, start);\n var endRel = coordinateRelationship(extent, end);\n\n if (startRel === Relationship.INTERSECTING || endRel === Relationship.INTERSECTING) {\n intersects = true;\n } else {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var startX = start[0];\n var startY = start[1];\n var endX = end[0];\n var endY = end[1];\n var slope = (endY - startY) / (endX - startX);\n var x = void 0,\n y = void 0;\n\n if (!!(endRel & Relationship.ABOVE) && !(startRel & Relationship.ABOVE)) {\n // potentially intersects top\n x = endX - (endY - maxY) / slope;\n intersects = x >= minX && x <= maxX;\n }\n\n if (!intersects && !!(endRel & Relationship.RIGHT) && !(startRel & Relationship.RIGHT)) {\n // potentially intersects right\n y = endY - (endX - maxX) * slope;\n intersects = y >= minY && y <= maxY;\n }\n\n if (!intersects && !!(endRel & Relationship.BELOW) && !(startRel & Relationship.BELOW)) {\n // potentially intersects bottom\n x = endX - (endY - minY) / slope;\n intersects = x >= minX && x <= maxX;\n }\n\n if (!intersects && !!(endRel & Relationship.LEFT) && !(startRel & Relationship.LEFT)) {\n // potentially intersects left\n y = endY - (endX - minX) * slope;\n intersects = y >= minY && y <= maxY;\n }\n }\n\n return intersects;\n}\n/**\n * Apply a transform function to the extent.\n * @param {Extent} extent Extent.\n * @param {import("./proj.js").TransformFunction} transformFn Transform function.\n * Called with `[minX, minY, maxX, maxY]` extent coordinates.\n * @param {Extent=} opt_extent Destination extent.\n * @param {number=} opt_stops Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {Extent} Extent.\n * @api\n */\n\nfunction applyTransform(extent, transformFn, opt_extent, opt_stops) {\n var coordinates = [];\n\n if (opt_stops > 1) {\n var width = extent[2] - extent[0];\n var height = extent[3] - extent[1];\n\n for (var i = 0; i < opt_stops; ++i) {\n coordinates.push(extent[0] + width * i / opt_stops, extent[1], extent[2], extent[1] + height * i / opt_stops, extent[2] - width * i / opt_stops, extent[3], extent[0], extent[3] - height * i / opt_stops);\n }\n } else {\n coordinates = [extent[0], extent[1], extent[2], extent[1], extent[2], extent[3], extent[0], extent[3]];\n }\n\n transformFn(coordinates, coordinates, 2);\n var xs = [];\n var ys = [];\n\n for (var i = 0, l = coordinates.length; i < l; i += 2) {\n xs.push(coordinates[i]);\n ys.push(coordinates[i + 1]);\n }\n\n return _boundingExtentXYs(xs, ys, opt_extent);\n}\n/**\n * Modifies the provided extent in-place to be within the real world\n * extent.\n *\n * @param {Extent} extent Extent.\n * @param {import("./proj/Projection.js").default} projection Projection\n * @return {Extent} The extent within the real world extent.\n */\n\nfunction wrapX(extent, projection) {\n var projectionExtent = projection.getExtent();\n var center = getCenter(extent);\n\n if (projection.canWrapX() && (center[0] < projectionExtent[0] || center[0] >= projectionExtent[2])) {\n var worldWidth = extent_getWidth(projectionExtent);\n var worldsAway = Math.floor((center[0] - projectionExtent[0]) / worldWidth);\n var offset = worldsAway * worldWidth;\n extent[0] -= offset;\n extent[2] -= offset;\n }\n\n return extent;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/math.js\n/**\n * @module ol/math\n */\n\n/**\n * Takes a number and clamps it to within the provided bounds.\n * @param {number} value The input number.\n * @param {number} min The minimum value to return.\n * @param {number} max The maximum value to return.\n * @return {number} The input number if it is within bounds, or the nearest\n * number within the bounds.\n */\nfunction math_clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n}\n/**\n * Return the hyperbolic cosine of a given number. The method will use the\n * native `Math.cosh` function if it is available, otherwise the hyperbolic\n * cosine will be calculated via the reference implementation of the Mozilla\n * developer network.\n *\n * @param {number} x X.\n * @return {number} Hyperbolic cosine of x.\n */\n\nvar cosh = function () {\n // Wrapped in a iife, to save the overhead of checking for the native\n // implementation on every invocation.\n var cosh;\n\n if (\'cosh\' in Math) {\n // The environment supports the native Math.cosh function, use it…\n cosh = Math.cosh;\n } else {\n // … else, use the reference implementation of MDN:\n cosh = function cosh(x) {\n var y =\n /** @type {Math} */\n Math.exp(x);\n return (y + 1 / y) / 2;\n };\n }\n\n return cosh;\n}();\n/**\n * Return the base 2 logarithm of a given number. The method will use the\n * native `Math.log2` function if it is available, otherwise the base 2\n * logarithm will be calculated via the reference implementation of the\n * Mozilla developer network.\n *\n * @param {number} x X.\n * @return {number} Base 2 logarithm of x.\n */\n\nvar log2 = function () {\n // Wrapped in a iife, to save the overhead of checking for the native\n // implementation on every invocation.\n var log2;\n\n if (\'log2\' in Math) {\n // The environment supports the native Math.log2 function, use it…\n log2 = Math.log2;\n } else {\n // … else, use the reference implementation of MDN:\n log2 = function log2(x) {\n return Math.log(x) * Math.LOG2E;\n };\n }\n\n return log2;\n}();\n/**\n * Returns the square of the closest distance between the point (x, y) and the\n * line segment (x1, y1) to (x2, y2).\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\n\nfunction squaredSegmentDistance(x, y, x1, y1, x2, y2) {\n var dx = x2 - x1;\n var dy = y2 - y1;\n\n if (dx !== 0 || dy !== 0) {\n var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n\n if (t > 1) {\n x1 = x2;\n y1 = y2;\n } else if (t > 0) {\n x1 += dx * t;\n y1 += dy * t;\n }\n }\n\n return math_squaredDistance(x, y, x1, y1);\n}\n/**\n * Returns the square of the distance between the points (x1, y1) and (x2, y2).\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\n\nfunction math_squaredDistance(x1, y1, x2, y2) {\n var dx = x2 - x1;\n var dy = y2 - y1;\n return dx * dx + dy * dy;\n}\n/**\n * Solves system of linear equations using Gaussian elimination method.\n *\n * @param {Array<Array<number>>} mat Augmented matrix (n x n + 1 column)\n * in row-major order.\n * @return {Array<number>} The resulting vector.\n */\n\nfunction solveLinearSystem(mat) {\n var n = mat.length;\n\n for (var i = 0; i < n; i++) {\n // Find max in the i-th column (ignoring i - 1 first rows)\n var maxRow = i;\n var maxEl = Math.abs(mat[i][i]);\n\n for (var r = i + 1; r < n; r++) {\n var absValue = Math.abs(mat[r][i]);\n\n if (absValue > maxEl) {\n maxEl = absValue;\n maxRow = r;\n }\n }\n\n if (maxEl === 0) {\n return null; // matrix is singular\n } // Swap max row with i-th (current) row\n\n\n var tmp = mat[maxRow];\n mat[maxRow] = mat[i];\n mat[i] = tmp; // Subtract the i-th row to make all the remaining rows 0 in the i-th column\n\n for (var j = i + 1; j < n; j++) {\n var coef = -mat[j][i] / mat[i][i];\n\n for (var k = i; k < n + 1; k++) {\n if (i == k) {\n mat[j][k] = 0;\n } else {\n mat[j][k] += coef * mat[i][k];\n }\n }\n }\n } // Solve Ax=b for upper triangular matrix A (mat)\n\n\n var x = new Array(n);\n\n for (var l = n - 1; l >= 0; l--) {\n x[l] = mat[l][n] / mat[l][l];\n\n for (var m = l - 1; m >= 0; m--) {\n mat[m][n] -= mat[m][l] * x[l];\n }\n }\n\n return x;\n}\n/**\n * Converts radians to to degrees.\n *\n * @param {number} angleInRadians Angle in radians.\n * @return {number} Angle in degrees.\n */\n\nfunction math_toDegrees(angleInRadians) {\n return angleInRadians * 180 / Math.PI;\n}\n/**\n * Converts degrees to radians.\n *\n * @param {number} angleInDegrees Angle in degrees.\n * @return {number} Angle in radians.\n */\n\nfunction math_toRadians(angleInDegrees) {\n return angleInDegrees * Math.PI / 180;\n}\n/**\n * Returns the modulo of a / b, depending on the sign of b.\n *\n * @param {number} a Dividend.\n * @param {number} b Divisor.\n * @return {number} Modulo.\n */\n\nfunction math_modulo(a, b) {\n var r = a % b;\n return r * b < 0 ? r + b : r;\n}\n/**\n * Calculates the linearly interpolated value of x between a and b.\n *\n * @param {number} a Number\n * @param {number} b Number\n * @param {number} x Value to be interpolated.\n * @return {number} Interpolated value.\n */\n\nfunction lerp(a, b, x) {\n return a + x * (b - a);\n}\n;// CONCATENATED MODULE: ./node_modules/ol/color.js\n/**\n * @module ol/color\n */\n\n\n/**\n * A color represented as a short array [red, green, blue, alpha].\n * red, green, and blue should be integers in the range 0..255 inclusive.\n * alpha should be a float in the range 0..1 inclusive. If no alpha value is\n * given then `1` will be used.\n * @typedef {Array<number>} Color\n * @api\n */\n\n/**\n * This RegExp matches # followed by 3, 4, 6, or 8 hex digits.\n * @const\n * @type {RegExp}\n * @private\n */\n\nvar HEX_COLOR_RE_ = /^#([a-f0-9]{3}|[a-f0-9]{4}(?:[a-f0-9]{2}){0,2})$/i;\n/**\n * Regular expression for matching potential named color style strings.\n * @const\n * @type {RegExp}\n * @private\n */\n\nvar NAMED_COLOR_RE_ = /^([a-z]*)$|^hsla?\\(.*\\)$/i;\n/**\n * Return the color as an rgba string.\n * @param {Color|string} color Color.\n * @return {string} Rgba string.\n * @api\n */\n\nfunction asString(color) {\n if (typeof color === \'string\') {\n return color;\n } else {\n return color_toString(color);\n }\n}\n/**\n * Return named color as an rgba string.\n * @param {string} color Named color.\n * @return {string} Rgb string.\n */\n\nfunction fromNamed(color) {\n var el = document.createElement(\'div\');\n el.style.color = color;\n\n if (el.style.color !== \'\') {\n document.body.appendChild(el);\n var rgb = getComputedStyle(el).color;\n document.body.removeChild(el);\n return rgb;\n } else {\n return \'\';\n }\n}\n/**\n * @param {string} s String.\n * @return {Color} Color.\n */\n\n\nvar fromString = function () {\n // We maintain a small cache of parsed strings. To provide cheap LRU-like\n // semantics, whenever the cache grows too large we simply delete an\n // arbitrary 25% of the entries.\n\n /**\n * @const\n * @type {number}\n */\n var MAX_CACHE_SIZE = 1024;\n /**\n * @type {Object<string, Color>}\n */\n\n var cache = {};\n /**\n * @type {number}\n */\n\n var cacheSize = 0;\n return (\n /**\n * @param {string} s String.\n * @return {Color} Color.\n */\n function (s) {\n var color;\n\n if (cache.hasOwnProperty(s)) {\n color = cache[s];\n } else {\n if (cacheSize >= MAX_CACHE_SIZE) {\n var i = 0;\n\n for (var key in cache) {\n if ((i++ & 3) === 0) {\n delete cache[key];\n --cacheSize;\n }\n }\n }\n\n color = fromStringInternal_(s);\n cache[s] = color;\n ++cacheSize;\n }\n\n return color;\n }\n );\n}();\n/**\n * Return the color as an array. This function maintains a cache of calculated\n * arrays which means the result should not be modified.\n * @param {Color|string} color Color.\n * @return {Color} Color.\n * @api\n */\n\nfunction asArray(color) {\n if (Array.isArray(color)) {\n return color;\n } else {\n return fromString(color);\n }\n}\n/**\n * @param {string} s String.\n * @private\n * @return {Color} Color.\n */\n\nfunction fromStringInternal_(s) {\n var r, g, b, a, color;\n\n if (NAMED_COLOR_RE_.exec(s)) {\n s = fromNamed(s);\n }\n\n if (HEX_COLOR_RE_.exec(s)) {\n // hex\n var n = s.length - 1; // number of hex digits\n\n var d = // number of digits per channel\n void 0; // number of digits per channel\n\n if (n <= 4) {\n d = 1;\n } else {\n d = 2;\n }\n\n var hasAlpha = n === 4 || n === 8;\n r = parseInt(s.substr(1 + 0 * d, d), 16);\n g = parseInt(s.substr(1 + 1 * d, d), 16);\n b = parseInt(s.substr(1 + 2 * d, d), 16);\n\n if (hasAlpha) {\n a = parseInt(s.substr(1 + 3 * d, d), 16);\n } else {\n a = 255;\n }\n\n if (d == 1) {\n r = (r << 4) + r;\n g = (g << 4) + g;\n b = (b << 4) + b;\n\n if (hasAlpha) {\n a = (a << 4) + a;\n }\n }\n\n color = [r, g, b, a / 255];\n } else if (s.indexOf(\'rgba(\') == 0) {\n // rgba()\n color = s.slice(5, -1).split(\',\').map(Number);\n normalize(color);\n } else if (s.indexOf(\'rgb(\') == 0) {\n // rgb()\n color = s.slice(4, -1).split(\',\').map(Number);\n color.push(1);\n normalize(color);\n } else {\n asserts_assert(false, 14); // Invalid color\n }\n\n return color;\n}\n/**\n * TODO this function is only used in the test, we probably shouldn\'t export it\n * @param {Color} color Color.\n * @return {Color} Clamped color.\n */\n\n\nfunction normalize(color) {\n color[0] = math_clamp(color[0] + 0.5 | 0, 0, 255);\n color[1] = math_clamp(color[1] + 0.5 | 0, 0, 255);\n color[2] = math_clamp(color[2] + 0.5 | 0, 0, 255);\n color[3] = math_clamp(color[3], 0, 1);\n return color;\n}\n/**\n * @param {Color} color Color.\n * @return {string} String.\n */\n\nfunction color_toString(color) {\n var r = color[0];\n\n if (r != (r | 0)) {\n r = r + 0.5 | 0;\n }\n\n var g = color[1];\n\n if (g != (g | 0)) {\n g = g + 0.5 | 0;\n }\n\n var b = color[2];\n\n if (b != (b | 0)) {\n b = b + 0.5 | 0;\n }\n\n var a = color[3] === undefined ? 1 : color[3];\n return \'rgba(\' + r + \',\' + g + \',\' + b + \',\' + a + \')\';\n}\n/**\n * @param {string} s String.\n * @return {boolean} Whether the string is actually a valid color\n */\n\nfunction isStringColor(s) {\n if (NAMED_COLOR_RE_.test(s)) {\n s = fromNamed(s);\n }\n\n return HEX_COLOR_RE_.test(s) || s.indexOf(\'rgba(\') === 0 || s.indexOf(\'rgb(\') === 0;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/style/IconImageCache.js\n/**\n * @module ol/style/IconImageCache\n */\n\n/**\n * @classdesc\n * Singleton class. Available through {@link module:ol/style/IconImageCache~shared}.\n */\n\nvar IconImageCache =\n/** @class */\nfunction () {\n function IconImageCache() {\n /**\n * @type {!Object<string, import("./IconImage.js").default>}\n * @private\n */\n this.cache_ = {};\n /**\n * @type {number}\n * @private\n */\n\n this.cacheSize_ = 0;\n /**\n * @type {number}\n * @private\n */\n\n this.maxCacheSize_ = 32;\n }\n /**\n * FIXME empty description for jsdoc\n */\n\n\n IconImageCache.prototype.clear = function () {\n this.cache_ = {};\n this.cacheSize_ = 0;\n };\n /**\n * @return {boolean} Can expire cache.\n */\n\n\n IconImageCache.prototype.canExpireCache = function () {\n return this.cacheSize_ > this.maxCacheSize_;\n };\n /**\n * FIXME empty description for jsdoc\n */\n\n\n IconImageCache.prototype.expire = function () {\n if (this.canExpireCache()) {\n var i = 0;\n\n for (var key in this.cache_) {\n var iconImage = this.cache_[key];\n\n if ((i++ & 3) === 0 && !iconImage.hasListener()) {\n delete this.cache_[key];\n --this.cacheSize_;\n }\n }\n }\n };\n /**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("../color.js").Color} color Color.\n * @return {import("./IconImage.js").default} Icon image.\n */\n\n\n IconImageCache.prototype.get = function (src, crossOrigin, color) {\n var key = getKey(src, crossOrigin, color);\n return key in this.cache_ ? this.cache_[key] : null;\n };\n /**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("../color.js").Color} color Color.\n * @param {import("./IconImage.js").default} iconImage Icon image.\n */\n\n\n IconImageCache.prototype.set = function (src, crossOrigin, color, iconImage) {\n var key = getKey(src, crossOrigin, color);\n this.cache_[key] = iconImage;\n ++this.cacheSize_;\n };\n /**\n * Set the cache size of the icon cache. Default is `32`. Change this value when\n * your map uses more than 32 different icon images and you are not caching icon\n * styles on the application level.\n * @param {number} maxCacheSize Cache max size.\n * @api\n */\n\n\n IconImageCache.prototype.setSize = function (maxCacheSize) {\n this.maxCacheSize_ = maxCacheSize;\n this.expire();\n };\n\n return IconImageCache;\n}();\n/**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("../color.js").Color} color Color.\n * @return {string} Cache key.\n */\n\n\nfunction getKey(src, crossOrigin, color) {\n var colorString = color ? asString(color) : \'null\';\n return crossOrigin + \':\' + src + \':\' + colorString;\n}\n\n/* harmony default export */ var style_IconImageCache = ((/* unused pure expression or super */ null && (IconImageCache)));\n/**\n * The {@link module:ol/style/IconImageCache~IconImageCache} for\n * {@link module:ol/style/Icon~Icon} images.\n * @api\n */\n\nvar shared = new IconImageCache();\n;// CONCATENATED MODULE: ./node_modules/ol/events/Event.js\n/**\n * @module ol/events/Event\n */\n\n/**\n * @classdesc\n * Stripped down implementation of the W3C DOM Level 2 Event interface.\n * See https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface.\n *\n * This implementation only provides `type` and `target` properties, and\n * `stopPropagation` and `preventDefault` methods. It is meant as base class\n * for higher level events defined in the library, and works with\n * {@link module:ol/events/Target~Target}.\n */\nvar BaseEvent =\n/** @class */\nfunction () {\n /**\n * @param {string} type Type.\n */\n function BaseEvent(type) {\n /**\n * @type {boolean}\n */\n this.propagationStopped;\n /**\n * The event type.\n * @type {string}\n * @api\n */\n\n this.type = type;\n /**\n * The event target.\n * @type {Object}\n * @api\n */\n\n this.target = null;\n }\n /**\n * Stop event propagation.\n * @api\n */\n\n\n BaseEvent.prototype.preventDefault = function () {\n this.propagationStopped = true;\n };\n /**\n * Stop event propagation.\n * @api\n */\n\n\n BaseEvent.prototype.stopPropagation = function () {\n this.propagationStopped = true;\n };\n\n return BaseEvent;\n}();\n/**\n * @param {Event|import("./Event.js").default} evt Event\n */\n\n\nfunction stopPropagation(evt) {\n evt.stopPropagation();\n}\n/**\n * @param {Event|import("./Event.js").default} evt Event\n */\n\nfunction preventDefault(evt) {\n evt.preventDefault();\n}\n/* harmony default export */ var Event = (BaseEvent);\n;// CONCATENATED MODULE: ./node_modules/ol/ObjectEventType.js\n/**\n * @module ol/ObjectEventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var ObjectEventType = ({\n /**\n * Triggered when a property is changed.\n * @event module:ol/Object.ObjectEvent#propertychange\n * @api\n */\n PROPERTYCHANGE: \'propertychange\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/obj.js\n/**\n * @module ol/obj\n */\n\n/**\n * Polyfill for Object.assign(). Assigns enumerable and own properties from\n * one or more source objects to a target object.\n * See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign.\n *\n * @param {!Object} target The target object.\n * @param {...Object} var_sources The source object(s).\n * @return {!Object} The modified target object.\n */\nvar obj_assign = typeof Object.assign === \'function\' ? Object.assign : function (target, var_sources) {\n if (target === undefined || target === null) {\n throw new TypeError(\'Cannot convert undefined or null to object\');\n }\n\n var output = Object(target);\n\n for (var i = 1, ii = arguments.length; i < ii; ++i) {\n var source = arguments[i];\n\n if (source !== undefined && source !== null) {\n for (var key in source) {\n if (source.hasOwnProperty(key)) {\n output[key] = source[key];\n }\n }\n }\n }\n\n return output;\n};\n/**\n * Removes all properties from an object.\n * @param {Object} object The object to clear.\n */\n\nfunction clear(object) {\n for (var property in object) {\n delete object[property];\n }\n}\n/**\n * Polyfill for Object.values(). Get an array of property values from an object.\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values\n *\n * @param {!Object<K,V>} object The object from which to get the values.\n * @return {!Array<V>} The property values.\n * @template K,V\n */\n\nvar getValues = typeof Object.values === \'function\' ? Object.values : function (object) {\n var values = [];\n\n for (var property in object) {\n values.push(object[property]);\n }\n\n return values;\n};\n/**\n * Determine if an object has any properties.\n * @param {Object} object The object to check.\n * @return {boolean} The object is empty.\n */\n\nfunction obj_isEmpty(object) {\n var property;\n\n for (property in object) {\n return false;\n }\n\n return !property;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/events/Target.js\nvar Target_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/events/Target\n */\n\n\n\n\n\n\n/**\n * @typedef {EventTarget|Target} EventTargetLike\n */\n\n/**\n * @classdesc\n * A simplified implementation of the W3C DOM Level 2 EventTarget interface.\n * See https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget.\n *\n * There are two important simplifications compared to the specification:\n *\n * 1. The handling of `useCapture` in `addEventListener` and\n * `removeEventListener`. There is no real capture model.\n * 2. The handling of `stopPropagation` and `preventDefault` on `dispatchEvent`.\n * There is no event target hierarchy. When a listener calls\n * `stopPropagation` or `preventDefault` on an event object, it means that no\n * more listeners after this one will be called. Same as when the listener\n * returns false.\n */\n\nvar Target =\n/** @class */\nfunction (_super) {\n Target_extends(Target, _super);\n /**\n * @param {*=} opt_target Default event target for dispatched events.\n */\n\n\n function Target(opt_target) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {*}\n */\n\n\n _this.eventTarget_ = opt_target;\n /**\n * @private\n * @type {Object<string, number>}\n */\n\n _this.pendingRemovals_ = null;\n /**\n * @private\n * @type {Object<string, number>}\n */\n\n _this.dispatching_ = null;\n /**\n * @private\n * @type {Object<string, Array<import("../events.js").Listener>>}\n */\n\n _this.listeners_ = null;\n return _this;\n }\n /**\n * @param {string} type Type.\n * @param {import("../events.js").Listener} listener Listener.\n */\n\n\n Target.prototype.addEventListener = function (type, listener) {\n if (!type || !listener) {\n return;\n }\n\n var listeners = this.listeners_ || (this.listeners_ = {});\n var listenersForType = listeners[type] || (listeners[type] = []);\n\n if (listenersForType.indexOf(listener) === -1) {\n listenersForType.push(listener);\n }\n };\n /**\n * Dispatches an event and calls all listeners listening for events\n * of this type. The event parameter can either be a string or an\n * Object with a `type` property.\n *\n * @param {import("./Event.js").default|string} event Event object.\n * @return {boolean|undefined} `false` if anyone called preventDefault on the\n * event object or if any of the listeners returned false.\n * @api\n */\n\n\n Target.prototype.dispatchEvent = function (event) {\n /** @type {import("./Event.js").default|Event} */\n var evt = typeof event === \'string\' ? new Event(event) : event;\n var type = evt.type;\n\n if (!evt.target) {\n evt.target = this.eventTarget_ || this;\n }\n\n var listeners = this.listeners_ && this.listeners_[type];\n var propagate;\n\n if (listeners) {\n var dispatching = this.dispatching_ || (this.dispatching_ = {});\n var pendingRemovals = this.pendingRemovals_ || (this.pendingRemovals_ = {});\n\n if (!(type in dispatching)) {\n dispatching[type] = 0;\n pendingRemovals[type] = 0;\n }\n\n ++dispatching[type];\n\n for (var i = 0, ii = listeners.length; i < ii; ++i) {\n if (\'handleEvent\' in listeners[i]) {\n propagate =\n /** @type {import("../events.js").ListenerObject} */\n listeners[i].handleEvent(evt);\n } else {\n propagate =\n /** @type {import("../events.js").ListenerFunction} */\n listeners[i].call(this, evt);\n }\n\n if (propagate === false || evt.propagationStopped) {\n propagate = false;\n break;\n }\n }\n\n --dispatching[type];\n\n if (dispatching[type] === 0) {\n var pr = pendingRemovals[type];\n delete pendingRemovals[type];\n\n while (pr--) {\n this.removeEventListener(type, VOID);\n }\n\n delete dispatching[type];\n }\n\n return propagate;\n }\n };\n /**\n * Clean up.\n */\n\n\n Target.prototype.disposeInternal = function () {\n this.listeners_ && clear(this.listeners_);\n };\n /**\n * Get the listeners for a specified event type. Listeners are returned in the\n * order that they will be called in.\n *\n * @param {string} type Type.\n * @return {Array<import("../events.js").Listener>|undefined} Listeners.\n */\n\n\n Target.prototype.getListeners = function (type) {\n return this.listeners_ && this.listeners_[type] || undefined;\n };\n /**\n * @param {string=} opt_type Type. If not provided,\n * `true` will be returned if this event target has any listeners.\n * @return {boolean} Has listeners.\n */\n\n\n Target.prototype.hasListener = function (opt_type) {\n if (!this.listeners_) {\n return false;\n }\n\n return opt_type ? opt_type in this.listeners_ : Object.keys(this.listeners_).length > 0;\n };\n /**\n * @param {string} type Type.\n * @param {import("../events.js").Listener} listener Listener.\n */\n\n\n Target.prototype.removeEventListener = function (type, listener) {\n var listeners = this.listeners_ && this.listeners_[type];\n\n if (listeners) {\n var index = listeners.indexOf(listener);\n\n if (index !== -1) {\n if (this.pendingRemovals_ && type in this.pendingRemovals_) {\n // make listener a no-op, and remove later in #dispatchEvent()\n listeners[index] = VOID;\n ++this.pendingRemovals_[type];\n } else {\n listeners.splice(index, 1);\n\n if (listeners.length === 0) {\n delete this.listeners_[type];\n }\n }\n }\n }\n };\n\n return Target;\n}(ol_Disposable);\n\n/* harmony default export */ var events_Target = (Target);\n;// CONCATENATED MODULE: ./node_modules/ol/events/EventType.js\n/**\n * @module ol/events/EventType\n */\n\n/**\n * @enum {string}\n * @const\n */\n/* harmony default export */ var EventType = ({\n /**\n * Generic change event. Triggered when the revision counter is increased.\n * @event module:ol/events/Event~BaseEvent#change\n * @api\n */\n CHANGE: \'change\',\n\n /**\n * Generic error event. Triggered when an error occurs.\n * @event module:ol/events/Event~BaseEvent#error\n * @api\n */\n ERROR: \'error\',\n BLUR: \'blur\',\n CLEAR: \'clear\',\n CONTEXTMENU: \'contextmenu\',\n CLICK: \'click\',\n DBLCLICK: \'dblclick\',\n DRAGENTER: \'dragenter\',\n DRAGOVER: \'dragover\',\n DROP: \'drop\',\n FOCUS: \'focus\',\n KEYDOWN: \'keydown\',\n KEYPRESS: \'keypress\',\n LOAD: \'load\',\n RESIZE: \'resize\',\n TOUCHMOVE: \'touchmove\',\n WHEEL: \'wheel\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/events.js\n/**\n * @module ol/events\n */\n\n/**\n * Key to use with {@link module:ol/Observable~Observable#unByKey}.\n * @typedef {Object} EventsKey\n * @property {ListenerFunction} listener\n * @property {import("./events/Target.js").EventTargetLike} target\n * @property {string} type\n * @api\n */\n\n/**\n * Listener function. This function is called with an event object as argument.\n * When the function returns `false`, event propagation will stop.\n *\n * @typedef {function((Event|import("./events/Event.js").default)): (void|boolean)} ListenerFunction\n * @api\n */\n\n/**\n * @typedef {Object} ListenerObject\n * @property {ListenerFunction} handleEvent\n */\n\n/**\n * @typedef {ListenerFunction|ListenerObject} Listener\n */\n\n/**\n * Registers an event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` to a `this` object, and returns\n * a key for use with {@link module:ol/events~unlistenByKey}.\n *\n * @param {import("./events/Target.js").EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {ListenerFunction} listener Listener.\n * @param {Object=} opt_this Object referenced by the `this` keyword in the\n * listener. Default is the `target`.\n * @param {boolean=} opt_once If true, add the listener as one-off listener.\n * @return {EventsKey} Unique key for the listener.\n */\n\nfunction listen(target, type, _listener, opt_this, opt_once) {\n if (opt_this && opt_this !== target) {\n _listener = _listener.bind(opt_this);\n }\n\n if (opt_once) {\n var originalListener_1 = _listener;\n\n _listener = function listener() {\n target.removeEventListener(type, _listener);\n originalListener_1.apply(this, arguments);\n };\n }\n\n var eventsKey = {\n target: target,\n type: type,\n listener: _listener\n };\n target.addEventListener(type, _listener);\n return eventsKey;\n}\n/**\n * Registers a one-off event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` as self-unregistering listener\n * to a `this` object, and returns a key for use with\n * {@link module:ol/events~unlistenByKey} in case the listener needs to be\n * unregistered before it is called.\n *\n * When {@link module:ol/events~listen} is called with the same arguments after this\n * function, the self-unregistering listener will be turned into a permanent\n * listener.\n *\n * @param {import("./events/Target.js").EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {ListenerFunction} listener Listener.\n * @param {Object=} opt_this Object referenced by the `this` keyword in the\n * listener. Default is the `target`.\n * @return {EventsKey} Key for unlistenByKey.\n */\n\nfunction listenOnce(target, type, listener, opt_this) {\n return listen(target, type, listener, opt_this, true);\n}\n/**\n * Unregisters event listeners on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * The argument passed to this function is the key returned from\n * {@link module:ol/events~listen} or {@link module:ol/events~listenOnce}.\n *\n * @param {EventsKey} key The key.\n */\n\nfunction unlistenByKey(key) {\n if (key && key.target) {\n key.target.removeEventListener(key.type, key.listener);\n clear(key);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/Observable.js\nvar Observable_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Observable\n */\n\n\n\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * An event target providing convenient methods for listener registration\n * and unregistration. A generic `change` event is always available through\n * {@link module:ol/Observable~Observable#changed}.\n *\n * @fires import("./events/Event.js").default\n * @api\n */\n\nvar Observable =\n/** @class */\nfunction (_super) {\n Observable_extends(Observable, _super);\n\n function Observable() {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {number}\n */\n\n\n _this.revision_ = 0;\n return _this;\n }\n /**\n * Increases the revision counter and dispatches a \'change\' event.\n * @api\n */\n\n\n Observable.prototype.changed = function () {\n ++this.revision_;\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * Get the version number for this object. Each time the object is modified,\n * its version number will be incremented.\n * @return {number} Revision.\n * @api\n */\n\n\n Observable.prototype.getRevision = function () {\n return this.revision_;\n };\n /**\n * Listen for a certain type of event.\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function(?): ?} listener The listener function.\n * @return {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} Unique key for the listener. If\n * called with an array of event types as the first argument, the return\n * will be an array of keys.\n * @api\n */\n\n\n Observable.prototype.on = function (type, listener) {\n if (Array.isArray(type)) {\n var len = type.length;\n var keys = new Array(len);\n\n for (var i = 0; i < len; ++i) {\n keys[i] = listen(this, type[i], listener);\n }\n\n return keys;\n } else {\n return listen(this,\n /** @type {string} */\n type, listener);\n }\n };\n /**\n * Listen once for a certain type of event.\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function(?): ?} listener The listener function.\n * @return {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} Unique key for the listener. If\n * called with an array of event types as the first argument, the return\n * will be an array of keys.\n * @api\n */\n\n\n Observable.prototype.once = function (type, listener) {\n var key;\n\n if (Array.isArray(type)) {\n var len = type.length;\n key = new Array(len);\n\n for (var i = 0; i < len; ++i) {\n key[i] = listenOnce(this, type[i], listener);\n }\n } else {\n key = listenOnce(this,\n /** @type {string} */\n type, listener);\n }\n /** @type {Object} */\n\n\n listener.ol_key = key;\n return key;\n };\n /**\n * Unlisten for a certain type of event.\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function(?): ?} listener The listener function.\n * @api\n */\n\n\n Observable.prototype.un = function (type, listener) {\n var key =\n /** @type {Object} */\n listener.ol_key;\n\n if (key) {\n unByKey(key);\n } else if (Array.isArray(type)) {\n for (var i = 0, ii = type.length; i < ii; ++i) {\n this.removeEventListener(type[i], listener);\n }\n } else {\n this.removeEventListener(type, listener);\n }\n };\n\n return Observable;\n}(events_Target);\n/**\n * Removes an event listener using the key returned by `on()` or `once()`.\n * @param {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} key The key returned by `on()`\n * or `once()` (or an array of keys).\n * @api\n */\n\n\nfunction unByKey(key) {\n if (Array.isArray(key)) {\n for (var i = 0, ii = key.length; i < ii; ++i) {\n unlistenByKey(key[i]);\n }\n } else {\n unlistenByKey(\n /** @type {import("./events.js").EventsKey} */\n key);\n }\n}\n/* harmony default export */ var ol_Observable = (Observable);\n;// CONCATENATED MODULE: ./node_modules/ol/Object.js\nvar Object_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Object\n */\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/Object~BaseObject} instances are instances of this type.\n */\n\nvar ObjectEvent =\n/** @class */\nfunction (_super) {\n Object_extends(ObjectEvent, _super);\n /**\n * @param {string} type The event type.\n * @param {string} key The property name.\n * @param {*} oldValue The old value for `key`.\n */\n\n\n function ObjectEvent(type, key, oldValue) {\n var _this = _super.call(this, type) || this;\n /**\n * The name of the property whose value is changing.\n * @type {string}\n * @api\n */\n\n\n _this.key = key;\n /**\n * The old value. To get the new value use `e.target.get(e.key)` where\n * `e` is the event object.\n * @type {*}\n * @api\n */\n\n _this.oldValue = oldValue;\n return _this;\n }\n\n return ObjectEvent;\n}(Event);\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Most non-trivial classes inherit from this.\n *\n * This extends {@link module:ol/Observable} with observable\n * properties, where each property is observable as well as the object as a\n * whole.\n *\n * Classes that inherit from this have pre-defined properties, to which you can\n * add your owns. The pre-defined properties are listed in this documentation as\n * \'Observable Properties\', and have their own accessors; for example,\n * {@link module:ol/Map~Map} has a `target` property, accessed with\n * `getTarget()` and changed with `setTarget()`. Not all properties are however\n * settable. There are also general-purpose accessors `get()` and `set()`. For\n * example, `get(\'target\')` is equivalent to `getTarget()`.\n *\n * The `set` accessors trigger a change event, and you can monitor this by\n * registering a listener. For example, {@link module:ol/View~View} has a\n * `center` property, so `view.on(\'change:center\', function(evt) {...});` would\n * call the function whenever the value of the center property changes. Within\n * the function, `evt.target` would be the view, so `evt.target.getCenter()`\n * would return the new center.\n *\n * You can add your own observable properties with\n * `object.set(\'prop\', \'value\')`, and retrieve that with `object.get(\'prop\')`.\n * You can listen for changes on that property value with\n * `object.on(\'change:prop\', listener)`. You can get a list of all\n * properties with {@link module:ol/Object~BaseObject#getProperties}.\n *\n * Note that the observable properties are separate from standard JS properties.\n * You can, for example, give your map object a title with\n * `map.title=\'New title\'` and with `map.set(\'title\', \'Another title\')`. The\n * first will be a `hasOwnProperty`; the second will appear in\n * `getProperties()`. Only the second is observable.\n *\n * Properties can be deleted by using the unset method. E.g.\n * object.unset(\'foo\').\n *\n * @fires ObjectEvent\n * @api\n */\n\nvar BaseObject =\n/** @class */\nfunction (_super) {\n Object_extends(BaseObject, _super);\n /**\n * @param {Object<string, *>=} opt_values An object with key-value pairs.\n */\n\n\n function BaseObject(opt_values) {\n var _this = _super.call(this) || this; // Call {@link module:ol/util~getUid} to ensure that the order of objects\' ids is\n // the same as the order in which they were created. This also helps to\n // ensure that object properties are always added in the same order, which\n // helps many JavaScript engines generate faster code.\n\n\n getUid(_this);\n /**\n * @private\n * @type {Object<string, *>}\n */\n\n _this.values_ = null;\n\n if (opt_values !== undefined) {\n _this.setProperties(opt_values);\n }\n\n return _this;\n }\n /**\n * Gets a value.\n * @param {string} key Key name.\n * @return {*} Value.\n * @api\n */\n\n\n BaseObject.prototype.get = function (key) {\n var value;\n\n if (this.values_ && this.values_.hasOwnProperty(key)) {\n value = this.values_[key];\n }\n\n return value;\n };\n /**\n * Get a list of object property names.\n * @return {Array<string>} List of property names.\n * @api\n */\n\n\n BaseObject.prototype.getKeys = function () {\n return this.values_ && Object.keys(this.values_) || [];\n };\n /**\n * Get an object of all property names and values.\n * @return {Object<string, *>} Object.\n * @api\n */\n\n\n BaseObject.prototype.getProperties = function () {\n return this.values_ && obj_assign({}, this.values_) || {};\n };\n /**\n * @return {boolean} The object has properties.\n */\n\n\n BaseObject.prototype.hasProperties = function () {\n return !!this.values_;\n };\n /**\n * @param {string} key Key name.\n * @param {*} oldValue Old value.\n */\n\n\n BaseObject.prototype.notify = function (key, oldValue) {\n var eventType;\n eventType = getChangeEventType(key);\n this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n eventType = ObjectEventType.PROPERTYCHANGE;\n this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n };\n /**\n * Sets a value.\n * @param {string} key Key name.\n * @param {*} value Value.\n * @param {boolean=} opt_silent Update without triggering an event.\n * @api\n */\n\n\n BaseObject.prototype.set = function (key, value, opt_silent) {\n var values = this.values_ || (this.values_ = {});\n\n if (opt_silent) {\n values[key] = value;\n } else {\n var oldValue = values[key];\n values[key] = value;\n\n if (oldValue !== value) {\n this.notify(key, oldValue);\n }\n }\n };\n /**\n * Sets a collection of key-value pairs. Note that this changes any existing\n * properties and adds new ones (it does not remove any existing properties).\n * @param {Object<string, *>} values Values.\n * @param {boolean=} opt_silent Update without triggering an event.\n * @api\n */\n\n\n BaseObject.prototype.setProperties = function (values, opt_silent) {\n for (var key in values) {\n this.set(key, values[key], opt_silent);\n }\n };\n /**\n * Apply any properties from another object without triggering events.\n * @param {BaseObject} source The source object.\n * @protected\n */\n\n\n BaseObject.prototype.applyProperties = function (source) {\n if (!source.values_) {\n return;\n }\n\n obj_assign(this.values_ || (this.values_ = {}), source.values_);\n };\n /**\n * Unsets a property.\n * @param {string} key Key name.\n * @param {boolean=} opt_silent Unset without triggering an event.\n * @api\n */\n\n\n BaseObject.prototype.unset = function (key, opt_silent) {\n if (this.values_ && key in this.values_) {\n var oldValue = this.values_[key];\n delete this.values_[key];\n\n if (obj_isEmpty(this.values_)) {\n this.values_ = null;\n }\n\n if (!opt_silent) {\n this.notify(key, oldValue);\n }\n }\n };\n\n return BaseObject;\n}(ol_Observable);\n/**\n * @type {Object<string, string>}\n */\n\n\nvar changeEventTypeCache = {};\n/**\n * @param {string} key Key name.\n * @return {string} Change name.\n */\n\nfunction getChangeEventType(key) {\n return changeEventTypeCache.hasOwnProperty(key) ? changeEventTypeCache[key] : changeEventTypeCache[key] = \'change:\' + key;\n}\n/* harmony default export */ var ol_Object = (BaseObject);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Property.js\n/**\n * @module ol/layer/Property\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var Property = ({\n OPACITY: \'opacity\',\n VISIBLE: \'visible\',\n EXTENT: \'extent\',\n Z_INDEX: \'zIndex\',\n MAX_RESOLUTION: \'maxResolution\',\n MIN_RESOLUTION: \'minResolution\',\n MAX_ZOOM: \'maxZoom\',\n MIN_ZOOM: \'minZoom\',\n SOURCE: \'source\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Base.js\nvar Base_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/Base\n */\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-layer\'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Note that with {@link module:ol/layer/Base} and all its subclasses, any property set in\n * the options is set as a {@link module:ol/Object} property on the layer object, so\n * is observable, and has get/set accessors.\n *\n * @api\n */\n\nvar BaseLayer =\n/** @class */\nfunction (_super) {\n Base_extends(BaseLayer, _super);\n /**\n * @param {Options} options Layer options.\n */\n\n\n function BaseLayer(options) {\n var _this = _super.call(this) || this;\n /**\n * @type {Object<string, *>}\n */\n\n\n var properties = obj_assign({}, options);\n properties[Property.OPACITY] = options.opacity !== undefined ? options.opacity : 1;\n asserts_assert(typeof properties[Property.OPACITY] === \'number\', 64); // Layer opacity must be a number\n\n properties[Property.VISIBLE] = options.visible !== undefined ? options.visible : true;\n properties[Property.Z_INDEX] = options.zIndex;\n properties[Property.MAX_RESOLUTION] = options.maxResolution !== undefined ? options.maxResolution : Infinity;\n properties[Property.MIN_RESOLUTION] = options.minResolution !== undefined ? options.minResolution : 0;\n properties[Property.MIN_ZOOM] = options.minZoom !== undefined ? options.minZoom : -Infinity;\n properties[Property.MAX_ZOOM] = options.maxZoom !== undefined ? options.maxZoom : Infinity;\n /**\n * @type {string}\n * @private\n */\n\n _this.className_ = properties.className !== undefined ? options.className : \'ol-layer\';\n delete properties.className;\n\n _this.setProperties(properties);\n /**\n * @type {import("./Layer.js").State}\n * @private\n */\n\n\n _this.state_ = null;\n return _this;\n }\n /**\n * @return {string} CSS class name.\n */\n\n\n BaseLayer.prototype.getClassName = function () {\n return this.className_;\n };\n /**\n * This method is not meant to be called by layers or layer renderers because the state\n * is incorrect if the layer is included in a layer group.\n *\n * @param {boolean=} opt_managed Layer is managed.\n * @return {import("./Layer.js").State} Layer state.\n */\n\n\n BaseLayer.prototype.getLayerState = function (opt_managed) {\n /** @type {import("./Layer.js").State} */\n var state = this.state_ ||\n /** @type {?} */\n {\n layer: this,\n managed: opt_managed === undefined ? true : opt_managed\n };\n var zIndex = this.getZIndex();\n state.opacity = math_clamp(Math.round(this.getOpacity() * 100) / 100, 0, 1);\n state.sourceState = this.getSourceState();\n state.visible = this.getVisible();\n state.extent = this.getExtent();\n state.zIndex = zIndex !== undefined ? zIndex : state.managed === false ? Infinity : 0;\n state.maxResolution = this.getMaxResolution();\n state.minResolution = Math.max(this.getMinResolution(), 0);\n state.minZoom = this.getMinZoom();\n state.maxZoom = this.getMaxZoom();\n this.state_ = state;\n return state;\n };\n /**\n * @abstract\n * @param {Array<import("./Layer.js").default>=} opt_array Array of layers (to be\n * modified in place).\n * @return {Array<import("./Layer.js").default>} Array of layers.\n */\n\n\n BaseLayer.prototype.getLayersArray = function (opt_array) {\n return util_abstract();\n };\n /**\n * @abstract\n * @param {Array<import("./Layer.js").State>=} opt_states Optional list of layer\n * states (to be modified in place).\n * @return {Array<import("./Layer.js").State>} List of layer states.\n */\n\n\n BaseLayer.prototype.getLayerStatesArray = function (opt_states) {\n return util_abstract();\n };\n /**\n * Return the {@link module:ol/extent~Extent extent} of the layer or `undefined` if it\n * will be visible regardless of extent.\n * @return {import("../extent.js").Extent|undefined} The layer extent.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getExtent = function () {\n return (\n /** @type {import("../extent.js").Extent|undefined} */\n this.get(Property.EXTENT)\n );\n };\n /**\n * Return the maximum resolution of the layer.\n * @return {number} The maximum resolution of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getMaxResolution = function () {\n return (\n /** @type {number} */\n this.get(Property.MAX_RESOLUTION)\n );\n };\n /**\n * Return the minimum resolution of the layer.\n * @return {number} The minimum resolution of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getMinResolution = function () {\n return (\n /** @type {number} */\n this.get(Property.MIN_RESOLUTION)\n );\n };\n /**\n * Return the minimum zoom level of the layer.\n * @return {number} The minimum zoom level of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getMinZoom = function () {\n return (\n /** @type {number} */\n this.get(Property.MIN_ZOOM)\n );\n };\n /**\n * Return the maximum zoom level of the layer.\n * @return {number} The maximum zoom level of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getMaxZoom = function () {\n return (\n /** @type {number} */\n this.get(Property.MAX_ZOOM)\n );\n };\n /**\n * Return the opacity of the layer (between 0 and 1).\n * @return {number} The opacity of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getOpacity = function () {\n return (\n /** @type {number} */\n this.get(Property.OPACITY)\n );\n };\n /**\n * @abstract\n * @return {import("../source/State.js").default} Source state.\n */\n\n\n BaseLayer.prototype.getSourceState = function () {\n return util_abstract();\n };\n /**\n * Return the visibility of the layer (`true` or `false`).\n * @return {boolean} The visibility of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getVisible = function () {\n return (\n /** @type {boolean} */\n this.get(Property.VISIBLE)\n );\n };\n /**\n * Return the Z-index of the layer, which is used to order layers before\n * rendering. The default Z-index is 0.\n * @return {number} The Z-index of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getZIndex = function () {\n return (\n /** @type {number} */\n this.get(Property.Z_INDEX)\n );\n };\n /**\n * Set the extent at which the layer is visible. If `undefined`, the layer\n * will be visible at all extents.\n * @param {import("../extent.js").Extent|undefined} extent The extent of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setExtent = function (extent) {\n this.set(Property.EXTENT, extent);\n };\n /**\n * Set the maximum resolution at which the layer is visible.\n * @param {number} maxResolution The maximum resolution of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setMaxResolution = function (maxResolution) {\n this.set(Property.MAX_RESOLUTION, maxResolution);\n };\n /**\n * Set the minimum resolution at which the layer is visible.\n * @param {number} minResolution The minimum resolution of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setMinResolution = function (minResolution) {\n this.set(Property.MIN_RESOLUTION, minResolution);\n };\n /**\n * Set the maximum zoom (exclusive) at which the layer is visible.\n * Note that the zoom levels for layer visibility are based on the\n * view zoom level, which may be different from a tile source zoom level.\n * @param {number} maxZoom The maximum zoom of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setMaxZoom = function (maxZoom) {\n this.set(Property.MAX_ZOOM, maxZoom);\n };\n /**\n * Set the minimum zoom (inclusive) at which the layer is visible.\n * Note that the zoom levels for layer visibility are based on the\n * view zoom level, which may be different from a tile source zoom level.\n * @param {number} minZoom The minimum zoom of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setMinZoom = function (minZoom) {\n this.set(Property.MIN_ZOOM, minZoom);\n };\n /**\n * Set the opacity of the layer, allowed values range from 0 to 1.\n * @param {number} opacity The opacity of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setOpacity = function (opacity) {\n asserts_assert(typeof opacity === \'number\', 64); // Layer opacity must be a number\n\n this.set(Property.OPACITY, opacity);\n };\n /**\n * Set the visibility of the layer (`true` or `false`).\n * @param {boolean} visible The visibility of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setVisible = function (visible) {\n this.set(Property.VISIBLE, visible);\n };\n /**\n * Set Z-index of the layer, which is used to order layers before rendering.\n * The default Z-index is 0.\n * @param {number} zindex The z-index of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setZIndex = function (zindex) {\n this.set(Property.Z_INDEX, zindex);\n };\n /**\n * Clean up.\n */\n\n\n BaseLayer.prototype.disposeInternal = function () {\n if (this.state_) {\n this.state_.layer = null;\n this.state_ = null;\n }\n\n _super.prototype.disposeInternal.call(this);\n };\n\n return BaseLayer;\n}(ol_Object);\n\n/* harmony default export */ var Base = (BaseLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/render/EventType.js\n/**\n * @module ol/render/EventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var render_EventType = ({\n /**\n * Triggered before a layer is rendered.\n * @event module:ol/render/Event~RenderEvent#prerender\n * @api\n */\n PRERENDER: \'prerender\',\n\n /**\n * Triggered after a layer is rendered.\n * @event module:ol/render/Event~RenderEvent#postrender\n * @api\n */\n POSTRENDER: \'postrender\',\n\n /**\n * Triggered before layers are rendered.\n * The event object will not have a `context` set.\n * @event module:ol/render/Event~RenderEvent#precompose\n * @api\n */\n PRECOMPOSE: \'precompose\',\n\n /**\n * Triggered after all layers are rendered.\n * The event object will not have a `context` set.\n * @event module:ol/render/Event~RenderEvent#postcompose\n * @api\n */\n POSTCOMPOSE: \'postcompose\',\n\n /**\n * Triggered when rendering is complete, i.e. all sources and tiles have\n * finished loading for the current viewport, and all tiles are faded in.\n * The event object will not have a `context` set.\n * @event module:ol/render/Event~RenderEvent#rendercomplete\n * @api\n */\n RENDERCOMPLETE: \'rendercomplete\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/source/State.js\n/**\n * @module ol/source/State\n */\n\n/**\n * @enum {string}\n * State of the source, one of \'undefined\', \'loading\', \'ready\' or \'error\'.\n */\n/* harmony default export */ var State = ({\n UNDEFINED: \'undefined\',\n LOADING: \'loading\',\n READY: \'ready\',\n ERROR: \'error\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Layer.js\nvar Layer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/Layer\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {function(import("../PluggableMap.js").FrameState):HTMLElement} RenderFunction\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-layer\'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {import("../source/Source.js").default} [source] Source for this layer. If not provided to the constructor,\n * the source can be set by calling {@link module:ol/layer/Layer#setSource layer.setSource(source)} after\n * construction.\n * @property {import("../PluggableMap.js").default} [map] Map.\n * @property {RenderFunction} [render] Render function. Takes the frame state as input and is expected to return an\n * HTML element. Will overwrite the default rendering for the layer.\n */\n\n/**\n * @typedef {Object} State\n * @property {import("./Layer.js").default} layer\n * @property {number} opacity Opacity, the value is rounded to two digits to appear after the decimal point.\n * @property {import("../source/State.js").default} sourceState\n * @property {boolean} visible\n * @property {boolean} managed\n * @property {import("../extent.js").Extent} [extent]\n * @property {number} zIndex\n * @property {number} maxResolution\n * @property {number} minResolution\n * @property {number} minZoom\n * @property {number} maxZoom\n */\n\n/**\n * @classdesc\n * Base class from which all layer types are derived. This should only be instantiated\n * in the case where a custom layer is be added to the map with a custom `render` function.\n * Such a function can be specified in the `options` object, and is expected to return an HTML element.\n *\n * A visual representation of raster or vector map data.\n * Layers group together those properties that pertain to how the data is to be\n * displayed, irrespective of the source of that data.\n *\n * Layers are usually added to a map with {@link module:ol/Map#addLayer}. Components\n * like {@link module:ol/interaction/Select~Select} use unmanaged layers\n * internally. These unmanaged layers are associated with the map using\n * {@link module:ol/layer/Layer~Layer#setMap} instead.\n *\n * A generic `change` event is fired when the state of the source changes.\n *\n * Please note that for performance reasons several layers might get rendered to\n * the same HTML element, which will cause {@link module:ol/Map~Map#forEachLayerAtPixel} to\n * give false positives. To avoid this, apply different `className` properties to the\n * layers at creation time.\n *\n * @fires import("../render/Event.js").RenderEvent#prerender\n * @fires import("../render/Event.js").RenderEvent#postrender\n *\n * @template {import("../source/Source.js").default} SourceType\n * @api\n */\n\nvar Layer =\n/** @class */\nfunction (_super) {\n Layer_extends(Layer, _super);\n /**\n * @param {Options} options Layer options.\n */\n\n\n function Layer(options) {\n var _this = this;\n\n var baseOptions = obj_assign({}, options);\n delete baseOptions.source;\n _this = _super.call(this, baseOptions) || this;\n /**\n * @private\n * @type {?import("../events.js").EventsKey}\n */\n\n _this.mapPrecomposeKey_ = null;\n /**\n * @private\n * @type {?import("../events.js").EventsKey}\n */\n\n _this.mapRenderKey_ = null;\n /**\n * @private\n * @type {?import("../events.js").EventsKey}\n */\n\n _this.sourceChangeKey_ = null;\n /**\n * @private\n * @type {import("../renderer/Layer.js").default}\n */\n\n _this.renderer_ = null; // Overwrite default render method with a custom one\n\n if (options.render) {\n _this.render = options.render;\n }\n\n if (options.map) {\n _this.setMap(options.map);\n }\n\n _this.addEventListener(getChangeEventType(Property.SOURCE), _this.handleSourcePropertyChange_);\n\n var source = options.source ?\n /** @type {SourceType} */\n options.source : null;\n\n _this.setSource(source);\n\n return _this;\n }\n /**\n * @param {Array<import("./Layer.js").default>=} opt_array Array of layers (to be modified in place).\n * @return {Array<import("./Layer.js").default>} Array of layers.\n */\n\n\n Layer.prototype.getLayersArray = function (opt_array) {\n var array = opt_array ? opt_array : [];\n array.push(this);\n return array;\n };\n /**\n * @param {Array<import("./Layer.js").State>=} opt_states Optional list of layer states (to be modified in place).\n * @return {Array<import("./Layer.js").State>} List of layer states.\n */\n\n\n Layer.prototype.getLayerStatesArray = function (opt_states) {\n var states = opt_states ? opt_states : [];\n states.push(this.getLayerState());\n return states;\n };\n /**\n * Get the layer source.\n * @return {SourceType} The layer source (or `null` if not yet set).\n * @observable\n * @api\n */\n\n\n Layer.prototype.getSource = function () {\n return (\n /** @type {SourceType} */\n this.get(Property.SOURCE) || null\n );\n };\n /**\n * @return {import("../source/State.js").default} Source state.\n */\n\n\n Layer.prototype.getSourceState = function () {\n var source = this.getSource();\n return !source ? State.UNDEFINED : source.getState();\n };\n /**\n * @private\n */\n\n\n Layer.prototype.handleSourceChange_ = function () {\n this.changed();\n };\n /**\n * @private\n */\n\n\n Layer.prototype.handleSourcePropertyChange_ = function () {\n if (this.sourceChangeKey_) {\n unlistenByKey(this.sourceChangeKey_);\n this.sourceChangeKey_ = null;\n }\n\n var source = this.getSource();\n\n if (source) {\n this.sourceChangeKey_ = listen(source, EventType.CHANGE, this.handleSourceChange_, this);\n }\n\n this.changed();\n };\n /**\n * @param {import("../pixel").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with\n * an array of features.\n */\n\n\n Layer.prototype.getFeatures = function (pixel) {\n return this.renderer_.getFeatures(pixel);\n };\n /**\n * In charge to manage the rendering of the layer. One layer type is\n * bounded with one layer renderer.\n * @param {?import("../PluggableMap.js").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target which the renderer may (but need not) use\n * for rendering its content.\n * @return {HTMLElement} The rendered element.\n */\n\n\n Layer.prototype.render = function (frameState, target) {\n var layerRenderer = this.getRenderer();\n\n if (layerRenderer.prepareFrame(frameState)) {\n return layerRenderer.renderFrame(frameState, target);\n }\n };\n /**\n * Sets the layer to be rendered on top of other layers on a map. The map will\n * not manage this layer in its layers collection, and the callback in\n * {@link module:ol/Map#forEachLayerAtPixel} will receive `null` as layer. This\n * is useful for temporary layers. To remove an unmanaged layer from the map,\n * use `#setMap(null)`.\n *\n * To add the layer to a map and have it managed by the map, use\n * {@link module:ol/Map#addLayer} instead.\n * @param {import("../PluggableMap.js").default} map Map.\n * @api\n */\n\n\n Layer.prototype.setMap = function (map) {\n if (this.mapPrecomposeKey_) {\n unlistenByKey(this.mapPrecomposeKey_);\n this.mapPrecomposeKey_ = null;\n }\n\n if (!map) {\n this.changed();\n }\n\n if (this.mapRenderKey_) {\n unlistenByKey(this.mapRenderKey_);\n this.mapRenderKey_ = null;\n }\n\n if (map) {\n this.mapPrecomposeKey_ = listen(map, render_EventType.PRECOMPOSE, function (evt) {\n var renderEvent =\n /** @type {import("../render/Event.js").default} */\n evt;\n var layerStatesArray = renderEvent.frameState.layerStatesArray;\n var layerState = this.getLayerState(false); // A layer can only be added to the map once. Use either `layer.setMap()` or `map.addLayer()`, not both.\n\n asserts_assert(!layerStatesArray.some(function (arrayLayerState) {\n return arrayLayerState.layer === layerState.layer;\n }), 67);\n layerStatesArray.push(layerState);\n }, this);\n this.mapRenderKey_ = listen(this, EventType.CHANGE, map.render, map);\n this.changed();\n }\n };\n /**\n * Set the layer source.\n * @param {SourceType} source The layer source.\n * @observable\n * @api\n */\n\n\n Layer.prototype.setSource = function (source) {\n this.set(Property.SOURCE, source);\n };\n /**\n * Get the renderer for this layer.\n * @return {import("../renderer/Layer.js").default} The layer renderer.\n */\n\n\n Layer.prototype.getRenderer = function () {\n if (!this.renderer_) {\n this.renderer_ = this.createRenderer();\n }\n\n return this.renderer_;\n };\n /**\n * @return {boolean} The layer has a renderer.\n */\n\n\n Layer.prototype.hasRenderer = function () {\n return !!this.renderer_;\n };\n /**\n * Create a renderer for this layer.\n * @return {import("../renderer/Layer.js").default} A layer renderer.\n * @protected\n */\n\n\n Layer.prototype.createRenderer = function () {\n return null;\n };\n /**\n * Clean up.\n */\n\n\n Layer.prototype.disposeInternal = function () {\n this.setSource(null);\n\n _super.prototype.disposeInternal.call(this);\n };\n\n return Layer;\n}(Base);\n/**\n * Return `true` if the layer is visible and if the provided view state\n * has resolution and zoom levels that are in range of the layer\'s min/max.\n * @param {State} layerState Layer state.\n * @param {import("../View.js").State} viewState View state.\n * @return {boolean} The layer is visible at the given view state.\n */\n\n\nfunction inView(layerState, viewState) {\n if (!layerState.visible) {\n return false;\n }\n\n var resolution = viewState.resolution;\n\n if (resolution < layerState.minResolution || resolution >= layerState.maxResolution) {\n return false;\n }\n\n var zoom = viewState.zoom;\n return zoom > layerState.minZoom && zoom <= layerState.maxZoom;\n}\n/* harmony default export */ var layer_Layer = (Layer);\n;// CONCATENATED MODULE: ./node_modules/ol/coordinate.js\n/**\n * @module ol/coordinate\n */\n\n\n\n/**\n * An array of numbers representing an xy coordinate. Example: `[16, 48]`.\n * @typedef {Array<number>} Coordinate\n * @api\n */\n\n/**\n * A function that takes a {@link module:ol/coordinate~Coordinate} and\n * transforms it into a `{string}`.\n *\n * @typedef {function((Coordinate|undefined)): string} CoordinateFormat\n * @api\n */\n\n/**\n * Add `delta` to `coordinate`. `coordinate` is modified in place and returned\n * by the function.\n *\n * Example:\n *\n * import {add} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * add(coord, [-2, 4]);\n * // coord is now [5.85, 51.983333]\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {Coordinate} delta Delta.\n * @return {Coordinate} The input coordinate adjusted by\n * the given delta.\n * @api\n */\n\nfunction add(coordinate, delta) {\n coordinate[0] += +delta[0];\n coordinate[1] += +delta[1];\n return coordinate;\n}\n/**\n * Calculates the point closest to the passed coordinate on the passed circle.\n *\n * @param {Coordinate} coordinate The coordinate.\n * @param {import("./geom/Circle.js").default} circle The circle.\n * @return {Coordinate} Closest point on the circumference.\n */\n\nfunction closestOnCircle(coordinate, circle) {\n var r = circle.getRadius();\n var center = circle.getCenter();\n var x0 = center[0];\n var y0 = center[1];\n var x1 = coordinate[0];\n var y1 = coordinate[1];\n var dx = x1 - x0;\n var dy = y1 - y0;\n\n if (dx === 0 && dy === 0) {\n dx = 1;\n }\n\n var d = Math.sqrt(dx * dx + dy * dy);\n var x = x0 + r * dx / d;\n var y = y0 + r * dy / d;\n return [x, y];\n}\n/**\n * Calculates the point closest to the passed coordinate on the passed segment.\n * This is the foot of the perpendicular of the coordinate to the segment when\n * the foot is on the segment, or the closest segment coordinate when the foot\n * is outside the segment.\n *\n * @param {Coordinate} coordinate The coordinate.\n * @param {Array<Coordinate>} segment The two coordinates\n * of the segment.\n * @return {Coordinate} The foot of the perpendicular of\n * the coordinate to the segment.\n */\n\nfunction closestOnSegment(coordinate, segment) {\n var x0 = coordinate[0];\n var y0 = coordinate[1];\n var start = segment[0];\n var end = segment[1];\n var x1 = start[0];\n var y1 = start[1];\n var x2 = end[0];\n var y2 = end[1];\n var dx = x2 - x1;\n var dy = y2 - y1;\n var along = dx === 0 && dy === 0 ? 0 : (dx * (x0 - x1) + dy * (y0 - y1)) / (dx * dx + dy * dy || 0);\n var x, y;\n\n if (along <= 0) {\n x = x1;\n y = y1;\n } else if (along >= 1) {\n x = x2;\n y = y2;\n } else {\n x = x1 + along * dx;\n y = y1 + along * dy;\n }\n\n return [x, y];\n}\n/**\n * Returns a {@link module:ol/coordinate~CoordinateFormat} function that can be\n * used to format\n * a {Coordinate} to a string.\n *\n * Example without specifying the fractional digits:\n *\n * import {createStringXY} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var stringifyFunc = createStringXY();\n * var out = stringifyFunc(coord);\n * // out is now \'8, 48\'\n *\n * Example with explicitly specifying 2 fractional digits:\n *\n * import {createStringXY} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var stringifyFunc = createStringXY(2);\n * var out = stringifyFunc(coord);\n * // out is now \'7.85, 47.98\'\n *\n * @param {number=} opt_fractionDigits The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {CoordinateFormat} Coordinate format.\n * @api\n */\n\nfunction createStringXY(opt_fractionDigits) {\n return (\n /**\n * @param {Coordinate} coordinate Coordinate.\n * @return {string} String XY.\n */\n function (coordinate) {\n return toStringXY(coordinate, opt_fractionDigits);\n }\n );\n}\n/**\n * @param {string} hemispheres Hemispheres.\n * @param {number} degrees Degrees.\n * @param {number=} opt_fractionDigits The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} String.\n */\n\nfunction degreesToStringHDMS(hemispheres, degrees, opt_fractionDigits) {\n var normalizedDegrees = modulo(degrees + 180, 360) - 180;\n var x = Math.abs(3600 * normalizedDegrees);\n var dflPrecision = opt_fractionDigits || 0;\n var precision = Math.pow(10, dflPrecision);\n var deg = Math.floor(x / 3600);\n var min = Math.floor((x - deg * 3600) / 60);\n var sec = x - deg * 3600 - min * 60;\n sec = Math.ceil(sec * precision) / precision;\n\n if (sec >= 60) {\n sec = 0;\n min += 1;\n }\n\n if (min >= 60) {\n min = 0;\n deg += 1;\n }\n\n return deg + "\\xB0 " + padNumber(min, 2) + "\\u2032 " + padNumber(sec, 2, dflPrecision) + "\\u2033" + (normalizedDegrees == 0 ? \'\' : \' \' + hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0));\n}\n/**\n * Transforms the given {@link module:ol/coordinate~Coordinate} to a string\n * using the given string template. The strings `{x}` and `{y}` in the template\n * will be replaced with the first and second coordinate values respectively.\n *\n * Example without specifying the fractional digits:\n *\n * import {format} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var template = \'Coordinate is ({x}|{y}).\';\n * var out = format(coord, template);\n * // out is now \'Coordinate is (8|48).\'\n *\n * Example explicitly specifying the fractional digits:\n *\n * import {format} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var template = \'Coordinate is ({x}|{y}).\';\n * var out = format(coord, template, 2);\n * // out is now \'Coordinate is (7.85|47.98).\'\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {string} template A template string with `{x}` and `{y}` placeholders\n * that will be replaced by first and second coordinate values.\n * @param {number=} opt_fractionDigits The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} Formatted coordinate.\n * @api\n */\n\nfunction format(coordinate, template, opt_fractionDigits) {\n if (coordinate) {\n return template.replace(\'{x}\', coordinate[0].toFixed(opt_fractionDigits)).replace(\'{y}\', coordinate[1].toFixed(opt_fractionDigits));\n } else {\n return \'\';\n }\n}\n/**\n * @param {Coordinate} coordinate1 First coordinate.\n * @param {Coordinate} coordinate2 Second coordinate.\n * @return {boolean} The two coordinates are equal.\n */\n\nfunction coordinate_equals(coordinate1, coordinate2) {\n var equals = true;\n\n for (var i = coordinate1.length - 1; i >= 0; --i) {\n if (coordinate1[i] != coordinate2[i]) {\n equals = false;\n break;\n }\n }\n\n return equals;\n}\n/**\n * Rotate `coordinate` by `angle`. `coordinate` is modified in place and\n * returned by the function.\n *\n * Example:\n *\n * import {rotate} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var rotateRadians = Math.PI / 2; // 90 degrees\n * rotate(coord, rotateRadians);\n * // coord is now [-47.983333, 7.85]\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number} angle Angle in radian.\n * @return {Coordinate} Coordinate.\n * @api\n */\n\nfunction coordinate_rotate(coordinate, angle) {\n var cosAngle = Math.cos(angle);\n var sinAngle = Math.sin(angle);\n var x = coordinate[0] * cosAngle - coordinate[1] * sinAngle;\n var y = coordinate[1] * cosAngle + coordinate[0] * sinAngle;\n coordinate[0] = x;\n coordinate[1] = y;\n return coordinate;\n}\n/**\n * Scale `coordinate` by `scale`. `coordinate` is modified in place and returned\n * by the function.\n *\n * Example:\n *\n * import {scale as scaleCoordinate} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var scale = 1.2;\n * scaleCoordinate(coord, scale);\n * // coord is now [9.42, 57.5799996]\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number} scale Scale factor.\n * @return {Coordinate} Coordinate.\n */\n\nfunction coordinate_scale(coordinate, scale) {\n coordinate[0] *= scale;\n coordinate[1] *= scale;\n return coordinate;\n}\n/**\n * @param {Coordinate} coord1 First coordinate.\n * @param {Coordinate} coord2 Second coordinate.\n * @return {number} Squared distance between coord1 and coord2.\n */\n\nfunction coordinate_squaredDistance(coord1, coord2) {\n var dx = coord1[0] - coord2[0];\n var dy = coord1[1] - coord2[1];\n return dx * dx + dy * dy;\n}\n/**\n * @param {Coordinate} coord1 First coordinate.\n * @param {Coordinate} coord2 Second coordinate.\n * @return {number} Distance between coord1 and coord2.\n */\n\nfunction distance(coord1, coord2) {\n return Math.sqrt(coordinate_squaredDistance(coord1, coord2));\n}\n/**\n * Calculate the squared distance from a coordinate to a line segment.\n *\n * @param {Coordinate} coordinate Coordinate of the point.\n * @param {Array<Coordinate>} segment Line segment (2\n * coordinates).\n * @return {number} Squared distance from the point to the line segment.\n */\n\nfunction squaredDistanceToSegment(coordinate, segment) {\n return coordinate_squaredDistance(coordinate, closestOnSegment(coordinate, segment));\n}\n/**\n * Format a geographic coordinate with the hemisphere, degrees, minutes, and\n * seconds.\n *\n * Example without specifying fractional digits:\n *\n * import {toStringHDMS} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringHDMS(coord);\n * // out is now \'47° 58′ 60″ N 7° 50′ 60″ E\'\n *\n * Example explicitly specifying 1 fractional digit:\n *\n * import {toStringHDMS} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringHDMS(coord, 1);\n * // out is now \'47° 58′ 60.0″ N 7° 50′ 60.0″ E\'\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number=} opt_fractionDigits The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} Hemisphere, degrees, minutes and seconds.\n * @api\n */\n\nfunction toStringHDMS(coordinate, opt_fractionDigits) {\n if (coordinate) {\n return degreesToStringHDMS(\'NS\', coordinate[1], opt_fractionDigits) + \' \' + degreesToStringHDMS(\'EW\', coordinate[0], opt_fractionDigits);\n } else {\n return \'\';\n }\n}\n/**\n * Format a coordinate as a comma delimited string.\n *\n * Example without specifying fractional digits:\n *\n * import {toStringXY} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringXY(coord);\n * // out is now \'8, 48\'\n *\n * Example explicitly specifying 1 fractional digit:\n *\n * import {toStringXY} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringXY(coord, 1);\n * // out is now \'7.8, 48.0\'\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number=} opt_fractionDigits The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} XY.\n * @api\n */\n\nfunction toStringXY(coordinate, opt_fractionDigits) {\n return format(coordinate, \'{x}, {y}\', opt_fractionDigits);\n}\n/**\n * Modifies the provided coordinate in-place to be within the real world\n * extent. The lower projection extent boundary is inclusive, the upper one\n * exclusive.\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {Coordinate} The coordinate within the real world extent.\n */\n\nfunction coordinate_wrapX(coordinate, projection) {\n if (projection.canWrapX()) {\n var worldWidth = extent_getWidth(projection.getExtent());\n var worldsAway = coordinate_getWorldsAway(coordinate, projection, worldWidth);\n\n if (worldsAway) {\n coordinate[0] -= worldsAway * worldWidth;\n }\n }\n\n return coordinate;\n}\n/**\n * @param {Coordinate} coordinate Coordinate.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @param {number=} opt_sourceExtentWidth Width of the source extent.\n * @return {number} Offset in world widths.\n */\n\nfunction coordinate_getWorldsAway(coordinate, projection, opt_sourceExtentWidth) {\n var projectionExtent = projection.getExtent();\n var worldsAway = 0;\n\n if (projection.canWrapX() && (coordinate[0] < projectionExtent[0] || coordinate[0] > projectionExtent[2])) {\n var sourceExtentWidth = opt_sourceExtentWidth || extent_getWidth(projectionExtent);\n worldsAway = Math.floor((coordinate[0] - projectionExtent[0]) / sourceExtentWidth);\n }\n\n return worldsAway;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/Map.js\nvar Map_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/Map\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef HitMatch\n * @property {import("../Feature.js").FeatureLike} feature\n * @property {import("../layer/Layer.js").default} layer\n * @property {import("../geom/SimpleGeometry.js").default} geometry\n * @property {number} distanceSq\n * @property {import("./vector.js").FeatureCallback<T>} callback\n * @template T\n */\n\n/**\n * @abstract\n */\n\nvar MapRenderer =\n/** @class */\nfunction (_super) {\n Map_extends(MapRenderer, _super);\n /**\n * @param {import("../PluggableMap.js").default} map Map.\n */\n\n\n function MapRenderer(map) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import("../PluggableMap.js").default}\n */\n\n\n _this.map_ = map;\n return _this;\n }\n /**\n * @abstract\n * @param {import("../render/EventType.js").default} type Event type.\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n MapRenderer.prototype.dispatchRenderEvent = function (type, frameState) {\n util_abstract();\n };\n /**\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @protected\n */\n\n\n MapRenderer.prototype.calculateMatrices2D = function (frameState) {\n var viewState = frameState.viewState;\n var coordinateToPixelTransform = frameState.coordinateToPixelTransform;\n var pixelToCoordinateTransform = frameState.pixelToCoordinateTransform;\n compose(coordinateToPixelTransform, frameState.size[0] / 2, frameState.size[1] / 2, 1 / viewState.resolution, -1 / viewState.resolution, -viewState.rotation, -viewState.center[0], -viewState.center[1]);\n makeInverse(pixelToCoordinateTransform, coordinateToPixelTransform);\n };\n /**\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {boolean} checkWrapped Check for wrapped geometries.\n * @param {import("./vector.js").FeatureCallback<T>} callback Feature callback.\n * @param {S} thisArg Value to use as `this` when executing `callback`.\n * @param {function(this: U, import("../layer/Layer.js").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @param {U} thisArg2 Value to use as `this` when executing `layerFilter`.\n * @return {T|undefined} Callback result.\n * @template S,T,U\n */\n\n\n MapRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, checkWrapped, callback, thisArg, layerFilter, thisArg2) {\n var result;\n var viewState = frameState.viewState;\n /**\n * @param {boolean} managed Managed layer.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../layer/Layer.js").default} layer Layer.\n * @param {import("../geom/Geometry.js").default} geometry Geometry.\n * @return {T|undefined} Callback result.\n */\n\n function forEachFeatureAtCoordinate(managed, feature, layer, geometry) {\n return callback.call(thisArg, feature, managed ? layer : null, geometry);\n }\n\n var projection = viewState.projection;\n var translatedCoordinate = coordinate_wrapX(coordinate.slice(), projection);\n var offsets = [[0, 0]];\n\n if (projection.canWrapX() && checkWrapped) {\n var projectionExtent = projection.getExtent();\n var worldWidth = extent_getWidth(projectionExtent);\n offsets.push([-worldWidth, 0], [worldWidth, 0]);\n }\n\n var layerStates = frameState.layerStatesArray;\n var numLayers = layerStates.length;\n var matches =\n /** @type {Array<HitMatch<T>>} */\n [];\n var tmpCoord = [];\n\n for (var i = 0; i < offsets.length; i++) {\n for (var j = numLayers - 1; j >= 0; --j) {\n var layerState = layerStates[j];\n var layer = layerState.layer;\n\n if (layer.hasRenderer() && inView(layerState, viewState) && layerFilter.call(thisArg2, layer)) {\n var layerRenderer = layer.getRenderer();\n var source = layer.getSource();\n\n if (layerRenderer && source) {\n var coordinates = source.getWrapX() ? translatedCoordinate : coordinate;\n var callback_1 = forEachFeatureAtCoordinate.bind(null, layerState.managed);\n tmpCoord[0] = coordinates[0] + offsets[i][0];\n tmpCoord[1] = coordinates[1] + offsets[i][1];\n result = layerRenderer.forEachFeatureAtCoordinate(tmpCoord, frameState, hitTolerance, callback_1, matches);\n }\n\n if (result) {\n return result;\n }\n }\n }\n }\n\n if (matches.length === 0) {\n return undefined;\n }\n\n var order = 1 / matches.length;\n matches.forEach(function (m, i) {\n return m.distanceSq += i * order;\n });\n matches.sort(function (a, b) {\n return a.distanceSq - b.distanceSq;\n });\n matches.some(function (m) {\n return result = m.callback(m.feature, m.layer, m.geometry);\n });\n return result;\n };\n /**\n * @abstract\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {function(import("../layer/Layer.js").default, (Uint8ClampedArray|Uint8Array)): T} callback Layer\n * callback.\n * @param {function(import("../layer/Layer.js").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n MapRenderer.prototype.forEachLayerAtPixel = function (pixel, frameState, hitTolerance, callback, layerFilter) {\n return util_abstract();\n };\n /**\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {boolean} checkWrapped Check for wrapped geometries.\n * @param {function(this: U, import("../layer/Layer.js").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @param {U} thisArg Value to use as `this` when executing `layerFilter`.\n * @return {boolean} Is there a feature at the given coordinate?\n * @template U\n */\n\n\n MapRenderer.prototype.hasFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, checkWrapped, layerFilter, thisArg) {\n var hasFeature = this.forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, checkWrapped, TRUE, this, layerFilter, thisArg);\n return hasFeature !== undefined;\n };\n /**\n * @return {import("../PluggableMap.js").default} Map.\n */\n\n\n MapRenderer.prototype.getMap = function () {\n return this.map_;\n };\n /**\n * Render.\n * @abstract\n * @param {?import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n MapRenderer.prototype.renderFrame = function (frameState) {\n util_abstract();\n };\n /**\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n * @protected\n */\n\n\n MapRenderer.prototype.scheduleExpireIconCache = function (frameState) {\n if (shared.canExpireCache()) {\n frameState.postRenderFunctions.push(expireIconCache);\n }\n };\n\n return MapRenderer;\n}(ol_Disposable);\n/**\n * @param {import("../PluggableMap.js").default} map Map.\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\nfunction expireIconCache(map, frameState) {\n shared.expire();\n}\n\n/* harmony default export */ var renderer_Map = (MapRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/render/Event.js\n/**\n * @module ol/render/Event\n */\nvar Event_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\nvar RenderEvent =\n/** @class */\nfunction (_super) {\n Event_extends(RenderEvent, _super);\n /**\n * @param {import("./EventType.js").default} type Type.\n * @param {import("../transform.js").Transform=} opt_inversePixelTransform Transform for\n * CSS pixels to rendered pixels.\n * @param {import("../PluggableMap.js").FrameState=} opt_frameState Frame state.\n * @param {?CanvasRenderingContext2D=} opt_context Context.\n */\n\n\n function RenderEvent(type, opt_inversePixelTransform, opt_frameState, opt_context) {\n var _this = _super.call(this, type) || this;\n /**\n * Transform from CSS pixels (relative to the top-left corner of the map viewport)\n * to rendered pixels on this event\'s `context`. Only available when a Canvas renderer is used, null otherwise.\n * @type {import("../transform.js").Transform|undefined}\n * @api\n */\n\n\n _this.inversePixelTransform = opt_inversePixelTransform;\n /**\n * An object representing the current render frame state.\n * @type {import("../PluggableMap.js").FrameState|undefined}\n * @api\n */\n\n _this.frameState = opt_frameState;\n /**\n * Canvas context. Not available when the event is dispatched by the map. Only available\n * when a Canvas renderer is used, null otherwise.\n * @type {CanvasRenderingContext2D|null|undefined}\n * @api\n */\n\n _this.context = opt_context;\n return _this;\n }\n\n return RenderEvent;\n}(Event);\n\n/* harmony default export */ var render_Event = (RenderEvent);\n;// CONCATENATED MODULE: ./node_modules/ol/css.js\n/**\n * @module ol/css\n */\n\n/**\n * @typedef {Object} FontParameters\n * @property {string} style\n * @property {string} variant\n * @property {string} weight\n * @property {string} size\n * @property {string} lineHeight\n * @property {string} family\n * @property {Array<string>} families\n */\n\n/**\n * The CSS class for hidden feature.\n *\n * @const\n * @type {string}\n */\nvar CLASS_HIDDEN = \'ol-hidden\';\n/**\n * The CSS class that we\'ll give the DOM elements to have them selectable.\n *\n * @const\n * @type {string}\n */\n\nvar CLASS_SELECTABLE = \'ol-selectable\';\n/**\n * The CSS class that we\'ll give the DOM elements to have them unselectable.\n *\n * @const\n * @type {string}\n */\n\nvar CLASS_UNSELECTABLE = \'ol-unselectable\';\n/**\n * The CSS class for unsupported feature.\n *\n * @const\n * @type {string}\n */\n\nvar CLASS_UNSUPPORTED = \'ol-unsupported\';\n/**\n * The CSS class for controls.\n *\n * @const\n * @type {string}\n */\n\nvar CLASS_CONTROL = \'ol-control\';\n/**\n * The CSS class that we\'ll give the DOM elements that are collapsed, i.e.\n * to those elements which usually can be expanded.\n *\n * @const\n * @type {string}\n */\n\nvar CLASS_COLLAPSED = \'ol-collapsed\';\n/**\n * From http://stackoverflow.com/questions/10135697/regex-to-parse-any-css-font\n * @type {RegExp}\n */\n\nvar fontRegEx = new RegExp([\'^\\\\s*(?=(?:(?:[-a-z]+\\\\s*){0,2}(italic|oblique))?)\', \'(?=(?:(?:[-a-z]+\\\\s*){0,2}(small-caps))?)\', \'(?=(?:(?:[-a-z]+\\\\s*){0,2}(bold(?:er)?|lighter|[1-9]00 ))?)\', \'(?:(?:normal|\\\\1|\\\\2|\\\\3)\\\\s*){0,3}((?:xx?-)?\', \'(?:small|large)|medium|smaller|larger|[\\\\.\\\\d]+(?:\\\\%|in|[cem]m|ex|p[ctx]))\', \'(?:\\\\s*\\\\/\\\\s*(normal|[\\\\.\\\\d]+(?:\\\\%|in|[cem]m|ex|p[ctx])?))\', \'?\\\\s*([-,\\\\"\\\\\\\'\\\\sa-z]+?)\\\\s*$\'].join(\'\'), \'i\');\nvar fontRegExMatchIndex = [\'style\', \'variant\', \'weight\', \'size\', \'lineHeight\', \'family\'];\n/**\n * Get the list of font families from a font spec. Note that this doesn\'t work\n * for font families that have commas in them.\n * @param {string} fontSpec The CSS font property.\n * @return {FontParameters} The font parameters (or null if the input spec is invalid).\n */\n\nvar getFontParameters = function getFontParameters(fontSpec) {\n var match = fontSpec.match(fontRegEx);\n\n if (!match) {\n return null;\n }\n\n var style =\n /** @type {FontParameters} */\n {\n lineHeight: \'normal\',\n size: \'1.2em\',\n style: \'normal\',\n weight: \'normal\',\n variant: \'normal\'\n };\n\n for (var i = 0, ii = fontRegExMatchIndex.length; i < ii; ++i) {\n var value = match[i + 1];\n\n if (value !== undefined) {\n style[fontRegExMatchIndex[i]] = value;\n }\n }\n\n style.families = style.family.split(/,\\s?/);\n return style;\n};\n;// CONCATENATED MODULE: ./node_modules/ol/has.js\n/**\n * @module ol/has\n */\nvar ua = typeof navigator !== \'undefined\' && typeof navigator.userAgent !== \'undefined\' ? navigator.userAgent.toLowerCase() : \'\';\n/**\n * User agent string says we are dealing with Firefox as browser.\n * @type {boolean}\n */\n\nvar FIREFOX = ua.indexOf(\'firefox\') !== -1;\n/**\n * User agent string says we are dealing with Safari as browser.\n * @type {boolean}\n */\n\nvar SAFARI = ua.indexOf(\'safari\') !== -1 && ua.indexOf(\'chrom\') == -1;\n/**\n * User agent string says we are dealing with a WebKit engine.\n * @type {boolean}\n */\n\nvar WEBKIT = ua.indexOf(\'webkit\') !== -1 && ua.indexOf(\'edge\') == -1;\n/**\n * User agent string says we are dealing with a Mac as platform.\n * @type {boolean}\n */\n\nvar has_MAC = ua.indexOf(\'macintosh\') !== -1;\n/**\n * The ratio between physical pixels and device-independent pixels\n * (dips) on the device (`window.devicePixelRatio`).\n * @const\n * @type {number}\n * @api\n */\n\nvar DEVICE_PIXEL_RATIO = typeof devicePixelRatio !== \'undefined\' ? devicePixelRatio : 1;\n/**\n * The execution context is a worker with OffscreenCanvas available.\n * @const\n * @type {boolean}\n */\n\nvar WORKER_OFFSCREEN_CANVAS = typeof WorkerGlobalScope !== \'undefined\' && typeof OffscreenCanvas !== \'undefined\' && self instanceof WorkerGlobalScope; //eslint-disable-line\n\n/**\n * Image.prototype.decode() is supported.\n * @type {boolean}\n */\n\nvar IMAGE_DECODE = typeof Image !== \'undefined\' && Image.prototype.decode;\n/**\n * @type {boolean}\n */\n\nvar PASSIVE_EVENT_LISTENERS = function () {\n var passive = false;\n\n try {\n var options = Object.defineProperty({}, \'passive\', {\n get: function get() {\n passive = true;\n }\n });\n window.addEventListener(\'_\', null, options);\n window.removeEventListener(\'_\', null, options);\n } catch (error) {// passive not supported\n }\n\n return passive;\n}();\n;// CONCATENATED MODULE: ./node_modules/ol/dom.js\n\n/**\n * @module ol/dom\n */\n//FIXME Move this function to the canvas module\n\n/**\n * Create an html canvas element and returns its 2d context.\n * @param {number=} opt_width Canvas width.\n * @param {number=} opt_height Canvas height.\n * @param {Array<HTMLCanvasElement>=} opt_canvasPool Canvas pool to take existing canvas from.\n * @return {CanvasRenderingContext2D} The context.\n */\n\nfunction createCanvasContext2D(opt_width, opt_height, opt_canvasPool) {\n var canvas = opt_canvasPool && opt_canvasPool.length ? opt_canvasPool.shift() : WORKER_OFFSCREEN_CANVAS ? new OffscreenCanvas(opt_width || 300, opt_height || 300) : document.createElement(\'canvas\');\n\n if (opt_width) {\n canvas.width = opt_width;\n }\n\n if (opt_height) {\n canvas.height = opt_height;\n } //FIXME Allow OffscreenCanvasRenderingContext2D as return type\n\n\n return (\n /** @type {CanvasRenderingContext2D} */\n canvas.getContext(\'2d\')\n );\n}\n/**\n * Get the current computed width for the given element including margin,\n * padding and border.\n * Equivalent to jQuery\'s `$(el).outerWidth(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The width.\n */\n\nfunction dom_outerWidth(element) {\n var width = element.offsetWidth;\n var style = getComputedStyle(element);\n width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);\n return width;\n}\n/**\n * Get the current computed height for the given element including margin,\n * padding and border.\n * Equivalent to jQuery\'s `$(el).outerHeight(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The height.\n */\n\nfunction dom_outerHeight(element) {\n var height = element.offsetHeight;\n var style = getComputedStyle(element);\n height += parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10);\n return height;\n}\n/**\n * @param {Node} newNode Node to replace old node\n * @param {Node} oldNode The node to be replaced\n */\n\nfunction replaceNode(newNode, oldNode) {\n var parent = oldNode.parentNode;\n\n if (parent) {\n parent.replaceChild(newNode, oldNode);\n }\n}\n/**\n * @param {Node} node The node to remove.\n * @returns {Node} The node that was removed or null.\n */\n\nfunction removeNode(node) {\n return node && node.parentNode ? node.parentNode.removeChild(node) : null;\n}\n/**\n * @param {Node} node The node to remove the children from.\n */\n\nfunction removeChildren(node) {\n while (node.lastChild) {\n node.removeChild(node.lastChild);\n }\n}\n/**\n * Transform the children of a parent node so they match the\n * provided list of children. This function aims to efficiently\n * remove, add, and reorder child nodes while maintaining a simple\n * implementation (it is not guaranteed to minimize DOM operations).\n * @param {Node} node The parent node whose children need reworking.\n * @param {Array<Node>} children The desired children.\n */\n\nfunction replaceChildren(node, children) {\n var oldChildren = node.childNodes;\n\n for (var i = 0; true; ++i) {\n var oldChild = oldChildren[i];\n var newChild = children[i]; // check if our work is done\n\n if (!oldChild && !newChild) {\n break;\n } // check if children match\n\n\n if (oldChild === newChild) {\n continue;\n } // check if a new child needs to be added\n\n\n if (!oldChild) {\n node.appendChild(newChild);\n continue;\n } // check if an old child needs to be removed\n\n\n if (!newChild) {\n node.removeChild(oldChild);\n --i;\n continue;\n } // reorder\n\n\n node.insertBefore(newChild, oldChild);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas.js\n/**\n * @module ol/render/canvas\n */\n\n\n\n\n\n\n\n/**\n * @typedef {Object} FillState\n * @property {import("../colorlike.js").ColorLike} fillStyle\n */\n\n/**\n * @typedef Label\n * @property {number} width\n * @property {number} height\n * @property {Array<string|number>} contextInstructions\n */\n\n/**\n * @typedef {Object} FillStrokeState\n * @property {import("../colorlike.js").ColorLike} [currentFillStyle]\n * @property {import("../colorlike.js").ColorLike} [currentStrokeStyle]\n * @property {CanvasLineCap} [currentLineCap]\n * @property {Array<number>} currentLineDash\n * @property {number} [currentLineDashOffset]\n * @property {CanvasLineJoin} [currentLineJoin]\n * @property {number} [currentLineWidth]\n * @property {number} [currentMiterLimit]\n * @property {number} [lastStroke]\n * @property {import("../colorlike.js").ColorLike} [fillStyle]\n * @property {import("../colorlike.js").ColorLike} [strokeStyle]\n * @property {CanvasLineCap} [lineCap]\n * @property {Array<number>} lineDash\n * @property {number} [lineDashOffset]\n * @property {CanvasLineJoin} [lineJoin]\n * @property {number} [lineWidth]\n * @property {number} [miterLimit]\n */\n\n/**\n * @typedef {Object} StrokeState\n * @property {CanvasLineCap} lineCap\n * @property {Array<number>} lineDash\n * @property {number} lineDashOffset\n * @property {CanvasLineJoin} lineJoin\n * @property {number} lineWidth\n * @property {number} miterLimit\n * @property {import("../colorlike.js").ColorLike} strokeStyle\n */\n\n/**\n * @typedef {Object} TextState\n * @property {string} font\n * @property {string} [textAlign]\n * @property {string} textBaseline\n * @property {string} [placement]\n * @property {number} [maxAngle]\n * @property {boolean} [overflow]\n * @property {import("../style/Fill.js").default} [backgroundFill]\n * @property {import("../style/Stroke.js").default} [backgroundStroke]\n * @property {import("../size.js").Size} [scale]\n * @property {Array<number>} [padding]\n */\n\n/**\n * @typedef {Object} SerializableInstructions\n * @property {Array<*>} instructions The rendering instructions.\n * @property {Array<*>} hitDetectionInstructions The rendering hit detection instructions.\n * @property {Array<number>} coordinates The array of all coordinates.\n * @property {!Object<string, TextState>} [textStates] The text states (decluttering).\n * @property {!Object<string, FillState>} [fillStates] The fill states (decluttering).\n * @property {!Object<string, StrokeState>} [strokeStates] The stroke states (decluttering).\n */\n\n/**\n * @typedef {Object<number, import("./canvas/Executor.js").ReplayImageOrLabelArgs>} DeclutterImageWithText\n */\n\n/**\n * @const\n * @type {string}\n */\n\nvar defaultFont = \'10px sans-serif\';\n/**\n * @const\n * @type {import("../colorlike.js").ColorLike}\n */\n\nvar defaultFillStyle = \'#000\';\n/**\n * @const\n * @type {CanvasLineCap}\n */\n\nvar defaultLineCap = \'round\';\n/**\n * @const\n * @type {Array<number>}\n */\n\nvar defaultLineDash = [];\n/**\n * @const\n * @type {number}\n */\n\nvar defaultLineDashOffset = 0;\n/**\n * @const\n * @type {CanvasLineJoin}\n */\n\nvar defaultLineJoin = \'round\';\n/**\n * @const\n * @type {number}\n */\n\nvar defaultMiterLimit = 10;\n/**\n * @const\n * @type {import("../colorlike.js").ColorLike}\n */\n\nvar defaultStrokeStyle = \'#000\';\n/**\n * @const\n * @type {string}\n */\n\nvar defaultTextAlign = \'center\';\n/**\n * @const\n * @type {string}\n */\n\nvar defaultTextBaseline = \'middle\';\n/**\n * @const\n * @type {Array<number>}\n */\n\nvar defaultPadding = [0, 0, 0, 0];\n/**\n * @const\n * @type {number}\n */\n\nvar defaultLineWidth = 1;\n/**\n * @type {BaseObject}\n */\n\nvar checkedFonts = new ol_Object();\n/**\n * The label cache for text rendering. To change the default cache size of 2048\n * entries, use {@link module:ol/structs/LRUCache#setSize}.\n * Deprecated - there is no label cache any more.\n * @type {?}\n * @api\n * @deprecated\n */\n\nvar labelCache = new events_Target();\n\nlabelCache.setSize = function () {\n console.warn(\'labelCache is deprecated.\'); //eslint-disable-line\n};\n/**\n * @type {CanvasRenderingContext2D}\n */\n\n\nvar measureContext = null;\n/**\n * @type {string}\n */\n\nvar measureFont;\n/**\n * @type {!Object<string, number>}\n */\n\nvar textHeights = {};\n/**\n * Clears the label cache when a font becomes available.\n * @param {string} fontSpec CSS font spec.\n */\n\nvar registerFont = function () {\n var retries = 100;\n var size = \'32px \';\n var referenceFonts = [\'monospace\', \'serif\'];\n var len = referenceFonts.length;\n var text = "wmytzilWMYTZIL@#/&?$%10\\uF013";\n var interval, referenceWidth;\n /**\n * @param {string} fontStyle Css font-style\n * @param {string} fontWeight Css font-weight\n * @param {*} fontFamily Css font-family\n * @return {boolean} Font with style and weight is available\n */\n\n function isAvailable(fontStyle, fontWeight, fontFamily) {\n var available = true;\n\n for (var i = 0; i < len; ++i) {\n var referenceFont = referenceFonts[i];\n referenceWidth = measureTextWidth(fontStyle + \' \' + fontWeight + \' \' + size + referenceFont, text);\n\n if (fontFamily != referenceFont) {\n var width = measureTextWidth(fontStyle + \' \' + fontWeight + \' \' + size + fontFamily + \',\' + referenceFont, text); // If width and referenceWidth are the same, then the fallback was used\n // instead of the font we wanted, so the font is not available.\n\n available = available && width != referenceWidth;\n }\n }\n\n if (available) {\n return true;\n }\n\n return false;\n }\n\n function check() {\n var done = true;\n var fonts = checkedFonts.getKeys();\n\n for (var i = 0, ii = fonts.length; i < ii; ++i) {\n var font = fonts[i];\n\n if (checkedFonts.get(font) < retries) {\n if (isAvailable.apply(this, font.split(\'\\n\'))) {\n clear(textHeights); // Make sure that loaded fonts are picked up by Safari\n\n measureContext = null;\n measureFont = undefined;\n checkedFonts.set(font, retries);\n } else {\n checkedFonts.set(font, checkedFonts.get(font) + 1, true);\n done = false;\n }\n }\n }\n\n if (done) {\n clearInterval(interval);\n interval = undefined;\n }\n }\n\n return function (fontSpec) {\n var font = getFontParameters(fontSpec);\n\n if (!font) {\n return;\n }\n\n var families = font.families;\n\n for (var i = 0, ii = families.length; i < ii; ++i) {\n var family = families[i];\n var key = font.style + \'\\n\' + font.weight + \'\\n\' + family;\n\n if (checkedFonts.get(key) === undefined) {\n checkedFonts.set(key, retries, true);\n\n if (!isAvailable(font.style, font.weight, family)) {\n checkedFonts.set(key, 0, true);\n\n if (interval === undefined) {\n interval = setInterval(check, 32);\n }\n }\n }\n }\n };\n}();\n/**\n * @param {string} font Font to use for measuring.\n * @return {import("../size.js").Size} Measurement.\n */\n\nvar measureTextHeight = function () {\n /**\n * @type {HTMLDivElement}\n */\n var div;\n return function (fontSpec) {\n var height = textHeights[fontSpec];\n\n if (height == undefined) {\n if (WORKER_OFFSCREEN_CANVAS) {\n var font = getFontParameters(fontSpec);\n var metrics = measureText(fontSpec, \'Žg\');\n var lineHeight = isNaN(Number(font.lineHeight)) ? 1.2 : Number(font.lineHeight);\n height = lineHeight * (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent);\n } else {\n if (!div) {\n div = document.createElement(\'div\');\n div.innerHTML = \'M\';\n div.style.margin = \'0 !important\';\n div.style.padding = \'0 !important\';\n div.style.position = \'absolute !important\';\n div.style.left = \'-99999px !important\';\n }\n\n div.style.font = fontSpec;\n document.body.appendChild(div);\n height = div.offsetHeight;\n document.body.removeChild(div);\n }\n\n textHeights[fontSpec] = height;\n }\n\n return height;\n };\n}();\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {TextMetrics} Text metrics.\n */\n\nfunction measureText(font, text) {\n if (!measureContext) {\n measureContext = createCanvasContext2D(1, 1);\n }\n\n if (font != measureFont) {\n measureContext.font = font;\n measureFont = measureContext.font;\n }\n\n return measureContext.measureText(text);\n}\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {number} Width.\n */\n\n\nfunction measureTextWidth(font, text) {\n return measureText(font, text).width;\n}\n/**\n * Measure text width using a cache.\n * @param {string} font The font.\n * @param {string} text The text to measure.\n * @param {Object<string, number>} cache A lookup of cached widths by text.\n * @returns {number} The text width.\n */\n\nfunction measureAndCacheTextWidth(font, text, cache) {\n if (text in cache) {\n return cache[text];\n }\n\n var width = measureTextWidth(font, text);\n cache[text] = width;\n return width;\n}\n/**\n * @param {string} font Font to use for measuring.\n * @param {Array<string>} lines Lines to measure.\n * @param {Array<number>} widths Array will be populated with the widths of\n * each line.\n * @return {number} Width of the whole text.\n */\n\nfunction measureTextWidths(font, lines, widths) {\n var numLines = lines.length;\n var width = 0;\n\n for (var i = 0; i < numLines; ++i) {\n var currentWidth = measureTextWidth(font, lines[i]);\n width = Math.max(width, currentWidth);\n widths.push(currentWidth);\n }\n\n return width;\n}\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} rotation Rotation.\n * @param {number} offsetX X offset.\n * @param {number} offsetY Y offset.\n */\n\nfunction rotateAtOffset(context, rotation, offsetX, offsetY) {\n if (rotation !== 0) {\n context.translate(offsetX, offsetY);\n context.rotate(rotation);\n context.translate(-offsetX, -offsetY);\n }\n}\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../transform.js").Transform|null} transform Transform.\n * @param {number} opacity Opacity.\n * @param {Label|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} labelOrImage Label.\n * @param {number} originX Origin X.\n * @param {number} originY Origin Y.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../size.js").Size} scale Scale.\n */\n\nfunction drawImageOrLabel(context, transform, opacity, labelOrImage, originX, originY, w, h, x, y, scale) {\n context.save();\n\n if (opacity !== 1) {\n context.globalAlpha *= opacity;\n }\n\n if (transform) {\n context.setTransform.apply(context, transform);\n }\n\n if (\n /** @type {*} */\n labelOrImage.contextInstructions) {\n // label\n context.translate(x, y);\n context.scale(scale[0], scale[1]);\n executeLabelInstructions(\n /** @type {Label} */\n labelOrImage, context);\n } else if (scale[0] < 0 || scale[1] < 0) {\n // flipped image\n context.translate(x, y);\n context.scale(scale[0], scale[1]);\n context.drawImage(\n /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */\n labelOrImage, originX, originY, w, h, 0, 0, w, h);\n } else {\n // if image not flipped translate and scale can be avoided\n context.drawImage(\n /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */\n labelOrImage, originX, originY, w, h, x, y, w * scale[0], h * scale[1]);\n }\n\n context.restore();\n}\n/**\n * @param {Label} label Label.\n * @param {CanvasRenderingContext2D} context Context.\n */\n\nfunction executeLabelInstructions(label, context) {\n var contextInstructions = label.contextInstructions;\n\n for (var i = 0, ii = contextInstructions.length; i < ii; i += 2) {\n if (Array.isArray(contextInstructions[i + 1])) {\n context[contextInstructions[i]].apply(context, contextInstructions[i + 1]);\n } else {\n context[contextInstructions[i]] = contextInstructions[i + 1];\n }\n }\n}\n/**\n * @type {HTMLCanvasElement}\n * @private\n */\n\n\nvar createTransformStringCanvas = null;\n/**\n * @param {import("../transform.js").Transform} transform Transform.\n * @return {string} CSS transform.\n */\n\nfunction createTransformString(transform) {\n if (WORKER_OFFSCREEN_CANVAS) {\n return transform_toString(transform);\n } else {\n if (!createTransformStringCanvas) {\n createTransformStringCanvas = createCanvasContext2D(1, 1).canvas;\n }\n\n createTransformStringCanvas.style.transform = transform_toString(transform);\n return createTransformStringCanvas.style.transform;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/Composite.js\nvar Composite_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/Composite\n */\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Canvas map renderer.\n * @api\n */\n\nvar CompositeMapRenderer =\n/** @class */\nfunction (_super) {\n Composite_extends(CompositeMapRenderer, _super);\n /**\n * @param {import("../PluggableMap.js").default} map Map.\n */\n\n\n function CompositeMapRenderer(map) {\n var _this = _super.call(this, map) || this;\n /**\n * @type {import("../events.js").EventsKey}\n */\n\n\n _this.fontChangeListenerKey_ = listen(checkedFonts, ObjectEventType.PROPERTYCHANGE, map.redrawText.bind(map));\n /**\n * @private\n * @type {HTMLDivElement}\n */\n\n _this.element_ = document.createElement(\'div\');\n var style = _this.element_.style;\n style.position = \'absolute\';\n style.width = \'100%\';\n style.height = \'100%\';\n style.zIndex = \'0\';\n _this.element_.className = CLASS_UNSELECTABLE + \' ol-layers\';\n var container = map.getViewport();\n container.insertBefore(_this.element_, container.firstChild || null);\n /**\n * @private\n * @type {Array<HTMLElement>}\n */\n\n _this.children_ = [];\n /**\n * @private\n * @type {boolean}\n */\n\n _this.renderedVisible_ = true;\n return _this;\n }\n /**\n * @param {import("../render/EventType.js").default} type Event type.\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n CompositeMapRenderer.prototype.dispatchRenderEvent = function (type, frameState) {\n var map = this.getMap();\n\n if (map.hasListener(type)) {\n var event_1 = new render_Event(type, undefined, frameState);\n map.dispatchEvent(event_1);\n }\n };\n\n CompositeMapRenderer.prototype.disposeInternal = function () {\n unlistenByKey(this.fontChangeListenerKey_);\n this.element_.parentNode.removeChild(this.element_);\n\n _super.prototype.disposeInternal.call(this);\n };\n /**\n * Render.\n * @param {?import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n CompositeMapRenderer.prototype.renderFrame = function (frameState) {\n if (!frameState) {\n if (this.renderedVisible_) {\n this.element_.style.display = \'none\';\n this.renderedVisible_ = false;\n }\n\n return;\n }\n\n this.calculateMatrices2D(frameState);\n this.dispatchRenderEvent(render_EventType.PRECOMPOSE, frameState);\n var layerStatesArray = frameState.layerStatesArray.sort(function (a, b) {\n return a.zIndex - b.zIndex;\n });\n var viewState = frameState.viewState;\n this.children_.length = 0;\n /**\n * @type {Array<import("../layer/BaseVector.js").default>}\n */\n\n var declutterLayers = [];\n var previousElement = null;\n\n for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n var layerState = layerStatesArray[i];\n frameState.layerIndex = i;\n\n if (!inView(layerState, viewState) || layerState.sourceState != State.READY && layerState.sourceState != State.UNDEFINED) {\n continue;\n }\n\n var layer = layerState.layer;\n var element = layer.render(frameState, previousElement);\n\n if (!element) {\n continue;\n }\n\n if (element !== previousElement) {\n this.children_.push(element);\n previousElement = element;\n }\n\n if (\'getDeclutter\' in layer) {\n declutterLayers.push(layer);\n }\n }\n\n for (var i = declutterLayers.length - 1; i >= 0; --i) {\n declutterLayers[i].renderDeclutter(frameState);\n }\n\n replaceChildren(this.element_, this.children_);\n this.dispatchRenderEvent(render_EventType.POSTCOMPOSE, frameState);\n\n if (!this.renderedVisible_) {\n this.element_.style.display = \'\';\n this.renderedVisible_ = true;\n }\n\n this.scheduleExpireIconCache(frameState);\n };\n /**\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {function(import("../layer/Layer.js").default, (Uint8ClampedArray|Uint8Array)): T} callback Layer\n * callback.\n * @param {function(import("../layer/Layer.js").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n CompositeMapRenderer.prototype.forEachLayerAtPixel = function (pixel, frameState, hitTolerance, callback, layerFilter) {\n var viewState = frameState.viewState;\n var layerStates = frameState.layerStatesArray;\n var numLayers = layerStates.length;\n\n for (var i = numLayers - 1; i >= 0; --i) {\n var layerState = layerStates[i];\n var layer = layerState.layer;\n\n if (layer.hasRenderer() && inView(layerState, viewState) && layerFilter(layer)) {\n var layerRenderer = layer.getRenderer();\n var data = layerRenderer.getDataAtPixel(pixel, frameState, hitTolerance);\n\n if (data) {\n var result = callback(layer, data);\n\n if (result) {\n return result;\n }\n }\n }\n }\n\n return undefined;\n };\n\n return CompositeMapRenderer;\n}(renderer_Map);\n\n/* harmony default export */ var Composite = (CompositeMapRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/CollectionEventType.js\n/**\n * @module ol/CollectionEventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var CollectionEventType = ({\n /**\n * Triggered when an item is added to the collection.\n * @event module:ol/Collection.CollectionEvent#add\n * @api\n */\n ADD: \'add\',\n\n /**\n * Triggered when an item is removed from the collection.\n * @event module:ol/Collection.CollectionEvent#remove\n * @api\n */\n REMOVE: \'remove\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/Collection.js\nvar Collection_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Collection\n */\n\n\n\n\n\n\n/**\n * @enum {string}\n * @private\n */\n\nvar Collection_Property = {\n LENGTH: \'length\'\n};\n/**\n * @classdesc\n * Events emitted by {@link module:ol/Collection~Collection} instances are instances of this\n * type.\n */\n\nvar CollectionEvent =\n/** @class */\nfunction (_super) {\n Collection_extends(CollectionEvent, _super);\n /**\n * @param {import("./CollectionEventType.js").default} type Type.\n * @param {*=} opt_element Element.\n * @param {number=} opt_index The index of the added or removed element.\n */\n\n\n function CollectionEvent(type, opt_element, opt_index) {\n var _this = _super.call(this, type) || this;\n /**\n * The element that is added to or removed from the collection.\n * @type {*}\n * @api\n */\n\n\n _this.element = opt_element;\n /**\n * The index of the added or removed element.\n * @type {number}\n * @api\n */\n\n _this.index = opt_index;\n return _this;\n }\n\n return CollectionEvent;\n}(Event);\n\n\n/**\n * @typedef {Object} Options\n * @property {boolean} [unique=false] Disallow the same item from being added to\n * the collection twice.\n */\n\n/**\n * @classdesc\n * An expanded version of standard JS Array, adding convenience methods for\n * manipulation. Add and remove changes to the Collection trigger a Collection\n * event. Note that this does not cover changes to the objects _within_ the\n * Collection; they trigger events on the appropriate object, not on the\n * Collection as a whole.\n *\n * @fires CollectionEvent\n *\n * @template T\n * @api\n */\n\nvar Collection =\n/** @class */\nfunction (_super) {\n Collection_extends(Collection, _super);\n /**\n * @param {Array<T>=} opt_array Array.\n * @param {Options=} opt_options Collection options.\n */\n\n\n function Collection(opt_array, opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options || {};\n /**\n * @private\n * @type {boolean}\n */\n\n _this.unique_ = !!options.unique;\n /**\n * @private\n * @type {!Array<T>}\n */\n\n _this.array_ = opt_array ? opt_array : [];\n\n if (_this.unique_) {\n for (var i = 0, ii = _this.array_.length; i < ii; ++i) {\n _this.assertUnique_(_this.array_[i], i);\n }\n }\n\n _this.updateLength_();\n\n return _this;\n }\n /**\n * Remove all elements from the collection.\n * @api\n */\n\n\n Collection.prototype.clear = function () {\n while (this.getLength() > 0) {\n this.pop();\n }\n };\n /**\n * Add elements to the collection. This pushes each item in the provided array\n * to the end of the collection.\n * @param {!Array<T>} arr Array.\n * @return {Collection<T>} This collection.\n * @api\n */\n\n\n Collection.prototype.extend = function (arr) {\n for (var i = 0, ii = arr.length; i < ii; ++i) {\n this.push(arr[i]);\n }\n\n return this;\n };\n /**\n * Iterate over each element, calling the provided callback.\n * @param {function(T, number, Array<T>): *} f The function to call\n * for every element. This function takes 3 arguments (the element, the\n * index and the array). The return value is ignored.\n * @api\n */\n\n\n Collection.prototype.forEach = function (f) {\n var array = this.array_;\n\n for (var i = 0, ii = array.length; i < ii; ++i) {\n f(array[i], i, array);\n }\n };\n /**\n * Get a reference to the underlying Array object. Warning: if the array\n * is mutated, no events will be dispatched by the collection, and the\n * collection\'s "length" property won\'t be in sync with the actual length\n * of the array.\n * @return {!Array<T>} Array.\n * @api\n */\n\n\n Collection.prototype.getArray = function () {\n return this.array_;\n };\n /**\n * Get the element at the provided index.\n * @param {number} index Index.\n * @return {T} Element.\n * @api\n */\n\n\n Collection.prototype.item = function (index) {\n return this.array_[index];\n };\n /**\n * Get the length of this collection.\n * @return {number} The length of the array.\n * @observable\n * @api\n */\n\n\n Collection.prototype.getLength = function () {\n return this.get(Collection_Property.LENGTH);\n };\n /**\n * Insert an element at the provided index.\n * @param {number} index Index.\n * @param {T} elem Element.\n * @api\n */\n\n\n Collection.prototype.insertAt = function (index, elem) {\n if (this.unique_) {\n this.assertUnique_(elem);\n }\n\n this.array_.splice(index, 0, elem);\n this.updateLength_();\n this.dispatchEvent(new CollectionEvent(CollectionEventType.ADD, elem, index));\n };\n /**\n * Remove the last element of the collection and return it.\n * Return `undefined` if the collection is empty.\n * @return {T|undefined} Element.\n * @api\n */\n\n\n Collection.prototype.pop = function () {\n return this.removeAt(this.getLength() - 1);\n };\n /**\n * Insert the provided element at the end of the collection.\n * @param {T} elem Element.\n * @return {number} New length of the collection.\n * @api\n */\n\n\n Collection.prototype.push = function (elem) {\n if (this.unique_) {\n this.assertUnique_(elem);\n }\n\n var n = this.getLength();\n this.insertAt(n, elem);\n return this.getLength();\n };\n /**\n * Remove the first occurrence of an element from the collection.\n * @param {T} elem Element.\n * @return {T|undefined} The removed element or undefined if none found.\n * @api\n */\n\n\n Collection.prototype.remove = function (elem) {\n var arr = this.array_;\n\n for (var i = 0, ii = arr.length; i < ii; ++i) {\n if (arr[i] === elem) {\n return this.removeAt(i);\n }\n }\n\n return undefined;\n };\n /**\n * Remove the element at the provided index and return it.\n * Return `undefined` if the collection does not contain this index.\n * @param {number} index Index.\n * @return {T|undefined} Value.\n * @api\n */\n\n\n Collection.prototype.removeAt = function (index) {\n var prev = this.array_[index];\n this.array_.splice(index, 1);\n this.updateLength_();\n this.dispatchEvent(new CollectionEvent(CollectionEventType.REMOVE, prev, index));\n return prev;\n };\n /**\n * Set the element at the provided index.\n * @param {number} index Index.\n * @param {T} elem Element.\n * @api\n */\n\n\n Collection.prototype.setAt = function (index, elem) {\n var n = this.getLength();\n\n if (index < n) {\n if (this.unique_) {\n this.assertUnique_(elem, index);\n }\n\n var prev = this.array_[index];\n this.array_[index] = elem;\n this.dispatchEvent(new CollectionEvent(CollectionEventType.REMOVE, prev, index));\n this.dispatchEvent(new CollectionEvent(CollectionEventType.ADD, elem, index));\n } else {\n for (var j = n; j < index; ++j) {\n this.insertAt(j, undefined);\n }\n\n this.insertAt(index, elem);\n }\n };\n /**\n * @private\n */\n\n\n Collection.prototype.updateLength_ = function () {\n this.set(Collection_Property.LENGTH, this.array_.length);\n };\n /**\n * @private\n * @param {T} elem Element.\n * @param {number=} opt_except Optional index to ignore.\n */\n\n\n Collection.prototype.assertUnique_ = function (elem, opt_except) {\n for (var i = 0, ii = this.array_.length; i < ii; ++i) {\n if (this.array_[i] === elem && i !== opt_except) {\n throw new ol_AssertionError(58);\n }\n }\n };\n\n return Collection;\n}(ol_Object);\n\n/* harmony default export */ var ol_Collection = (Collection);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Group.js\nvar Group_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/Group\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {Array<import("./Base.js").default>|import("../Collection.js").default<import("./Base.js").default>} [layers] Child layers.\n */\n\n/**\n * @enum {string}\n * @private\n */\n\nvar Group_Property = {\n LAYERS: \'layers\'\n};\n/**\n * @classdesc\n * A {@link module:ol/Collection~Collection} of layers that are handled together.\n *\n * A generic `change` event is triggered when the group/Collection changes.\n *\n * @api\n */\n\nvar LayerGroup =\n/** @class */\nfunction (_super) {\n Group_extends(LayerGroup, _super);\n /**\n * @param {Options=} opt_options Layer options.\n */\n\n\n function LayerGroup(opt_options) {\n var _this = this;\n\n var options = opt_options || {};\n var baseOptions =\n /** @type {Options} */\n obj_assign({}, options);\n delete baseOptions.layers;\n var layers = options.layers;\n _this = _super.call(this, baseOptions) || this;\n /**\n * @private\n * @type {Array<import("../events.js").EventsKey>}\n */\n\n _this.layersListenerKeys_ = [];\n /**\n * @private\n * @type {Object<string, Array<import("../events.js").EventsKey>>}\n */\n\n _this.listenerKeys_ = {};\n\n _this.addEventListener(getChangeEventType(Group_Property.LAYERS), _this.handleLayersChanged_);\n\n if (layers) {\n if (Array.isArray(layers)) {\n layers = new ol_Collection(layers.slice(), {\n unique: true\n });\n } else {\n asserts_assert(typeof\n /** @type {?} */\n layers.getArray === \'function\', 43); // Expected `layers` to be an array or a `Collection`\n }\n } else {\n layers = new ol_Collection(undefined, {\n unique: true\n });\n }\n\n _this.setLayers(layers);\n\n return _this;\n }\n /**\n * @private\n */\n\n\n LayerGroup.prototype.handleLayerChange_ = function () {\n this.changed();\n };\n /**\n * @private\n */\n\n\n LayerGroup.prototype.handleLayersChanged_ = function () {\n this.layersListenerKeys_.forEach(unlistenByKey);\n this.layersListenerKeys_.length = 0;\n var layers = this.getLayers();\n this.layersListenerKeys_.push(listen(layers, CollectionEventType.ADD, this.handleLayersAdd_, this), listen(layers, CollectionEventType.REMOVE, this.handleLayersRemove_, this));\n\n for (var id in this.listenerKeys_) {\n this.listenerKeys_[id].forEach(unlistenByKey);\n }\n\n clear(this.listenerKeys_);\n var layersArray = layers.getArray();\n\n for (var i = 0, ii = layersArray.length; i < ii; i++) {\n var layer = layersArray[i];\n this.listenerKeys_[getUid(layer)] = [listen(layer, ObjectEventType.PROPERTYCHANGE, this.handleLayerChange_, this), listen(layer, EventType.CHANGE, this.handleLayerChange_, this)];\n }\n\n this.changed();\n };\n /**\n * @param {import("../Collection.js").CollectionEvent} collectionEvent CollectionEvent.\n * @private\n */\n\n\n LayerGroup.prototype.handleLayersAdd_ = function (collectionEvent) {\n var layer =\n /** @type {import("./Base.js").default} */\n collectionEvent.element;\n this.listenerKeys_[getUid(layer)] = [listen(layer, ObjectEventType.PROPERTYCHANGE, this.handleLayerChange_, this), listen(layer, EventType.CHANGE, this.handleLayerChange_, this)];\n this.changed();\n };\n /**\n * @param {import("../Collection.js").CollectionEvent} collectionEvent CollectionEvent.\n * @private\n */\n\n\n LayerGroup.prototype.handleLayersRemove_ = function (collectionEvent) {\n var layer =\n /** @type {import("./Base.js").default} */\n collectionEvent.element;\n var key = getUid(layer);\n this.listenerKeys_[key].forEach(unlistenByKey);\n delete this.listenerKeys_[key];\n this.changed();\n };\n /**\n * Returns the {@link module:ol/Collection collection} of {@link module:ol/layer/Layer~Layer layers}\n * in this group.\n * @return {!import("../Collection.js").default<import("./Base.js").default>} Collection of\n * {@link module:ol/layer/Base layers} that are part of this group.\n * @observable\n * @api\n */\n\n\n LayerGroup.prototype.getLayers = function () {\n return (\n /** @type {!import("../Collection.js").default<import("./Base.js").default>} */\n this.get(Group_Property.LAYERS)\n );\n };\n /**\n * Set the {@link module:ol/Collection collection} of {@link module:ol/layer/Layer~Layer layers}\n * in this group.\n * @param {!import("../Collection.js").default<import("./Base.js").default>} layers Collection of\n * {@link module:ol/layer/Base layers} that are part of this group.\n * @observable\n * @api\n */\n\n\n LayerGroup.prototype.setLayers = function (layers) {\n this.set(Group_Property.LAYERS, layers);\n };\n /**\n * @param {Array<import("./Layer.js").default>=} opt_array Array of layers (to be modified in place).\n * @return {Array<import("./Layer.js").default>} Array of layers.\n */\n\n\n LayerGroup.prototype.getLayersArray = function (opt_array) {\n var array = opt_array !== undefined ? opt_array : [];\n this.getLayers().forEach(function (layer) {\n layer.getLayersArray(array);\n });\n return array;\n };\n /**\n * @param {Array<import("./Layer.js").State>=} opt_states Optional list of layer states (to be modified in place).\n * @return {Array<import("./Layer.js").State>} List of layer states.\n */\n\n\n LayerGroup.prototype.getLayerStatesArray = function (opt_states) {\n var states = opt_states !== undefined ? opt_states : [];\n var pos = states.length;\n this.getLayers().forEach(function (layer) {\n layer.getLayerStatesArray(states);\n });\n var ownLayerState = this.getLayerState();\n\n for (var i = pos, ii = states.length; i < ii; i++) {\n var layerState = states[i];\n layerState.opacity *= ownLayerState.opacity;\n layerState.visible = layerState.visible && ownLayerState.visible;\n layerState.maxResolution = Math.min(layerState.maxResolution, ownLayerState.maxResolution);\n layerState.minResolution = Math.max(layerState.minResolution, ownLayerState.minResolution);\n layerState.minZoom = Math.max(layerState.minZoom, ownLayerState.minZoom);\n layerState.maxZoom = Math.min(layerState.maxZoom, ownLayerState.maxZoom);\n\n if (ownLayerState.extent !== undefined) {\n if (layerState.extent !== undefined) {\n layerState.extent = getIntersection(layerState.extent, ownLayerState.extent);\n } else {\n layerState.extent = ownLayerState.extent;\n }\n }\n }\n\n return states;\n };\n /**\n * @return {import("../source/State.js").default} Source state.\n */\n\n\n LayerGroup.prototype.getSourceState = function () {\n return State.READY;\n };\n\n return LayerGroup;\n}(Base);\n\n/* harmony default export */ var Group = (LayerGroup);\n;// CONCATENATED MODULE: ./node_modules/ol/MapEvent.js\nvar MapEvent_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/MapEvent\n */\n\n\n\n/**\n * @classdesc\n * Events emitted as map events are instances of this type.\n * See {@link module:ol/PluggableMap~PluggableMap} for which events trigger a map event.\n */\n\nvar MapEvent =\n/** @class */\nfunction (_super) {\n MapEvent_extends(MapEvent, _super);\n /**\n * @param {string} type Event type.\n * @param {import("./PluggableMap.js").default} map Map.\n * @param {?import("./PluggableMap.js").FrameState=} opt_frameState Frame state.\n */\n\n\n function MapEvent(type, map, opt_frameState) {\n var _this = _super.call(this, type) || this;\n /**\n * The map where the event occurred.\n * @type {import("./PluggableMap.js").default}\n * @api\n */\n\n\n _this.map = map;\n /**\n * The frame state at the time of the event.\n * @type {?import("./PluggableMap.js").FrameState}\n * @api\n */\n\n _this.frameState = opt_frameState !== undefined ? opt_frameState : null;\n return _this;\n }\n\n return MapEvent;\n}(Event);\n\n/* harmony default export */ var ol_MapEvent = (MapEvent);\n;// CONCATENATED MODULE: ./node_modules/ol/MapBrowserEvent.js\nvar MapBrowserEvent_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/MapBrowserEvent\n */\n\n\n\n/**\n * @classdesc\n * Events emitted as map browser events are instances of this type.\n * See {@link module:ol/PluggableMap~PluggableMap} for which events trigger a map browser event.\n * @template {UIEvent} EVENT\n */\n\nvar MapBrowserEvent =\n/** @class */\nfunction (_super) {\n MapBrowserEvent_extends(MapBrowserEvent, _super);\n /**\n * @param {string} type Event type.\n * @param {import("./PluggableMap.js").default} map Map.\n * @param {EVENT} originalEvent Original event.\n * @param {boolean=} opt_dragging Is the map currently being dragged?\n * @param {?import("./PluggableMap.js").FrameState=} opt_frameState Frame state.\n */\n\n\n function MapBrowserEvent(type, map, originalEvent, opt_dragging, opt_frameState) {\n var _this = _super.call(this, type, map, opt_frameState) || this;\n /**\n * The original browser event.\n * @const\n * @type {EVENT}\n * @api\n */\n\n\n _this.originalEvent = originalEvent;\n /**\n * The map pixel relative to the viewport corresponding to the original browser event.\n * @type {?import("./pixel.js").Pixel}\n */\n\n _this.pixel_ = null;\n /**\n * The coordinate in the user projection corresponding to the original browser event.\n * @type {?import("./coordinate.js").Coordinate}\n */\n\n _this.coordinate_ = null;\n /**\n * Indicates if the map is currently being dragged. Only set for\n * `POINTERDRAG` and `POINTERMOVE` events. Default is `false`.\n *\n * @type {boolean}\n * @api\n */\n\n _this.dragging = opt_dragging !== undefined ? opt_dragging : false;\n return _this;\n }\n\n Object.defineProperty(MapBrowserEvent.prototype, "pixel", {\n /**\n * The map pixel relative to the viewport corresponding to the original event.\n * @type {import("./pixel.js").Pixel}\n * @api\n */\n get: function get() {\n if (!this.pixel_) {\n this.pixel_ = this.map.getEventPixel(this.originalEvent);\n }\n\n return this.pixel_;\n },\n set: function set(pixel) {\n this.pixel_ = pixel;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(MapBrowserEvent.prototype, "coordinate", {\n /**\n * The coordinate corresponding to the original browser event. This will be in the user\n * projection if one is set. Otherwise it will be in the view projection.\n * @type {import("./coordinate.js").Coordinate}\n * @api\n */\n get: function get() {\n if (!this.coordinate_) {\n this.coordinate_ = this.map.getCoordinateFromPixel(this.pixel);\n }\n\n return this.coordinate_;\n },\n set: function set(coordinate) {\n this.coordinate_ = coordinate;\n },\n enumerable: false,\n configurable: true\n });\n /**\n * Prevents the default browser action.\n * See https://developer.mozilla.org/en-US/docs/Web/API/event.preventDefault.\n * @api\n */\n\n MapBrowserEvent.prototype.preventDefault = function () {\n _super.prototype.preventDefault.call(this);\n\n this.originalEvent.preventDefault();\n };\n /**\n * Prevents further propagation of the current event.\n * See https://developer.mozilla.org/en-US/docs/Web/API/event.stopPropagation.\n * @api\n */\n\n\n MapBrowserEvent.prototype.stopPropagation = function () {\n _super.prototype.stopPropagation.call(this);\n\n this.originalEvent.stopPropagation();\n };\n\n return MapBrowserEvent;\n}(ol_MapEvent);\n\n/* harmony default export */ var ol_MapBrowserEvent = (MapBrowserEvent);\n;// CONCATENATED MODULE: ./node_modules/ol/MapBrowserEventType.js\n/**\n * @module ol/MapBrowserEventType\n */\n\n/**\n * Constants for event names.\n * @enum {string}\n */\n\n/* harmony default export */ var ol_MapBrowserEventType = ({\n /**\n * A true single click with no dragging and no double click. Note that this\n * event is delayed by 250 ms to ensure that it is not a double click.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#singleclick\n * @api\n */\n SINGLECLICK: \'singleclick\',\n\n /**\n * A click with no dragging. A double click will fire two of this.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#click\n * @api\n */\n CLICK: EventType.CLICK,\n\n /**\n * A true double click, with no dragging.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#dblclick\n * @api\n */\n DBLCLICK: EventType.DBLCLICK,\n\n /**\n * Triggered when a pointer is dragged.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointerdrag\n * @api\n */\n POINTERDRAG: \'pointerdrag\',\n\n /**\n * Triggered when a pointer is moved. Note that on touch devices this is\n * triggered when the map is panned, so is not the same as mousemove.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointermove\n * @api\n */\n POINTERMOVE: \'pointermove\',\n POINTERDOWN: \'pointerdown\',\n POINTERUP: \'pointerup\',\n POINTEROVER: \'pointerover\',\n POINTEROUT: \'pointerout\',\n POINTERENTER: \'pointerenter\',\n POINTERLEAVE: \'pointerleave\',\n POINTERCANCEL: \'pointercancel\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/pointer/EventType.js\n/**\n * @module ol/pointer/EventType\n */\n\n/**\n * Constants for event names.\n * @enum {string}\n */\n/* harmony default export */ var pointer_EventType = ({\n POINTERMOVE: \'pointermove\',\n POINTERDOWN: \'pointerdown\',\n POINTERUP: \'pointerup\',\n POINTEROVER: \'pointerover\',\n POINTEROUT: \'pointerout\',\n POINTERENTER: \'pointerenter\',\n POINTERLEAVE: \'pointerleave\',\n POINTERCANCEL: \'pointercancel\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/MapBrowserEventHandler.js\n/**\n * @module ol/MapBrowserEventHandler\n */\nvar MapBrowserEventHandler_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\nvar MapBrowserEventHandler =\n/** @class */\nfunction (_super) {\n MapBrowserEventHandler_extends(MapBrowserEventHandler, _super);\n /**\n * @param {import("./PluggableMap.js").default} map The map with the viewport to listen to events on.\n * @param {number=} moveTolerance The minimal distance the pointer must travel to trigger a move.\n */\n\n\n function MapBrowserEventHandler(map, moveTolerance) {\n var _this = _super.call(this, map) || this;\n /**\n * This is the element that we will listen to the real events on.\n * @type {import("./PluggableMap.js").default}\n * @private\n */\n\n\n _this.map_ = map;\n /**\n * @type {any}\n * @private\n */\n\n _this.clickTimeoutId_;\n /**\n * Emulate dblclick and singleclick. Will be true when only one pointer is active.\n * @type {boolean}\n */\n\n _this.emulateClicks_ = false;\n /**\n * @type {boolean}\n * @private\n */\n\n _this.dragging_ = false;\n /**\n * @type {!Array<import("./events.js").EventsKey>}\n * @private\n */\n\n _this.dragListenerKeys_ = [];\n /**\n * @type {number}\n * @private\n */\n\n _this.moveTolerance_ = moveTolerance ? moveTolerance * DEVICE_PIXEL_RATIO : DEVICE_PIXEL_RATIO;\n /**\n * The most recent "down" type event (or null if none have occurred).\n * Set on pointerdown.\n * @type {PointerEvent}\n * @private\n */\n\n _this.down_ = null;\n\n var element = _this.map_.getViewport();\n /**\n * @type {number}\n * @private\n */\n\n\n _this.activePointers_ = 0;\n /**\n * @type {!Object<number, boolean>}\n * @private\n */\n\n _this.trackedTouches_ = {};\n _this.element_ = element;\n /**\n * @type {?import("./events.js").EventsKey}\n * @private\n */\n\n _this.pointerdownListenerKey_ = listen(element, pointer_EventType.POINTERDOWN, _this.handlePointerDown_, _this);\n /**\n * @type {PointerEvent}\n * @private\n */\n\n _this.originalPointerMoveEvent_;\n /**\n * @type {?import("./events.js").EventsKey}\n * @private\n */\n\n _this.relayedListenerKey_ = listen(element, pointer_EventType.POINTERMOVE, _this.relayEvent_, _this);\n /**\n * @private\n */\n\n _this.boundHandleTouchMove_ = _this.handleTouchMove_.bind(_this);\n\n _this.element_.addEventListener(EventType.TOUCHMOVE, _this.boundHandleTouchMove_, PASSIVE_EVENT_LISTENERS ? {\n passive: false\n } : false);\n\n return _this;\n }\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.emulateClick_ = function (pointerEvent) {\n var newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.CLICK, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n\n if (this.clickTimeoutId_ !== undefined) {\n // double-click\n clearTimeout(this.clickTimeoutId_);\n this.clickTimeoutId_ = undefined;\n newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.DBLCLICK, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n } else {\n // click\n this.clickTimeoutId_ = setTimeout(\n /** @this {MapBrowserEventHandler} */\n function () {\n this.clickTimeoutId_ = undefined;\n var newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.SINGLECLICK, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n }.bind(this), 250);\n }\n };\n /**\n * Keeps track on how many pointers are currently active.\n *\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.updateActivePointers_ = function (pointerEvent) {\n var event = pointerEvent;\n\n if (event.type == ol_MapBrowserEventType.POINTERUP || event.type == ol_MapBrowserEventType.POINTERCANCEL) {\n delete this.trackedTouches_[event.pointerId];\n } else if (event.type == ol_MapBrowserEventType.POINTERDOWN) {\n this.trackedTouches_[event.pointerId] = true;\n }\n\n this.activePointers_ = Object.keys(this.trackedTouches_).length;\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.handlePointerUp_ = function (pointerEvent) {\n this.updateActivePointers_(pointerEvent);\n var newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.POINTERUP, this.map_, pointerEvent);\n this.dispatchEvent(newEvent); // We emulate click events on left mouse button click, touch contact, and pen\n // contact. isMouseActionButton returns true in these cases (evt.button is set\n // to 0).\n // See http://www.w3.org/TR/pointerevents/#button-states\n // We only fire click, singleclick, and doubleclick if nobody has called\n // event.stopPropagation() or event.preventDefault().\n\n if (this.emulateClicks_ && !newEvent.propagationStopped && !this.dragging_ && this.isMouseActionButton_(pointerEvent)) {\n this.emulateClick_(this.down_);\n }\n\n if (this.activePointers_ === 0) {\n this.dragListenerKeys_.forEach(unlistenByKey);\n this.dragListenerKeys_.length = 0;\n this.dragging_ = false;\n this.down_ = null;\n }\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @return {boolean} If the left mouse button was pressed.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.isMouseActionButton_ = function (pointerEvent) {\n return pointerEvent.button === 0;\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.handlePointerDown_ = function (pointerEvent) {\n this.emulateClicks_ = this.activePointers_ === 0;\n this.updateActivePointers_(pointerEvent);\n var newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.POINTERDOWN, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n this.down_ = pointerEvent;\n\n if (this.dragListenerKeys_.length === 0) {\n var doc = this.map_.getOwnerDocument();\n this.dragListenerKeys_.push(listen(doc, ol_MapBrowserEventType.POINTERMOVE, this.handlePointerMove_, this), listen(doc, ol_MapBrowserEventType.POINTERUP, this.handlePointerUp_, this),\n /* Note that the listener for `pointercancel is set up on\n * `pointerEventHandler_` and not `documentPointerEventHandler_` like\n * the `pointerup` and `pointermove` listeners.\n *\n * The reason for this is the following: `TouchSource.vacuumTouches_()`\n * issues `pointercancel` events, when there was no `touchend` for a\n * `touchstart`. Now, let\'s say a first `touchstart` is registered on\n * `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.\n * But `documentPointerEventHandler_` doesn\'t know about the first\n * `touchstart`. If there is no `touchend` for the `touchstart`, we can\n * only receive a `touchcancel` from `pointerEventHandler_`, because it is\n * only registered there.\n */\n listen(this.element_, ol_MapBrowserEventType.POINTERCANCEL, this.handlePointerUp_, this));\n\n if (this.element_.getRootNode && this.element_.getRootNode() !== doc) {\n this.dragListenerKeys_.push(listen(this.element_.getRootNode(), ol_MapBrowserEventType.POINTERUP, this.handlePointerUp_, this));\n }\n }\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.handlePointerMove_ = function (pointerEvent) {\n // Between pointerdown and pointerup, pointermove events are triggered.\n // To avoid a \'false\' touchmove event to be dispatched, we test if the pointer\n // moved a significant distance.\n if (this.isMoving_(pointerEvent)) {\n this.dragging_ = true;\n var newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.POINTERDRAG, this.map_, pointerEvent, this.dragging_);\n this.dispatchEvent(newEvent);\n }\n };\n /**\n * Wrap and relay a pointer event. Note that this requires that the type\n * string for the MapBrowserEvent matches the PointerEvent type.\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.relayEvent_ = function (pointerEvent) {\n this.originalPointerMoveEvent_ = pointerEvent;\n var dragging = !!(this.down_ && this.isMoving_(pointerEvent));\n this.dispatchEvent(new ol_MapBrowserEvent(pointerEvent.type, this.map_, pointerEvent, dragging));\n };\n /**\n * Flexible handling of a `touch-action: none` css equivalent: because calling\n * `preventDefault()` on a `pointermove` event does not stop native page scrolling\n * and zooming, we also listen for `touchmove` and call `preventDefault()` on it\n * when an interaction (currently `DragPan` handles the event.\n * @param {TouchEvent} event Event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.handleTouchMove_ = function (event) {\n // Due to https://github.com/mpizenberg/elm-pep/issues/2, `this.originalPointerMoveEvent_`\n // may not be initialized yet when we get here on a platform without native pointer events.\n if (!this.originalPointerMoveEvent_ || this.originalPointerMoveEvent_.defaultPrevented) {\n event.preventDefault();\n }\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @return {boolean} Is moving.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.isMoving_ = function (pointerEvent) {\n return this.dragging_ || Math.abs(pointerEvent.clientX - this.down_.clientX) > this.moveTolerance_ || Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_;\n };\n /**\n * Clean up.\n */\n\n\n MapBrowserEventHandler.prototype.disposeInternal = function () {\n if (this.relayedListenerKey_) {\n unlistenByKey(this.relayedListenerKey_);\n this.relayedListenerKey_ = null;\n }\n\n this.element_.removeEventListener(EventType.TOUCHMOVE, this.boundHandleTouchMove_);\n\n if (this.pointerdownListenerKey_) {\n unlistenByKey(this.pointerdownListenerKey_);\n this.pointerdownListenerKey_ = null;\n }\n\n this.dragListenerKeys_.forEach(unlistenByKey);\n this.dragListenerKeys_.length = 0;\n this.element_ = null;\n\n _super.prototype.disposeInternal.call(this);\n };\n\n return MapBrowserEventHandler;\n}(events_Target);\n\n/* harmony default export */ var ol_MapBrowserEventHandler = (MapBrowserEventHandler);\n;// CONCATENATED MODULE: ./node_modules/ol/MapEventType.js\n/**\n * @module ol/MapEventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var MapEventType = ({\n /**\n * Triggered after a map frame is rendered.\n * @event module:ol/MapEvent~MapEvent#postrender\n * @api\n */\n POSTRENDER: \'postrender\',\n\n /**\n * Triggered when the map starts moving.\n * @event module:ol/MapEvent~MapEvent#movestart\n * @api\n */\n MOVESTART: \'movestart\',\n\n /**\n * Triggered after the map is moved.\n * @event module:ol/MapEvent~MapEvent#moveend\n * @api\n */\n MOVEEND: \'moveend\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/MapProperty.js\n/**\n * @module ol/MapProperty\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var MapProperty = ({\n LAYERGROUP: \'layergroup\',\n SIZE: \'size\',\n TARGET: \'target\',\n VIEW: \'view\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/structs/PriorityQueue.js\n/**\n * @module ol/structs/PriorityQueue\n */\n\n\n/**\n * @type {number}\n */\n\nvar DROP = Infinity;\n/**\n * @classdesc\n * Priority queue.\n *\n * The implementation is inspired from the Closure Library\'s Heap class and\n * Python\'s heapq module.\n *\n * See http://closure-library.googlecode.com/svn/docs/closure_goog_structs_heap.js.source.html\n * and http://hg.python.org/cpython/file/2.7/Lib/heapq.py.\n *\n * @template T\n */\n\nvar PriorityQueue =\n/** @class */\nfunction () {\n /**\n * @param {function(T): number} priorityFunction Priority function.\n * @param {function(T): string} keyFunction Key function.\n */\n function PriorityQueue(priorityFunction, keyFunction) {\n /**\n * @type {function(T): number}\n * @private\n */\n this.priorityFunction_ = priorityFunction;\n /**\n * @type {function(T): string}\n * @private\n */\n\n this.keyFunction_ = keyFunction;\n /**\n * @type {Array<T>}\n * @private\n */\n\n this.elements_ = [];\n /**\n * @type {Array<number>}\n * @private\n */\n\n this.priorities_ = [];\n /**\n * @type {!Object<string, boolean>}\n * @private\n */\n\n this.queuedElements_ = {};\n }\n /**\n * FIXME empty description for jsdoc\n */\n\n\n PriorityQueue.prototype.clear = function () {\n this.elements_.length = 0;\n this.priorities_.length = 0;\n clear(this.queuedElements_);\n };\n /**\n * Remove and return the highest-priority element. O(log N).\n * @return {T} Element.\n */\n\n\n PriorityQueue.prototype.dequeue = function () {\n var elements = this.elements_;\n var priorities = this.priorities_;\n var element = elements[0];\n\n if (elements.length == 1) {\n elements.length = 0;\n priorities.length = 0;\n } else {\n elements[0] = elements.pop();\n priorities[0] = priorities.pop();\n this.siftUp_(0);\n }\n\n var elementKey = this.keyFunction_(element);\n delete this.queuedElements_[elementKey];\n return element;\n };\n /**\n * Enqueue an element. O(log N).\n * @param {T} element Element.\n * @return {boolean} The element was added to the queue.\n */\n\n\n PriorityQueue.prototype.enqueue = function (element) {\n asserts_assert(!(this.keyFunction_(element) in this.queuedElements_), 31); // Tried to enqueue an `element` that was already added to the queue\n\n var priority = this.priorityFunction_(element);\n\n if (priority != DROP) {\n this.elements_.push(element);\n this.priorities_.push(priority);\n this.queuedElements_[this.keyFunction_(element)] = true;\n this.siftDown_(0, this.elements_.length - 1);\n return true;\n }\n\n return false;\n };\n /**\n * @return {number} Count.\n */\n\n\n PriorityQueue.prototype.getCount = function () {\n return this.elements_.length;\n };\n /**\n * Gets the index of the left child of the node at the given index.\n * @param {number} index The index of the node to get the left child for.\n * @return {number} The index of the left child.\n * @private\n */\n\n\n PriorityQueue.prototype.getLeftChildIndex_ = function (index) {\n return index * 2 + 1;\n };\n /**\n * Gets the index of the right child of the node at the given index.\n * @param {number} index The index of the node to get the right child for.\n * @return {number} The index of the right child.\n * @private\n */\n\n\n PriorityQueue.prototype.getRightChildIndex_ = function (index) {\n return index * 2 + 2;\n };\n /**\n * Gets the index of the parent of the node at the given index.\n * @param {number} index The index of the node to get the parent for.\n * @return {number} The index of the parent.\n * @private\n */\n\n\n PriorityQueue.prototype.getParentIndex_ = function (index) {\n return index - 1 >> 1;\n };\n /**\n * Make this a heap. O(N).\n * @private\n */\n\n\n PriorityQueue.prototype.heapify_ = function () {\n var i;\n\n for (i = (this.elements_.length >> 1) - 1; i >= 0; i--) {\n this.siftUp_(i);\n }\n };\n /**\n * @return {boolean} Is empty.\n */\n\n\n PriorityQueue.prototype.isEmpty = function () {\n return this.elements_.length === 0;\n };\n /**\n * @param {string} key Key.\n * @return {boolean} Is key queued.\n */\n\n\n PriorityQueue.prototype.isKeyQueued = function (key) {\n return key in this.queuedElements_;\n };\n /**\n * @param {T} element Element.\n * @return {boolean} Is queued.\n */\n\n\n PriorityQueue.prototype.isQueued = function (element) {\n return this.isKeyQueued(this.keyFunction_(element));\n };\n /**\n * @param {number} index The index of the node to move down.\n * @private\n */\n\n\n PriorityQueue.prototype.siftUp_ = function (index) {\n var elements = this.elements_;\n var priorities = this.priorities_;\n var count = elements.length;\n var element = elements[index];\n var priority = priorities[index];\n var startIndex = index;\n\n while (index < count >> 1) {\n var lIndex = this.getLeftChildIndex_(index);\n var rIndex = this.getRightChildIndex_(index);\n var smallerChildIndex = rIndex < count && priorities[rIndex] < priorities[lIndex] ? rIndex : lIndex;\n elements[index] = elements[smallerChildIndex];\n priorities[index] = priorities[smallerChildIndex];\n index = smallerChildIndex;\n }\n\n elements[index] = element;\n priorities[index] = priority;\n this.siftDown_(startIndex, index);\n };\n /**\n * @param {number} startIndex The index of the root.\n * @param {number} index The index of the node to move up.\n * @private\n */\n\n\n PriorityQueue.prototype.siftDown_ = function (startIndex, index) {\n var elements = this.elements_;\n var priorities = this.priorities_;\n var element = elements[index];\n var priority = priorities[index];\n\n while (index > startIndex) {\n var parentIndex = this.getParentIndex_(index);\n\n if (priorities[parentIndex] > priority) {\n elements[index] = elements[parentIndex];\n priorities[index] = priorities[parentIndex];\n index = parentIndex;\n } else {\n break;\n }\n }\n\n elements[index] = element;\n priorities[index] = priority;\n };\n /**\n * FIXME empty description for jsdoc\n */\n\n\n PriorityQueue.prototype.reprioritize = function () {\n var priorityFunction = this.priorityFunction_;\n var elements = this.elements_;\n var priorities = this.priorities_;\n var index = 0;\n var n = elements.length;\n var element, i, priority;\n\n for (i = 0; i < n; ++i) {\n element = elements[i];\n priority = priorityFunction(element);\n\n if (priority == DROP) {\n delete this.queuedElements_[this.keyFunction_(element)];\n } else {\n priorities[index] = priority;\n elements[index++] = element;\n }\n }\n\n elements.length = index;\n priorities.length = index;\n this.heapify_();\n };\n\n return PriorityQueue;\n}();\n\n/* harmony default export */ var structs_PriorityQueue = (PriorityQueue);\n;// CONCATENATED MODULE: ./node_modules/ol/TileState.js\n/**\n * @module ol/TileState\n */\n\n/**\n * @enum {number}\n */\n/* harmony default export */ var TileState = ({\n IDLE: 0,\n LOADING: 1,\n LOADED: 2,\n\n /**\n * Indicates that tile loading failed\n * @type {number}\n */\n ERROR: 3,\n EMPTY: 4\n});\n;// CONCATENATED MODULE: ./node_modules/ol/TileQueue.js\nvar TileQueue_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/TileQueue\n */\n\n\n\n\n\n/**\n * @typedef {function(import("./Tile.js").default, string, import("./coordinate.js").Coordinate, number): number} PriorityFunction\n */\n\nvar TileQueue =\n/** @class */\nfunction (_super) {\n TileQueue_extends(TileQueue, _super);\n /**\n * @param {PriorityFunction} tilePriorityFunction Tile priority function.\n * @param {function(): ?} tileChangeCallback Function called on each tile change event.\n */\n\n\n function TileQueue(tilePriorityFunction, tileChangeCallback) {\n var _this = _super.call(this,\n /**\n * @param {Array} element Element.\n * @return {number} Priority.\n */\n function (element) {\n return tilePriorityFunction.apply(null, element);\n },\n /**\n * @param {Array} element Element.\n * @return {string} Key.\n */\n function (element) {\n return (\n /** @type {import("./Tile.js").default} */\n element[0].getKey()\n );\n }) || this;\n /** @private */\n\n\n _this.boundHandleTileChange_ = _this.handleTileChange.bind(_this);\n /**\n * @private\n * @type {function(): ?}\n */\n\n _this.tileChangeCallback_ = tileChangeCallback;\n /**\n * @private\n * @type {number}\n */\n\n _this.tilesLoading_ = 0;\n /**\n * @private\n * @type {!Object<string,boolean>}\n */\n\n _this.tilesLoadingKeys_ = {};\n return _this;\n }\n /**\n * @param {Array} element Element.\n * @return {boolean} The element was added to the queue.\n */\n\n\n TileQueue.prototype.enqueue = function (element) {\n var added = _super.prototype.enqueue.call(this, element);\n\n if (added) {\n var tile = element[0];\n tile.addEventListener(EventType.CHANGE, this.boundHandleTileChange_);\n }\n\n return added;\n };\n /**\n * @return {number} Number of tiles loading.\n */\n\n\n TileQueue.prototype.getTilesLoading = function () {\n return this.tilesLoading_;\n };\n /**\n * @param {import("./events/Event.js").default} event Event.\n * @protected\n */\n\n\n TileQueue.prototype.handleTileChange = function (event) {\n var tile =\n /** @type {import("./Tile.js").default} */\n event.target;\n var state = tile.getState();\n\n if (tile.hifi && state === TileState.LOADED || state === TileState.ERROR || state === TileState.EMPTY) {\n tile.removeEventListener(EventType.CHANGE, this.boundHandleTileChange_);\n var tileKey = tile.getKey();\n\n if (tileKey in this.tilesLoadingKeys_) {\n delete this.tilesLoadingKeys_[tileKey];\n --this.tilesLoading_;\n }\n\n this.tileChangeCallback_();\n }\n };\n /**\n * @param {number} maxTotalLoading Maximum number tiles to load simultaneously.\n * @param {number} maxNewLoads Maximum number of new tiles to load.\n */\n\n\n TileQueue.prototype.loadMoreTiles = function (maxTotalLoading, maxNewLoads) {\n var newLoads = 0;\n var state, tile, tileKey;\n\n while (this.tilesLoading_ < maxTotalLoading && newLoads < maxNewLoads && this.getCount() > 0) {\n tile =\n /** @type {import("./Tile.js").default} */\n this.dequeue()[0];\n tileKey = tile.getKey();\n state = tile.getState();\n\n if (state === TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) {\n this.tilesLoadingKeys_[tileKey] = true;\n ++this.tilesLoading_;\n ++newLoads;\n tile.load();\n }\n }\n };\n\n return TileQueue;\n}(structs_PriorityQueue);\n\n/* harmony default export */ var ol_TileQueue = (TileQueue);\n/**\n * @param {import(\'./PluggableMap.js\').FrameState} frameState Frame state.\n * @param {import("./Tile.js").default} tile Tile.\n * @param {string} tileSourceKey Tile source key.\n * @param {import("./coordinate.js").Coordinate} tileCenter Tile center.\n * @param {number} tileResolution Tile resolution.\n * @return {number} Tile priority.\n */\n\nfunction getTilePriority(frameState, tile, tileSourceKey, tileCenter, tileResolution) {\n // Filter out tiles at higher zoom levels than the current zoom level, or that\n // are outside the visible extent.\n if (!frameState || !(tileSourceKey in frameState.wantedTiles)) {\n return DROP;\n }\n\n if (!frameState.wantedTiles[tileSourceKey][tile.getKey()]) {\n return DROP;\n } // Prioritize the highest zoom level tiles closest to the focus.\n // Tiles at higher zoom levels are prioritized using Math.log(tileResolution).\n // Within a zoom level, tiles are prioritized by the distance in pixels between\n // the center of the tile and the center of the viewport. The factor of 65536\n // means that the prioritization should behave as desired for tiles up to\n // 65536 * Math.log(2) = 45426 pixels from the focus.\n\n\n var center = frameState.viewState.center;\n var deltaX = tileCenter[0] - center[0];\n var deltaY = tileCenter[1] - center[1];\n return 65536 * Math.log(tileResolution) + Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/GeometryType.js\n/**\n * @module ol/geom/GeometryType\n */\n\n/**\n * The geometry type. One of `\'Point\'`, `\'LineString\'`, `\'LinearRing\'`,\n * `\'Polygon\'`, `\'MultiPoint\'`, `\'MultiLineString\'`, `\'MultiPolygon\'`,\n * `\'GeometryCollection\'`, `\'Circle\'`.\n * @enum {string}\n */\n/* harmony default export */ var geom_GeometryType = ({\n POINT: \'Point\',\n LINE_STRING: \'LineString\',\n LINEAR_RING: \'LinearRing\',\n POLYGON: \'Polygon\',\n MULTI_POINT: \'MultiPoint\',\n MULTI_LINE_STRING: \'MultiLineString\',\n MULTI_POLYGON: \'MultiPolygon\',\n GEOMETRY_COLLECTION: \'GeometryCollection\',\n CIRCLE: \'Circle\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/proj/Units.js\n/**\n * @module ol/proj/Units\n */\n\n/**\n * Projection units: `\'degrees\'`, `\'ft\'`, `\'m\'`, `\'pixels\'`, `\'tile-pixels\'` or\n * `\'us-ft\'`.\n * @enum {string}\n */\nvar Units = {\n /**\n * Degrees\n * @api\n */\n DEGREES: \'degrees\',\n\n /**\n * Feet\n * @api\n */\n FEET: \'ft\',\n\n /**\n * Meters\n * @api\n */\n METERS: \'m\',\n\n /**\n * Pixels\n * @api\n */\n PIXELS: \'pixels\',\n\n /**\n * Tile Pixels\n * @api\n */\n TILE_PIXELS: \'tile-pixels\',\n\n /**\n * US Feet\n * @api\n */\n USFEET: \'us-ft\'\n};\n/**\n * Meters per unit lookup table.\n * @const\n * @type {Object<Units, number>}\n * @api\n */\n\nvar METERS_PER_UNIT = {}; // use the radius of the Normal sphere\n\nMETERS_PER_UNIT[Units.DEGREES] = 2 * Math.PI * 6370997 / 360;\nMETERS_PER_UNIT[Units.FEET] = 0.3048;\nMETERS_PER_UNIT[Units.METERS] = 1;\nMETERS_PER_UNIT[Units.USFEET] = 1200 / 3937;\n/* harmony default export */ var proj_Units = (Units);\n;// CONCATENATED MODULE: ./node_modules/ol/ViewHint.js\n/**\n * @module ol/ViewHint\n */\n\n/**\n * @enum {number}\n */\n/* harmony default export */ var ViewHint = ({\n ANIMATING: 0,\n INTERACTING: 1\n});\n;// CONCATENATED MODULE: ./node_modules/ol/ViewProperty.js\n/**\n * @module ol/ViewProperty\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var ViewProperty = ({\n CENTER: \'center\',\n RESOLUTION: \'resolution\',\n ROTATION: \'rotation\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/tilegrid/common.js\n/**\n * @module ol/tilegrid/common\n */\n\n/**\n * Default maximum zoom for default tile grids.\n * @type {number}\n */\nvar DEFAULT_MAX_ZOOM = 42;\n/**\n * Default tile size.\n * @type {number}\n */\n\nvar DEFAULT_TILE_SIZE = 256;\n;// CONCATENATED MODULE: ./node_modules/ol/proj/Projection.js\n/**\n * @module ol/proj/Projection\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} code The SRS identifier code, e.g. `EPSG:4326`.\n * @property {import("./Units.js").default|string} [units] Units. Required unless a\n * proj4 projection is defined for `code`.\n * @property {import("../extent.js").Extent} [extent] The validity extent for the SRS.\n * @property {string} [axisOrientation=\'enu\'] The axis orientation as specified in Proj4.\n * @property {boolean} [global=false] Whether the projection is valid for the whole globe.\n * @property {number} [metersPerUnit] The meters per unit for the SRS.\n * If not provided, the `units` are used to get the meters per unit from the {@link module:ol/proj/Units~METERS_PER_UNIT}\n * lookup table.\n * @property {import("../extent.js").Extent} [worldExtent] The world extent for the SRS.\n * @property {function(number, import("../coordinate.js").Coordinate):number} [getPointResolution]\n * Function to determine resolution at a point. The function is called with a\n * `{number}` view resolution and an `{import("../coordinate.js").Coordinate}` as arguments, and returns\n * the `{number}` resolution in projection units at the passed coordinate. If this is `undefined`,\n * the default {@link module:ol/proj#getPointResolution} function will be used.\n */\n\n/**\n * @classdesc\n * Projection definition class. One of these is created for each projection\n * supported in the application and stored in the {@link module:ol/proj} namespace.\n * You can use these in applications, but this is not required, as API params\n * and options use {@link module:ol/proj~ProjectionLike} which means the simple string\n * code will suffice.\n *\n * You can use {@link module:ol/proj~get} to retrieve the object for a particular\n * projection.\n *\n * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together\n * with the following aliases:\n * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326,\n * urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84,\n * http://www.opengis.net/gml/srs/epsg.xml#4326,\n * urn:x-ogc:def:crs:EPSG:4326\n * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913,\n * urn:ogc:def:crs:EPSG:6.18:3:3857,\n * http://www.opengis.net/gml/srs/epsg.xml#3857\n *\n * If you use [proj4js](https://github.com/proj4js/proj4js), aliases can\n * be added using `proj4.defs()`. After all required projection definitions are\n * added, call the {@link module:ol/proj/proj4~register} function.\n *\n * @api\n */\n\nvar Projection =\n/** @class */\nfunction () {\n /**\n * @param {Options} options Projection options.\n */\n function Projection(options) {\n /**\n * @private\n * @type {string}\n */\n this.code_ = options.code;\n /**\n * Units of projected coordinates. When set to `TILE_PIXELS`, a\n * `this.extent_` and `this.worldExtent_` must be configured properly for each\n * tile.\n * @private\n * @type {import("./Units.js").default}\n */\n\n this.units_ =\n /** @type {import("./Units.js").default} */\n options.units;\n /**\n * Validity extent of the projection in projected coordinates. For projections\n * with `TILE_PIXELS` units, this is the extent of the tile in\n * tile pixel space.\n * @private\n * @type {import("../extent.js").Extent}\n */\n\n this.extent_ = options.extent !== undefined ? options.extent : null;\n /**\n * Extent of the world in EPSG:4326. For projections with\n * `TILE_PIXELS` units, this is the extent of the tile in\n * projected coordinate space.\n * @private\n * @type {import("../extent.js").Extent}\n */\n\n this.worldExtent_ = options.worldExtent !== undefined ? options.worldExtent : null;\n /**\n * @private\n * @type {string}\n */\n\n this.axisOrientation_ = options.axisOrientation !== undefined ? options.axisOrientation : \'enu\';\n /**\n * @private\n * @type {boolean}\n */\n\n this.global_ = options.global !== undefined ? options.global : false;\n /**\n * @private\n * @type {boolean}\n */\n\n this.canWrapX_ = !!(this.global_ && this.extent_);\n /**\n * @private\n * @type {function(number, import("../coordinate.js").Coordinate):number|undefined}\n */\n\n this.getPointResolutionFunc_ = options.getPointResolution;\n /**\n * @private\n * @type {import("../tilegrid/TileGrid.js").default}\n */\n\n this.defaultTileGrid_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.metersPerUnit_ = options.metersPerUnit;\n }\n /**\n * @return {boolean} The projection is suitable for wrapping the x-axis\n */\n\n\n Projection.prototype.canWrapX = function () {\n return this.canWrapX_;\n };\n /**\n * Get the code for this projection, e.g. \'EPSG:4326\'.\n * @return {string} Code.\n * @api\n */\n\n\n Projection.prototype.getCode = function () {\n return this.code_;\n };\n /**\n * Get the validity extent for this projection.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n Projection.prototype.getExtent = function () {\n return this.extent_;\n };\n /**\n * Get the units of this projection.\n * @return {import("./Units.js").default} Units.\n * @api\n */\n\n\n Projection.prototype.getUnits = function () {\n return this.units_;\n };\n /**\n * Get the amount of meters per unit of this projection. If the projection is\n * not configured with `metersPerUnit` or a units identifier, the return is\n * `undefined`.\n * @return {number|undefined} Meters.\n * @api\n */\n\n\n Projection.prototype.getMetersPerUnit = function () {\n return this.metersPerUnit_ || METERS_PER_UNIT[this.units_];\n };\n /**\n * Get the world extent for this projection.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n Projection.prototype.getWorldExtent = function () {\n return this.worldExtent_;\n };\n /**\n * Get the axis orientation of this projection.\n * Example values are:\n * enu - the default easting, northing, elevation.\n * neu - northing, easting, up - useful for "lat/long" geographic coordinates,\n * or south orientated transverse mercator.\n * wnu - westing, northing, up - some planetary coordinate systems have\n * "west positive" coordinate systems\n * @return {string} Axis orientation.\n * @api\n */\n\n\n Projection.prototype.getAxisOrientation = function () {\n return this.axisOrientation_;\n };\n /**\n * Is this projection a global projection which spans the whole world?\n * @return {boolean} Whether the projection is global.\n * @api\n */\n\n\n Projection.prototype.isGlobal = function () {\n return this.global_;\n };\n /**\n * Set if the projection is a global projection which spans the whole world\n * @param {boolean} global Whether the projection is global.\n * @api\n */\n\n\n Projection.prototype.setGlobal = function (global) {\n this.global_ = global;\n this.canWrapX_ = !!(global && this.extent_);\n };\n /**\n * @return {import("../tilegrid/TileGrid.js").default} The default tile grid.\n */\n\n\n Projection.prototype.getDefaultTileGrid = function () {\n return this.defaultTileGrid_;\n };\n /**\n * @param {import("../tilegrid/TileGrid.js").default} tileGrid The default tile grid.\n */\n\n\n Projection.prototype.setDefaultTileGrid = function (tileGrid) {\n this.defaultTileGrid_ = tileGrid;\n };\n /**\n * Set the validity extent for this projection.\n * @param {import("../extent.js").Extent} extent Extent.\n * @api\n */\n\n\n Projection.prototype.setExtent = function (extent) {\n this.extent_ = extent;\n this.canWrapX_ = !!(this.global_ && extent);\n };\n /**\n * Set the world extent for this projection.\n * @param {import("../extent.js").Extent} worldExtent World extent\n * [minlon, minlat, maxlon, maxlat].\n * @api\n */\n\n\n Projection.prototype.setWorldExtent = function (worldExtent) {\n this.worldExtent_ = worldExtent;\n };\n /**\n * Set the getPointResolution function (see {@link module:ol/proj~getPointResolution}\n * for this projection.\n * @param {function(number, import("../coordinate.js").Coordinate):number} func Function\n * @api\n */\n\n\n Projection.prototype.setGetPointResolution = function (func) {\n this.getPointResolutionFunc_ = func;\n };\n /**\n * Get the custom point resolution function for this projection (if set).\n * @return {function(number, import("../coordinate.js").Coordinate):number|undefined} The custom point\n * resolution function (if set).\n */\n\n\n Projection.prototype.getPointResolutionFunc = function () {\n return this.getPointResolutionFunc_;\n };\n\n return Projection;\n}();\n\n/* harmony default export */ var proj_Projection = (Projection);\n;// CONCATENATED MODULE: ./node_modules/ol/proj/epsg3857.js\nvar epsg3857_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/proj/epsg3857\n */\n\n\n\n\n\n/**\n * Radius of WGS84 sphere\n *\n * @const\n * @type {number}\n */\n\nvar RADIUS = 6378137;\n/**\n * @const\n * @type {number}\n */\n\nvar HALF_SIZE = Math.PI * RADIUS;\n/**\n * @const\n * @type {import("../extent.js").Extent}\n */\n\nvar EXTENT = [-HALF_SIZE, -HALF_SIZE, HALF_SIZE, HALF_SIZE];\n/**\n * @const\n * @type {import("../extent.js").Extent}\n */\n\nvar WORLD_EXTENT = [-180, -85, 180, 85];\n/**\n * Maximum safe value in y direction\n * @const\n * @type {number}\n */\n\nvar MAX_SAFE_Y = RADIUS * Math.log(Math.tan(Math.PI / 2));\n/**\n * @classdesc\n * Projection object for web/spherical Mercator (EPSG:3857).\n */\n\nvar EPSG3857Projection =\n/** @class */\nfunction (_super) {\n epsg3857_extends(EPSG3857Projection, _super);\n /**\n * @param {string} code Code.\n */\n\n\n function EPSG3857Projection(code) {\n return _super.call(this, {\n code: code,\n units: proj_Units.METERS,\n extent: EXTENT,\n global: true,\n worldExtent: WORLD_EXTENT,\n getPointResolution: function getPointResolution(resolution, point) {\n return resolution / cosh(point[1] / RADIUS);\n }\n }) || this;\n }\n\n return EPSG3857Projection;\n}(proj_Projection);\n/**\n * Projections equal to EPSG:3857.\n *\n * @const\n * @type {Array<import("./Projection.js").default>}\n */\n\n\nvar PROJECTIONS = [new EPSG3857Projection(\'EPSG:3857\'), new EPSG3857Projection(\'EPSG:102100\'), new EPSG3857Projection(\'EPSG:102113\'), new EPSG3857Projection(\'EPSG:900913\'), new EPSG3857Projection(\'http://www.opengis.net/gml/srs/epsg.xml#3857\')];\n/**\n * Transformation from EPSG:4326 to EPSG:3857.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\n\nfunction fromEPSG4326(input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var output = opt_output;\n\n if (output === undefined) {\n if (dimension > 2) {\n // preserve values beyond second dimension\n output = input.slice();\n } else {\n output = new Array(length);\n }\n }\n\n for (var i = 0; i < length; i += dimension) {\n output[i] = HALF_SIZE * input[i] / 180;\n var y = RADIUS * Math.log(Math.tan(Math.PI * (+input[i + 1] + 90) / 360));\n\n if (y > MAX_SAFE_Y) {\n y = MAX_SAFE_Y;\n } else if (y < -MAX_SAFE_Y) {\n y = -MAX_SAFE_Y;\n }\n\n output[i + 1] = y;\n }\n\n return output;\n}\n/**\n * Transformation from EPSG:3857 to EPSG:4326.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\n\nfunction toEPSG4326(input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var output = opt_output;\n\n if (output === undefined) {\n if (dimension > 2) {\n // preserve values beyond second dimension\n output = input.slice();\n } else {\n output = new Array(length);\n }\n }\n\n for (var i = 0; i < length; i += dimension) {\n output[i] = 180 * input[i] / HALF_SIZE;\n output[i + 1] = 360 * Math.atan(Math.exp(input[i + 1] / RADIUS)) / Math.PI - 90;\n }\n\n return output;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/proj/epsg4326.js\nvar epsg4326_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/proj/epsg4326\n */\n\n\n\n\n/**\n * Semi-major radius of the WGS84 ellipsoid.\n *\n * @const\n * @type {number}\n */\n\nvar epsg4326_RADIUS = 6378137;\n/**\n * Extent of the EPSG:4326 projection which is the whole world.\n *\n * @const\n * @type {import("../extent.js").Extent}\n */\n\nvar epsg4326_EXTENT = [-180, -90, 180, 90];\n/**\n * @const\n * @type {number}\n */\n\nvar epsg4326_METERS_PER_UNIT = Math.PI * epsg4326_RADIUS / 180;\n/**\n * @classdesc\n * Projection object for WGS84 geographic coordinates (EPSG:4326).\n *\n * Note that OpenLayers does not strictly comply with the EPSG definition.\n * The EPSG registry defines 4326 as a CRS for Latitude,Longitude (y,x).\n * OpenLayers treats EPSG:4326 as a pseudo-projection, with x,y coordinates.\n */\n\nvar EPSG4326Projection =\n/** @class */\nfunction (_super) {\n epsg4326_extends(EPSG4326Projection, _super);\n /**\n * @param {string} code Code.\n * @param {string=} opt_axisOrientation Axis orientation.\n */\n\n\n function EPSG4326Projection(code, opt_axisOrientation) {\n return _super.call(this, {\n code: code,\n units: proj_Units.DEGREES,\n extent: epsg4326_EXTENT,\n axisOrientation: opt_axisOrientation,\n global: true,\n metersPerUnit: epsg4326_METERS_PER_UNIT,\n worldExtent: epsg4326_EXTENT\n }) || this;\n }\n\n return EPSG4326Projection;\n}(proj_Projection);\n/**\n * Projections equal to EPSG:4326.\n *\n * @const\n * @type {Array<import("./Projection.js").default>}\n */\n\n\nvar epsg4326_PROJECTIONS = [new EPSG4326Projection(\'CRS:84\'), new EPSG4326Projection(\'EPSG:4326\', \'neu\'), new EPSG4326Projection(\'urn:ogc:def:crs:OGC:1.3:CRS84\'), new EPSG4326Projection(\'urn:ogc:def:crs:OGC:2:84\'), new EPSG4326Projection(\'http://www.opengis.net/gml/srs/epsg.xml#4326\', \'neu\')];\n;// CONCATENATED MODULE: ./node_modules/ol/proj/projections.js\n/**\n * @module ol/proj/projections\n */\n\n/**\n * @type {Object<string, import("./Projection.js").default>}\n */\nvar cache = {};\n/**\n * Clear the projections cache.\n */\n\nfunction projections_clear() {\n cache = {};\n}\n/**\n * Get a cached projection by code.\n * @param {string} code The code for the projection.\n * @return {import("./Projection.js").default} The projection (if cached).\n */\n\nfunction get(code) {\n return cache[code] || cache[code.replace(/urn:(x-)?ogc:def:crs:EPSG:(.*:)?(\\w+)$/, \'EPSG:$3\')] || null;\n}\n/**\n * Add a projection to the cache.\n * @param {string} code The projection code.\n * @param {import("./Projection.js").default} projection The projection to cache.\n */\n\nfunction projections_add(code, projection) {\n cache[code] = projection;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/proj/transforms.js\n/**\n * @module ol/proj/transforms\n */\n\n/**\n * @private\n * @type {!Object<string, Object<string, import("../proj.js").TransformFunction>>}\n */\n\nvar transforms = {};\n/**\n * Clear the transform cache.\n */\n\nfunction transforms_clear() {\n transforms = {};\n}\n/**\n * Registers a conversion function to convert coordinates from the source\n * projection to the destination projection.\n *\n * @param {import("./Projection.js").default} source Source.\n * @param {import("./Projection.js").default} destination Destination.\n * @param {import("../proj.js").TransformFunction} transformFn Transform.\n */\n\nfunction transforms_add(source, destination, transformFn) {\n var sourceCode = source.getCode();\n var destinationCode = destination.getCode();\n\n if (!(sourceCode in transforms)) {\n transforms[sourceCode] = {};\n }\n\n transforms[sourceCode][destinationCode] = transformFn;\n}\n/**\n * Unregisters the conversion function to convert coordinates from the source\n * projection to the destination projection. This method is used to clean up\n * cached transforms during testing.\n *\n * @param {import("./Projection.js").default} source Source projection.\n * @param {import("./Projection.js").default} destination Destination projection.\n * @return {import("../proj.js").TransformFunction} transformFn The unregistered transform.\n */\n\nfunction transforms_remove(source, destination) {\n var sourceCode = source.getCode();\n var destinationCode = destination.getCode();\n var transform = transforms[sourceCode][destinationCode];\n delete transforms[sourceCode][destinationCode];\n\n if (isEmpty(transforms[sourceCode])) {\n delete transforms[sourceCode];\n }\n\n return transform;\n}\n/**\n * Get a transform given a source code and a destination code.\n * @param {string} sourceCode The code for the source projection.\n * @param {string} destinationCode The code for the destination projection.\n * @return {import("../proj.js").TransformFunction|undefined} The transform function (if found).\n */\n\nfunction transforms_get(sourceCode, destinationCode) {\n var transform;\n\n if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {\n transform = transforms[sourceCode][destinationCode];\n }\n\n return transform;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/sphere.js\n/**\n * @module ol/sphere\n */\n\n\n/**\n * Object literal with options for the {@link getLength} or {@link getArea}\n * functions.\n * @typedef {Object} SphereMetricOptions\n * @property {import("./proj.js").ProjectionLike} [projection=\'EPSG:3857\']\n * Projection of the geometry. By default, the geometry is assumed to be in\n * Web Mercator.\n * @property {number} [radius=6371008.8] Sphere radius. By default, the\n * [mean Earth radius](https://en.wikipedia.org/wiki/Earth_radius#Mean_radius)\n * for the WGS84 ellipsoid is used.\n */\n\n/**\n * The mean Earth radius (1/3 * (2a + b)) for the WGS84 ellipsoid.\n * https://en.wikipedia.org/wiki/Earth_radius#Mean_radius\n * @type {number}\n */\n\nvar DEFAULT_RADIUS = 6371008.8;\n/**\n * Get the great circle distance (in meters) between two geographic coordinates.\n * @param {Array} c1 Starting coordinate.\n * @param {Array} c2 Ending coordinate.\n * @param {number=} opt_radius The sphere radius to use. Defaults to the Earth\'s\n * mean radius using the WGS84 ellipsoid.\n * @return {number} The great circle distance between the points (in meters).\n * @api\n */\n\nfunction getDistance(c1, c2, opt_radius) {\n var radius = opt_radius || DEFAULT_RADIUS;\n var lat1 = math_toRadians(c1[1]);\n var lat2 = math_toRadians(c2[1]);\n var deltaLatBy2 = (lat2 - lat1) / 2;\n var deltaLonBy2 = math_toRadians(c2[0] - c1[0]) / 2;\n var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) + Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) * Math.cos(lat1) * Math.cos(lat2);\n return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n}\n/**\n * Get the cumulative great circle length of linestring coordinates (geographic).\n * @param {Array} coordinates Linestring coordinates.\n * @param {number} radius The sphere radius to use.\n * @return {number} The length (in meters).\n */\n\nfunction getLengthInternal(coordinates, radius) {\n var length = 0;\n\n for (var i = 0, ii = coordinates.length; i < ii - 1; ++i) {\n length += getDistance(coordinates[i], coordinates[i + 1], radius);\n }\n\n return length;\n}\n/**\n * Get the spherical length of a geometry. This length is the sum of the\n * great circle distances between coordinates. For polygons, the length is\n * the sum of all rings. For points, the length is zero. For multi-part\n * geometries, the length is the sum of the length of each part.\n * @param {import("./geom/Geometry.js").default} geometry A geometry.\n * @param {SphereMetricOptions=} opt_options Options for the\n * length calculation. By default, geometries are assumed to be in \'EPSG:3857\'.\n * You can change this by providing a `projection` option.\n * @return {number} The spherical length (in meters).\n * @api\n */\n\n\nfunction getLength(geometry, opt_options) {\n var options = opt_options || {};\n var radius = options.radius || DEFAULT_RADIUS;\n var projection = options.projection || \'EPSG:3857\';\n var type = geometry.getType();\n\n if (type !== GeometryType.GEOMETRY_COLLECTION) {\n geometry = geometry.clone().transform(projection, \'EPSG:4326\');\n }\n\n var length = 0;\n var coordinates, coords, i, ii, j, jj;\n\n switch (type) {\n case GeometryType.POINT:\n case GeometryType.MULTI_POINT:\n {\n break;\n }\n\n case GeometryType.LINE_STRING:\n case GeometryType.LINEAR_RING:\n {\n coordinates =\n /** @type {import("./geom/SimpleGeometry.js").default} */\n geometry.getCoordinates();\n length = getLengthInternal(coordinates, radius);\n break;\n }\n\n case GeometryType.MULTI_LINE_STRING:\n case GeometryType.POLYGON:\n {\n coordinates =\n /** @type {import("./geom/SimpleGeometry.js").default} */\n geometry.getCoordinates();\n\n for (i = 0, ii = coordinates.length; i < ii; ++i) {\n length += getLengthInternal(coordinates[i], radius);\n }\n\n break;\n }\n\n case GeometryType.MULTI_POLYGON:\n {\n coordinates =\n /** @type {import("./geom/SimpleGeometry.js").default} */\n geometry.getCoordinates();\n\n for (i = 0, ii = coordinates.length; i < ii; ++i) {\n coords = coordinates[i];\n\n for (j = 0, jj = coords.length; j < jj; ++j) {\n length += getLengthInternal(coords[j], radius);\n }\n }\n\n break;\n }\n\n case GeometryType.GEOMETRY_COLLECTION:\n {\n var geometries =\n /** @type {import("./geom/GeometryCollection.js").default} */\n geometry.getGeometries();\n\n for (i = 0, ii = geometries.length; i < ii; ++i) {\n length += getLength(geometries[i], opt_options);\n }\n\n break;\n }\n\n default:\n {\n throw new Error(\'Unsupported geometry type: \' + type);\n }\n }\n\n return length;\n}\n/**\n * Returns the spherical area for a list of coordinates.\n *\n * [Reference](https://trs-new.jpl.nasa.gov/handle/2014/40409)\n * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for\n * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion\n * Laboratory, Pasadena, CA, June 2007\n *\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates List of coordinates of a linear\n * ring. If the ring is oriented clockwise, the area will be positive,\n * otherwise it will be negative.\n * @param {number} radius The sphere radius.\n * @return {number} Area (in square meters).\n */\n\nfunction getAreaInternal(coordinates, radius) {\n var area = 0;\n var len = coordinates.length;\n var x1 = coordinates[len - 1][0];\n var y1 = coordinates[len - 1][1];\n\n for (var i = 0; i < len; i++) {\n var x2 = coordinates[i][0];\n var y2 = coordinates[i][1];\n area += toRadians(x2 - x1) * (2 + Math.sin(toRadians(y1)) + Math.sin(toRadians(y2)));\n x1 = x2;\n y1 = y2;\n }\n\n return area * radius * radius / 2.0;\n}\n/**\n * Get the spherical area of a geometry. This is the area (in meters) assuming\n * that polygon edges are segments of great circles on a sphere.\n * @param {import("./geom/Geometry.js").default} geometry A geometry.\n * @param {SphereMetricOptions=} opt_options Options for the area\n * calculation. By default, geometries are assumed to be in \'EPSG:3857\'.\n * You can change this by providing a `projection` option.\n * @return {number} The spherical area (in square meters).\n * @api\n */\n\n\nfunction sphere_getArea(geometry, opt_options) {\n var options = opt_options || {};\n var radius = options.radius || DEFAULT_RADIUS;\n var projection = options.projection || \'EPSG:3857\';\n var type = geometry.getType();\n\n if (type !== GeometryType.GEOMETRY_COLLECTION) {\n geometry = geometry.clone().transform(projection, \'EPSG:4326\');\n }\n\n var area = 0;\n var coordinates, coords, i, ii, j, jj;\n\n switch (type) {\n case GeometryType.POINT:\n case GeometryType.MULTI_POINT:\n case GeometryType.LINE_STRING:\n case GeometryType.MULTI_LINE_STRING:\n case GeometryType.LINEAR_RING:\n {\n break;\n }\n\n case GeometryType.POLYGON:\n {\n coordinates =\n /** @type {import("./geom/Polygon.js").default} */\n geometry.getCoordinates();\n area = Math.abs(getAreaInternal(coordinates[0], radius));\n\n for (i = 1, ii = coordinates.length; i < ii; ++i) {\n area -= Math.abs(getAreaInternal(coordinates[i], radius));\n }\n\n break;\n }\n\n case GeometryType.MULTI_POLYGON:\n {\n coordinates =\n /** @type {import("./geom/SimpleGeometry.js").default} */\n geometry.getCoordinates();\n\n for (i = 0, ii = coordinates.length; i < ii; ++i) {\n coords = coordinates[i];\n area += Math.abs(getAreaInternal(coords[0], radius));\n\n for (j = 1, jj = coords.length; j < jj; ++j) {\n area -= Math.abs(getAreaInternal(coords[j], radius));\n }\n }\n\n break;\n }\n\n case GeometryType.GEOMETRY_COLLECTION:\n {\n var geometries =\n /** @type {import("./geom/GeometryCollection.js").default} */\n geometry.getGeometries();\n\n for (i = 0, ii = geometries.length; i < ii; ++i) {\n area += sphere_getArea(geometries[i], opt_options);\n }\n\n break;\n }\n\n default:\n {\n throw new Error(\'Unsupported geometry type: \' + type);\n }\n }\n\n return area;\n}\n/**\n * Returns the coordinate at the given distance and bearing from `c1`.\n *\n * @param {import("./coordinate.js").Coordinate} c1 The origin point (`[lon, lat]` in degrees).\n * @param {number} distance The great-circle distance between the origin\n * point and the target point.\n * @param {number} bearing The bearing (in radians).\n * @param {number=} opt_radius The sphere radius to use. Defaults to the Earth\'s\n * mean radius using the WGS84 ellipsoid.\n * @return {import("./coordinate.js").Coordinate} The target point.\n */\n\nfunction offset(c1, distance, bearing, opt_radius) {\n var radius = opt_radius || DEFAULT_RADIUS;\n var lat1 = toRadians(c1[1]);\n var lon1 = toRadians(c1[0]);\n var dByR = distance / radius;\n var lat = Math.asin(Math.sin(lat1) * Math.cos(dByR) + Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing));\n var lon = lon1 + Math.atan2(Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1), Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat));\n return [toDegrees(lon), toDegrees(lat)];\n}\n;// CONCATENATED MODULE: ./node_modules/ol/proj.js\n/**\n * @module ol/proj\n */\n\n/**\n * The ol/proj module stores:\n * * a list of {@link module:ol/proj/Projection}\n * objects, one for each projection supported by the application\n * * a list of transform functions needed to convert coordinates in one projection\n * into another.\n *\n * The static functions are the methods used to maintain these.\n * Each transform function can handle not only simple coordinate pairs, but also\n * large arrays of coordinates such as vector geometries.\n *\n * When loaded, the library adds projection objects for EPSG:4326 (WGS84\n * geographic coordinates) and EPSG:3857 (Web or Spherical Mercator, as used\n * for example by Bing Maps or OpenStreetMap), together with the relevant\n * transform functions.\n *\n * Additional transforms may be added by using the http://proj4js.org/\n * library (version 2.2 or later). You can use the full build supplied by\n * Proj4js, or create a custom build to support those projections you need; see\n * the Proj4js website for how to do this. You also need the Proj4js definitions\n * for the required projections. These definitions can be obtained from\n * https://epsg.io/, and are a JS function, so can be loaded in a script\n * tag (as in the examples) or pasted into your application.\n *\n * After all required projection definitions are added to proj4\'s registry (by\n * using `proj4.defs()`), simply call `register(proj4)` from the `ol/proj/proj4`\n * package. Existing transforms are not changed by this function. See\n * examples/wms-image-custom-proj for an example of this.\n *\n * Additional projection definitions can be registered with `proj4.defs()` any\n * time. Just make sure to call `register(proj4)` again; for example, with user-supplied data where you don\'t\n * know in advance what projections are needed, you can initially load minimal\n * support and then load whichever are requested.\n *\n * Note that Proj4js does not support projection extents. If you want to add\n * one for creating default tile grids, you can add it after the Projection\n * object has been created with `setExtent`, for example,\n * `get(\'EPSG:1234\').setExtent(extent)`.\n *\n * In addition to Proj4js support, any transform functions can be added with\n * {@link module:ol/proj~addCoordinateTransforms}. To use this, you must first create\n * a {@link module:ol/proj/Projection} object for the new projection and add it with\n * {@link module:ol/proj~addProjection}. You can then add the forward and inverse\n * functions with {@link module:ol/proj~addCoordinateTransforms}. See\n * examples/wms-custom-proj for an example of this.\n *\n * Note that if no transforms are needed and you only need to define the\n * projection, just add a {@link module:ol/proj/Projection} with\n * {@link module:ol/proj~addProjection}. See examples/wms-no-proj for an example of\n * this.\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * A projection as {@link module:ol/proj/Projection}, SRS identifier\n * string or undefined.\n * @typedef {Projection|string|undefined} ProjectionLike\n * @api\n */\n\n/**\n * A transform function accepts an array of input coordinate values, an optional\n * output array, and an optional dimension (default should be 2). The function\n * transforms the input coordinate values, populates the output array, and\n * returns the output array.\n *\n * @typedef {function(Array<number>, Array<number>=, number=): Array<number>} TransformFunction\n * @api\n */\n\n\n\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension.\n * @return {Array<number>} Output coordinate array (new array, same coordinate\n * values).\n */\n\nfunction cloneTransform(input, opt_output, opt_dimension) {\n var output;\n\n if (opt_output !== undefined) {\n for (var i = 0, ii = input.length; i < ii; ++i) {\n opt_output[i] = input[i];\n }\n\n output = opt_output;\n } else {\n output = input.slice();\n }\n\n return output;\n}\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension.\n * @return {Array<number>} Input coordinate array (same array as input).\n */\n\nfunction identityTransform(input, opt_output, opt_dimension) {\n if (opt_output !== undefined && input !== opt_output) {\n for (var i = 0, ii = input.length; i < ii; ++i) {\n opt_output[i] = input[i];\n }\n\n input = opt_output;\n }\n\n return input;\n}\n/**\n * Add a Projection object to the list of supported projections that can be\n * looked up by their code.\n *\n * @param {Projection} projection Projection instance.\n * @api\n */\n\nfunction addProjection(projection) {\n projections_add(projection.getCode(), projection);\n transforms_add(projection, projection, cloneTransform);\n}\n/**\n * @param {Array<Projection>} projections Projections.\n */\n\nfunction addProjections(projections) {\n projections.forEach(addProjection);\n}\n/**\n * Fetches a Projection object for the code specified.\n *\n * @param {ProjectionLike} projectionLike Either a code string which is\n * a combination of authority and identifier such as "EPSG:4326", or an\n * existing projection object, or undefined.\n * @return {Projection} Projection object, or null if not in list.\n * @api\n */\n\nfunction proj_get(projectionLike) {\n return typeof projectionLike === \'string\' ? get(\n /** @type {string} */\n projectionLike) :\n /** @type {Projection} */\n projectionLike || null;\n}\n/**\n * Get the resolution of the point in degrees or distance units.\n * For projections with degrees as the unit this will simply return the\n * provided resolution. For other projections the point resolution is\n * by default estimated by transforming the \'point\' pixel to EPSG:4326,\n * measuring its width and height on the normal sphere,\n * and taking the average of the width and height.\n * A custom function can be provided for a specific projection, either\n * by setting the `getPointResolution` option in the\n * {@link module:ol/proj/Projection~Projection} constructor or by using\n * {@link module:ol/proj/Projection~Projection#setGetPointResolution} to change an existing\n * projection object.\n * @param {ProjectionLike} projection The projection.\n * @param {number} resolution Nominal resolution in projection units.\n * @param {import("./coordinate.js").Coordinate} point Point to find adjusted resolution at.\n * @param {import("./proj/Units.js").default=} opt_units Units to get the point resolution in.\n * Default is the projection\'s units.\n * @return {number} Point resolution.\n * @api\n */\n\nfunction getPointResolution(projection, resolution, point, opt_units) {\n projection = proj_get(projection);\n var pointResolution;\n var getter = projection.getPointResolutionFunc();\n\n if (getter) {\n pointResolution = getter(resolution, point);\n\n if (opt_units && opt_units !== projection.getUnits()) {\n var metersPerUnit = projection.getMetersPerUnit();\n\n if (metersPerUnit) {\n pointResolution = pointResolution * metersPerUnit / METERS_PER_UNIT[opt_units];\n }\n }\n } else {\n var units = projection.getUnits();\n\n if (units == proj_Units.DEGREES && !opt_units || opt_units == proj_Units.DEGREES) {\n pointResolution = resolution;\n } else {\n // Estimate point resolution by transforming the center pixel to EPSG:4326,\n // measuring its width and height on the normal sphere, and taking the\n // average of the width and height.\n var toEPSG4326_1 = getTransformFromProjections(projection, proj_get(\'EPSG:4326\'));\n\n if (toEPSG4326_1 === identityTransform && units !== proj_Units.DEGREES) {\n // no transform is available\n pointResolution = resolution * projection.getMetersPerUnit();\n } else {\n var vertices = [point[0] - resolution / 2, point[1], point[0] + resolution / 2, point[1], point[0], point[1] - resolution / 2, point[0], point[1] + resolution / 2];\n vertices = toEPSG4326_1(vertices, vertices, 2);\n var width = getDistance(vertices.slice(0, 2), vertices.slice(2, 4));\n var height = getDistance(vertices.slice(4, 6), vertices.slice(6, 8));\n pointResolution = (width + height) / 2;\n }\n\n var metersPerUnit = opt_units ? METERS_PER_UNIT[opt_units] : projection.getMetersPerUnit();\n\n if (metersPerUnit !== undefined) {\n pointResolution /= metersPerUnit;\n }\n }\n }\n\n return pointResolution;\n}\n/**\n * Registers transformation functions that don\'t alter coordinates. Those allow\n * to transform between projections with equal meaning.\n *\n * @param {Array<Projection>} projections Projections.\n * @api\n */\n\nfunction addEquivalentProjections(projections) {\n addProjections(projections);\n projections.forEach(function (source) {\n projections.forEach(function (destination) {\n if (source !== destination) {\n transforms_add(source, destination, cloneTransform);\n }\n });\n });\n}\n/**\n * Registers transformation functions to convert coordinates in any projection\n * in projection1 to any projection in projection2.\n *\n * @param {Array<Projection>} projections1 Projections with equal\n * meaning.\n * @param {Array<Projection>} projections2 Projections with equal\n * meaning.\n * @param {TransformFunction} forwardTransform Transformation from any\n * projection in projection1 to any projection in projection2.\n * @param {TransformFunction} inverseTransform Transform from any projection\n * in projection2 to any projection in projection1..\n */\n\nfunction addEquivalentTransforms(projections1, projections2, forwardTransform, inverseTransform) {\n projections1.forEach(function (projection1) {\n projections2.forEach(function (projection2) {\n transforms_add(projection1, projection2, forwardTransform);\n transforms_add(projection2, projection1, inverseTransform);\n });\n });\n}\n/**\n * Clear all cached projections and transforms.\n */\n\nfunction clearAllProjections() {\n clearProj();\n clearTransformFuncs();\n}\n/**\n * @param {Projection|string|undefined} projection Projection.\n * @param {string} defaultCode Default code.\n * @return {Projection} Projection.\n */\n\nfunction createProjection(projection, defaultCode) {\n if (!projection) {\n return proj_get(defaultCode);\n } else if (typeof projection === \'string\') {\n return proj_get(projection);\n } else {\n return (\n /** @type {Projection} */\n projection\n );\n }\n}\n/**\n * Creates a {@link module:ol/proj~TransformFunction} from a simple 2D coordinate transform\n * function.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} coordTransform Coordinate\n * transform.\n * @return {TransformFunction} Transform function.\n */\n\nfunction createTransformFromCoordinateTransform(coordTransform) {\n return (\n /**\n * @param {Array<number>} input Input.\n * @param {Array<number>=} opt_output Output.\n * @param {number=} opt_dimension Dimension.\n * @return {Array<number>} Output.\n */\n function (input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension !== undefined ? opt_dimension : 2;\n var output = opt_output !== undefined ? opt_output : new Array(length);\n\n for (var i = 0; i < length; i += dimension) {\n var point = coordTransform([input[i], input[i + 1]]);\n output[i] = point[0];\n output[i + 1] = point[1];\n\n for (var j = dimension - 1; j >= 2; --j) {\n output[i + j] = input[i + j];\n }\n }\n\n return output;\n }\n );\n}\n/**\n * Registers coordinate transform functions to convert coordinates between the\n * source projection and the destination projection.\n * The forward and inverse functions convert coordinate pairs; this function\n * converts these into the functions used internally which also handle\n * extents and coordinate arrays.\n *\n * @param {ProjectionLike} source Source projection.\n * @param {ProjectionLike} destination Destination projection.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} forward The forward transform\n * function (that is, from the source projection to the destination\n * projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n * the transformed {@link module:ol/coordinate~Coordinate}.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} inverse The inverse transform\n * function (that is, from the destination projection to the source\n * projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n * the transformed {@link module:ol/coordinate~Coordinate}.\n * @api\n */\n\nfunction addCoordinateTransforms(source, destination, forward, inverse) {\n var sourceProj = proj_get(source);\n var destProj = proj_get(destination);\n addTransformFunc(sourceProj, destProj, createTransformFromCoordinateTransform(forward));\n addTransformFunc(destProj, sourceProj, createTransformFromCoordinateTransform(inverse));\n}\n/**\n * Transforms a coordinate from longitude/latitude to a different projection.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate as longitude and latitude, i.e.\n * an array with longitude as 1st and latitude as 2nd element.\n * @param {ProjectionLike=} opt_projection Target projection. The\n * default is Web Mercator, i.e. \'EPSG:3857\'.\n * @return {import("./coordinate.js").Coordinate} Coordinate projected to the target projection.\n * @api\n */\n\nfunction fromLonLat(coordinate, opt_projection) {\n return transform(coordinate, \'EPSG:4326\', opt_projection !== undefined ? opt_projection : \'EPSG:3857\');\n}\n/**\n * Transforms a coordinate to longitude/latitude.\n * @param {import("./coordinate.js").Coordinate} coordinate Projected coordinate.\n * @param {ProjectionLike=} opt_projection Projection of the coordinate.\n * The default is Web Mercator, i.e. \'EPSG:3857\'.\n * @return {import("./coordinate.js").Coordinate} Coordinate as longitude and latitude, i.e. an array\n * with longitude as 1st and latitude as 2nd element.\n * @api\n */\n\nfunction toLonLat(coordinate, opt_projection) {\n var lonLat = transform(coordinate, opt_projection !== undefined ? opt_projection : \'EPSG:3857\', \'EPSG:4326\');\n var lon = lonLat[0];\n\n if (lon < -180 || lon > 180) {\n lonLat[0] = modulo(lon + 180, 360) - 180;\n }\n\n return lonLat;\n}\n/**\n * Checks if two projections are the same, that is every coordinate in one\n * projection does represent the same geographic point as the same coordinate in\n * the other projection.\n *\n * @param {Projection} projection1 Projection 1.\n * @param {Projection} projection2 Projection 2.\n * @return {boolean} Equivalent.\n * @api\n */\n\nfunction equivalent(projection1, projection2) {\n if (projection1 === projection2) {\n return true;\n }\n\n var equalUnits = projection1.getUnits() === projection2.getUnits();\n\n if (projection1.getCode() === projection2.getCode()) {\n return equalUnits;\n } else {\n var transformFunc = getTransformFromProjections(projection1, projection2);\n return transformFunc === cloneTransform && equalUnits;\n }\n}\n/**\n * Searches in the list of transform functions for the function for converting\n * coordinates from the source projection to the destination projection.\n *\n * @param {Projection} sourceProjection Source Projection object.\n * @param {Projection} destinationProjection Destination Projection\n * object.\n * @return {TransformFunction} Transform function.\n */\n\nfunction getTransformFromProjections(sourceProjection, destinationProjection) {\n var sourceCode = sourceProjection.getCode();\n var destinationCode = destinationProjection.getCode();\n var transformFunc = transforms_get(sourceCode, destinationCode);\n\n if (!transformFunc) {\n transformFunc = identityTransform;\n }\n\n return transformFunc;\n}\n/**\n * Given the projection-like objects, searches for a transformation\n * function to convert a coordinates array from the source projection to the\n * destination projection.\n *\n * @param {ProjectionLike} source Source.\n * @param {ProjectionLike} destination Destination.\n * @return {TransformFunction} Transform function.\n * @api\n */\n\nfunction getTransform(source, destination) {\n var sourceProjection = proj_get(source);\n var destinationProjection = proj_get(destination);\n return getTransformFromProjections(sourceProjection, destinationProjection);\n}\n/**\n * Transforms a coordinate from source projection to destination projection.\n * This returns a new coordinate (and does not modify the original).\n *\n * See {@link module:ol/proj~transformExtent} for extent transformation.\n * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its\n * subclasses for geometry transforms.\n *\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @return {import("./coordinate.js").Coordinate} Coordinate.\n * @api\n */\n\nfunction transform(coordinate, source, destination) {\n var transformFunc = getTransform(source, destination);\n return transformFunc(coordinate, undefined, coordinate.length);\n}\n/**\n * Transforms an extent from source projection to destination projection. This\n * returns a new extent (and does not modify the original).\n *\n * @param {import("./extent.js").Extent} extent The extent to transform.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @param {number=} opt_stops Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {import("./extent.js").Extent} The transformed extent.\n * @api\n */\n\nfunction proj_transformExtent(extent, source, destination, opt_stops) {\n var transformFunc = getTransform(source, destination);\n return applyTransform(extent, transformFunc, undefined, opt_stops);\n}\n/**\n * Transforms the given point to the destination projection.\n *\n * @param {import("./coordinate.js").Coordinate} point Point.\n * @param {Projection} sourceProjection Source projection.\n * @param {Projection} destinationProjection Destination projection.\n * @return {import("./coordinate.js").Coordinate} Point.\n */\n\nfunction transformWithProjections(point, sourceProjection, destinationProjection) {\n var transformFunc = getTransformFromProjections(sourceProjection, destinationProjection);\n return transformFunc(point);\n}\n/**\n * @type {?Projection}\n */\n\nvar userProjection = null;\n/**\n * Set the projection for coordinates supplied from and returned by API methods.\n * Note that this method is not yet a part of the stable API. Support for user\n * projections is not yet complete and should be considered experimental.\n * @param {ProjectionLike} projection The user projection.\n */\n\nfunction setUserProjection(projection) {\n userProjection = proj_get(projection);\n}\n/**\n * Clear the user projection if set. Note that this method is not yet a part of\n * the stable API. Support for user projections is not yet complete and should\n * be considered experimental.\n */\n\nfunction clearUserProjection() {\n userProjection = null;\n}\n/**\n * Get the projection for coordinates supplied from and returned by API methods.\n * Note that this method is not yet a part of the stable API. Support for user\n * projections is not yet complete and should be considered experimental.\n * @returns {?Projection} The user projection (or null if not set).\n */\n\nfunction getUserProjection() {\n return userProjection;\n}\n/**\n * Use geographic coordinates (WGS-84 datum) in API methods. Note that this\n * method is not yet a part of the stable API. Support for user projections is\n * not yet complete and should be considered experimental.\n */\n\nfunction useGeographic() {\n setUserProjection(\'EPSG:4326\');\n}\n/**\n * Return a coordinate transformed into the user projection. If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} sourceProjection The input coordinate projection.\n * @returns {Array<number>} The input coordinate in the user projection.\n */\n\nfunction toUserCoordinate(coordinate, sourceProjection) {\n if (!userProjection) {\n return coordinate;\n }\n\n return transform(coordinate, sourceProjection, userProjection);\n}\n/**\n * Return a coordinate transformed from the user projection. If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} destProjection The destination projection.\n * @returns {Array<number>} The input coordinate transformed.\n */\n\nfunction fromUserCoordinate(coordinate, destProjection) {\n if (!userProjection) {\n return coordinate;\n }\n\n return transform(coordinate, userProjection, destProjection);\n}\n/**\n * Return an extent transformed into the user projection. If no user projection\n * is set, the original extent is returned.\n * @param {import("./extent.js").Extent} extent Input extent.\n * @param {ProjectionLike} sourceProjection The input extent projection.\n * @returns {import("./extent.js").Extent} The input extent in the user projection.\n */\n\nfunction toUserExtent(extent, sourceProjection) {\n if (!userProjection) {\n return extent;\n }\n\n return proj_transformExtent(extent, sourceProjection, userProjection);\n}\n/**\n * Return an extent transformed from the user projection. If no user projection\n * is set, the original extent is returned.\n * @param {import("./extent.js").Extent} extent Input extent.\n * @param {ProjectionLike} destProjection The destination projection.\n * @returns {import("./extent.js").Extent} The input extent transformed.\n */\n\nfunction fromUserExtent(extent, destProjection) {\n if (!userProjection) {\n return extent;\n }\n\n return proj_transformExtent(extent, userProjection, destProjection);\n}\n/**\n * Creates a safe coordinate transform function from a coordinate transform function.\n * "Safe" means that it can handle wrapping of x-coordinates for global projections,\n * and that coordinates exceeding the source projection validity extent\'s range will be\n * clamped to the validity range.\n * @param {Projection} sourceProj Source projection.\n * @param {Projection} destProj Destination projection.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} transform Transform function (source to destiation).\n * @return {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} Safe transform function (source to destiation).\n */\n\nfunction createSafeCoordinateTransform(sourceProj, destProj, transform) {\n return function (coord) {\n var sourceX = coord[0];\n var sourceY = coord[1];\n var transformed, worldsAway;\n\n if (sourceProj.canWrapX()) {\n var sourceExtent = sourceProj.getExtent();\n var sourceExtentWidth = getWidth(sourceExtent);\n worldsAway = getWorldsAway(coord, sourceProj, sourceExtentWidth);\n\n if (worldsAway) {\n // Move x to the real world\n sourceX = sourceX - worldsAway * sourceExtentWidth;\n }\n\n sourceX = clamp(sourceX, sourceExtent[0], sourceExtent[2]);\n sourceY = clamp(sourceY, sourceExtent[1], sourceExtent[3]);\n transformed = transform([sourceX, sourceY]);\n } else {\n transformed = transform(coord);\n }\n\n if (worldsAway && destProj.canWrapX()) {\n // Move transformed coordinate back to the offset world\n transformed[0] += worldsAway * getWidth(destProj.getExtent());\n }\n\n return transformed;\n };\n}\n/**\n * Add transforms to and from EPSG:4326 and EPSG:3857. This function is called\n * by when this module is executed and should only need to be called again after\n * `clearAllProjections()` is called (e.g. in tests).\n */\n\nfunction addCommon() {\n // Add transformations that don\'t alter coordinates to convert within set of\n // projections with equal meaning.\n addEquivalentProjections(PROJECTIONS);\n addEquivalentProjections(epsg4326_PROJECTIONS); // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like\n // coordinates and back.\n\n addEquivalentTransforms(epsg4326_PROJECTIONS, PROJECTIONS, fromEPSG4326, toEPSG4326);\n}\naddCommon();\n;// CONCATENATED MODULE: ./node_modules/ol/centerconstraint.js\n/**\n * @module ol/centerconstraint\n */\n\n/**\n * @typedef {function((import("./coordinate.js").Coordinate|undefined), number, import("./size.js").Size, boolean=, Array<number>=): (import("./coordinate.js").Coordinate|undefined)} Type\n */\n\n/**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {boolean} onlyCenter If true, the constraint will only apply to the view center.\n * @param {boolean} smooth If true, the view will be able to go slightly out of the given extent\n * (only during interaction and animation).\n * @return {Type} The constraint.\n */\n\nfunction createExtent(extent, onlyCenter, smooth) {\n return (\n /**\n * @param {import("./coordinate.js").Coordinate|undefined} center Center.\n * @param {number} resolution Resolution.\n * @param {import("./size.js").Size} size Viewport size; unused if `onlyCenter` was specified.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @param {Array<number>=} opt_centerShift Shift between map center and viewport center.\n * @return {import("./coordinate.js").Coordinate|undefined} Center.\n */\n function (center, resolution, size, opt_isMoving, opt_centerShift) {\n if (center) {\n var viewWidth = onlyCenter ? 0 : size[0] * resolution;\n var viewHeight = onlyCenter ? 0 : size[1] * resolution;\n var shiftX = opt_centerShift ? opt_centerShift[0] : 0;\n var shiftY = opt_centerShift ? opt_centerShift[1] : 0;\n var minX = extent[0] + viewWidth / 2 + shiftX;\n var maxX = extent[2] - viewWidth / 2 + shiftX;\n var minY = extent[1] + viewHeight / 2 + shiftY;\n var maxY = extent[3] - viewHeight / 2 + shiftY; // note: when zooming out of bounds, min and max values for x and y may\n // end up inverted (min > max); this has to be accounted for\n\n if (minX > maxX) {\n minX = (maxX + minX) / 2;\n maxX = minX;\n }\n\n if (minY > maxY) {\n minY = (maxY + minY) / 2;\n maxY = minY;\n }\n\n var x = math_clamp(center[0], minX, maxX);\n var y = math_clamp(center[1], minY, maxY);\n var ratio = 30 * resolution; // during an interaction, allow some overscroll\n\n if (opt_isMoving && smooth) {\n x += -ratio * Math.log(1 + Math.max(0, minX - center[0]) / ratio) + ratio * Math.log(1 + Math.max(0, center[0] - maxX) / ratio);\n y += -ratio * Math.log(1 + Math.max(0, minY - center[1]) / ratio) + ratio * Math.log(1 + Math.max(0, center[1] - maxY) / ratio);\n }\n\n return [x, y];\n } else {\n return undefined;\n }\n }\n );\n}\n/**\n * @param {import("./coordinate.js").Coordinate=} center Center.\n * @return {import("./coordinate.js").Coordinate|undefined} Center.\n */\n\nfunction none(center) {\n return center;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/resolutionconstraint.js\n/**\n * @module ol/resolutionconstraint\n */\n\n\n\n/**\n * @typedef {function((number|undefined), number, import("./size.js").Size, boolean=): (number|undefined)} Type\n */\n\n/**\n * Returns a modified resolution taking into account the viewport size and maximum\n * allowed extent.\n * @param {number} resolution Resolution\n * @param {import("./extent.js").Extent} maxExtent Maximum allowed extent.\n * @param {import("./size.js").Size} viewportSize Viewport size.\n * @param {boolean} showFullExtent Whether to show the full extent.\n * @return {number} Capped resolution.\n */\n\nfunction getViewportClampedResolution(resolution, maxExtent, viewportSize, showFullExtent) {\n var xResolution = extent_getWidth(maxExtent) / viewportSize[0];\n var yResolution = getHeight(maxExtent) / viewportSize[1];\n\n if (showFullExtent) {\n return Math.min(resolution, Math.max(xResolution, yResolution));\n }\n\n return Math.min(resolution, Math.min(xResolution, yResolution));\n}\n/**\n * Returns a modified resolution to be between maxResolution and minResolution while\n * still allowing the value to be slightly out of bounds.\n * Note: the computation is based on the logarithm function (ln):\n * - at 1, ln(x) is 0\n * - above 1, ln(x) keeps increasing but at a much slower pace than x\n * The final result is clamped to prevent getting too far away from bounds.\n * @param {number} resolution Resolution.\n * @param {number} maxResolution Max resolution.\n * @param {number} minResolution Min resolution.\n * @return {number} Smoothed resolution.\n */\n\n\nfunction getSmoothClampedResolution(resolution, maxResolution, minResolution) {\n var result = Math.min(resolution, maxResolution);\n var ratio = 50;\n result *= Math.log(1 + ratio * Math.max(0, resolution / maxResolution - 1)) / ratio + 1;\n\n if (minResolution) {\n result = Math.max(result, minResolution);\n result /= Math.log(1 + ratio * Math.max(0, minResolution / resolution - 1)) / ratio + 1;\n }\n\n return math_clamp(result, minResolution / 2, maxResolution * 2);\n}\n/**\n * @param {Array<number>} resolutions Resolutions.\n * @param {boolean=} opt_smooth If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import("./extent.js").Extent=} opt_maxExtent Maximum allowed extent.\n * @param {boolean=} opt_showFullExtent If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\n\n\nfunction createSnapToResolutions(resolutions, opt_smooth, opt_maxExtent, opt_showFullExtent) {\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import("./size.js").Size} size Viewport size.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, opt_isMoving) {\n if (resolution !== undefined) {\n var maxResolution = resolutions[0];\n var minResolution = resolutions[resolutions.length - 1];\n var cappedMaxRes = opt_maxExtent ? getViewportClampedResolution(maxResolution, opt_maxExtent, size, opt_showFullExtent) : maxResolution; // during interacting or animating, allow intermediary values\n\n if (opt_isMoving) {\n var smooth = opt_smooth !== undefined ? opt_smooth : true;\n\n if (!smooth) {\n return math_clamp(resolution, minResolution, cappedMaxRes);\n }\n\n return getSmoothClampedResolution(resolution, cappedMaxRes, minResolution);\n }\n\n var capped = Math.min(cappedMaxRes, resolution);\n var z = Math.floor(linearFindNearest(resolutions, capped, direction));\n\n if (resolutions[z] > cappedMaxRes && z < resolutions.length - 1) {\n return resolutions[z + 1];\n }\n\n return resolutions[z];\n } else {\n return undefined;\n }\n }\n );\n}\n/**\n * @param {number} power Power.\n * @param {number} maxResolution Maximum resolution.\n * @param {number=} opt_minResolution Minimum resolution.\n * @param {boolean=} opt_smooth If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import("./extent.js").Extent=} opt_maxExtent Maximum allowed extent.\n * @param {boolean=} opt_showFullExtent If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\n\nfunction createSnapToPower(power, maxResolution, opt_minResolution, opt_smooth, opt_maxExtent, opt_showFullExtent) {\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import("./size.js").Size} size Viewport size.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, opt_isMoving) {\n if (resolution !== undefined) {\n var cappedMaxRes = opt_maxExtent ? getViewportClampedResolution(maxResolution, opt_maxExtent, size, opt_showFullExtent) : maxResolution;\n var minResolution = opt_minResolution !== undefined ? opt_minResolution : 0; // during interacting or animating, allow intermediary values\n\n if (opt_isMoving) {\n var smooth = opt_smooth !== undefined ? opt_smooth : true;\n\n if (!smooth) {\n return math_clamp(resolution, minResolution, cappedMaxRes);\n }\n\n return getSmoothClampedResolution(resolution, cappedMaxRes, minResolution);\n }\n\n var tolerance = 1e-9;\n var minZoomLevel = Math.ceil(Math.log(maxResolution / cappedMaxRes) / Math.log(power) - tolerance);\n var offset = -direction * (0.5 - tolerance) + 0.5;\n var capped = Math.min(cappedMaxRes, resolution);\n var cappedZoomLevel = Math.floor(Math.log(maxResolution / capped) / Math.log(power) + offset);\n var zoomLevel = Math.max(minZoomLevel, cappedZoomLevel);\n var newResolution = maxResolution / Math.pow(power, zoomLevel);\n return math_clamp(newResolution, minResolution, cappedMaxRes);\n } else {\n return undefined;\n }\n }\n );\n}\n/**\n * @param {number} maxResolution Max resolution.\n * @param {number} minResolution Min resolution.\n * @param {boolean=} opt_smooth If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import("./extent.js").Extent=} opt_maxExtent Maximum allowed extent.\n * @param {boolean=} opt_showFullExtent If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\n\nfunction createMinMaxResolution(maxResolution, minResolution, opt_smooth, opt_maxExtent, opt_showFullExtent) {\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import("./size.js").Size} size Viewport size.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, opt_isMoving) {\n if (resolution !== undefined) {\n var cappedMaxRes = opt_maxExtent ? getViewportClampedResolution(maxResolution, opt_maxExtent, size, opt_showFullExtent) : maxResolution;\n var smooth = opt_smooth !== undefined ? opt_smooth : true;\n\n if (!smooth || !opt_isMoving) {\n return math_clamp(resolution, minResolution, cappedMaxRes);\n }\n\n return getSmoothClampedResolution(resolution, cappedMaxRes, minResolution);\n } else {\n return undefined;\n }\n }\n );\n}\n;// CONCATENATED MODULE: ./node_modules/ol/rotationconstraint.js\n/**\n * @module ol/rotationconstraint\n */\n\n/**\n * @typedef {function((number|undefined), boolean=): (number|undefined)} Type\n */\n\n/**\n * @param {number|undefined} rotation Rotation.\n * @return {number|undefined} Rotation.\n */\n\nfunction disable(rotation) {\n if (rotation !== undefined) {\n return 0;\n } else {\n return undefined;\n }\n}\n/**\n * @param {number|undefined} rotation Rotation.\n * @return {number|undefined} Rotation.\n */\n\nfunction rotationconstraint_none(rotation) {\n if (rotation !== undefined) {\n return rotation;\n } else {\n return undefined;\n }\n}\n/**\n * @param {number} n N.\n * @return {Type} Rotation constraint.\n */\n\nfunction createSnapToN(n) {\n var theta = 2 * Math.PI / n;\n return (\n /**\n * @param {number|undefined} rotation Rotation.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @return {number|undefined} Rotation.\n */\n function (rotation, opt_isMoving) {\n if (opt_isMoving) {\n return rotation;\n }\n\n if (rotation !== undefined) {\n rotation = Math.floor(rotation / theta + 0.5) * theta;\n return rotation;\n } else {\n return undefined;\n }\n }\n );\n}\n/**\n * @param {number=} opt_tolerance Tolerance.\n * @return {Type} Rotation constraint.\n */\n\nfunction createSnapToZero(opt_tolerance) {\n var tolerance = opt_tolerance || math_toRadians(5);\n return (\n /**\n * @param {number|undefined} rotation Rotation.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @return {number|undefined} Rotation.\n */\n function (rotation, opt_isMoving) {\n if (opt_isMoving) {\n return rotation;\n }\n\n if (rotation !== undefined) {\n if (Math.abs(rotation) <= tolerance) {\n return 0;\n } else {\n return rotation;\n }\n } else {\n return undefined;\n }\n }\n );\n}\n;// CONCATENATED MODULE: ./node_modules/ol/easing.js\n/**\n * @module ol/easing\n */\n\n/**\n * Start slow and speed up.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nfunction easeIn(t) {\n return Math.pow(t, 3);\n}\n/**\n * Start fast and slow down.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\n\nfunction easeOut(t) {\n return 1 - easeIn(1 - t);\n}\n/**\n * Start slow, speed up, and then slow down again.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\n\nfunction inAndOut(t) {\n return 3 * t * t - 2 * t * t * t;\n}\n/**\n * Maintain a constant speed over time.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\n\nfunction linear(t) {\n return t;\n}\n/**\n * Start slow, speed up, and at the very end slow down again. This has the\n * same general behavior as {@link module:ol/easing~inAndOut}, but the final\n * slowdown is delayed.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\n\nfunction upAndDown(t) {\n if (t < 0.5) {\n return inAndOut(2 * t);\n } else {\n return 1 - inAndOut(2 * (t - 0.5));\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/GeometryLayout.js\n/**\n * @module ol/geom/GeometryLayout\n */\n\n/**\n * The coordinate layout for geometries, indicating whether a 3rd or 4th z (\'Z\')\n * or measure (\'M\') coordinate is available. Supported values are `\'XY\'`,\n * `\'XYZ\'`, `\'XYM\'`, `\'XYZM\'`.\n * @enum {string}\n */\n/* harmony default export */ var geom_GeometryLayout = ({\n XY: \'XY\',\n XYZ: \'XYZ\',\n XYM: \'XYM\',\n XYZM: \'XYZM\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/transform.js\n/**\n * @module ol/geom/flat/transform\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Transformed coordinates.\n */\nfunction transform2D(flatCoordinates, offset, end, stride, transform, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var i = 0;\n\n for (var j = offset; j < end; j += stride) {\n var x = flatCoordinates[j];\n var y = flatCoordinates[j + 1];\n dest[i++] = transform[0] * x + transform[2] * y + transform[4];\n dest[i++] = transform[1] * x + transform[3] * y + transform[5];\n }\n\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n\n return dest;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} angle Angle.\n * @param {Array<number>} anchor Rotation anchor point.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Transformed coordinates.\n */\n\nfunction transform_rotate(flatCoordinates, offset, end, stride, angle, anchor, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var cos = Math.cos(angle);\n var sin = Math.sin(angle);\n var anchorX = anchor[0];\n var anchorY = anchor[1];\n var i = 0;\n\n for (var j = offset; j < end; j += stride) {\n var deltaX = flatCoordinates[j] - anchorX;\n var deltaY = flatCoordinates[j + 1] - anchorY;\n dest[i++] = anchorX + deltaX * cos - deltaY * sin;\n dest[i++] = anchorY + deltaX * sin + deltaY * cos;\n\n for (var k = j + 2; k < j + stride; ++k) {\n dest[i++] = flatCoordinates[k];\n }\n }\n\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n\n return dest;\n}\n/**\n * Scale the coordinates.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} sx Scale factor in the x-direction.\n * @param {number} sy Scale factor in the y-direction.\n * @param {Array<number>} anchor Scale anchor point.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Transformed coordinates.\n */\n\nfunction transform_scale(flatCoordinates, offset, end, stride, sx, sy, anchor, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var anchorX = anchor[0];\n var anchorY = anchor[1];\n var i = 0;\n\n for (var j = offset; j < end; j += stride) {\n var deltaX = flatCoordinates[j] - anchorX;\n var deltaY = flatCoordinates[j + 1] - anchorY;\n dest[i++] = anchorX + sx * deltaX;\n dest[i++] = anchorY + sy * deltaY;\n\n for (var k = j + 2; k < j + stride; ++k) {\n dest[i++] = flatCoordinates[k];\n }\n }\n\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n\n return dest;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Transformed coordinates.\n */\n\nfunction transform_translate(flatCoordinates, offset, end, stride, deltaX, deltaY, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var i = 0;\n\n for (var j = offset; j < end; j += stride) {\n dest[i++] = flatCoordinates[j] + deltaX;\n dest[i++] = flatCoordinates[j + 1] + deltaY;\n\n for (var k = j + 2; k < j + stride; ++k) {\n dest[i++] = flatCoordinates[k];\n }\n }\n\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n\n return dest;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/Geometry.js\nvar Geometry_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/Geometry\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * @type {import("../transform.js").Transform}\n */\n\nvar tmpTransform = create();\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for vector geometries.\n *\n * To get notified of changes to the geometry, register a listener for the\n * generic `change` event on your geometry instance.\n *\n * @abstract\n * @api\n */\n\nvar Geometry =\n/** @class */\nfunction (_super) {\n Geometry_extends(Geometry, _super);\n\n function Geometry() {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import("../extent.js").Extent}\n */\n\n\n _this.extent_ = createEmpty();\n /**\n * @private\n * @type {number}\n */\n\n _this.extentRevision_ = -1;\n /**\n * @protected\n * @type {number}\n */\n\n _this.simplifiedGeometryMaxMinSquaredTolerance = 0;\n /**\n * @protected\n * @type {number}\n */\n\n _this.simplifiedGeometryRevision = 0;\n /**\n * Get a transformed and simplified version of the geometry.\n * @abstract\n * @param {number} revision The geometry revision.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import("../proj.js").TransformFunction} [opt_transform] Optional transform function.\n * @return {Geometry} Simplified geometry.\n */\n\n _this.simplifyTransformedInternal = memoizeOne(function (revision, squaredTolerance, opt_transform) {\n if (!opt_transform) {\n return this.getSimplifiedGeometry(squaredTolerance);\n }\n\n var clone = this.clone();\n clone.applyTransform(opt_transform);\n return clone.getSimplifiedGeometry(squaredTolerance);\n });\n return _this;\n }\n /**\n * Get a transformed and simplified version of the geometry.\n * @abstract\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import("../proj.js").TransformFunction} [opt_transform] Optional transform function.\n * @return {Geometry} Simplified geometry.\n */\n\n\n Geometry.prototype.simplifyTransformed = function (squaredTolerance, opt_transform) {\n return this.simplifyTransformedInternal(this.getRevision(), squaredTolerance, opt_transform);\n };\n /**\n * Make a complete copy of the geometry.\n * @abstract\n * @return {!Geometry} Clone.\n */\n\n\n Geometry.prototype.clone = function () {\n return util_abstract();\n };\n /**\n * @abstract\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n Geometry.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n return util_abstract();\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\n\n Geometry.prototype.containsXY = function (x, y) {\n var coord = this.getClosestPoint([x, y]);\n return coord[0] === x && coord[1] === y;\n };\n /**\n * Return the closest point of the geometry to the passed point as\n * {@link module:ol/coordinate~Coordinate coordinate}.\n * @param {import("../coordinate.js").Coordinate} point Point.\n * @param {import("../coordinate.js").Coordinate=} opt_closestPoint Closest point.\n * @return {import("../coordinate.js").Coordinate} Closest point.\n * @api\n */\n\n\n Geometry.prototype.getClosestPoint = function (point, opt_closestPoint) {\n var closestPoint = opt_closestPoint ? opt_closestPoint : [NaN, NaN];\n this.closestPointXY(point[0], point[1], closestPoint, Infinity);\n return closestPoint;\n };\n /**\n * Returns true if this geometry includes the specified coordinate. If the\n * coordinate is on the boundary of the geometry, returns false.\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @return {boolean} Contains coordinate.\n * @api\n */\n\n\n Geometry.prototype.intersectsCoordinate = function (coordinate) {\n return this.containsXY(coordinate[0], coordinate[1]);\n };\n /**\n * @abstract\n * @param {import("../extent.js").Extent} extent Extent.\n * @protected\n * @return {import("../extent.js").Extent} extent Extent.\n */\n\n\n Geometry.prototype.computeExtent = function (extent) {\n return util_abstract();\n };\n /**\n * Get the extent of the geometry.\n * @param {import("../extent.js").Extent=} opt_extent Extent.\n * @return {import("../extent.js").Extent} extent Extent.\n * @api\n */\n\n\n Geometry.prototype.getExtent = function (opt_extent) {\n if (this.extentRevision_ != this.getRevision()) {\n var extent = this.computeExtent(this.extent_);\n\n if (isNaN(extent[0]) || isNaN(extent[1])) {\n createOrUpdateEmpty(extent);\n }\n\n this.extentRevision_ = this.getRevision();\n }\n\n return returnOrUpdate(this.extent_, opt_extent);\n };\n /**\n * Rotate the geometry around a given coordinate. This modifies the geometry\n * coordinates in place.\n * @abstract\n * @param {number} angle Rotation angle in radians.\n * @param {import("../coordinate.js").Coordinate} anchor The rotation center.\n * @api\n */\n\n\n Geometry.prototype.rotate = function (angle, anchor) {\n util_abstract();\n };\n /**\n * Scale the geometry (with an optional origin). This modifies the geometry\n * coordinates in place.\n * @abstract\n * @param {number} sx The scaling factor in the x-direction.\n * @param {number=} opt_sy The scaling factor in the y-direction (defaults to sx).\n * @param {import("../coordinate.js").Coordinate=} opt_anchor The scale origin (defaults to the center\n * of the geometry extent).\n * @api\n */\n\n\n Geometry.prototype.scale = function (sx, opt_sy, opt_anchor) {\n util_abstract();\n };\n /**\n * Create a simplified version of this geometry. For linestrings, this uses\n * the [Douglas Peucker](https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm)\n * algorithm. For polygons, a quantization-based\n * simplification is used to preserve topology.\n * @param {number} tolerance The tolerance distance for simplification.\n * @return {Geometry} A new, simplified version of the original geometry.\n * @api\n */\n\n\n Geometry.prototype.simplify = function (tolerance) {\n return this.getSimplifiedGeometry(tolerance * tolerance);\n };\n /**\n * Create a simplified version of this geometry using the Douglas Peucker\n * algorithm.\n * See https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm.\n * @abstract\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Geometry} Simplified geometry.\n */\n\n\n Geometry.prototype.getSimplifiedGeometry = function (squaredTolerance) {\n return util_abstract();\n };\n /**\n * Get the type of this geometry.\n * @abstract\n * @return {import("./GeometryType.js").default} Geometry type.\n */\n\n\n Geometry.prototype.getType = function () {\n return util_abstract();\n };\n /**\n * Apply a transform function to the coordinates of the geometry.\n * The geometry is modified in place.\n * If you do not want the geometry modified in place, first `clone()` it and\n * then use this function on the clone.\n * @abstract\n * @param {import("../proj.js").TransformFunction} transformFn Transform function.\n * Called with a flat array of geometry coordinates.\n */\n\n\n Geometry.prototype.applyTransform = function (transformFn) {\n util_abstract();\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @abstract\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n */\n\n\n Geometry.prototype.intersectsExtent = function (extent) {\n return util_abstract();\n };\n /**\n * Translate the geometry. This modifies the geometry coordinates in place. If\n * instead you want a new geometry, first `clone()` this geometry.\n * @abstract\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @api\n */\n\n\n Geometry.prototype.translate = function (deltaX, deltaY) {\n util_abstract();\n };\n /**\n * Transform each coordinate of the geometry from one coordinate reference\n * system to another. The geometry is modified in place.\n * For example, a line will be transformed to a line and a circle to a circle.\n * If you do not want the geometry modified in place, first `clone()` it and\n * then use this function on the clone.\n *\n * @param {import("../proj.js").ProjectionLike} source The current projection. Can be a\n * string identifier or a {@link module:ol/proj/Projection~Projection} object.\n * @param {import("../proj.js").ProjectionLike} destination The desired projection. Can be a\n * string identifier or a {@link module:ol/proj/Projection~Projection} object.\n * @return {Geometry} This geometry. Note that original geometry is\n * modified in place.\n * @api\n */\n\n\n Geometry.prototype.transform = function (source, destination) {\n /** @type {import("../proj/Projection.js").default} */\n var sourceProj = proj_get(source);\n var transformFn = sourceProj.getUnits() == proj_Units.TILE_PIXELS ? function (inCoordinates, outCoordinates, stride) {\n var pixelExtent = sourceProj.getExtent();\n var projectedExtent = sourceProj.getWorldExtent();\n var scale = getHeight(projectedExtent) / getHeight(pixelExtent);\n compose(tmpTransform, projectedExtent[0], projectedExtent[3], scale, -scale, 0, 0, 0);\n transform2D(inCoordinates, 0, inCoordinates.length, stride, tmpTransform, outCoordinates);\n return getTransform(sourceProj, destination)(inCoordinates, outCoordinates, stride);\n } : getTransform(sourceProj, destination);\n this.applyTransform(transformFn);\n return this;\n };\n\n return Geometry;\n}(ol_Object);\n\n/* harmony default export */ var geom_Geometry = (Geometry);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/SimpleGeometry.js\nvar SimpleGeometry_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/SimpleGeometry\n */\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Abstract base class; only used for creating subclasses; do not instantiate\n * in apps, as cannot be rendered.\n *\n * @abstract\n * @api\n */\n\nvar SimpleGeometry =\n/** @class */\nfunction (_super) {\n SimpleGeometry_extends(SimpleGeometry, _super);\n\n function SimpleGeometry() {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {import("./GeometryLayout.js").default}\n */\n\n\n _this.layout = geom_GeometryLayout.XY;\n /**\n * @protected\n * @type {number}\n */\n\n _this.stride = 2;\n /**\n * @protected\n * @type {Array<number>}\n */\n\n _this.flatCoordinates = null;\n return _this;\n }\n /**\n * @param {import("../extent.js").Extent} extent Extent.\n * @protected\n * @return {import("../extent.js").Extent} extent Extent.\n */\n\n\n SimpleGeometry.prototype.computeExtent = function (extent) {\n return createOrUpdateFromFlatCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, extent);\n };\n /**\n * @abstract\n * @return {Array<*>} Coordinates.\n */\n\n\n SimpleGeometry.prototype.getCoordinates = function () {\n return util_abstract();\n };\n /**\n * Return the first coordinate of the geometry.\n * @return {import("../coordinate.js").Coordinate} First coordinate.\n * @api\n */\n\n\n SimpleGeometry.prototype.getFirstCoordinate = function () {\n return this.flatCoordinates.slice(0, this.stride);\n };\n /**\n * @return {Array<number>} Flat coordinates.\n */\n\n\n SimpleGeometry.prototype.getFlatCoordinates = function () {\n return this.flatCoordinates;\n };\n /**\n * Return the last coordinate of the geometry.\n * @return {import("../coordinate.js").Coordinate} Last point.\n * @api\n */\n\n\n SimpleGeometry.prototype.getLastCoordinate = function () {\n return this.flatCoordinates.slice(this.flatCoordinates.length - this.stride);\n };\n /**\n * Return the {@link module:ol/geom/GeometryLayout layout} of the geometry.\n * @return {import("./GeometryLayout.js").default} Layout.\n * @api\n */\n\n\n SimpleGeometry.prototype.getLayout = function () {\n return this.layout;\n };\n /**\n * Create a simplified version of this geometry using the Douglas Peucker algorithm.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {SimpleGeometry} Simplified geometry.\n */\n\n\n SimpleGeometry.prototype.getSimplifiedGeometry = function (squaredTolerance) {\n if (this.simplifiedGeometryRevision !== this.getRevision()) {\n this.simplifiedGeometryMaxMinSquaredTolerance = 0;\n this.simplifiedGeometryRevision = this.getRevision();\n } // If squaredTolerance is negative or if we know that simplification will not\n // have any effect then just return this.\n\n\n if (squaredTolerance < 0 || this.simplifiedGeometryMaxMinSquaredTolerance !== 0 && squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance) {\n return this;\n }\n\n var simplifiedGeometry = this.getSimplifiedGeometryInternal(squaredTolerance);\n var simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();\n\n if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {\n return simplifiedGeometry;\n } else {\n // Simplification did not actually remove any coordinates. We now know\n // that any calls to getSimplifiedGeometry with a squaredTolerance less\n // than or equal to the current squaredTolerance will also not have any\n // effect. This allows us to short circuit simplification (saving CPU\n // cycles) and prevents the cache of simplified geometries from filling\n // up with useless identical copies of this geometry (saving memory).\n this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;\n return this;\n }\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {SimpleGeometry} Simplified geometry.\n * @protected\n */\n\n\n SimpleGeometry.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n return this;\n };\n /**\n * @return {number} Stride.\n */\n\n\n SimpleGeometry.prototype.getStride = function () {\n return this.stride;\n };\n /**\n * @param {import("./GeometryLayout.js").default} layout Layout.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n */\n\n\n SimpleGeometry.prototype.setFlatCoordinates = function (layout, flatCoordinates) {\n this.stride = getStrideForLayout(layout);\n this.layout = layout;\n this.flatCoordinates = flatCoordinates;\n };\n /**\n * @abstract\n * @param {!Array<*>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n */\n\n\n SimpleGeometry.prototype.setCoordinates = function (coordinates, opt_layout) {\n util_abstract();\n };\n /**\n * @param {import("./GeometryLayout.js").default|undefined} layout Layout.\n * @param {Array<*>} coordinates Coordinates.\n * @param {number} nesting Nesting.\n * @protected\n */\n\n\n SimpleGeometry.prototype.setLayout = function (layout, coordinates, nesting) {\n /** @type {number} */\n var stride;\n\n if (layout) {\n stride = getStrideForLayout(layout);\n } else {\n for (var i = 0; i < nesting; ++i) {\n if (coordinates.length === 0) {\n this.layout = geom_GeometryLayout.XY;\n this.stride = 2;\n return;\n } else {\n coordinates =\n /** @type {Array} */\n coordinates[0];\n }\n }\n\n stride = coordinates.length;\n layout = getLayoutForStride(stride);\n }\n\n this.layout = layout;\n this.stride = stride;\n };\n /**\n * Apply a transform function to the coordinates of the geometry.\n * The geometry is modified in place.\n * If you do not want the geometry modified in place, first `clone()` it and\n * then use this function on the clone.\n * @param {import("../proj.js").TransformFunction} transformFn Transform function.\n * Called with a flat array of geometry coordinates.\n * @api\n */\n\n\n SimpleGeometry.prototype.applyTransform = function (transformFn) {\n if (this.flatCoordinates) {\n transformFn(this.flatCoordinates, this.flatCoordinates, this.stride);\n this.changed();\n }\n };\n /**\n * Rotate the geometry around a given coordinate. This modifies the geometry\n * coordinates in place.\n * @param {number} angle Rotation angle in counter-clockwise radians.\n * @param {import("../coordinate.js").Coordinate} anchor The rotation center.\n * @api\n */\n\n\n SimpleGeometry.prototype.rotate = function (angle, anchor) {\n var flatCoordinates = this.getFlatCoordinates();\n\n if (flatCoordinates) {\n var stride = this.getStride();\n transform_rotate(flatCoordinates, 0, flatCoordinates.length, stride, angle, anchor, flatCoordinates);\n this.changed();\n }\n };\n /**\n * Scale the geometry (with an optional origin). This modifies the geometry\n * coordinates in place.\n * @param {number} sx The scaling factor in the x-direction.\n * @param {number=} opt_sy The scaling factor in the y-direction (defaults to sx).\n * @param {import("../coordinate.js").Coordinate=} opt_anchor The scale origin (defaults to the center\n * of the geometry extent).\n * @api\n */\n\n\n SimpleGeometry.prototype.scale = function (sx, opt_sy, opt_anchor) {\n var sy = opt_sy;\n\n if (sy === undefined) {\n sy = sx;\n }\n\n var anchor = opt_anchor;\n\n if (!anchor) {\n anchor = getCenter(this.getExtent());\n }\n\n var flatCoordinates = this.getFlatCoordinates();\n\n if (flatCoordinates) {\n var stride = this.getStride();\n transform_scale(flatCoordinates, 0, flatCoordinates.length, stride, sx, sy, anchor, flatCoordinates);\n this.changed();\n }\n };\n /**\n * Translate the geometry. This modifies the geometry coordinates in place. If\n * instead you want a new geometry, first `clone()` this geometry.\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @api\n */\n\n\n SimpleGeometry.prototype.translate = function (deltaX, deltaY) {\n var flatCoordinates = this.getFlatCoordinates();\n\n if (flatCoordinates) {\n var stride = this.getStride();\n transform_translate(flatCoordinates, 0, flatCoordinates.length, stride, deltaX, deltaY, flatCoordinates);\n this.changed();\n }\n };\n\n return SimpleGeometry;\n}(geom_Geometry);\n/**\n * @param {number} stride Stride.\n * @return {import("./GeometryLayout.js").default} layout Layout.\n */\n\n\nfunction getLayoutForStride(stride) {\n var layout;\n\n if (stride == 2) {\n layout = geom_GeometryLayout.XY;\n } else if (stride == 3) {\n layout = geom_GeometryLayout.XYZ;\n } else if (stride == 4) {\n layout = geom_GeometryLayout.XYZM;\n }\n\n return (\n /** @type {import("./GeometryLayout.js").default} */\n layout\n );\n}\n/**\n * @param {import("./GeometryLayout.js").default} layout Layout.\n * @return {number} Stride.\n */\n\n\nfunction getStrideForLayout(layout) {\n var stride;\n\n if (layout == geom_GeometryLayout.XY) {\n stride = 2;\n } else if (layout == geom_GeometryLayout.XYZ || layout == geom_GeometryLayout.XYM) {\n stride = 3;\n } else if (layout == geom_GeometryLayout.XYZM) {\n stride = 4;\n }\n\n return (\n /** @type {number} */\n stride\n );\n}\n/**\n * @param {SimpleGeometry} simpleGeometry Simple geometry.\n * @param {import("../transform.js").Transform} transform Transform.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Transformed flat coordinates.\n */\n\nfunction transformGeom2D(simpleGeometry, transform, opt_dest) {\n var flatCoordinates = simpleGeometry.getFlatCoordinates();\n\n if (!flatCoordinates) {\n return null;\n } else {\n var stride = simpleGeometry.getStride();\n return transform2D(flatCoordinates, 0, flatCoordinates.length, stride, transform, opt_dest);\n }\n}\n/* harmony default export */ var geom_SimpleGeometry = (SimpleGeometry);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/closest.js\n/**\n * @module ol/geom/flat/closest\n */\n\n/**\n * Returns the point on the 2D line segment flatCoordinates[offset1] to\n * flatCoordinates[offset2] that is closest to the point (x, y). Extra\n * dimensions are linearly interpolated.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset1 Offset 1.\n * @param {number} offset2 Offset 2.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n */\n\nfunction assignClosest(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) {\n var x1 = flatCoordinates[offset1];\n var y1 = flatCoordinates[offset1 + 1];\n var dx = flatCoordinates[offset2] - x1;\n var dy = flatCoordinates[offset2 + 1] - y1;\n var offset;\n\n if (dx === 0 && dy === 0) {\n offset = offset1;\n } else {\n var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n\n if (t > 1) {\n offset = offset2;\n } else if (t > 0) {\n for (var i = 0; i < stride; ++i) {\n closestPoint[i] = lerp(flatCoordinates[offset1 + i], flatCoordinates[offset2 + i], t);\n }\n\n closestPoint.length = stride;\n return;\n } else {\n offset = offset1;\n }\n }\n\n for (var i = 0; i < stride; ++i) {\n closestPoint[i] = flatCoordinates[offset + i];\n }\n\n closestPoint.length = stride;\n}\n/**\n * Return the squared of the largest distance between any pair of consecutive\n * coordinates.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\n\n\nfunction maxSquaredDelta(flatCoordinates, offset, end, stride, max) {\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1];\n\n for (offset += stride; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n var squaredDelta = math_squaredDistance(x1, y1, x2, y2);\n\n if (squaredDelta > max) {\n max = squaredDelta;\n }\n\n x1 = x2;\n y1 = y2;\n }\n\n return max;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\n\nfunction arrayMaxSquaredDelta(flatCoordinates, offset, ends, stride, max) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n max = maxSquaredDelta(flatCoordinates, offset, end, stride, max);\n offset = end;\n }\n\n return max;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\n\nfunction multiArrayMaxSquaredDelta(flatCoordinates, offset, endss, stride, max) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n max = arrayMaxSquaredDelta(flatCoordinates, offset, ends, stride, max);\n offset = ends[ends.length - 1];\n }\n\n return max;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array<number>=} opt_tmpPoint Temporary point object.\n * @return {number} Minimum squared distance.\n */\n\nfunction assignClosestPoint(flatCoordinates, offset, end, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) {\n if (offset == end) {\n return minSquaredDistance;\n }\n\n var i, squaredDistance;\n\n if (maxDelta === 0) {\n // All points are identical, so just test the first point.\n squaredDistance = math_squaredDistance(x, y, flatCoordinates[offset], flatCoordinates[offset + 1]);\n\n if (squaredDistance < minSquaredDistance) {\n for (i = 0; i < stride; ++i) {\n closestPoint[i] = flatCoordinates[offset + i];\n }\n\n closestPoint.length = stride;\n return squaredDistance;\n } else {\n return minSquaredDistance;\n }\n }\n\n var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n var index = offset + stride;\n\n while (index < end) {\n assignClosest(flatCoordinates, index - stride, index, stride, x, y, tmpPoint);\n squaredDistance = math_squaredDistance(x, y, tmpPoint[0], tmpPoint[1]);\n\n if (squaredDistance < minSquaredDistance) {\n minSquaredDistance = squaredDistance;\n\n for (i = 0; i < stride; ++i) {\n closestPoint[i] = tmpPoint[i];\n }\n\n closestPoint.length = stride;\n index += stride;\n } else {\n // Skip ahead multiple points, because we know that all the skipped\n // points cannot be any closer than the closest point we have found so\n // far. We know this because we know how close the current point is, how\n // close the closest point we have found so far is, and the maximum\n // distance between consecutive points. For example, if we\'re currently\n // at distance 10, the best we\'ve found so far is 3, and that the maximum\n // distance between consecutive points is 2, then we\'ll need to skip at\n // least (10 - 3) / 2 == 3 (rounded down) points to have any chance of\n // finding a closer point. We use Math.max(..., 1) to ensure that we\n // always advance at least one point, to avoid an infinite loop.\n index += stride * Math.max((Math.sqrt(squaredDistance) - Math.sqrt(minSquaredDistance)) / maxDelta | 0, 1);\n }\n }\n\n if (isRing) {\n // Check the closing segment.\n assignClosest(flatCoordinates, end - stride, offset, stride, x, y, tmpPoint);\n squaredDistance = math_squaredDistance(x, y, tmpPoint[0], tmpPoint[1]);\n\n if (squaredDistance < minSquaredDistance) {\n minSquaredDistance = squaredDistance;\n\n for (i = 0; i < stride; ++i) {\n closestPoint[i] = tmpPoint[i];\n }\n\n closestPoint.length = stride;\n }\n }\n\n return minSquaredDistance;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array<number>=} opt_tmpPoint Temporary point object.\n * @return {number} Minimum squared distance.\n */\n\nfunction assignClosestArrayPoint(flatCoordinates, offset, ends, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) {\n var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n minSquaredDistance = assignClosestPoint(flatCoordinates, offset, end, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint);\n offset = end;\n }\n\n return minSquaredDistance;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array<number>=} opt_tmpPoint Temporary point object.\n * @return {number} Minimum squared distance.\n */\n\nfunction assignClosestMultiArrayPoint(flatCoordinates, offset, endss, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) {\n var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n minSquaredDistance = assignClosestArrayPoint(flatCoordinates, offset, ends, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint);\n offset = ends[ends.length - 1];\n }\n\n return minSquaredDistance;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/deflate.js\n/**\n * @module ol/geom/flat/deflate\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {number} stride Stride.\n * @return {number} offset Offset.\n */\nfunction deflateCoordinate(flatCoordinates, offset, coordinate, stride) {\n for (var i = 0, ii = coordinate.length; i < ii; ++i) {\n flatCoordinates[offset++] = coordinate[i];\n }\n\n return offset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<import("../../coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {number} stride Stride.\n * @return {number} offset Offset.\n */\n\nfunction deflateCoordinates(flatCoordinates, offset, coordinates, stride) {\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n var coordinate = coordinates[i];\n\n for (var j = 0; j < stride; ++j) {\n flatCoordinates[offset++] = coordinate[j];\n }\n }\n\n return offset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<import("../../coordinate.js").Coordinate>>} coordinatess Coordinatess.\n * @param {number} stride Stride.\n * @param {Array<number>=} opt_ends Ends.\n * @return {Array<number>} Ends.\n */\n\nfunction deflateCoordinatesArray(flatCoordinates, offset, coordinatess, stride, opt_ends) {\n var ends = opt_ends ? opt_ends : [];\n var i = 0;\n\n for (var j = 0, jj = coordinatess.length; j < jj; ++j) {\n var end = deflateCoordinates(flatCoordinates, offset, coordinatess[j], stride);\n ends[i++] = end;\n offset = end;\n }\n\n ends.length = i;\n return ends;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<Array<import("../../coordinate.js").Coordinate>>>} coordinatesss Coordinatesss.\n * @param {number} stride Stride.\n * @param {Array<Array<number>>=} opt_endss Endss.\n * @return {Array<Array<number>>} Endss.\n */\n\nfunction deflateMultiCoordinatesArray(flatCoordinates, offset, coordinatesss, stride, opt_endss) {\n var endss = opt_endss ? opt_endss : [];\n var i = 0;\n\n for (var j = 0, jj = coordinatesss.length; j < jj; ++j) {\n var ends = deflateCoordinatesArray(flatCoordinates, offset, coordinatesss[j], stride, endss[i]);\n endss[i++] = ends;\n offset = ends[ends.length - 1];\n }\n\n endss.length = i;\n return endss;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/simplify.js\n/**\n * @module ol/geom/flat/simplify\n */\n// Based on simplify-js https://github.com/mourner/simplify-js\n// Copyright (c) 2012, Vladimir Agafonkin\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are met:\n//\n// 1. Redistributions of source code must retain the above copyright notice,\n// this list of conditions and the following disclaimer.\n//\n// 2. Redistributions in binary form must reproduce the above copyright\n// notice, this list of conditions and the following disclaimer in the\n// documentation and/or other materials provided with the distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\n// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n// POSSIBILITY OF SUCH DAMAGE.\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {boolean} highQuality Highest quality.\n * @param {Array<number>=} opt_simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @return {Array<number>} Simplified line string.\n */\n\nfunction simplifyLineString(flatCoordinates, offset, end, stride, squaredTolerance, highQuality, opt_simplifiedFlatCoordinates) {\n var simplifiedFlatCoordinates = opt_simplifiedFlatCoordinates !== undefined ? opt_simplifiedFlatCoordinates : [];\n\n if (!highQuality) {\n end = radialDistance(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n flatCoordinates = simplifiedFlatCoordinates;\n offset = 0;\n stride = 2;\n }\n\n simplifiedFlatCoordinates.length = douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n return simplifiedFlatCoordinates;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\n\nfunction douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n var n = (end - offset) / stride;\n\n if (n < 3) {\n for (; offset < end; offset += stride) {\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + 1];\n }\n\n return simplifiedOffset;\n }\n /** @type {Array<number>} */\n\n\n var markers = new Array(n);\n markers[0] = 1;\n markers[n - 1] = 1;\n /** @type {Array<number>} */\n\n var stack = [offset, end - stride];\n var index = 0;\n\n while (stack.length > 0) {\n var last = stack.pop();\n var first = stack.pop();\n var maxSquaredDistance = 0;\n var x1 = flatCoordinates[first];\n var y1 = flatCoordinates[first + 1];\n var x2 = flatCoordinates[last];\n var y2 = flatCoordinates[last + 1];\n\n for (var i = first + stride; i < last; i += stride) {\n var x = flatCoordinates[i];\n var y = flatCoordinates[i + 1];\n var squaredDistance_1 = squaredSegmentDistance(x, y, x1, y1, x2, y2);\n\n if (squaredDistance_1 > maxSquaredDistance) {\n index = i;\n maxSquaredDistance = squaredDistance_1;\n }\n }\n\n if (maxSquaredDistance > squaredTolerance) {\n markers[(index - offset) / stride] = 1;\n\n if (first + stride < index) {\n stack.push(first, index);\n }\n\n if (index + stride < last) {\n stack.push(index, last);\n }\n }\n }\n\n for (var i = 0; i < n; ++i) {\n if (markers[i]) {\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + i * stride];\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + i * stride + 1];\n }\n }\n\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<number>} simplifiedEnds Simplified ends.\n * @return {number} Simplified offset.\n */\n\nfunction douglasPeuckerArray(flatCoordinates, offset, ends, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n simplifiedOffset = douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset);\n simplifiedEnds.push(simplifiedOffset);\n offset = end;\n }\n\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<Array<number>>} simplifiedEndss Simplified endss.\n * @return {number} Simplified offset.\n */\n\nfunction douglasPeuckerMultiArray(flatCoordinates, offset, endss, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEndss) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n var simplifiedEnds = [];\n simplifiedOffset = douglasPeuckerArray(flatCoordinates, offset, ends, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds);\n simplifiedEndss.push(simplifiedEnds);\n offset = ends[ends.length - 1];\n }\n\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\n\nfunction radialDistance(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n if (end <= offset + stride) {\n // zero or one point, no simplification possible, so copy and return\n for (; offset < end; offset += stride) {\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + 1];\n }\n\n return simplifiedOffset;\n }\n\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1]; // copy first point\n\n simplifiedFlatCoordinates[simplifiedOffset++] = x1;\n simplifiedFlatCoordinates[simplifiedOffset++] = y1;\n var x2 = x1;\n var y2 = y1;\n\n for (offset += stride; offset < end; offset += stride) {\n x2 = flatCoordinates[offset];\n y2 = flatCoordinates[offset + 1];\n\n if (squaredDistance(x1, y1, x2, y2) > squaredTolerance) {\n // copy point at offset\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n x1 = x2;\n y1 = y2;\n }\n }\n\n if (x2 != x1 || y2 != y1) {\n // copy last point\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n }\n\n return simplifiedOffset;\n}\n/**\n * @param {number} value Value.\n * @param {number} tolerance Tolerance.\n * @return {number} Rounded value.\n */\n\nfunction snap(value, tolerance) {\n return tolerance * Math.round(value / tolerance);\n}\n/**\n * Simplifies a line string using an algorithm designed by Tim Schaub.\n * Coordinates are snapped to the nearest value in a virtual grid and\n * consecutive duplicate coordinates are discarded. This effectively preserves\n * topology as the simplification of any subsection of a line string is\n * independent of the rest of the line string. This means that, for examples,\n * the common edge between two polygons will be simplified to the same line\n * string independently in both polygons. This implementation uses a single\n * pass over the coordinates and eliminates intermediate collinear points.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\n\nfunction quantize(flatCoordinates, offset, end, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n // do nothing if the line is empty\n if (offset == end) {\n return simplifiedOffset;\n } // snap the first coordinate (P1)\n\n\n var x1 = snap(flatCoordinates[offset], tolerance);\n var y1 = snap(flatCoordinates[offset + 1], tolerance);\n offset += stride; // add the first coordinate to the output\n\n simplifiedFlatCoordinates[simplifiedOffset++] = x1;\n simplifiedFlatCoordinates[simplifiedOffset++] = y1; // find the next coordinate that does not snap to the same value as the first\n // coordinate (P2)\n\n var x2, y2;\n\n do {\n x2 = snap(flatCoordinates[offset], tolerance);\n y2 = snap(flatCoordinates[offset + 1], tolerance);\n offset += stride;\n\n if (offset == end) {\n // all coordinates snap to the same value, the line collapses to a point\n // push the last snapped value anyway to ensure that the output contains\n // at least two points\n // FIXME should we really return at least two points anyway?\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n return simplifiedOffset;\n }\n } while (x2 == x1 && y2 == y1);\n\n while (offset < end) {\n // snap the next coordinate (P3)\n var x3 = snap(flatCoordinates[offset], tolerance);\n var y3 = snap(flatCoordinates[offset + 1], tolerance);\n offset += stride; // skip P3 if it is equal to P2\n\n if (x3 == x2 && y3 == y2) {\n continue;\n } // calculate the delta between P1 and P2\n\n\n var dx1 = x2 - x1;\n var dy1 = y2 - y1; // calculate the delta between P3 and P1\n\n var dx2 = x3 - x1;\n var dy2 = y3 - y1; // if P1, P2, and P3 are colinear and P3 is further from P1 than P2 is from\n // P1 in the same direction then P2 is on the straight line between P1 and\n // P3\n\n if (dx1 * dy2 == dy1 * dx2 && (dx1 < 0 && dx2 < dx1 || dx1 == dx2 || dx1 > 0 && dx2 > dx1) && (dy1 < 0 && dy2 < dy1 || dy1 == dy2 || dy1 > 0 && dy2 > dy1)) {\n // discard P2 and set P2 = P3\n x2 = x3;\n y2 = y3;\n continue;\n } // either P1, P2, and P3 are not colinear, or they are colinear but P3 is\n // between P3 and P1 or on the opposite half of the line to P2. add P2,\n // and continue with P1 = P2 and P2 = P3\n\n\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n x1 = x2;\n y1 = y2;\n x2 = x3;\n y2 = y3;\n } // add the last point (P2)\n\n\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<number>} simplifiedEnds Simplified ends.\n * @return {number} Simplified offset.\n */\n\nfunction quantizeArray(flatCoordinates, offset, ends, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n simplifiedOffset = quantize(flatCoordinates, offset, end, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset);\n simplifiedEnds.push(simplifiedOffset);\n offset = end;\n }\n\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<Array<number>>} simplifiedEndss Simplified endss.\n * @return {number} Simplified offset.\n */\n\nfunction quantizeMultiArray(flatCoordinates, offset, endss, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEndss) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n var simplifiedEnds = [];\n simplifiedOffset = quantizeArray(flatCoordinates, offset, ends, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds);\n simplifiedEndss.push(simplifiedEnds);\n offset = ends[ends.length - 1];\n }\n\n return simplifiedOffset;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/inflate.js\n/**\n * @module ol/geom/flat/inflate\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {Array<import("../../coordinate.js").Coordinate>=} opt_coordinates Coordinates.\n * @return {Array<import("../../coordinate.js").Coordinate>} Coordinates.\n */\nfunction inflateCoordinates(flatCoordinates, offset, end, stride, opt_coordinates) {\n var coordinates = opt_coordinates !== undefined ? opt_coordinates : [];\n var i = 0;\n\n for (var j = offset; j < end; j += stride) {\n coordinates[i++] = flatCoordinates.slice(j, j + stride);\n }\n\n coordinates.length = i;\n return coordinates;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array<Array<import("../../coordinate.js").Coordinate>>=} opt_coordinatess Coordinatess.\n * @return {Array<Array<import("../../coordinate.js").Coordinate>>} Coordinatess.\n */\n\nfunction inflateCoordinatesArray(flatCoordinates, offset, ends, stride, opt_coordinatess) {\n var coordinatess = opt_coordinatess !== undefined ? opt_coordinatess : [];\n var i = 0;\n\n for (var j = 0, jj = ends.length; j < jj; ++j) {\n var end = ends[j];\n coordinatess[i++] = inflateCoordinates(flatCoordinates, offset, end, stride, coordinatess[i]);\n offset = end;\n }\n\n coordinatess.length = i;\n return coordinatess;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {Array<Array<Array<import("../../coordinate.js").Coordinate>>>=} opt_coordinatesss\n * Coordinatesss.\n * @return {Array<Array<Array<import("../../coordinate.js").Coordinate>>>} Coordinatesss.\n */\n\nfunction inflateMultiCoordinatesArray(flatCoordinates, offset, endss, stride, opt_coordinatesss) {\n var coordinatesss = opt_coordinatesss !== undefined ? opt_coordinatesss : [];\n var i = 0;\n\n for (var j = 0, jj = endss.length; j < jj; ++j) {\n var ends = endss[j];\n coordinatesss[i++] = inflateCoordinatesArray(flatCoordinates, offset, ends, stride, coordinatesss[i]);\n offset = ends[ends.length - 1];\n }\n\n coordinatesss.length = i;\n return coordinatesss;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/area.js\n/**\n * @module ol/geom/flat/area\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\nfunction linearRing(flatCoordinates, offset, end, stride) {\n var twiceArea = 0;\n var x1 = flatCoordinates[end - stride];\n var y1 = flatCoordinates[end - stride + 1];\n\n for (; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n twiceArea += y1 * x2 - x1 * y2;\n x1 = x2;\n y1 = y2;\n }\n\n return twiceArea / 2;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\n\nfunction linearRings(flatCoordinates, offset, ends, stride) {\n var area = 0;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n area += linearRing(flatCoordinates, offset, end, stride);\n offset = end;\n }\n\n return area;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\n\nfunction linearRingss(flatCoordinates, offset, endss, stride) {\n var area = 0;\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n area += linearRings(flatCoordinates, offset, ends, stride);\n offset = ends[ends.length - 1];\n }\n\n return area;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/LinearRing.js\nvar LinearRing_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/LinearRing\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Linear ring geometry. Only used as part of polygon; cannot be rendered\n * on its own.\n *\n * @api\n */\n\nvar LinearRing =\n/** @class */\nfunction (_super) {\n LinearRing_extends(LinearRing, _super);\n /**\n * @param {Array<import("../coordinate.js").Coordinate>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n */\n\n\n function LinearRing(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {number}\n */\n\n\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDeltaRevision_ = -1;\n\n if (opt_layout !== undefined && !Array.isArray(coordinates[0])) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n } else {\n _this.setCoordinates(\n /** @type {Array<import("../coordinate.js").Coordinate>} */\n coordinates, opt_layout);\n }\n\n return _this;\n }\n /**\n * Make a complete copy of the geometry.\n * @return {!LinearRing} Clone.\n * @api\n */\n\n\n LinearRing.prototype.clone = function () {\n return new LinearRing(this.flatCoordinates.slice(), this.layout);\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n LinearRing.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(maxSquaredDelta(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n\n return assignClosestPoint(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * Return the area of the linear ring on projected plane.\n * @return {number} Area (on projected plane).\n * @api\n */\n\n\n LinearRing.prototype.getArea = function () {\n return linearRing(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * Return the coordinates of the linear ring.\n * @return {Array<import("../coordinate.js").Coordinate>} Coordinates.\n * @api\n */\n\n\n LinearRing.prototype.getCoordinates = function () {\n return inflateCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {LinearRing} Simplified LinearRing.\n * @protected\n */\n\n\n LinearRing.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n simplifiedFlatCoordinates.length = douglasPeucker(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n return new LinearRing(simplifiedFlatCoordinates, geom_GeometryLayout.XY);\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n LinearRing.prototype.getType = function () {\n return geom_GeometryType.LINEAR_RING;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n LinearRing.prototype.intersectsExtent = function (extent) {\n return false;\n };\n /**\n * Set the coordinates of the linear ring.\n * @param {!Array<import("../coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n LinearRing.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 1);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n this.flatCoordinates.length = deflateCoordinates(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n\n return LinearRing;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_LinearRing = (LinearRing);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/Point.js\nvar Point_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/Point\n */\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Point geometry.\n *\n * @api\n */\n\nvar Point =\n/** @class */\nfunction (_super) {\n Point_extends(Point, _super);\n /**\n * @param {import("../coordinate.js").Coordinate} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n */\n\n\n function Point(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n\n _this.setCoordinates(coordinates, opt_layout);\n\n return _this;\n }\n /**\n * Make a complete copy of the geometry.\n * @return {!Point} Clone.\n * @api\n */\n\n\n Point.prototype.clone = function () {\n var point = new Point(this.flatCoordinates.slice(), this.layout);\n point.applyProperties(this);\n return point;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n Point.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n var flatCoordinates = this.flatCoordinates;\n var squaredDistance = math_squaredDistance(x, y, flatCoordinates[0], flatCoordinates[1]);\n\n if (squaredDistance < minSquaredDistance) {\n var stride = this.stride;\n\n for (var i = 0; i < stride; ++i) {\n closestPoint[i] = flatCoordinates[i];\n }\n\n closestPoint.length = stride;\n return squaredDistance;\n } else {\n return minSquaredDistance;\n }\n };\n /**\n * Return the coordinate of the point.\n * @return {import("../coordinate.js").Coordinate} Coordinates.\n * @api\n */\n\n\n Point.prototype.getCoordinates = function () {\n return !this.flatCoordinates ? [] : this.flatCoordinates.slice();\n };\n /**\n * @param {import("../extent.js").Extent} extent Extent.\n * @protected\n * @return {import("../extent.js").Extent} extent Extent.\n */\n\n\n Point.prototype.computeExtent = function (extent) {\n return createOrUpdateFromCoordinate(this.flatCoordinates, extent);\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n Point.prototype.getType = function () {\n return geom_GeometryType.POINT;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n Point.prototype.intersectsExtent = function (extent) {\n return containsXY(extent, this.flatCoordinates[0], this.flatCoordinates[1]);\n };\n /**\n * @param {!Array<*>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n Point.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 0);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n this.flatCoordinates.length = deflateCoordinate(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n\n return Point;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_Point = (Point);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/contains.js\n/**\n * @module ol/geom/flat/contains\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} Contains extent.\n */\n\nfunction linearRingContainsExtent(flatCoordinates, offset, end, stride, extent) {\n var outside = forEachCorner(extent,\n /**\n * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.\n * @return {boolean} Contains (x, y).\n */\n function (coordinate) {\n return !linearRingContainsXY(flatCoordinates, offset, end, stride, coordinate[0], coordinate[1]);\n });\n return !outside;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\nfunction linearRingContainsXY(flatCoordinates, offset, end, stride, x, y) {\n // http://geomalgorithms.com/a03-_inclusion.html\n // Copyright 2000 softSurfer, 2012 Dan Sunday\n // This code may be freely used and modified for any purpose\n // providing that this copyright notice is included with it.\n // SoftSurfer makes no warranty for this code, and cannot be held\n // liable for any real or imagined damage resulting from its use.\n // Users of this code must verify correctness for their application.\n var wn = 0;\n var x1 = flatCoordinates[end - stride];\n var y1 = flatCoordinates[end - stride + 1];\n\n for (; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n\n if (y1 <= y) {\n if (y2 > y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) > 0) {\n wn++;\n }\n } else if (y2 <= y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) < 0) {\n wn--;\n }\n\n x1 = x2;\n y1 = y2;\n }\n\n return wn !== 0;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\nfunction linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y) {\n if (ends.length === 0) {\n return false;\n }\n\n if (!linearRingContainsXY(flatCoordinates, offset, ends[0], stride, x, y)) {\n return false;\n }\n\n for (var i = 1, ii = ends.length; i < ii; ++i) {\n if (linearRingContainsXY(flatCoordinates, ends[i - 1], ends[i], stride, x, y)) {\n return false;\n }\n }\n\n return true;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\nfunction linearRingssContainsXY(flatCoordinates, offset, endss, stride, x, y) {\n if (endss.length === 0) {\n return false;\n }\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n\n if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {\n return true;\n }\n\n offset = ends[ends.length - 1];\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/interiorpoint.js\n/**\n * @module ol/geom/flat/interiorpoint\n */\n\n\n/**\n * Calculates a point that is likely to lie in the interior of the linear rings.\n * Inspired by JTS\'s com.vividsolutions.jts.geom.Geometry#getInteriorPoint.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array<number>} flatCenters Flat centers.\n * @param {number} flatCentersOffset Flat center offset.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Destination point as XYM coordinate, where M is the\n * length of the horizontal intersection that the point belongs to.\n */\n\nfunction getInteriorPointOfArray(flatCoordinates, offset, ends, stride, flatCenters, flatCentersOffset, opt_dest) {\n var i, ii, x, x1, x2, y1, y2;\n var y = flatCenters[flatCentersOffset + 1];\n /** @type {Array<number>} */\n\n var intersections = []; // Calculate intersections with the horizontal line\n\n for (var r = 0, rr = ends.length; r < rr; ++r) {\n var end = ends[r];\n x1 = flatCoordinates[end - stride];\n y1 = flatCoordinates[end - stride + 1];\n\n for (i = offset; i < end; i += stride) {\n x2 = flatCoordinates[i];\n y2 = flatCoordinates[i + 1];\n\n if (y <= y1 && y2 <= y || y1 <= y && y <= y2) {\n x = (y - y1) / (y2 - y1) * (x2 - x1) + x1;\n intersections.push(x);\n }\n\n x1 = x2;\n y1 = y2;\n }\n } // Find the longest segment of the horizontal line that has its center point\n // inside the linear ring.\n\n\n var pointX = NaN;\n var maxSegmentLength = -Infinity;\n intersections.sort(numberSafeCompareFunction);\n x1 = intersections[0];\n\n for (i = 1, ii = intersections.length; i < ii; ++i) {\n x2 = intersections[i];\n var segmentLength = Math.abs(x2 - x1);\n\n if (segmentLength > maxSegmentLength) {\n x = (x1 + x2) / 2;\n\n if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {\n pointX = x;\n maxSegmentLength = segmentLength;\n }\n }\n\n x1 = x2;\n }\n\n if (isNaN(pointX)) {\n // There is no horizontal line that has its center point inside the linear\n // ring. Use the center of the the linear ring\'s extent.\n pointX = flatCenters[flatCentersOffset];\n }\n\n if (opt_dest) {\n opt_dest.push(pointX, y, maxSegmentLength);\n return opt_dest;\n } else {\n return [pointX, y, maxSegmentLength];\n }\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {Array<number>} flatCenters Flat centers.\n * @return {Array<number>} Interior points as XYM coordinates, where M is the\n * length of the horizontal intersection that the point belongs to.\n */\n\nfunction getInteriorPointsOfMultiArray(flatCoordinates, offset, endss, stride, flatCenters) {\n var interiorPoints = [];\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n interiorPoints = getInteriorPointOfArray(flatCoordinates, offset, ends, stride, flatCenters, 2 * i, interiorPoints);\n offset = ends[ends.length - 1];\n }\n\n return interiorPoints;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/segments.js\n/**\n * @module ol/geom/flat/segments\n */\n\n/**\n * This function calls `callback` for each segment of the flat coordinates\n * array. If the callback returns a truthy value the function returns that\n * value immediately. Otherwise the function returns `false`.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {function(import("../../coordinate.js").Coordinate, import("../../coordinate.js").Coordinate): T} callback Function\n * called for each segment.\n * @return {T|boolean} Value.\n * @template T\n */\nfunction forEach(flatCoordinates, offset, end, stride, callback) {\n var point1 = [flatCoordinates[offset], flatCoordinates[offset + 1]];\n var point2 = [];\n var ret;\n\n for (; offset + stride < end; offset += stride) {\n point2[0] = flatCoordinates[offset + stride];\n point2[1] = flatCoordinates[offset + stride + 1];\n ret = callback(point1, point2);\n\n if (ret) {\n return ret;\n }\n\n point1[0] = point2[0];\n point1[1] = point2[1];\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/intersectsextent.js\n/**\n * @module ol/geom/flat/intersectsextent\n */\n\n\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\n\nfunction intersectsLineString(flatCoordinates, offset, end, stride, extent) {\n var coordinatesExtent = extendFlatCoordinates(createEmpty(), flatCoordinates, offset, end, stride);\n\n if (!intersects(extent, coordinatesExtent)) {\n return false;\n }\n\n if (containsExtent(extent, coordinatesExtent)) {\n return true;\n }\n\n if (coordinatesExtent[0] >= extent[0] && coordinatesExtent[2] <= extent[2]) {\n return true;\n }\n\n if (coordinatesExtent[1] >= extent[1] && coordinatesExtent[3] <= extent[3]) {\n return true;\n }\n\n return forEach(flatCoordinates, offset, end, stride,\n /**\n * @param {import("../../coordinate.js").Coordinate} point1 Start point.\n * @param {import("../../coordinate.js").Coordinate} point2 End point.\n * @return {boolean} `true` if the segment and the extent intersect,\n * `false` otherwise.\n */\n function (point1, point2) {\n return intersectsSegment(extent, point1, point2);\n });\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\n\nfunction intersectsLineStringArray(flatCoordinates, offset, ends, stride, extent) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n if (intersectsLineString(flatCoordinates, offset, ends[i], stride, extent)) {\n return true;\n }\n\n offset = ends[i];\n }\n\n return false;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\n\nfunction intersectsLinearRing(flatCoordinates, offset, end, stride, extent) {\n if (intersectsLineString(flatCoordinates, offset, end, stride, extent)) {\n return true;\n }\n\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[0], extent[1])) {\n return true;\n }\n\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[0], extent[3])) {\n return true;\n }\n\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[2], extent[1])) {\n return true;\n }\n\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[2], extent[3])) {\n return true;\n }\n\n return false;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\n\nfunction intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent) {\n if (!intersectsLinearRing(flatCoordinates, offset, ends[0], stride, extent)) {\n return false;\n }\n\n if (ends.length === 1) {\n return true;\n }\n\n for (var i = 1, ii = ends.length; i < ii; ++i) {\n if (linearRingContainsExtent(flatCoordinates, ends[i - 1], ends[i], stride, extent)) {\n if (!intersectsLineString(flatCoordinates, ends[i - 1], ends[i], stride, extent)) {\n return false;\n }\n }\n }\n\n return true;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\n\nfunction intersectsLinearRingMultiArray(flatCoordinates, offset, endss, stride, extent) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n\n if (intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent)) {\n return true;\n }\n\n offset = ends[ends.length - 1];\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/reverse.js\n/**\n * @module ol/geom/flat/reverse\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n */\nfunction coordinates(flatCoordinates, offset, end, stride) {\n while (offset < end - stride) {\n for (var i = 0; i < stride; ++i) {\n var tmp = flatCoordinates[offset + i];\n flatCoordinates[offset + i] = flatCoordinates[end - stride + i];\n flatCoordinates[end - stride + i] = tmp;\n }\n\n offset += stride;\n end -= stride;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/orient.js\n/**\n * @module ol/geom/flat/orient\n */\n\n/**\n * Is the linear ring oriented clockwise in a coordinate system with a bottom-left\n * coordinate origin? For a coordinate system with a top-left coordinate origin,\n * the ring\'s orientation is clockwise when this function returns false.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {boolean} Is clockwise.\n */\n\nfunction linearRingIsClockwise(flatCoordinates, offset, end, stride) {\n // http://tinyurl.com/clockwise-method\n // https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp\n var edge = 0;\n var x1 = flatCoordinates[end - stride];\n var y1 = flatCoordinates[end - stride + 1];\n\n for (; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n edge += (x2 - x1) * (y2 + y1);\n x1 = x2;\n y1 = y2;\n }\n\n return edge === 0 ? undefined : edge > 0;\n}\n/**\n * Determines if linear rings are oriented. By default, left-hand orientation\n * is tested (first ring must be clockwise, remaining rings counter-clockwise).\n * To test for right-hand orientation, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Test for right-hand orientation\n * (counter-clockwise exterior ring and clockwise interior rings).\n * @return {boolean} Rings are correctly oriented.\n */\n\nfunction linearRingsAreOriented(flatCoordinates, offset, ends, stride, opt_right) {\n var right = opt_right !== undefined ? opt_right : false;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var isClockwise = linearRingIsClockwise(flatCoordinates, offset, end, stride);\n\n if (i === 0) {\n if (right && isClockwise || !right && !isClockwise) {\n return false;\n }\n } else {\n if (right && !isClockwise || !right && isClockwise) {\n return false;\n }\n }\n\n offset = end;\n }\n\n return true;\n}\n/**\n * Determines if linear rings are oriented. By default, left-hand orientation\n * is tested (first ring must be clockwise, remaining rings counter-clockwise).\n * To test for right-hand orientation, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Array of array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Test for right-hand orientation\n * (counter-clockwise exterior ring and clockwise interior rings).\n * @return {boolean} Rings are correctly oriented.\n */\n\nfunction linearRingssAreOriented(flatCoordinates, offset, endss, stride, opt_right) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n\n if (!linearRingsAreOriented(flatCoordinates, offset, ends, stride, opt_right)) {\n return false;\n }\n\n if (ends.length) {\n offset = ends[ends.length - 1];\n }\n }\n\n return true;\n}\n/**\n * Orient coordinates in a flat array of linear rings. By default, rings\n * are oriented following the left-hand rule (clockwise for exterior and\n * counter-clockwise for interior rings). To orient according to the\n * right-hand rule, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Follow the right-hand rule for orientation.\n * @return {number} End.\n */\n\nfunction orientLinearRings(flatCoordinates, offset, ends, stride, opt_right) {\n var right = opt_right !== undefined ? opt_right : false;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var isClockwise = linearRingIsClockwise(flatCoordinates, offset, end, stride);\n var reverse = i === 0 ? right && isClockwise || !right && !isClockwise : right && !isClockwise || !right && isClockwise;\n\n if (reverse) {\n coordinates(flatCoordinates, offset, end, stride);\n }\n\n offset = end;\n }\n\n return offset;\n}\n/**\n * Orient coordinates in a flat array of linear rings. By default, rings\n * are oriented following the left-hand rule (clockwise for exterior and\n * counter-clockwise for interior rings). To orient according to the\n * right-hand rule, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Array of array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Follow the right-hand rule for orientation.\n * @return {number} End.\n */\n\nfunction orientLinearRingsArray(flatCoordinates, offset, endss, stride, opt_right) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n offset = orientLinearRings(flatCoordinates, offset, endss[i], stride, opt_right);\n }\n\n return offset;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/Polygon.js\nvar Polygon_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/Polygon\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Polygon geometry.\n *\n * @api\n */\n\nvar Polygon =\n/** @class */\nfunction (_super) {\n Polygon_extends(Polygon, _super);\n /**\n * @param {!Array<Array<import("../coordinate.js").Coordinate>>|!Array<number>} coordinates\n * Array of linear rings that define the polygon. The first linear ring of the\n * array defines the outer-boundary or surface of the polygon. Each subsequent\n * linear ring defines a hole in the surface of the polygon. A linear ring is\n * an array of vertices\' coordinates where the first coordinate and the last are\n * equivalent. (For internal use, flat coordinates in combination with\n * `opt_layout` and `opt_ends` are also accepted.)\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @param {Array<number>=} opt_ends Ends (for internal use with flat coordinates).\n */\n\n\n function Polygon(coordinates, opt_layout, opt_ends) {\n var _this = _super.call(this) || this;\n /**\n * @type {Array<number>}\n * @private\n */\n\n\n _this.ends_ = [];\n /**\n * @private\n * @type {number}\n */\n\n _this.flatInteriorPointRevision_ = -1;\n /**\n * @private\n * @type {import("../coordinate.js").Coordinate}\n */\n\n _this.flatInteriorPoint_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDeltaRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.orientedRevision_ = -1;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.orientedFlatCoordinates_ = null;\n\n if (opt_layout !== undefined && opt_ends) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n\n _this.ends_ = opt_ends;\n } else {\n _this.setCoordinates(\n /** @type {Array<Array<import("../coordinate.js").Coordinate>>} */\n coordinates, opt_layout);\n }\n\n return _this;\n }\n /**\n * Append the passed linear ring to this polygon.\n * @param {LinearRing} linearRing Linear ring.\n * @api\n */\n\n\n Polygon.prototype.appendLinearRing = function (linearRing) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = linearRing.getFlatCoordinates().slice();\n } else {\n array_extend(this.flatCoordinates, linearRing.getFlatCoordinates());\n }\n\n this.ends_.push(this.flatCoordinates.length);\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!Polygon} Clone.\n * @api\n */\n\n\n Polygon.prototype.clone = function () {\n var polygon = new Polygon(this.flatCoordinates.slice(), this.layout, this.ends_.slice());\n polygon.applyProperties(this);\n return polygon;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n Polygon.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(arrayMaxSquaredDelta(this.flatCoordinates, 0, this.ends_, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n\n return assignClosestArrayPoint(this.flatCoordinates, 0, this.ends_, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\n\n Polygon.prototype.containsXY = function (x, y) {\n return linearRingsContainsXY(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, x, y);\n };\n /**\n * Return the area of the polygon on projected plane.\n * @return {number} Area (on projected plane).\n * @api\n */\n\n\n Polygon.prototype.getArea = function () {\n return linearRings(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride);\n };\n /**\n * Get the coordinate array for this geometry. This array has the structure\n * of a GeoJSON coordinate array for polygons.\n *\n * @param {boolean=} opt_right Orient coordinates according to the right-hand\n * rule (counter-clockwise for exterior and clockwise for interior rings).\n * If `false`, coordinates will be oriented according to the left-hand rule\n * (clockwise for exterior and counter-clockwise for interior rings).\n * By default, coordinate orientation will depend on how the geometry was\n * constructed.\n * @return {Array<Array<import("../coordinate.js").Coordinate>>} Coordinates.\n * @api\n */\n\n\n Polygon.prototype.getCoordinates = function (opt_right) {\n var flatCoordinates;\n\n if (opt_right !== undefined) {\n flatCoordinates = this.getOrientedFlatCoordinates().slice();\n orientLinearRings(flatCoordinates, 0, this.ends_, this.stride, opt_right);\n } else {\n flatCoordinates = this.flatCoordinates;\n }\n\n return inflateCoordinatesArray(flatCoordinates, 0, this.ends_, this.stride);\n };\n /**\n * @return {Array<number>} Ends.\n */\n\n\n Polygon.prototype.getEnds = function () {\n return this.ends_;\n };\n /**\n * @return {Array<number>} Interior point.\n */\n\n\n Polygon.prototype.getFlatInteriorPoint = function () {\n if (this.flatInteriorPointRevision_ != this.getRevision()) {\n var flatCenter = getCenter(this.getExtent());\n this.flatInteriorPoint_ = getInteriorPointOfArray(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, flatCenter, 0);\n this.flatInteriorPointRevision_ = this.getRevision();\n }\n\n return this.flatInteriorPoint_;\n };\n /**\n * Return an interior point of the polygon.\n * @return {Point} Interior point as XYM coordinate, where M is the\n * length of the horizontal intersection that the point belongs to.\n * @api\n */\n\n\n Polygon.prototype.getInteriorPoint = function () {\n return new geom_Point(this.getFlatInteriorPoint(), geom_GeometryLayout.XYM);\n };\n /**\n * Return the number of rings of the polygon, this includes the exterior\n * ring and any interior rings.\n *\n * @return {number} Number of rings.\n * @api\n */\n\n\n Polygon.prototype.getLinearRingCount = function () {\n return this.ends_.length;\n };\n /**\n * Return the Nth linear ring of the polygon geometry. Return `null` if the\n * given index is out of range.\n * The exterior linear ring is available at index `0` and the interior rings\n * at index `1` and beyond.\n *\n * @param {number} index Index.\n * @return {LinearRing} Linear ring.\n * @api\n */\n\n\n Polygon.prototype.getLinearRing = function (index) {\n if (index < 0 || this.ends_.length <= index) {\n return null;\n }\n\n return new geom_LinearRing(this.flatCoordinates.slice(index === 0 ? 0 : this.ends_[index - 1], this.ends_[index]), this.layout);\n };\n /**\n * Return the linear rings of the polygon.\n * @return {Array<LinearRing>} Linear rings.\n * @api\n */\n\n\n Polygon.prototype.getLinearRings = function () {\n var layout = this.layout;\n var flatCoordinates = this.flatCoordinates;\n var ends = this.ends_;\n var linearRings = [];\n var offset = 0;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var linearRing = new geom_LinearRing(flatCoordinates.slice(offset, end), layout);\n linearRings.push(linearRing);\n offset = end;\n }\n\n return linearRings;\n };\n /**\n * @return {Array<number>} Oriented flat coordinates.\n */\n\n\n Polygon.prototype.getOrientedFlatCoordinates = function () {\n if (this.orientedRevision_ != this.getRevision()) {\n var flatCoordinates = this.flatCoordinates;\n\n if (linearRingsAreOriented(flatCoordinates, 0, this.ends_, this.stride)) {\n this.orientedFlatCoordinates_ = flatCoordinates;\n } else {\n this.orientedFlatCoordinates_ = flatCoordinates.slice();\n this.orientedFlatCoordinates_.length = orientLinearRings(this.orientedFlatCoordinates_, 0, this.ends_, this.stride);\n }\n\n this.orientedRevision_ = this.getRevision();\n }\n\n return this.orientedFlatCoordinates_;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Polygon} Simplified Polygon.\n * @protected\n */\n\n\n Polygon.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n var simplifiedEnds = [];\n simplifiedFlatCoordinates.length = quantizeArray(this.flatCoordinates, 0, this.ends_, this.stride, Math.sqrt(squaredTolerance), simplifiedFlatCoordinates, 0, simplifiedEnds);\n return new Polygon(simplifiedFlatCoordinates, geom_GeometryLayout.XY, simplifiedEnds);\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n Polygon.prototype.getType = function () {\n return geom_GeometryType.POLYGON;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n Polygon.prototype.intersectsExtent = function (extent) {\n return intersectsLinearRingArray(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, extent);\n };\n /**\n * Set the coordinates of the polygon.\n * @param {!Array<Array<import("../coordinate.js").Coordinate>>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n Polygon.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 2);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n var ends = deflateCoordinatesArray(this.flatCoordinates, 0, coordinates, this.stride, this.ends_);\n this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];\n this.changed();\n };\n\n return Polygon;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_Polygon = (Polygon);\n/**\n * Create an approximation of a circle on the surface of a sphere.\n * @param {import("../coordinate.js").Coordinate} center Center (`[lon, lat]` in degrees).\n * @param {number} radius The great-circle distance from the center to\n * the polygon vertices.\n * @param {number=} opt_n Optional number of vertices for the resulting\n * polygon. Default is `32`.\n * @param {number=} opt_sphereRadius Optional radius for the sphere (defaults to\n * the Earth\'s mean radius using the WGS84 ellipsoid).\n * @return {Polygon} The "circular" polygon.\n * @api\n */\n\nfunction circular(center, radius, opt_n, opt_sphereRadius) {\n var n = opt_n ? opt_n : 32;\n /** @type {Array<number>} */\n\n var flatCoordinates = [];\n\n for (var i = 0; i < n; ++i) {\n extend(flatCoordinates, sphereOffset(center, radius, 2 * Math.PI * i / n, opt_sphereRadius));\n }\n\n flatCoordinates.push(flatCoordinates[0], flatCoordinates[1]);\n return new Polygon(flatCoordinates, GeometryLayout.XY, [flatCoordinates.length]);\n}\n/**\n * Create a polygon from an extent. The layout used is `XY`.\n * @param {import("../extent.js").Extent} extent The extent.\n * @return {Polygon} The polygon.\n * @api\n */\n\nfunction fromExtent(extent) {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var flatCoordinates = [minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY];\n return new Polygon(flatCoordinates, geom_GeometryLayout.XY, [flatCoordinates.length]);\n}\n/**\n * Create a regular polygon from a circle.\n * @param {import("./Circle.js").default} circle Circle geometry.\n * @param {number=} opt_sides Number of sides of the polygon. Default is 32.\n * @param {number=} opt_angle Start angle for the first vertex of the polygon in\n * counter-clockwise radians. 0 means East. Default is 0.\n * @return {Polygon} Polygon geometry.\n * @api\n */\n\nfunction fromCircle(circle, opt_sides, opt_angle) {\n var sides = opt_sides ? opt_sides : 32;\n var stride = circle.getStride();\n var layout = circle.getLayout();\n var center = circle.getCenter();\n var arrayLength = stride * (sides + 1);\n var flatCoordinates = new Array(arrayLength);\n\n for (var i = 0; i < arrayLength; i += stride) {\n flatCoordinates[i] = 0;\n flatCoordinates[i + 1] = 0;\n\n for (var j = 2; j < stride; j++) {\n flatCoordinates[i + j] = center[j];\n }\n }\n\n var ends = [flatCoordinates.length];\n var polygon = new Polygon(flatCoordinates, layout, ends);\n makeRegular(polygon, center, circle.getRadius(), opt_angle);\n return polygon;\n}\n/**\n * Modify the coordinates of a polygon to make it a regular polygon.\n * @param {Polygon} polygon Polygon geometry.\n * @param {import("../coordinate.js").Coordinate} center Center of the regular polygon.\n * @param {number} radius Radius of the regular polygon.\n * @param {number=} opt_angle Start angle for the first vertex of the polygon in\n * counter-clockwise radians. 0 means East. Default is 0.\n */\n\nfunction makeRegular(polygon, center, radius, opt_angle) {\n var flatCoordinates = polygon.getFlatCoordinates();\n var stride = polygon.getStride();\n var sides = flatCoordinates.length / stride - 1;\n var startAngle = opt_angle ? opt_angle : 0;\n\n for (var i = 0; i <= sides; ++i) {\n var offset = i * stride;\n var angle = startAngle + modulo(i, sides) * 2 * Math.PI / sides;\n flatCoordinates[offset] = center[0] + radius * Math.cos(angle);\n flatCoordinates[offset + 1] = center[1] + radius * Math.sin(angle);\n }\n\n polygon.changed();\n}\n;// CONCATENATED MODULE: ./node_modules/ol/View.js\nvar View_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/View\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * An animation configuration\n *\n * @typedef {Object} Animation\n * @property {import("./coordinate.js").Coordinate} [sourceCenter]\n * @property {import("./coordinate.js").Coordinate} [targetCenter]\n * @property {number} [sourceResolution]\n * @property {number} [targetResolution]\n * @property {number} [sourceRotation]\n * @property {number} [targetRotation]\n * @property {import("./coordinate.js").Coordinate} [anchor]\n * @property {number} start\n * @property {number} duration\n * @property {boolean} complete\n * @property {function(number):number} easing\n * @property {function(boolean):void} callback\n */\n\n/**\n * @typedef {Object} Constraints\n * @property {import("./centerconstraint.js").Type} center\n * @property {import("./resolutionconstraint.js").Type} resolution\n * @property {import("./rotationconstraint.js").Type} rotation\n */\n\n/**\n * @typedef {Object} FitOptions\n * @property {import("./size.js").Size} [size] The size in pixels of the box to fit\n * the extent into. Default is the current size of the first map in the DOM that\n * uses this view, or `[100, 100]` if no such map is found.\n * @property {!Array<number>} [padding=[0, 0, 0, 0]] Padding (in pixels) to be\n * cleared inside the view. Values in the array are top, right, bottom and left\n * padding.\n * @property {boolean} [nearest=false] If the view `constrainResolution` option is `true`,\n * get the nearest extent instead of the closest that actually fits the view.\n * @property {number} [minResolution=0] Minimum resolution that we zoom to.\n * @property {number} [maxZoom] Maximum zoom level that we zoom to. If\n * `minResolution` is given, this property is ignored.\n * @property {number} [duration] The duration of the animation in milliseconds.\n * By default, there is no animation to the target extent.\n * @property {function(number):number} [easing] The easing function used during\n * the animation (defaults to {@link module:ol/easing~inAndOut}).\n * The function will be called for each frame with a number representing a\n * fraction of the animation\'s duration. The function should return a number\n * between 0 and 1 representing the progress toward the destination state.\n * @property {function(boolean):void} [callback] Function called when the view is in\n * its final position. The callback will be called with `true` if the animation\n * series completed on its own or `false` if it was cancelled.\n */\n\n/**\n * @typedef {Object} ViewOptions\n * @property {import("./coordinate.js").Coordinate} [center] The initial center for\n * the view. If a user projection is not set, the coordinate system for the center is\n * specified with the `projection` option. Layer sources will not be fetched if this\n * is not set, but the center can be set later with {@link #setCenter}.\n * @property {boolean|number} [constrainRotation=true] Rotation constraint.\n * `false` means no constraint. `true` means no constraint, but snap to zero\n * near zero. A number constrains the rotation to that number of values. For\n * example, `4` will constrain the rotation to 0, 90, 180, and 270 degrees.\n * @property {boolean} [enableRotation=true] Enable rotation.\n * If `false`, a rotation constraint that always sets the rotation to zero is\n * used. The `constrainRotation` option has no effect if `enableRotation` is\n * `false`.\n * @property {import("./extent.js").Extent} [extent] The extent that constrains the\n * view, in other words, nothing outside of this extent can be visible on the map.\n * @property {boolean} [constrainOnlyCenter=false] If true, the extent\n * constraint will only apply to the view center and not the whole extent.\n * @property {boolean} [smoothExtentConstraint=true] If true, the extent\n * constraint will be applied smoothly, i.e. allow the view to go slightly outside\n * of the given `extent`.\n * @property {number} [maxResolution] The maximum resolution used to determine\n * the resolution constraint. It is used together with `minResolution` (or\n * `maxZoom`) and `zoomFactor`. If unspecified it is calculated in such a way\n * that the projection\'s validity extent fits in a 256x256 px tile. If the\n * projection is Spherical Mercator (the default) then `maxResolution` defaults\n * to `40075016.68557849 / 256 = 156543.03392804097`.\n * @property {number} [minResolution] The minimum resolution used to determine\n * the resolution constraint. It is used together with `maxResolution` (or\n * `minZoom`) and `zoomFactor`. If unspecified it is calculated assuming 29\n * zoom levels (with a factor of 2). If the projection is Spherical Mercator\n * (the default) then `minResolution` defaults to\n * `40075016.68557849 / 256 / Math.pow(2, 28) = 0.0005831682455839253`.\n * @property {number} [maxZoom=28] The maximum zoom level used to determine the\n * resolution constraint. It is used together with `minZoom` (or\n * `maxResolution`) and `zoomFactor`. Note that if `minResolution` is also\n * provided, it is given precedence over `maxZoom`.\n * @property {number} [minZoom=0] The minimum zoom level used to determine the\n * resolution constraint. It is used together with `maxZoom` (or\n * `minResolution`) and `zoomFactor`. Note that if `maxResolution` is also\n * provided, it is given precedence over `minZoom`.\n * @property {boolean} [multiWorld=false] If `false` the view is constrained so\n * only one world is visible, and you cannot pan off the edge. If `true` the map\n * may show multiple worlds at low zoom levels. Only used if the `projection` is\n * global. Note that if `extent` is also provided it is given precedence.\n * @property {boolean} [constrainResolution=false] If true, the view will always\n * animate to the closest zoom level after an interaction; false means\n * intermediary zoom levels are allowed.\n * @property {boolean} [smoothResolutionConstraint=true] If true, the resolution\n * min/max values will be applied smoothly, i. e. allow the view to exceed slightly\n * the given resolution or zoom bounds.\n * @property {boolean} [showFullExtent=false] Allow the view to be zoomed out to\n * show the full configured extent. By default, when a view is configured with an\n * extent, users will not be able to zoom out so the viewport exceeds the extent in\n * either dimension. This means the full extent may not be visible if the viewport\n * is taller or wider than the aspect ratio of the configured extent. If\n * showFullExtent is true, the user will be able to zoom out so that the viewport\n * exceeds the height or width of the configured extent, but not both, allowing the\n * full extent to be shown.\n * @property {import("./proj.js").ProjectionLike} [projection=\'EPSG:3857\'] The\n * projection. The default is Spherical Mercator.\n * @property {number} [resolution] The initial resolution for the view. The\n * units are `projection` units per pixel (e.g. meters per pixel). An\n * alternative to setting this is to set `zoom`. Layer sources will not be\n * fetched if neither this nor `zoom` are defined, but they can be set later\n * with {@link #setZoom} or {@link #setResolution}.\n * @property {Array<number>} [resolutions] Resolutions to determine the\n * resolution constraint. If set the `maxResolution`, `minResolution`,\n * `minZoom`, `maxZoom`, and `zoomFactor` options are ignored.\n * @property {number} [rotation=0] The initial rotation for the view in radians\n * (positive rotation clockwise, 0 means North).\n * @property {number} [zoom] Only used if `resolution` is not defined. Zoom\n * level used to calculate the initial resolution for the view.\n * @property {number} [zoomFactor=2] The zoom factor used to compute the\n * corresponding resolution.\n * @property {!Array<number>} [padding=[0, 0, 0, 0]] Padding (in css pixels).\n * If the map viewport is partially covered with other content (overlays) along\n * its edges, this setting allows to shift the center of the viewport away from\n * that content. The order of the values is top, right, bottom, left.\n */\n\n/**\n * @typedef {Object} AnimationOptions\n * @property {import("./coordinate.js").Coordinate} [center] The center of the view at the end of\n * the animation.\n * @property {number} [zoom] The zoom level of the view at the end of the\n * animation. This takes precedence over `resolution`.\n * @property {number} [resolution] The resolution of the view at the end\n * of the animation. If `zoom` is also provided, this option will be ignored.\n * @property {number} [rotation] The rotation of the view at the end of\n * the animation.\n * @property {import("./coordinate.js").Coordinate} [anchor] Optional anchor to remain fixed\n * during a rotation or resolution animation.\n * @property {number} [duration=1000] The duration of the animation in milliseconds.\n * @property {function(number):number} [easing] The easing function used\n * during the animation (defaults to {@link module:ol/easing~inAndOut}).\n * The function will be called for each frame with a number representing a\n * fraction of the animation\'s duration. The function should return a number\n * between 0 and 1 representing the progress toward the destination state.\n */\n\n/**\n * @typedef {Object} State\n * @property {import("./coordinate.js").Coordinate} center\n * @property {import("./proj/Projection.js").default} projection\n * @property {number} resolution\n * @property {number} rotation\n * @property {number} zoom\n */\n\n/**\n * Default min zoom level for the map view.\n * @type {number}\n */\n\nvar DEFAULT_MIN_ZOOM = 0;\n/**\n * @classdesc\n * A View object represents a simple 2D view of the map.\n *\n * This is the object to act upon to change the center, resolution,\n * and rotation of the map.\n *\n * A View has a `projection`. The projection determines the\n * coordinate system of the center, and its units determine the units of the\n * resolution (projection units per pixel). The default projection is\n * Spherical Mercator (EPSG:3857).\n *\n * ### The view states\n *\n * A View is determined by three states: `center`, `resolution`,\n * and `rotation`. Each state has a corresponding getter and setter, e.g.\n * `getCenter` and `setCenter` for the `center` state.\n *\n * The `zoom` state is actually not saved on the view: all computations\n * internally use the `resolution` state. Still, the `setZoom` and `getZoom`\n * methods are available, as well as `getResolutionForZoom` and\n * `getZoomForResolution` to switch from one system to the other.\n *\n * ### The constraints\n *\n * `setCenter`, `setResolution` and `setRotation` can be used to change the\n * states of the view, but any constraint defined in the constructor will\n * be applied along the way.\n *\n * A View object can have a *resolution constraint*, a *rotation constraint*\n * and a *center constraint*.\n *\n * The *resolution constraint* typically restricts min/max values and\n * snaps to specific resolutions. It is determined by the following\n * options: `resolutions`, `maxResolution`, `maxZoom` and `zoomFactor`.\n * If `resolutions` is set, the other three options are ignored. See\n * documentation for each option for more information. By default, the view\n * only has a min/max restriction and allow intermediary zoom levels when\n * pinch-zooming for example.\n *\n * The *rotation constraint* snaps to specific angles. It is determined\n * by the following options: `enableRotation` and `constrainRotation`.\n * By default rotation is allowed and its value is snapped to zero when approaching the\n * horizontal.\n *\n * The *center constraint* is determined by the `extent` option. By\n * default the view center is not constrained at all.\n *\n * ### Changing the view state\n *\n * It is important to note that `setZoom`, `setResolution`, `setCenter` and\n * `setRotation` are subject to the above mentioned constraints. As such, it\n * may sometimes not be possible to know in advance the resulting state of the\n * View. For example, calling `setResolution(10)` does not guarantee that\n * `getResolution()` will return `10`.\n *\n * A consequence of this is that, when applying a delta on the view state, one\n * should use `adjustCenter`, `adjustRotation`, `adjustZoom` and `adjustResolution`\n * rather than the corresponding setters. This will let view do its internal\n * computations. Besides, the `adjust*` methods also take an `opt_anchor`\n * argument which allows specifying an origin for the transformation.\n *\n * ### Interacting with the view\n *\n * View constraints are usually only applied when the view is *at rest*, meaning that\n * no interaction or animation is ongoing. As such, if the user puts the view in a\n * state that is not equivalent to a constrained one (e.g. rotating the view when\n * the snap angle is 0), an animation will be triggered at the interaction end to\n * put back the view to a stable state;\n *\n * @api\n */\n\nvar View =\n/** @class */\nfunction (_super) {\n View_extends(View, _super);\n /**\n * @param {ViewOptions=} opt_options View options.\n */\n\n\n function View(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = obj_assign({}, opt_options);\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.hints_ = [0, 0];\n /**\n * @private\n * @type {Array<Array<Animation>>}\n */\n\n _this.animations_ = [];\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.updateAnimationKey_;\n /**\n * @private\n * @const\n * @type {import("./proj/Projection.js").default}\n */\n\n _this.projection_ = createProjection(options.projection, \'EPSG:3857\');\n /**\n * @private\n * @type {import("./size.js").Size}\n */\n\n _this.viewportSize_ = [100, 100];\n /**\n * @private\n * @type {import("./coordinate.js").Coordinate|undefined}\n */\n\n _this.targetCenter_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.targetResolution_;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.targetRotation_;\n /**\n * @private\n * @type {import("./coordinate.js").Coordinate|undefined}\n */\n\n _this.cancelAnchor_ = undefined;\n\n if (options.center) {\n options.center = fromUserCoordinate(options.center, _this.projection_);\n }\n\n if (options.extent) {\n options.extent = fromUserExtent(options.extent, _this.projection_);\n }\n\n _this.applyOptions_(options);\n\n return _this;\n }\n /**\n * Set up the view with the given options.\n * @param {ViewOptions} options View options.\n */\n\n\n View.prototype.applyOptions_ = function (options) {\n /**\n * @type {Object<string, *>}\n */\n var properties = {};\n var resolutionConstraintInfo = createResolutionConstraint(options);\n /**\n * @private\n * @type {number}\n */\n\n this.maxResolution_ = resolutionConstraintInfo.maxResolution;\n /**\n * @private\n * @type {number}\n */\n\n this.minResolution_ = resolutionConstraintInfo.minResolution;\n /**\n * @private\n * @type {number}\n */\n\n this.zoomFactor_ = resolutionConstraintInfo.zoomFactor;\n /**\n * @private\n * @type {Array<number>|undefined}\n */\n\n this.resolutions_ = options.resolutions;\n /**\n * Padding (in css pixels).\n * If the map viewport is partially covered with other content (overlays) along\n * its edges, this setting allows to shift the center of the viewport away from that\n * content. The order of the values in the array is top, right, bottom, left.\n * The default is no padding, which is equivalent to `[0, 0, 0, 0]`.\n * @type {Array<number>|undefined}\n * @api\n */\n\n this.padding = options.padding;\n /**\n * @private\n * @type {number}\n */\n\n this.minZoom_ = resolutionConstraintInfo.minZoom;\n var centerConstraint = createCenterConstraint(options);\n var resolutionConstraint = resolutionConstraintInfo.constraint;\n var rotationConstraint = createRotationConstraint(options);\n /**\n * @private\n * @type {Constraints}\n */\n\n this.constraints_ = {\n center: centerConstraint,\n resolution: resolutionConstraint,\n rotation: rotationConstraint\n };\n this.setRotation(options.rotation !== undefined ? options.rotation : 0);\n this.setCenterInternal(options.center !== undefined ? options.center : null);\n\n if (options.resolution !== undefined) {\n this.setResolution(options.resolution);\n } else if (options.zoom !== undefined) {\n this.setZoom(options.zoom);\n }\n\n this.setProperties(properties);\n /**\n * @private\n * @type {ViewOptions}\n */\n\n this.options_ = options;\n };\n /**\n * Get an updated version of the view options used to construct the view. The\n * current resolution (or zoom), center, and rotation are applied to any stored\n * options. The provided options can be used to apply new min/max zoom or\n * resolution limits.\n * @param {ViewOptions} newOptions New options to be applied.\n * @return {ViewOptions} New options updated with the current view state.\n */\n\n\n View.prototype.getUpdatedOptions_ = function (newOptions) {\n var options = obj_assign({}, this.options_); // preserve resolution (or zoom)\n\n if (options.resolution !== undefined) {\n options.resolution = this.getResolution();\n } else {\n options.zoom = this.getZoom();\n } // preserve center\n\n\n options.center = this.getCenterInternal(); // preserve rotation\n\n options.rotation = this.getRotation();\n return obj_assign({}, options, newOptions);\n };\n /**\n * Animate the view. The view\'s center, zoom (or resolution), and rotation\n * can be animated for smooth transitions between view states. For example,\n * to animate the view to a new zoom level:\n *\n * view.animate({zoom: view.getZoom() + 1});\n *\n * By default, the animation lasts one second and uses in-and-out easing. You\n * can customize this behavior by including `duration` (in milliseconds) and\n * `easing` options (see {@link module:ol/easing}).\n *\n * To chain together multiple animations, call the method with multiple\n * animation objects. For example, to first zoom and then pan:\n *\n * view.animate({zoom: 10}, {center: [0, 0]});\n *\n * If you provide a function as the last argument to the animate method, it\n * will get called at the end of an animation series. The callback will be\n * called with `true` if the animation series completed on its own or `false`\n * if it was cancelled.\n *\n * Animations are cancelled by user interactions (e.g. dragging the map) or by\n * calling `view.setCenter()`, `view.setResolution()`, or `view.setRotation()`\n * (or another method that calls one of these).\n *\n * @param {...(AnimationOptions|function(boolean): void)} var_args Animation\n * options. Multiple animations can be run in series by passing multiple\n * options objects. To run multiple animations in parallel, call the method\n * multiple times. An optional callback can be provided as a final\n * argument. The callback will be called with a boolean indicating whether\n * the animation completed without being cancelled.\n * @api\n */\n\n\n View.prototype.animate = function (var_args) {\n if (this.isDef() && !this.getAnimating()) {\n this.resolveConstraints(0);\n }\n\n var args = new Array(arguments.length);\n\n for (var i = 0; i < args.length; ++i) {\n var options = arguments[i];\n\n if (options.center) {\n options = obj_assign({}, options);\n options.center = fromUserCoordinate(options.center, this.getProjection());\n }\n\n if (options.anchor) {\n options = obj_assign({}, options);\n options.anchor = fromUserCoordinate(options.anchor, this.getProjection());\n }\n\n args[i] = options;\n }\n\n this.animateInternal.apply(this, args);\n };\n /**\n * @param {...(AnimationOptions|function(boolean): void)} var_args Animation options.\n */\n\n\n View.prototype.animateInternal = function (var_args) {\n var animationCount = arguments.length;\n var callback;\n\n if (animationCount > 1 && typeof arguments[animationCount - 1] === \'function\') {\n callback = arguments[animationCount - 1];\n --animationCount;\n }\n\n if (!this.isDef()) {\n // if view properties are not yet set, shortcut to the final state\n var state = arguments[animationCount - 1];\n\n if (state.center) {\n this.setCenterInternal(state.center);\n }\n\n if (state.zoom !== undefined) {\n this.setZoom(state.zoom);\n }\n\n if (state.rotation !== undefined) {\n this.setRotation(state.rotation);\n }\n\n if (callback) {\n animationCallback(callback, true);\n }\n\n return;\n }\n\n var start = Date.now();\n var center = this.targetCenter_.slice();\n var resolution = this.targetResolution_;\n var rotation = this.targetRotation_;\n var series = [];\n\n for (var i = 0; i < animationCount; ++i) {\n var options =\n /** @type {AnimationOptions} */\n arguments[i];\n var animation = {\n start: start,\n complete: false,\n anchor: options.anchor,\n duration: options.duration !== undefined ? options.duration : 1000,\n easing: options.easing || inAndOut,\n callback: callback\n };\n\n if (options.center) {\n animation.sourceCenter = center;\n animation.targetCenter = options.center.slice();\n center = animation.targetCenter;\n }\n\n if (options.zoom !== undefined) {\n animation.sourceResolution = resolution;\n animation.targetResolution = this.getResolutionForZoom(options.zoom);\n resolution = animation.targetResolution;\n } else if (options.resolution) {\n animation.sourceResolution = resolution;\n animation.targetResolution = options.resolution;\n resolution = animation.targetResolution;\n }\n\n if (options.rotation !== undefined) {\n animation.sourceRotation = rotation;\n var delta = math_modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) - Math.PI;\n animation.targetRotation = rotation + delta;\n rotation = animation.targetRotation;\n } // check if animation is a no-op\n\n\n if (isNoopAnimation(animation)) {\n animation.complete = true; // we still push it onto the series for callback handling\n } else {\n start += animation.duration;\n }\n\n series.push(animation);\n }\n\n this.animations_.push(series);\n this.setHint(ViewHint.ANIMATING, 1);\n this.updateAnimations_();\n };\n /**\n * Determine if the view is being animated.\n * @return {boolean} The view is being animated.\n * @api\n */\n\n\n View.prototype.getAnimating = function () {\n return this.hints_[ViewHint.ANIMATING] > 0;\n };\n /**\n * Determine if the user is interacting with the view, such as panning or zooming.\n * @return {boolean} The view is being interacted with.\n * @api\n */\n\n\n View.prototype.getInteracting = function () {\n return this.hints_[ViewHint.INTERACTING] > 0;\n };\n /**\n * Cancel any ongoing animations.\n * @api\n */\n\n\n View.prototype.cancelAnimations = function () {\n this.setHint(ViewHint.ANIMATING, -this.hints_[ViewHint.ANIMATING]);\n var anchor;\n\n for (var i = 0, ii = this.animations_.length; i < ii; ++i) {\n var series = this.animations_[i];\n\n if (series[0].callback) {\n animationCallback(series[0].callback, false);\n }\n\n if (!anchor) {\n for (var j = 0, jj = series.length; j < jj; ++j) {\n var animation = series[j];\n\n if (!animation.complete) {\n anchor = animation.anchor;\n break;\n }\n }\n }\n }\n\n this.animations_.length = 0;\n this.cancelAnchor_ = anchor;\n };\n /**\n * Update all animations.\n */\n\n\n View.prototype.updateAnimations_ = function () {\n if (this.updateAnimationKey_ !== undefined) {\n cancelAnimationFrame(this.updateAnimationKey_);\n this.updateAnimationKey_ = undefined;\n }\n\n if (!this.getAnimating()) {\n return;\n }\n\n var now = Date.now();\n var more = false;\n\n for (var i = this.animations_.length - 1; i >= 0; --i) {\n var series = this.animations_[i];\n var seriesComplete = true;\n\n for (var j = 0, jj = series.length; j < jj; ++j) {\n var animation = series[j];\n\n if (animation.complete) {\n continue;\n }\n\n var elapsed = now - animation.start;\n var fraction = animation.duration > 0 ? elapsed / animation.duration : 1;\n\n if (fraction >= 1) {\n animation.complete = true;\n fraction = 1;\n } else {\n seriesComplete = false;\n }\n\n var progress = animation.easing(fraction);\n\n if (animation.sourceCenter) {\n var x0 = animation.sourceCenter[0];\n var y0 = animation.sourceCenter[1];\n var x1 = animation.targetCenter[0];\n var y1 = animation.targetCenter[1];\n var x = x0 + progress * (x1 - x0);\n var y = y0 + progress * (y1 - y0);\n this.targetCenter_ = [x, y];\n }\n\n if (animation.sourceResolution && animation.targetResolution) {\n var resolution = progress === 1 ? animation.targetResolution : animation.sourceResolution + progress * (animation.targetResolution - animation.sourceResolution);\n\n if (animation.anchor) {\n var size = this.getViewportSize_(this.getRotation());\n var constrainedResolution = this.constraints_.resolution(resolution, 0, size, true);\n this.targetCenter_ = this.calculateCenterZoom(constrainedResolution, animation.anchor);\n }\n\n this.targetResolution_ = resolution;\n this.applyTargetState_(true);\n }\n\n if (animation.sourceRotation !== undefined && animation.targetRotation !== undefined) {\n var rotation = progress === 1 ? math_modulo(animation.targetRotation + Math.PI, 2 * Math.PI) - Math.PI : animation.sourceRotation + progress * (animation.targetRotation - animation.sourceRotation);\n\n if (animation.anchor) {\n var constrainedRotation = this.constraints_.rotation(rotation, true);\n this.targetCenter_ = this.calculateCenterRotate(constrainedRotation, animation.anchor);\n }\n\n this.targetRotation_ = rotation;\n }\n\n this.applyTargetState_(true);\n more = true;\n\n if (!animation.complete) {\n break;\n }\n }\n\n if (seriesComplete) {\n this.animations_[i] = null;\n this.setHint(ViewHint.ANIMATING, -1);\n var callback = series[0].callback;\n\n if (callback) {\n animationCallback(callback, true);\n }\n }\n } // prune completed series\n\n\n this.animations_ = this.animations_.filter(Boolean);\n\n if (more && this.updateAnimationKey_ === undefined) {\n this.updateAnimationKey_ = requestAnimationFrame(this.updateAnimations_.bind(this));\n }\n };\n /**\n * @param {number} rotation Target rotation.\n * @param {import("./coordinate.js").Coordinate} anchor Rotation anchor.\n * @return {import("./coordinate.js").Coordinate|undefined} Center for rotation and anchor.\n */\n\n\n View.prototype.calculateCenterRotate = function (rotation, anchor) {\n var center;\n var currentCenter = this.getCenterInternal();\n\n if (currentCenter !== undefined) {\n center = [currentCenter[0] - anchor[0], currentCenter[1] - anchor[1]];\n coordinate_rotate(center, rotation - this.getRotation());\n add(center, anchor);\n }\n\n return center;\n };\n /**\n * @param {number} resolution Target resolution.\n * @param {import("./coordinate.js").Coordinate} anchor Zoom anchor.\n * @return {import("./coordinate.js").Coordinate|undefined} Center for resolution and anchor.\n */\n\n\n View.prototype.calculateCenterZoom = function (resolution, anchor) {\n var center;\n var currentCenter = this.getCenterInternal();\n var currentResolution = this.getResolution();\n\n if (currentCenter !== undefined && currentResolution !== undefined) {\n var x = anchor[0] - resolution * (anchor[0] - currentCenter[0]) / currentResolution;\n var y = anchor[1] - resolution * (anchor[1] - currentCenter[1]) / currentResolution;\n center = [x, y];\n }\n\n return center;\n };\n /**\n * Returns the current viewport size.\n * @private\n * @param {number=} opt_rotation Take into account the rotation of the viewport when giving the size\n * @return {import("./size.js").Size} Viewport size or `[100, 100]` when no viewport is found.\n */\n\n\n View.prototype.getViewportSize_ = function (opt_rotation) {\n var size = this.viewportSize_;\n\n if (opt_rotation) {\n var w = size[0];\n var h = size[1];\n return [Math.abs(w * Math.cos(opt_rotation)) + Math.abs(h * Math.sin(opt_rotation)), Math.abs(w * Math.sin(opt_rotation)) + Math.abs(h * Math.cos(opt_rotation))];\n } else {\n return size;\n }\n };\n /**\n * Stores the viewport size on the view. The viewport size is not read every time from the DOM\n * to avoid performance hit and layout reflow.\n * This should be done on map size change.\n * Note: the constraints are not resolved during an animation to avoid stopping it\n * @param {import("./size.js").Size=} opt_size Viewport size; if undefined, [100, 100] is assumed\n */\n\n\n View.prototype.setViewportSize = function (opt_size) {\n this.viewportSize_ = Array.isArray(opt_size) ? opt_size.slice() : [100, 100];\n\n if (!this.getAnimating()) {\n this.resolveConstraints(0);\n }\n };\n /**\n * Get the view center.\n * @return {import("./coordinate.js").Coordinate|undefined} The center of the view.\n * @observable\n * @api\n */\n\n\n View.prototype.getCenter = function () {\n var center = this.getCenterInternal();\n\n if (!center) {\n return center;\n }\n\n return toUserCoordinate(center, this.getProjection());\n };\n /**\n * Get the view center without transforming to user projection.\n * @return {import("./coordinate.js").Coordinate|undefined} The center of the view.\n */\n\n\n View.prototype.getCenterInternal = function () {\n return (\n /** @type {import("./coordinate.js").Coordinate|undefined} */\n this.get(ViewProperty.CENTER)\n );\n };\n /**\n * @return {Constraints} Constraints.\n */\n\n\n View.prototype.getConstraints = function () {\n return this.constraints_;\n };\n /**\n * @return {boolean} Resolution constraint is set\n */\n\n\n View.prototype.getConstrainResolution = function () {\n return this.options_.constrainResolution;\n };\n /**\n * @param {Array<number>=} opt_hints Destination array.\n * @return {Array<number>} Hint.\n */\n\n\n View.prototype.getHints = function (opt_hints) {\n if (opt_hints !== undefined) {\n opt_hints[0] = this.hints_[0];\n opt_hints[1] = this.hints_[1];\n return opt_hints;\n } else {\n return this.hints_.slice();\n }\n };\n /**\n * Calculate the extent for the current view state and the passed size.\n * The size is the pixel dimensions of the box into which the calculated extent\n * should fit. In most cases you want to get the extent of the entire map,\n * that is `map.getSize()`.\n * @param {import("./size.js").Size=} opt_size Box pixel size. If not provided, the size\n * of the map that uses this view will be used.\n * @return {import("./extent.js").Extent} Extent.\n * @api\n */\n\n\n View.prototype.calculateExtent = function (opt_size) {\n var extent = this.calculateExtentInternal(opt_size);\n return toUserExtent(extent, this.getProjection());\n };\n /**\n * @param {import("./size.js").Size=} opt_size Box pixel size. If not provided,\n * the map\'s last known viewport size will be used.\n * @return {import("./extent.js").Extent} Extent.\n */\n\n\n View.prototype.calculateExtentInternal = function (opt_size) {\n var size = opt_size || this.getViewportSize_();\n var center =\n /** @type {!import("./coordinate.js").Coordinate} */\n this.getCenterInternal();\n asserts_assert(center, 1); // The view center is not defined\n\n var resolution =\n /** @type {!number} */\n this.getResolution();\n asserts_assert(resolution !== undefined, 2); // The view resolution is not defined\n\n var rotation =\n /** @type {!number} */\n this.getRotation();\n asserts_assert(rotation !== undefined, 3); // The view rotation is not defined\n\n return getForViewAndSize(center, resolution, rotation, size);\n };\n /**\n * Get the maximum resolution of the view.\n * @return {number} The maximum resolution of the view.\n * @api\n */\n\n\n View.prototype.getMaxResolution = function () {\n return this.maxResolution_;\n };\n /**\n * Get the minimum resolution of the view.\n * @return {number} The minimum resolution of the view.\n * @api\n */\n\n\n View.prototype.getMinResolution = function () {\n return this.minResolution_;\n };\n /**\n * Get the maximum zoom level for the view.\n * @return {number} The maximum zoom level.\n * @api\n */\n\n\n View.prototype.getMaxZoom = function () {\n return (\n /** @type {number} */\n this.getZoomForResolution(this.minResolution_)\n );\n };\n /**\n * Set a new maximum zoom level for the view.\n * @param {number} zoom The maximum zoom level.\n * @api\n */\n\n\n View.prototype.setMaxZoom = function (zoom) {\n this.applyOptions_(this.getUpdatedOptions_({\n maxZoom: zoom\n }));\n };\n /**\n * Get the minimum zoom level for the view.\n * @return {number} The minimum zoom level.\n * @api\n */\n\n\n View.prototype.getMinZoom = function () {\n return (\n /** @type {number} */\n this.getZoomForResolution(this.maxResolution_)\n );\n };\n /**\n * Set a new minimum zoom level for the view.\n * @param {number} zoom The minimum zoom level.\n * @api\n */\n\n\n View.prototype.setMinZoom = function (zoom) {\n this.applyOptions_(this.getUpdatedOptions_({\n minZoom: zoom\n }));\n };\n /**\n * Set whether the view shoud allow intermediary zoom levels.\n * @param {boolean} enabled Whether the resolution is constrained.\n * @api\n */\n\n\n View.prototype.setConstrainResolution = function (enabled) {\n this.applyOptions_(this.getUpdatedOptions_({\n constrainResolution: enabled\n }));\n };\n /**\n * Get the view projection.\n * @return {import("./proj/Projection.js").default} The projection of the view.\n * @api\n */\n\n\n View.prototype.getProjection = function () {\n return this.projection_;\n };\n /**\n * Get the view resolution.\n * @return {number|undefined} The resolution of the view.\n * @observable\n * @api\n */\n\n\n View.prototype.getResolution = function () {\n return (\n /** @type {number|undefined} */\n this.get(ViewProperty.RESOLUTION)\n );\n };\n /**\n * Get the resolutions for the view. This returns the array of resolutions\n * passed to the constructor of the View, or undefined if none were given.\n * @return {Array<number>|undefined} The resolutions of the view.\n * @api\n */\n\n\n View.prototype.getResolutions = function () {\n return this.resolutions_;\n };\n /**\n * Get the resolution for a provided extent (in map units) and size (in pixels).\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {import("./size.js").Size=} opt_size Box pixel size.\n * @return {number} The resolution at which the provided extent will render at\n * the given size.\n * @api\n */\n\n\n View.prototype.getResolutionForExtent = function (extent, opt_size) {\n return this.getResolutionForExtentInternal(fromUserExtent(extent, this.getProjection()), opt_size);\n };\n /**\n * Get the resolution for a provided extent (in map units) and size (in pixels).\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {import("./size.js").Size=} opt_size Box pixel size.\n * @return {number} The resolution at which the provided extent will render at\n * the given size.\n */\n\n\n View.prototype.getResolutionForExtentInternal = function (extent, opt_size) {\n var size = opt_size || this.getViewportSize_();\n var xResolution = extent_getWidth(extent) / size[0];\n var yResolution = getHeight(extent) / size[1];\n return Math.max(xResolution, yResolution);\n };\n /**\n * Return a function that returns a value between 0 and 1 for a\n * resolution. Exponential scaling is assumed.\n * @param {number=} opt_power Power.\n * @return {function(number): number} Resolution for value function.\n */\n\n\n View.prototype.getResolutionForValueFunction = function (opt_power) {\n var power = opt_power || 2;\n var maxResolution = this.getConstrainedResolution(this.maxResolution_);\n var minResolution = this.minResolution_;\n var max = Math.log(maxResolution / minResolution) / Math.log(power);\n return (\n /**\n * @param {number} value Value.\n * @return {number} Resolution.\n */\n function (value) {\n var resolution = maxResolution / Math.pow(power, value * max);\n return resolution;\n }\n );\n };\n /**\n * Get the view rotation.\n * @return {number} The rotation of the view in radians.\n * @observable\n * @api\n */\n\n\n View.prototype.getRotation = function () {\n return (\n /** @type {number} */\n this.get(ViewProperty.ROTATION)\n );\n };\n /**\n * Return a function that returns a resolution for a value between\n * 0 and 1. Exponential scaling is assumed.\n * @param {number=} opt_power Power.\n * @return {function(number): number} Value for resolution function.\n */\n\n\n View.prototype.getValueForResolutionFunction = function (opt_power) {\n var logPower = Math.log(opt_power || 2);\n var maxResolution = this.getConstrainedResolution(this.maxResolution_);\n var minResolution = this.minResolution_;\n var max = Math.log(maxResolution / minResolution) / logPower;\n return (\n /**\n * @param {number} resolution Resolution.\n * @return {number} Value.\n */\n function (resolution) {\n var value = Math.log(maxResolution / resolution) / logPower / max;\n return value;\n }\n );\n };\n /**\n * Returns the size of the viewport minus padding.\n * @private\n * @param {number=} opt_rotation Take into account the rotation of the viewport when giving the size\n * @return {import("./size.js").Size} Viewport size reduced by the padding.\n */\n\n\n View.prototype.getViewportSizeMinusPadding_ = function (opt_rotation) {\n var size = this.getViewportSize_(opt_rotation);\n var padding = this.padding;\n\n if (padding) {\n size = [size[0] - padding[1] - padding[3], size[1] - padding[0] - padding[2]];\n }\n\n return size;\n };\n /**\n * @return {State} View state.\n */\n\n\n View.prototype.getState = function () {\n var projection = this.getProjection();\n var resolution =\n /** @type {number} */\n this.getResolution();\n var rotation = this.getRotation();\n var center =\n /** @type {import("./coordinate.js").Coordinate} */\n this.getCenterInternal();\n var padding = this.padding;\n\n if (padding) {\n var reducedSize = this.getViewportSizeMinusPadding_();\n center = calculateCenterOn(center, this.getViewportSize_(), [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]], resolution, rotation);\n }\n\n return {\n center: center.slice(0),\n projection: projection !== undefined ? projection : null,\n resolution: resolution,\n rotation: rotation,\n zoom: this.getZoom()\n };\n };\n /**\n * Get the current zoom level. This method may return non-integer zoom levels\n * if the view does not constrain the resolution, or if an interaction or\n * animation is underway.\n * @return {number|undefined} Zoom.\n * @api\n */\n\n\n View.prototype.getZoom = function () {\n var zoom;\n var resolution = this.getResolution();\n\n if (resolution !== undefined) {\n zoom = this.getZoomForResolution(resolution);\n }\n\n return zoom;\n };\n /**\n * Get the zoom level for a resolution.\n * @param {number} resolution The resolution.\n * @return {number|undefined} The zoom level for the provided resolution.\n * @api\n */\n\n\n View.prototype.getZoomForResolution = function (resolution) {\n var offset = this.minZoom_ || 0;\n var max, zoomFactor;\n\n if (this.resolutions_) {\n var nearest = linearFindNearest(this.resolutions_, resolution, 1);\n offset = nearest;\n max = this.resolutions_[nearest];\n\n if (nearest == this.resolutions_.length - 1) {\n zoomFactor = 2;\n } else {\n zoomFactor = max / this.resolutions_[nearest + 1];\n }\n } else {\n max = this.maxResolution_;\n zoomFactor = this.zoomFactor_;\n }\n\n return offset + Math.log(max / resolution) / Math.log(zoomFactor);\n };\n /**\n * Get the resolution for a zoom level.\n * @param {number} zoom Zoom level.\n * @return {number} The view resolution for the provided zoom level.\n * @api\n */\n\n\n View.prototype.getResolutionForZoom = function (zoom) {\n if (this.resolutions_) {\n if (this.resolutions_.length <= 1) {\n return 0;\n }\n\n var baseLevel = math_clamp(Math.floor(zoom), 0, this.resolutions_.length - 2);\n var zoomFactor = this.resolutions_[baseLevel] / this.resolutions_[baseLevel + 1];\n return this.resolutions_[baseLevel] / Math.pow(zoomFactor, math_clamp(zoom - baseLevel, 0, 1));\n } else {\n return this.maxResolution_ / Math.pow(this.zoomFactor_, zoom - this.minZoom_);\n }\n };\n /**\n * Fit the given geometry or extent based on the given map size and border.\n * The size is pixel dimensions of the box to fit the extent into.\n * In most cases you will want to use the map size, that is `map.getSize()`.\n * Takes care of the map angle.\n * @param {import("./geom/SimpleGeometry.js").default|import("./extent.js").Extent} geometryOrExtent The geometry or\n * extent to fit the view to.\n * @param {FitOptions=} opt_options Options.\n * @api\n */\n\n\n View.prototype.fit = function (geometryOrExtent, opt_options) {\n /** @type {import("./geom/SimpleGeometry.js").default} */\n var geometry;\n asserts_assert(Array.isArray(geometryOrExtent) || typeof\n /** @type {?} */\n geometryOrExtent.getSimplifiedGeometry === \'function\', 24); // Invalid extent or geometry provided as `geometry`\n\n if (Array.isArray(geometryOrExtent)) {\n asserts_assert(!extent_isEmpty(geometryOrExtent), 25); // Cannot fit empty extent provided as `geometry`\n\n var extent = fromUserExtent(geometryOrExtent, this.getProjection());\n geometry = fromExtent(extent);\n } else if (geometryOrExtent.getType() === geom_GeometryType.CIRCLE) {\n var extent = fromUserExtent(geometryOrExtent.getExtent(), this.getProjection());\n geometry = fromExtent(extent);\n geometry.rotate(this.getRotation(), getCenter(extent));\n } else {\n var userProjection = getUserProjection();\n\n if (userProjection) {\n geometry =\n /** @type {import("./geom/SimpleGeometry.js").default} */\n geometryOrExtent.clone().transform(userProjection, this.getProjection());\n } else {\n geometry = geometryOrExtent;\n }\n }\n\n this.fitInternal(geometry, opt_options);\n };\n /**\n * @param {import("./geom/SimpleGeometry.js").default} geometry The geometry.\n * @param {FitOptions=} opt_options Options.\n */\n\n\n View.prototype.fitInternal = function (geometry, opt_options) {\n var options = opt_options || {};\n var size = options.size;\n\n if (!size) {\n size = this.getViewportSizeMinusPadding_();\n }\n\n var padding = options.padding !== undefined ? options.padding : [0, 0, 0, 0];\n var nearest = options.nearest !== undefined ? options.nearest : false;\n var minResolution;\n\n if (options.minResolution !== undefined) {\n minResolution = options.minResolution;\n } else if (options.maxZoom !== undefined) {\n minResolution = this.getResolutionForZoom(options.maxZoom);\n } else {\n minResolution = 0;\n }\n\n var coords = geometry.getFlatCoordinates(); // calculate rotated extent\n\n var rotation = this.getRotation();\n var cosAngle = Math.cos(-rotation);\n var sinAngle = Math.sin(-rotation);\n var minRotX = +Infinity;\n var minRotY = +Infinity;\n var maxRotX = -Infinity;\n var maxRotY = -Infinity;\n var stride = geometry.getStride();\n\n for (var i = 0, ii = coords.length; i < ii; i += stride) {\n var rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle;\n var rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle;\n minRotX = Math.min(minRotX, rotX);\n minRotY = Math.min(minRotY, rotY);\n maxRotX = Math.max(maxRotX, rotX);\n maxRotY = Math.max(maxRotY, rotY);\n } // calculate resolution\n\n\n var resolution = this.getResolutionForExtentInternal([minRotX, minRotY, maxRotX, maxRotY], [size[0] - padding[1] - padding[3], size[1] - padding[0] - padding[2]]);\n resolution = isNaN(resolution) ? minResolution : Math.max(resolution, minResolution);\n resolution = this.getConstrainedResolution(resolution, nearest ? 0 : 1); // calculate center\n\n sinAngle = -sinAngle; // go back to original rotation\n\n var centerRotX = (minRotX + maxRotX) / 2;\n var centerRotY = (minRotY + maxRotY) / 2;\n centerRotX += (padding[1] - padding[3]) / 2 * resolution;\n centerRotY += (padding[0] - padding[2]) / 2 * resolution;\n var centerX = centerRotX * cosAngle - centerRotY * sinAngle;\n var centerY = centerRotY * cosAngle + centerRotX * sinAngle;\n var center = this.getConstrainedCenter([centerX, centerY], resolution);\n var callback = options.callback ? options.callback : VOID;\n\n if (options.duration !== undefined) {\n this.animateInternal({\n resolution: resolution,\n center: center,\n duration: options.duration,\n easing: options.easing\n }, callback);\n } else {\n this.targetResolution_ = resolution;\n this.targetCenter_ = center;\n this.applyTargetState_(false, true);\n animationCallback(callback, true);\n }\n };\n /**\n * Center on coordinate and view position.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("./size.js").Size} size Box pixel size.\n * @param {import("./pixel.js").Pixel} position Position on the view to center on.\n * @api\n */\n\n\n View.prototype.centerOn = function (coordinate, size, position) {\n this.centerOnInternal(fromUserCoordinate(coordinate, this.getProjection()), size, position);\n };\n /**\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("./size.js").Size} size Box pixel size.\n * @param {import("./pixel.js").Pixel} position Position on the view to center on.\n */\n\n\n View.prototype.centerOnInternal = function (coordinate, size, position) {\n this.setCenterInternal(calculateCenterOn(coordinate, size, position, this.getResolution(), this.getRotation()));\n };\n /**\n * Calculates the shift between map and viewport center.\n * @param {import("./coordinate.js").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import("./size.js").Size} size Size.\n * @return {Array<number>|undefined} Center shift.\n */\n\n\n View.prototype.calculateCenterShift = function (center, resolution, rotation, size) {\n var centerShift;\n var padding = this.padding;\n\n if (padding && center) {\n var reducedSize = this.getViewportSizeMinusPadding_(-rotation);\n var shiftedCenter = calculateCenterOn(center, size, [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]], resolution, rotation);\n centerShift = [center[0] - shiftedCenter[0], center[1] - shiftedCenter[1]];\n }\n\n return centerShift;\n };\n /**\n * @return {boolean} Is defined.\n */\n\n\n View.prototype.isDef = function () {\n return !!this.getCenterInternal() && this.getResolution() !== undefined;\n };\n /**\n * Adds relative coordinates to the center of the view. Any extent constraint will apply.\n * @param {import("./coordinate.js").Coordinate} deltaCoordinates Relative value to add.\n * @api\n */\n\n\n View.prototype.adjustCenter = function (deltaCoordinates) {\n var center = toUserCoordinate(this.targetCenter_, this.getProjection());\n this.setCenter([center[0] + deltaCoordinates[0], center[1] + deltaCoordinates[1]]);\n };\n /**\n * Adds relative coordinates to the center of the view. Any extent constraint will apply.\n * @param {import("./coordinate.js").Coordinate} deltaCoordinates Relative value to add.\n */\n\n\n View.prototype.adjustCenterInternal = function (deltaCoordinates) {\n var center = this.targetCenter_;\n this.setCenterInternal([center[0] + deltaCoordinates[0], center[1] + deltaCoordinates[1]]);\n };\n /**\n * Multiply the view resolution by a ratio, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} ratio The ratio to apply on the view resolution.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n * @api\n */\n\n\n View.prototype.adjustResolution = function (ratio, opt_anchor) {\n var anchor = opt_anchor && fromUserCoordinate(opt_anchor, this.getProjection());\n this.adjustResolutionInternal(ratio, anchor);\n };\n /**\n * Multiply the view resolution by a ratio, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} ratio The ratio to apply on the view resolution.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n */\n\n\n View.prototype.adjustResolutionInternal = function (ratio, opt_anchor) {\n var isMoving = this.getAnimating() || this.getInteracting();\n var size = this.getViewportSize_(this.getRotation());\n var newResolution = this.constraints_.resolution(this.targetResolution_ * ratio, 0, size, isMoving);\n\n if (opt_anchor) {\n this.targetCenter_ = this.calculateCenterZoom(newResolution, opt_anchor);\n }\n\n this.targetResolution_ *= ratio;\n this.applyTargetState_();\n };\n /**\n * Adds a value to the view zoom level, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} delta Relative value to add to the zoom level.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n * @api\n */\n\n\n View.prototype.adjustZoom = function (delta, opt_anchor) {\n this.adjustResolution(Math.pow(this.zoomFactor_, -delta), opt_anchor);\n };\n /**\n * Adds a value to the view rotation, optionally using an anchor. Any rotation\n * constraint will apply.\n * @param {number} delta Relative value to add to the zoom rotation, in radians.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The rotation center.\n * @api\n */\n\n\n View.prototype.adjustRotation = function (delta, opt_anchor) {\n if (opt_anchor) {\n opt_anchor = fromUserCoordinate(opt_anchor, this.getProjection());\n }\n\n this.adjustRotationInternal(delta, opt_anchor);\n };\n /**\n * @param {number} delta Relative value to add to the zoom rotation, in radians.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The rotation center.\n */\n\n\n View.prototype.adjustRotationInternal = function (delta, opt_anchor) {\n var isMoving = this.getAnimating() || this.getInteracting();\n var newRotation = this.constraints_.rotation(this.targetRotation_ + delta, isMoving);\n\n if (opt_anchor) {\n this.targetCenter_ = this.calculateCenterRotate(newRotation, opt_anchor);\n }\n\n this.targetRotation_ += delta;\n this.applyTargetState_();\n };\n /**\n * Set the center of the current view. Any extent constraint will apply.\n * @param {import("./coordinate.js").Coordinate|undefined} center The center of the view.\n * @observable\n * @api\n */\n\n\n View.prototype.setCenter = function (center) {\n this.setCenterInternal(fromUserCoordinate(center, this.getProjection()));\n };\n /**\n * Set the center using the view projection (not the user projection).\n * @param {import("./coordinate.js").Coordinate|undefined} center The center of the view.\n */\n\n\n View.prototype.setCenterInternal = function (center) {\n this.targetCenter_ = center;\n this.applyTargetState_();\n };\n /**\n * @param {import("./ViewHint.js").default} hint Hint.\n * @param {number} delta Delta.\n * @return {number} New value.\n */\n\n\n View.prototype.setHint = function (hint, delta) {\n this.hints_[hint] += delta;\n this.changed();\n return this.hints_[hint];\n };\n /**\n * Set the resolution for this view. Any resolution constraint will apply.\n * @param {number|undefined} resolution The resolution of the view.\n * @observable\n * @api\n */\n\n\n View.prototype.setResolution = function (resolution) {\n this.targetResolution_ = resolution;\n this.applyTargetState_();\n };\n /**\n * Set the rotation for this view. Any rotation constraint will apply.\n * @param {number} rotation The rotation of the view in radians.\n * @observable\n * @api\n */\n\n\n View.prototype.setRotation = function (rotation) {\n this.targetRotation_ = rotation;\n this.applyTargetState_();\n };\n /**\n * Zoom to a specific zoom level. Any resolution constrain will apply.\n * @param {number} zoom Zoom level.\n * @api\n */\n\n\n View.prototype.setZoom = function (zoom) {\n this.setResolution(this.getResolutionForZoom(zoom));\n };\n /**\n * Recompute rotation/resolution/center based on target values.\n * Note: we have to compute rotation first, then resolution and center considering that\n * parameters can influence one another in case a view extent constraint is present.\n * @param {boolean=} opt_doNotCancelAnims Do not cancel animations.\n * @param {boolean=} opt_forceMoving Apply constraints as if the view is moving.\n * @private\n */\n\n\n View.prototype.applyTargetState_ = function (opt_doNotCancelAnims, opt_forceMoving) {\n var isMoving = this.getAnimating() || this.getInteracting() || opt_forceMoving; // compute rotation\n\n var newRotation = this.constraints_.rotation(this.targetRotation_, isMoving);\n var size = this.getViewportSize_(newRotation);\n var newResolution = this.constraints_.resolution(this.targetResolution_, 0, size, isMoving);\n var newCenter = this.constraints_.center(this.targetCenter_, newResolution, size, isMoving, this.calculateCenterShift(this.targetCenter_, newResolution, newRotation, size));\n\n if (this.get(ViewProperty.ROTATION) !== newRotation) {\n this.set(ViewProperty.ROTATION, newRotation);\n }\n\n if (this.get(ViewProperty.RESOLUTION) !== newResolution) {\n this.set(ViewProperty.RESOLUTION, newResolution);\n }\n\n if (!this.get(ViewProperty.CENTER) || !coordinate_equals(this.get(ViewProperty.CENTER), newCenter)) {\n this.set(ViewProperty.CENTER, newCenter);\n }\n\n if (this.getAnimating() && !opt_doNotCancelAnims) {\n this.cancelAnimations();\n }\n\n this.cancelAnchor_ = undefined;\n };\n /**\n * If any constraints need to be applied, an animation will be triggered.\n * This is typically done on interaction end.\n * Note: calling this with a duration of 0 will apply the constrained values straight away,\n * without animation.\n * @param {number=} opt_duration The animation duration in ms.\n * @param {number=} opt_resolutionDirection Which direction to zoom.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n */\n\n\n View.prototype.resolveConstraints = function (opt_duration, opt_resolutionDirection, opt_anchor) {\n var duration = opt_duration !== undefined ? opt_duration : 200;\n var direction = opt_resolutionDirection || 0;\n var newRotation = this.constraints_.rotation(this.targetRotation_);\n var size = this.getViewportSize_(newRotation);\n var newResolution = this.constraints_.resolution(this.targetResolution_, direction, size);\n var newCenter = this.constraints_.center(this.targetCenter_, newResolution, size, false, this.calculateCenterShift(this.targetCenter_, newResolution, newRotation, size));\n\n if (duration === 0 && !this.cancelAnchor_) {\n this.targetResolution_ = newResolution;\n this.targetRotation_ = newRotation;\n this.targetCenter_ = newCenter;\n this.applyTargetState_();\n return;\n }\n\n var anchor = opt_anchor || (duration === 0 ? this.cancelAnchor_ : undefined);\n this.cancelAnchor_ = undefined;\n\n if (this.getResolution() !== newResolution || this.getRotation() !== newRotation || !this.getCenterInternal() || !coordinate_equals(this.getCenterInternal(), newCenter)) {\n if (this.getAnimating()) {\n this.cancelAnimations();\n }\n\n this.animateInternal({\n rotation: newRotation,\n center: newCenter,\n resolution: newResolution,\n duration: duration,\n easing: easeOut,\n anchor: anchor\n });\n }\n };\n /**\n * Notify the View that an interaction has started.\n * The view state will be resolved to a stable one if needed\n * (depending on its constraints).\n * @api\n */\n\n\n View.prototype.beginInteraction = function () {\n this.resolveConstraints(0);\n this.setHint(ViewHint.INTERACTING, 1);\n };\n /**\n * Notify the View that an interaction has ended. The view state will be resolved\n * to a stable one if needed (depending on its constraints).\n * @param {number=} opt_duration Animation duration in ms.\n * @param {number=} opt_resolutionDirection Which direction to zoom.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n * @api\n */\n\n\n View.prototype.endInteraction = function (opt_duration, opt_resolutionDirection, opt_anchor) {\n var anchor = opt_anchor && fromUserCoordinate(opt_anchor, this.getProjection());\n this.endInteractionInternal(opt_duration, opt_resolutionDirection, anchor);\n };\n /**\n * Notify the View that an interaction has ended. The view state will be resolved\n * to a stable one if needed (depending on its constraints).\n * @param {number=} opt_duration Animation duration in ms.\n * @param {number=} opt_resolutionDirection Which direction to zoom.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n */\n\n\n View.prototype.endInteractionInternal = function (opt_duration, opt_resolutionDirection, opt_anchor) {\n this.setHint(ViewHint.INTERACTING, -1);\n this.resolveConstraints(opt_duration, opt_resolutionDirection, opt_anchor);\n };\n /**\n * Get a valid position for the view center according to the current constraints.\n * @param {import("./coordinate.js").Coordinate|undefined} targetCenter Target center position.\n * @param {number=} opt_targetResolution Target resolution. If not supplied, the current one will be used.\n * This is useful to guess a valid center position at a different zoom level.\n * @return {import("./coordinate.js").Coordinate|undefined} Valid center position.\n */\n\n\n View.prototype.getConstrainedCenter = function (targetCenter, opt_targetResolution) {\n var size = this.getViewportSize_(this.getRotation());\n return this.constraints_.center(targetCenter, opt_targetResolution || this.getResolution(), size);\n };\n /**\n * Get a valid zoom level according to the current view constraints.\n * @param {number|undefined} targetZoom Target zoom.\n * @param {number=} [opt_direction=0] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @return {number|undefined} Valid zoom level.\n */\n\n\n View.prototype.getConstrainedZoom = function (targetZoom, opt_direction) {\n var targetRes = this.getResolutionForZoom(targetZoom);\n return this.getZoomForResolution(this.getConstrainedResolution(targetRes, opt_direction));\n };\n /**\n * Get a valid resolution according to the current view constraints.\n * @param {number|undefined} targetResolution Target resolution.\n * @param {number=} [opt_direction=0] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @return {number|undefined} Valid resolution.\n */\n\n\n View.prototype.getConstrainedResolution = function (targetResolution, opt_direction) {\n var direction = opt_direction || 0;\n var size = this.getViewportSize_(this.getRotation());\n return this.constraints_.resolution(targetResolution, direction, size);\n };\n\n return View;\n}(ol_Object);\n/**\n * @param {Function} callback Callback.\n * @param {*} returnValue Return value.\n */\n\n\nfunction animationCallback(callback, returnValue) {\n setTimeout(function () {\n callback(returnValue);\n }, 0);\n}\n/**\n * @param {ViewOptions} options View options.\n * @return {import("./centerconstraint.js").Type} The constraint.\n */\n\n\nfunction createCenterConstraint(options) {\n if (options.extent !== undefined) {\n var smooth = options.smoothExtentConstraint !== undefined ? options.smoothExtentConstraint : true;\n return createExtent(options.extent, options.constrainOnlyCenter, smooth);\n }\n\n var projection = createProjection(options.projection, \'EPSG:3857\');\n\n if (options.multiWorld !== true && projection.isGlobal()) {\n var extent = projection.getExtent().slice();\n extent[0] = -Infinity;\n extent[2] = Infinity;\n return createExtent(extent, false, false);\n }\n\n return none;\n}\n/**\n * @param {ViewOptions} options View options.\n * @return {{constraint: import("./resolutionconstraint.js").Type, maxResolution: number,\n * minResolution: number, minZoom: number, zoomFactor: number}} The constraint.\n */\n\nfunction createResolutionConstraint(options) {\n var resolutionConstraint;\n var maxResolution;\n var minResolution; // TODO: move these to be ol constants\n // see https://github.com/openlayers/openlayers/issues/2076\n\n var defaultMaxZoom = 28;\n var defaultZoomFactor = 2;\n var minZoom = options.minZoom !== undefined ? options.minZoom : DEFAULT_MIN_ZOOM;\n var maxZoom = options.maxZoom !== undefined ? options.maxZoom : defaultMaxZoom;\n var zoomFactor = options.zoomFactor !== undefined ? options.zoomFactor : defaultZoomFactor;\n var multiWorld = options.multiWorld !== undefined ? options.multiWorld : false;\n var smooth = options.smoothResolutionConstraint !== undefined ? options.smoothResolutionConstraint : true;\n var showFullExtent = options.showFullExtent !== undefined ? options.showFullExtent : false;\n var projection = createProjection(options.projection, \'EPSG:3857\');\n var projExtent = projection.getExtent();\n var constrainOnlyCenter = options.constrainOnlyCenter;\n var extent = options.extent;\n\n if (!multiWorld && !extent && projection.isGlobal()) {\n constrainOnlyCenter = false;\n extent = projExtent;\n }\n\n if (options.resolutions !== undefined) {\n var resolutions = options.resolutions;\n maxResolution = resolutions[minZoom];\n minResolution = resolutions[maxZoom] !== undefined ? resolutions[maxZoom] : resolutions[resolutions.length - 1];\n\n if (options.constrainResolution) {\n resolutionConstraint = createSnapToResolutions(resolutions, smooth, !constrainOnlyCenter && extent, showFullExtent);\n } else {\n resolutionConstraint = createMinMaxResolution(maxResolution, minResolution, smooth, !constrainOnlyCenter && extent, showFullExtent);\n }\n } else {\n // calculate the default min and max resolution\n var size = !projExtent ? // use an extent that can fit the whole world if need be\n 360 * METERS_PER_UNIT[proj_Units.DEGREES] / projection.getMetersPerUnit() : Math.max(extent_getWidth(projExtent), getHeight(projExtent));\n var defaultMaxResolution = size / DEFAULT_TILE_SIZE / Math.pow(defaultZoomFactor, DEFAULT_MIN_ZOOM);\n var defaultMinResolution = defaultMaxResolution / Math.pow(defaultZoomFactor, defaultMaxZoom - DEFAULT_MIN_ZOOM); // user provided maxResolution takes precedence\n\n maxResolution = options.maxResolution;\n\n if (maxResolution !== undefined) {\n minZoom = 0;\n } else {\n maxResolution = defaultMaxResolution / Math.pow(zoomFactor, minZoom);\n } // user provided minResolution takes precedence\n\n\n minResolution = options.minResolution;\n\n if (minResolution === undefined) {\n if (options.maxZoom !== undefined) {\n if (options.maxResolution !== undefined) {\n minResolution = maxResolution / Math.pow(zoomFactor, maxZoom);\n } else {\n minResolution = defaultMaxResolution / Math.pow(zoomFactor, maxZoom);\n }\n } else {\n minResolution = defaultMinResolution;\n }\n } // given discrete zoom levels, minResolution may be different than provided\n\n\n maxZoom = minZoom + Math.floor(Math.log(maxResolution / minResolution) / Math.log(zoomFactor));\n minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom);\n\n if (options.constrainResolution) {\n resolutionConstraint = createSnapToPower(zoomFactor, maxResolution, minResolution, smooth, !constrainOnlyCenter && extent, showFullExtent);\n } else {\n resolutionConstraint = createMinMaxResolution(maxResolution, minResolution, smooth, !constrainOnlyCenter && extent, showFullExtent);\n }\n }\n\n return {\n constraint: resolutionConstraint,\n maxResolution: maxResolution,\n minResolution: minResolution,\n minZoom: minZoom,\n zoomFactor: zoomFactor\n };\n}\n/**\n * @param {ViewOptions} options View options.\n * @return {import("./rotationconstraint.js").Type} Rotation constraint.\n */\n\nfunction createRotationConstraint(options) {\n var enableRotation = options.enableRotation !== undefined ? options.enableRotation : true;\n\n if (enableRotation) {\n var constrainRotation = options.constrainRotation;\n\n if (constrainRotation === undefined || constrainRotation === true) {\n return createSnapToZero();\n } else if (constrainRotation === false) {\n return rotationconstraint_none;\n } else if (typeof constrainRotation === \'number\') {\n return createSnapToN(constrainRotation);\n } else {\n return rotationconstraint_none;\n }\n } else {\n return disable;\n }\n}\n/**\n * Determine if an animation involves no view change.\n * @param {Animation} animation The animation.\n * @return {boolean} The animation involves no view change.\n */\n\nfunction isNoopAnimation(animation) {\n if (animation.sourceCenter && animation.targetCenter) {\n if (!coordinate_equals(animation.sourceCenter, animation.targetCenter)) {\n return false;\n }\n }\n\n if (animation.sourceResolution !== animation.targetResolution) {\n return false;\n }\n\n if (animation.sourceRotation !== animation.targetRotation) {\n return false;\n }\n\n return true;\n}\n/**\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("./size.js").Size} size Box pixel size.\n * @param {import("./pixel.js").Pixel} position Position on the view to center on.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @return {import("./coordinate.js").Coordinate} Shifted center.\n */\n\nfunction calculateCenterOn(coordinate, size, position, resolution, rotation) {\n // calculate rotated position\n var cosAngle = Math.cos(-rotation);\n var sinAngle = Math.sin(-rotation);\n var rotX = coordinate[0] * cosAngle - coordinate[1] * sinAngle;\n var rotY = coordinate[1] * cosAngle + coordinate[0] * sinAngle;\n rotX += (size[0] / 2 - position[0]) * resolution;\n rotY += (position[1] - size[1] / 2) * resolution; // go back to original angle\n\n sinAngle = -sinAngle; // go back to original rotation\n\n var centerX = rotX * cosAngle - rotY * sinAngle;\n var centerY = rotY * cosAngle + rotX * sinAngle;\n return [centerX, centerY];\n}\n\n/* harmony default export */ var ol_View = (View);\n;// CONCATENATED MODULE: ./node_modules/ol/size.js\n/**\n * @module ol/size\n */\n\n/**\n * An array of numbers representing a size: `[width, height]`.\n * @typedef {Array<number>} Size\n * @api\n */\n\n/**\n * Returns a buffered size.\n * @param {Size} size Size.\n * @param {number} num The amount by which to buffer.\n * @param {Size=} opt_size Optional reusable size array.\n * @return {Size} The buffered size.\n */\nfunction size_buffer(size, num, opt_size) {\n if (opt_size === undefined) {\n opt_size = [0, 0];\n }\n\n opt_size[0] = size[0] + 2 * num;\n opt_size[1] = size[1] + 2 * num;\n return opt_size;\n}\n/**\n * Determines if a size has a positive area.\n * @param {Size} size The size to test.\n * @return {boolean} The size has a positive area.\n */\n\nfunction hasArea(size) {\n return size[0] > 0 && size[1] > 0;\n}\n/**\n * Returns a size scaled by a ratio. The result will be an array of integers.\n * @param {Size} size Size.\n * @param {number} ratio Ratio.\n * @param {Size=} opt_size Optional reusable size array.\n * @return {Size} The scaled size.\n */\n\nfunction size_scale(size, ratio, opt_size) {\n if (opt_size === undefined) {\n opt_size = [0, 0];\n }\n\n opt_size[0] = size[0] * ratio + 0.5 | 0;\n opt_size[1] = size[1] * ratio + 0.5 | 0;\n return opt_size;\n}\n/**\n * Returns an `Size` array for the passed in number (meaning: square) or\n * `Size` array.\n * (meaning: non-square),\n * @param {number|Size} size Width and height.\n * @param {Size=} opt_size Optional reusable size array.\n * @return {Size} Size.\n * @api\n */\n\nfunction toSize(size, opt_size) {\n if (Array.isArray(size)) {\n return size;\n } else {\n if (opt_size === undefined) {\n opt_size = [size, size];\n } else {\n opt_size[0] = size;\n opt_size[1] = size;\n }\n\n return opt_size;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/PluggableMap.js\nvar PluggableMap_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/PluggableMap\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * State of the current frame. Only `pixelRatio`, `time` and `viewState` should\n * be used in applications.\n * @typedef {Object} FrameState\n * @property {number} pixelRatio The pixel ratio of the frame.\n * @property {number} time The time when rendering of the frame was requested.\n * @property {import("./View.js").State} viewState The state of the current view.\n * @property {boolean} animate\n * @property {import("./transform.js").Transform} coordinateToPixelTransform\n * @property {import("rbush").default} declutterTree\n * @property {null|import("./extent.js").Extent} extent\n * @property {number} index\n * @property {Array<import("./layer/Layer.js").State>} layerStatesArray\n * @property {number} layerIndex\n * @property {import("./transform.js").Transform} pixelToCoordinateTransform\n * @property {Array<PostRenderFunction>} postRenderFunctions\n * @property {import("./size.js").Size} size\n * @property {TileQueue} tileQueue\n * @property {!Object<string, Object<string, boolean>>} usedTiles\n * @property {Array<number>} viewHints\n * @property {!Object<string, Object<string, boolean>>} wantedTiles\n */\n\n/**\n * @typedef {function(PluggableMap, ?FrameState): any} PostRenderFunction\n */\n\n/**\n * @typedef {Object} AtPixelOptions\n * @property {undefined|function(import("./layer/Layer.js").default): boolean} [layerFilter] Layer filter\n * function. The filter function will receive one argument, the\n * {@link module:ol/layer/Layer layer-candidate} and it should return a boolean value.\n * Only layers which are visible and for which this function returns `true`\n * will be tested for features. By default, all visible layers will be tested.\n * @property {number} [hitTolerance=0] Hit-detection tolerance in css pixels. Pixels\n * inside the radius around the given position will be checked for features.\n * @property {boolean} [checkWrapped=true] Check-Wrapped Will check for for wrapped geometries inside the range of\n * +/- 1 world width. Works only if a projection is used that can be wrapped.\n */\n\n/**\n * @typedef {Object} MapOptionsInternal\n * @property {Collection<import("./control/Control.js").default>} [controls]\n * @property {Collection<import("./interaction/Interaction.js").default>} [interactions]\n * @property {HTMLElement|Document} keyboardEventTarget\n * @property {Collection<import("./Overlay.js").default>} overlays\n * @property {Object<string, *>} values\n */\n\n/**\n * Object literal with config options for the map.\n * @typedef {Object} MapOptions\n * @property {Collection<import("./control/Control.js").default>|Array<import("./control/Control.js").default>} [controls]\n * Controls initially added to the map. If not specified,\n * {@link module:ol/control~defaults} is used.\n * @property {number} [pixelRatio=window.devicePixelRatio] The ratio between\n * physical pixels and device-independent pixels (dips) on the device.\n * @property {Collection<import("./interaction/Interaction.js").default>|Array<import("./interaction/Interaction.js").default>} [interactions]\n * Interactions that are initially added to the map. If not specified,\n * {@link module:ol/interaction~defaults} is used.\n * @property {HTMLElement|Document|string} [keyboardEventTarget] The element to\n * listen to keyboard events on. This determines when the `KeyboardPan` and\n * `KeyboardZoom` interactions trigger. For example, if this option is set to\n * `document` the keyboard interactions will always trigger. If this option is\n * not specified, the element the library listens to keyboard events on is the\n * map target (i.e. the user-provided div for the map). If this is not\n * `document`, the target element needs to be focused for key events to be\n * emitted, requiring that the target element has a `tabindex` attribute.\n * @property {Array<import("./layer/Base.js").default>|Collection<import("./layer/Base.js").default>|LayerGroup} [layers]\n * Layers. If this is not defined, a map with no layers will be rendered. Note\n * that layers are rendered in the order supplied, so if you want, for example,\n * a vector layer to appear on top of a tile layer, it must come after the tile\n * layer.\n * @property {number} [maxTilesLoading=16] Maximum number tiles to load\n * simultaneously.\n * @property {number} [moveTolerance=1] The minimum distance in pixels the\n * cursor must move to be detected as a map move event instead of a click.\n * Increasing this value can make it easier to click on the map.\n * @property {Collection<import("./Overlay.js").default>|Array<import("./Overlay.js").default>} [overlays]\n * Overlays initially added to the map. By default, no overlays are added.\n * @property {HTMLElement|string} [target] The container for the map, either the\n * element itself or the `id` of the element. If not specified at construction\n * time, {@link module:ol/Map~Map#setTarget} must be called for the map to be\n * rendered. If passed by element, the container can be in a secondary document.\n * @property {View} [view] The map\'s view. No layer sources will be\n * fetched unless this is specified at construction time or through\n * {@link module:ol/Map~Map#setView}.\n */\n\n/**\n * @fires import("./MapBrowserEvent.js").MapBrowserEvent\n * @fires import("./MapEvent.js").MapEvent\n * @fires import("./render/Event.js").default#precompose\n * @fires import("./render/Event.js").default#postcompose\n * @fires import("./render/Event.js").default#rendercomplete\n * @api\n */\n\nvar PluggableMap =\n/** @class */\nfunction (_super) {\n PluggableMap_extends(PluggableMap, _super);\n /**\n * @param {MapOptions} options Map options.\n */\n\n\n function PluggableMap(options) {\n var _this = _super.call(this) || this;\n\n var optionsInternal = createOptionsInternal(options);\n /** @private */\n\n _this.boundHandleBrowserEvent_ = _this.handleBrowserEvent.bind(_this);\n /**\n * @type {number}\n * @private\n */\n\n _this.maxTilesLoading_ = options.maxTilesLoading !== undefined ? options.maxTilesLoading : 16;\n /**\n * @private\n * @type {number}\n */\n\n _this.pixelRatio_ = options.pixelRatio !== undefined ? options.pixelRatio : DEVICE_PIXEL_RATIO;\n /**\n * @private\n * @type {*}\n */\n\n _this.postRenderTimeoutHandle_;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.animationDelayKey_;\n /**\n * @private\n */\n\n _this.animationDelay_ =\n /** @this {PluggableMap} */\n function () {\n this.animationDelayKey_ = undefined;\n this.renderFrame_(Date.now());\n }.bind(_this);\n /**\n * @private\n * @type {import("./transform.js").Transform}\n */\n\n\n _this.coordinateToPixelTransform_ = create();\n /**\n * @private\n * @type {import("./transform.js").Transform}\n */\n\n _this.pixelToCoordinateTransform_ = create();\n /**\n * @private\n * @type {number}\n */\n\n _this.frameIndex_ = 0;\n /**\n * @private\n * @type {?FrameState}\n */\n\n _this.frameState_ = null;\n /**\n * The extent at the previous \'moveend\' event.\n * @private\n * @type {import("./extent.js").Extent}\n */\n\n _this.previousExtent_ = null;\n /**\n * @private\n * @type {?import("./events.js").EventsKey}\n */\n\n _this.viewPropertyListenerKey_ = null;\n /**\n * @private\n * @type {?import("./events.js").EventsKey}\n */\n\n _this.viewChangeListenerKey_ = null;\n /**\n * @private\n * @type {?Array<import("./events.js").EventsKey>}\n */\n\n _this.layerGroupPropertyListenerKeys_ = null;\n /**\n * @private\n * @type {!HTMLElement}\n */\n\n _this.viewport_ = document.createElement(\'div\');\n _this.viewport_.className = \'ol-viewport\' + (\'ontouchstart\' in window ? \' ol-touch\' : \'\');\n _this.viewport_.style.position = \'relative\';\n _this.viewport_.style.overflow = \'hidden\';\n _this.viewport_.style.width = \'100%\';\n _this.viewport_.style.height = \'100%\';\n /**\n * @private\n * @type {!HTMLElement}\n */\n\n _this.overlayContainer_ = document.createElement(\'div\');\n _this.overlayContainer_.style.position = \'absolute\';\n _this.overlayContainer_.style.zIndex = \'0\';\n _this.overlayContainer_.style.width = \'100%\';\n _this.overlayContainer_.style.height = \'100%\';\n _this.overlayContainer_.style.pointerEvents = \'none\';\n _this.overlayContainer_.className = \'ol-overlaycontainer\';\n\n _this.viewport_.appendChild(_this.overlayContainer_);\n /**\n * @private\n * @type {!HTMLElement}\n */\n\n\n _this.overlayContainerStopEvent_ = document.createElement(\'div\');\n _this.overlayContainerStopEvent_.style.position = \'absolute\';\n _this.overlayContainerStopEvent_.style.zIndex = \'0\';\n _this.overlayContainerStopEvent_.style.width = \'100%\';\n _this.overlayContainerStopEvent_.style.height = \'100%\';\n _this.overlayContainerStopEvent_.style.pointerEvents = \'none\';\n _this.overlayContainerStopEvent_.className = \'ol-overlaycontainer-stopevent\';\n\n _this.viewport_.appendChild(_this.overlayContainerStopEvent_);\n /**\n * @private\n * @type {MapBrowserEventHandler}\n */\n\n\n _this.mapBrowserEventHandler_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.moveTolerance_ = options.moveTolerance;\n /**\n * @private\n * @type {HTMLElement|Document}\n */\n\n _this.keyboardEventTarget_ = optionsInternal.keyboardEventTarget;\n /**\n * @private\n * @type {?Array<import("./events.js").EventsKey>}\n */\n\n _this.keyHandlerKeys_ = null;\n /**\n * @type {Collection<import("./control/Control.js").default>}\n * @protected\n */\n\n _this.controls = optionsInternal.controls || new ol_Collection();\n /**\n * @type {Collection<import("./interaction/Interaction.js").default>}\n * @protected\n */\n\n _this.interactions = optionsInternal.interactions || new ol_Collection();\n /**\n * @type {Collection<import("./Overlay.js").default>}\n * @private\n */\n\n _this.overlays_ = optionsInternal.overlays;\n /**\n * A lookup of overlays by id.\n * @private\n * @type {Object<string, import("./Overlay.js").default>}\n */\n\n _this.overlayIdIndex_ = {};\n /**\n * @type {import("./renderer/Map.js").default}\n * @private\n */\n\n _this.renderer_ = null;\n /**\n * @type {undefined|function(Event): void}\n * @private\n */\n\n _this.handleResize_;\n /**\n * @private\n * @type {!Array<PostRenderFunction>}\n */\n\n _this.postRenderFunctions_ = [];\n /**\n * @private\n * @type {TileQueue}\n */\n\n _this.tileQueue_ = new ol_TileQueue(_this.getTilePriority.bind(_this), _this.handleTileChange_.bind(_this));\n\n _this.addEventListener(getChangeEventType(MapProperty.LAYERGROUP), _this.handleLayerGroupChanged_);\n\n _this.addEventListener(getChangeEventType(MapProperty.VIEW), _this.handleViewChanged_);\n\n _this.addEventListener(getChangeEventType(MapProperty.SIZE), _this.handleSizeChanged_);\n\n _this.addEventListener(getChangeEventType(MapProperty.TARGET), _this.handleTargetChanged_); // setProperties will trigger the rendering of the map if the map\n // is "defined" already.\n\n\n _this.setProperties(optionsInternal.values);\n\n _this.controls.forEach(\n /**\n * @param {import("./control/Control.js").default} control Control.\n * @this {PluggableMap}\n */\n function (control) {\n control.setMap(this);\n }.bind(_this));\n\n _this.controls.addEventListener(CollectionEventType.ADD,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(this);\n }.bind(_this));\n\n _this.controls.addEventListener(CollectionEventType.REMOVE,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(null);\n }.bind(_this));\n\n _this.interactions.forEach(\n /**\n * @param {import("./interaction/Interaction.js").default} interaction Interaction.\n * @this {PluggableMap}\n */\n function (interaction) {\n interaction.setMap(this);\n }.bind(_this));\n\n _this.interactions.addEventListener(CollectionEventType.ADD,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(this);\n }.bind(_this));\n\n _this.interactions.addEventListener(CollectionEventType.REMOVE,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(null);\n }.bind(_this));\n\n _this.overlays_.forEach(_this.addOverlayInternal_.bind(_this));\n\n _this.overlays_.addEventListener(CollectionEventType.ADD,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n this.addOverlayInternal_(\n /** @type {import("./Overlay.js").default} */\n event.element);\n }.bind(_this));\n\n _this.overlays_.addEventListener(CollectionEventType.REMOVE,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n var overlay =\n /** @type {import("./Overlay.js").default} */\n event.element;\n var id = overlay.getId();\n\n if (id !== undefined) {\n delete this.overlayIdIndex_[id.toString()];\n }\n\n event.element.setMap(null);\n }.bind(_this));\n\n return _this;\n }\n /**\n * @abstract\n * @return {import("./renderer/Map.js").default} The map renderer\n */\n\n\n PluggableMap.prototype.createRenderer = function () {\n throw new Error(\'Use a map type that has a createRenderer method\');\n };\n /**\n * Add the given control to the map.\n * @param {import("./control/Control.js").default} control Control.\n * @api\n */\n\n\n PluggableMap.prototype.addControl = function (control) {\n this.getControls().push(control);\n };\n /**\n * Add the given interaction to the map. If you want to add an interaction\n * at another point of the collection use `getInteraction()` and the methods\n * available on {@link module:ol/Collection~Collection}. This can be used to\n * stop the event propagation from the handleEvent function. The interactions\n * get to handle the events in the reverse order of this collection.\n * @param {import("./interaction/Interaction.js").default} interaction Interaction to add.\n * @api\n */\n\n\n PluggableMap.prototype.addInteraction = function (interaction) {\n this.getInteractions().push(interaction);\n };\n /**\n * Adds the given layer to the top of this map. If you want to add a layer\n * elsewhere in the stack, use `getLayers()` and the methods available on\n * {@link module:ol/Collection~Collection}.\n * @param {import("./layer/Base.js").default} layer Layer.\n * @api\n */\n\n\n PluggableMap.prototype.addLayer = function (layer) {\n var layers = this.getLayerGroup().getLayers();\n layers.push(layer);\n };\n /**\n * Add the given overlay to the map.\n * @param {import("./Overlay.js").default} overlay Overlay.\n * @api\n */\n\n\n PluggableMap.prototype.addOverlay = function (overlay) {\n this.getOverlays().push(overlay);\n };\n /**\n * This deals with map\'s overlay collection changes.\n * @param {import("./Overlay.js").default} overlay Overlay.\n * @private\n */\n\n\n PluggableMap.prototype.addOverlayInternal_ = function (overlay) {\n var id = overlay.getId();\n\n if (id !== undefined) {\n this.overlayIdIndex_[id.toString()] = overlay;\n }\n\n overlay.setMap(this);\n };\n /**\n *\n * Clean up.\n */\n\n\n PluggableMap.prototype.disposeInternal = function () {\n this.setTarget(null);\n\n _super.prototype.disposeInternal.call(this);\n };\n /**\n * Detect features that intersect a pixel on the viewport, and execute a\n * callback with each intersecting feature. Layers included in the detection can\n * be configured through the `layerFilter` option in `opt_options`.\n * @param {import("./pixel.js").Pixel} pixel Pixel.\n * @param {function(import("./Feature.js").FeatureLike, import("./layer/Layer.js").default, import("./geom/SimpleGeometry.js").default): T} callback Feature callback. The callback will be\n * called with two arguments. The first argument is one\n * {@link module:ol/Feature feature} or\n * {@link module:ol/render/Feature render feature} at the pixel, the second is\n * the {@link module:ol/layer/Layer layer} of the feature and will be null for\n * unmanaged layers. To stop detection, callback functions can return a\n * truthy value.\n * @param {AtPixelOptions=} opt_options Optional options.\n * @return {T|undefined} Callback result, i.e. the return value of last\n * callback execution, or the first truthy callback return value.\n * @template S,T\n * @api\n */\n\n\n PluggableMap.prototype.forEachFeatureAtPixel = function (pixel, callback, opt_options) {\n if (!this.frameState_) {\n return;\n }\n\n var coordinate = this.getCoordinateFromPixelInternal(pixel);\n opt_options = opt_options !== undefined ? opt_options : {};\n var hitTolerance = opt_options.hitTolerance !== undefined ? opt_options.hitTolerance : 0;\n var layerFilter = opt_options.layerFilter !== undefined ? opt_options.layerFilter : TRUE;\n var checkWrapped = opt_options.checkWrapped !== false;\n return this.renderer_.forEachFeatureAtCoordinate(coordinate, this.frameState_, hitTolerance, checkWrapped, callback, null, layerFilter, null);\n };\n /**\n * Get all features that intersect a pixel on the viewport.\n * @param {import("./pixel.js").Pixel} pixel Pixel.\n * @param {AtPixelOptions=} opt_options Optional options.\n * @return {Array<import("./Feature.js").FeatureLike>} The detected features or\n * an empty array if none were found.\n * @api\n */\n\n\n PluggableMap.prototype.getFeaturesAtPixel = function (pixel, opt_options) {\n var features = [];\n this.forEachFeatureAtPixel(pixel, function (feature) {\n features.push(feature);\n }, opt_options);\n return features;\n };\n /**\n * Detect layers that have a color value at a pixel on the viewport, and\n * execute a callback with each matching layer. Layers included in the\n * detection can be configured through `opt_layerFilter`.\n *\n * Note: this may give false positives unless the map layers have had different `className`\n * properties assigned to them.\n *\n * @param {import("./pixel.js").Pixel} pixel Pixel.\n * @param {function(this: S, import("./layer/Layer.js").default, (Uint8ClampedArray|Uint8Array)): T} callback\n * Layer callback. This callback will receive two arguments: first is the\n * {@link module:ol/layer/Layer layer}, second argument is an array representing\n * [R, G, B, A] pixel values (0 - 255) and will be `null` for layer types\n * that do not currently support this argument. To stop detection, callback\n * functions can return a truthy value.\n * @param {AtPixelOptions=} opt_options Configuration options.\n * @return {T|undefined} Callback result, i.e. the return value of last\n * callback execution, or the first truthy callback return value.\n * @template S,T\n * @api\n */\n\n\n PluggableMap.prototype.forEachLayerAtPixel = function (pixel, callback, opt_options) {\n if (!this.frameState_) {\n return;\n }\n\n var options = opt_options || {};\n var hitTolerance = options.hitTolerance !== undefined ? options.hitTolerance : 0;\n var layerFilter = options.layerFilter || TRUE;\n return this.renderer_.forEachLayerAtPixel(pixel, this.frameState_, hitTolerance, callback, layerFilter);\n };\n /**\n * Detect if features intersect a pixel on the viewport. Layers included in the\n * detection can be configured through `opt_layerFilter`.\n * @param {import("./pixel.js").Pixel} pixel Pixel.\n * @param {AtPixelOptions=} opt_options Optional options.\n * @return {boolean} Is there a feature at the given pixel?\n * @api\n */\n\n\n PluggableMap.prototype.hasFeatureAtPixel = function (pixel, opt_options) {\n if (!this.frameState_) {\n return false;\n }\n\n var coordinate = this.getCoordinateFromPixelInternal(pixel);\n opt_options = opt_options !== undefined ? opt_options : {};\n var layerFilter = opt_options.layerFilter !== undefined ? opt_options.layerFilter : TRUE;\n var hitTolerance = opt_options.hitTolerance !== undefined ? opt_options.hitTolerance : 0;\n var checkWrapped = opt_options.checkWrapped !== false;\n return this.renderer_.hasFeatureAtCoordinate(coordinate, this.frameState_, hitTolerance, checkWrapped, layerFilter, null);\n };\n /**\n * Returns the coordinate in user projection for a browser event.\n * @param {MouseEvent} event Event.\n * @return {import("./coordinate.js").Coordinate} Coordinate.\n * @api\n */\n\n\n PluggableMap.prototype.getEventCoordinate = function (event) {\n return this.getCoordinateFromPixel(this.getEventPixel(event));\n };\n /**\n * Returns the coordinate in view projection for a browser event.\n * @param {MouseEvent} event Event.\n * @return {import("./coordinate.js").Coordinate} Coordinate.\n */\n\n\n PluggableMap.prototype.getEventCoordinateInternal = function (event) {\n return this.getCoordinateFromPixelInternal(this.getEventPixel(event));\n };\n /**\n * Returns the map pixel position for a browser event relative to the viewport.\n * @param {UIEvent} event Event.\n * @return {import("./pixel.js").Pixel} Pixel.\n * @api\n */\n\n\n PluggableMap.prototype.getEventPixel = function (event) {\n var viewportPosition = this.viewport_.getBoundingClientRect();\n var eventPosition = //FIXME Are we really calling this with a TouchEvent anywhere?\n \'changedTouches\' in event ?\n /** @type {TouchEvent} */\n event.changedTouches[0] :\n /** @type {MouseEvent} */\n event;\n return [eventPosition.clientX - viewportPosition.left, eventPosition.clientY - viewportPosition.top];\n };\n /**\n * Get the target in which this map is rendered.\n * Note that this returns what is entered as an option or in setTarget:\n * if that was an element, it returns an element; if a string, it returns that.\n * @return {HTMLElement|string|undefined} The Element or id of the Element that the\n * map is rendered in.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.getTarget = function () {\n return (\n /** @type {HTMLElement|string|undefined} */\n this.get(MapProperty.TARGET)\n );\n };\n /**\n * Get the DOM element into which this map is rendered. In contrast to\n * `getTarget` this method always return an `Element`, or `null` if the\n * map has no target.\n * @return {HTMLElement} The element that the map is rendered in.\n * @api\n */\n\n\n PluggableMap.prototype.getTargetElement = function () {\n var target = this.getTarget();\n\n if (target !== undefined) {\n return typeof target === \'string\' ? document.getElementById(target) : target;\n } else {\n return null;\n }\n };\n /**\n * Get the coordinate for a given pixel. This returns a coordinate in the\n * user projection.\n * @param {import("./pixel.js").Pixel} pixel Pixel position in the map viewport.\n * @return {import("./coordinate.js").Coordinate} The coordinate for the pixel position.\n * @api\n */\n\n\n PluggableMap.prototype.getCoordinateFromPixel = function (pixel) {\n return toUserCoordinate(this.getCoordinateFromPixelInternal(pixel), this.getView().getProjection());\n };\n /**\n * Get the coordinate for a given pixel. This returns a coordinate in the\n * map view projection.\n * @param {import("./pixel.js").Pixel} pixel Pixel position in the map viewport.\n * @return {import("./coordinate.js").Coordinate} The coordinate for the pixel position.\n */\n\n\n PluggableMap.prototype.getCoordinateFromPixelInternal = function (pixel) {\n var frameState = this.frameState_;\n\n if (!frameState) {\n return null;\n } else {\n return apply(frameState.pixelToCoordinateTransform, pixel.slice());\n }\n };\n /**\n * Get the map controls. Modifying this collection changes the controls\n * associated with the map.\n * @return {Collection<import("./control/Control.js").default>} Controls.\n * @api\n */\n\n\n PluggableMap.prototype.getControls = function () {\n return this.controls;\n };\n /**\n * Get the map overlays. Modifying this collection changes the overlays\n * associated with the map.\n * @return {Collection<import("./Overlay.js").default>} Overlays.\n * @api\n */\n\n\n PluggableMap.prototype.getOverlays = function () {\n return this.overlays_;\n };\n /**\n * Get an overlay by its identifier (the value returned by overlay.getId()).\n * Note that the index treats string and numeric identifiers as the same. So\n * `map.getOverlayById(2)` will return an overlay with id `\'2\'` or `2`.\n * @param {string|number} id Overlay identifier.\n * @return {import("./Overlay.js").default} Overlay.\n * @api\n */\n\n\n PluggableMap.prototype.getOverlayById = function (id) {\n var overlay = this.overlayIdIndex_[id.toString()];\n return overlay !== undefined ? overlay : null;\n };\n /**\n * Get the map interactions. Modifying this collection changes the interactions\n * associated with the map.\n *\n * Interactions are used for e.g. pan, zoom and rotate.\n * @return {Collection<import("./interaction/Interaction.js").default>} Interactions.\n * @api\n */\n\n\n PluggableMap.prototype.getInteractions = function () {\n return this.interactions;\n };\n /**\n * Get the layergroup associated with this map.\n * @return {LayerGroup} A layer group containing the layers in this map.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.getLayerGroup = function () {\n return (\n /** @type {LayerGroup} */\n this.get(MapProperty.LAYERGROUP)\n );\n };\n /**\n * Get the collection of layers associated with this map.\n * @return {!Collection<import("./layer/Base.js").default>} Layers.\n * @api\n */\n\n\n PluggableMap.prototype.getLayers = function () {\n var layers = this.getLayerGroup().getLayers();\n return layers;\n };\n /**\n * @return {boolean} Layers have sources that are still loading.\n */\n\n\n PluggableMap.prototype.getLoading = function () {\n var layerStatesArray = this.getLayerGroup().getLayerStatesArray();\n\n for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n var layer = layerStatesArray[i].layer;\n var source =\n /** @type {import("./layer/Layer.js").default} */\n layer.getSource();\n\n if (source && source.loading) {\n return true;\n }\n }\n\n return false;\n };\n /**\n * Get the pixel for a coordinate. This takes a coordinate in the user\n * projection and returns the corresponding pixel.\n * @param {import("./coordinate.js").Coordinate} coordinate A map coordinate.\n * @return {import("./pixel.js").Pixel} A pixel position in the map viewport.\n * @api\n */\n\n\n PluggableMap.prototype.getPixelFromCoordinate = function (coordinate) {\n var viewCoordinate = fromUserCoordinate(coordinate, this.getView().getProjection());\n return this.getPixelFromCoordinateInternal(viewCoordinate);\n };\n /**\n * Get the pixel for a coordinate. This takes a coordinate in the map view\n * projection and returns the corresponding pixel.\n * @param {import("./coordinate.js").Coordinate} coordinate A map coordinate.\n * @return {import("./pixel.js").Pixel} A pixel position in the map viewport.\n */\n\n\n PluggableMap.prototype.getPixelFromCoordinateInternal = function (coordinate) {\n var frameState = this.frameState_;\n\n if (!frameState) {\n return null;\n } else {\n return apply(frameState.coordinateToPixelTransform, coordinate.slice(0, 2));\n }\n };\n /**\n * Get the map renderer.\n * @return {import("./renderer/Map.js").default} Renderer\n */\n\n\n PluggableMap.prototype.getRenderer = function () {\n return this.renderer_;\n };\n /**\n * Get the size of this map.\n * @return {import("./size.js").Size|undefined} The size in pixels of the map in the DOM.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.getSize = function () {\n return (\n /** @type {import("./size.js").Size|undefined} */\n this.get(MapProperty.SIZE)\n );\n };\n /**\n * Get the view associated with this map. A view manages properties such as\n * center and resolution.\n * @return {View} The view that controls this map.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.getView = function () {\n return (\n /** @type {View} */\n this.get(MapProperty.VIEW)\n );\n };\n /**\n * Get the element that serves as the map viewport.\n * @return {HTMLElement} Viewport.\n * @api\n */\n\n\n PluggableMap.prototype.getViewport = function () {\n return this.viewport_;\n };\n /**\n * Get the element that serves as the container for overlays. Elements added to\n * this container will let mousedown and touchstart events through to the map,\n * so clicks and gestures on an overlay will trigger {@link module:ol/MapBrowserEvent~MapBrowserEvent}\n * events.\n * @return {!HTMLElement} The map\'s overlay container.\n */\n\n\n PluggableMap.prototype.getOverlayContainer = function () {\n return this.overlayContainer_;\n };\n /**\n * Get the element that serves as a container for overlays that don\'t allow\n * event propagation. Elements added to this container won\'t let mousedown and\n * touchstart events through to the map, so clicks and gestures on an overlay\n * don\'t trigger any {@link module:ol/MapBrowserEvent~MapBrowserEvent}.\n * @return {!HTMLElement} The map\'s overlay container that stops events.\n */\n\n\n PluggableMap.prototype.getOverlayContainerStopEvent = function () {\n return this.overlayContainerStopEvent_;\n };\n /**\n * @return {!Document} The document where the map is displayed.\n */\n\n\n PluggableMap.prototype.getOwnerDocument = function () {\n return this.getTargetElement() ? this.getTargetElement().ownerDocument : document;\n };\n /**\n * @param {import("./Tile.js").default} tile Tile.\n * @param {string} tileSourceKey Tile source key.\n * @param {import("./coordinate.js").Coordinate} tileCenter Tile center.\n * @param {number} tileResolution Tile resolution.\n * @return {number} Tile priority.\n */\n\n\n PluggableMap.prototype.getTilePriority = function (tile, tileSourceKey, tileCenter, tileResolution) {\n return getTilePriority(this.frameState_, tile, tileSourceKey, tileCenter, tileResolution);\n };\n /**\n * @param {UIEvent} browserEvent Browser event.\n * @param {string=} opt_type Type.\n */\n\n\n PluggableMap.prototype.handleBrowserEvent = function (browserEvent, opt_type) {\n var type = opt_type || browserEvent.type;\n var mapBrowserEvent = new ol_MapBrowserEvent(type, this, browserEvent);\n this.handleMapBrowserEvent(mapBrowserEvent);\n };\n /**\n * @param {MapBrowserEvent} mapBrowserEvent The event to handle.\n */\n\n\n PluggableMap.prototype.handleMapBrowserEvent = function (mapBrowserEvent) {\n if (!this.frameState_) {\n // With no view defined, we cannot translate pixels into geographical\n // coordinates so interactions cannot be used.\n return;\n }\n\n var originalEvent =\n /** @type {PointerEvent} */\n mapBrowserEvent.originalEvent;\n var eventType = originalEvent.type;\n\n if (eventType === pointer_EventType.POINTERDOWN || eventType === EventType.WHEEL || eventType === EventType.KEYDOWN) {\n var doc = this.getOwnerDocument();\n var rootNode = this.viewport_.getRootNode ? this.viewport_.getRootNode() : doc;\n var target = \'host\' in rootNode // ShadowRoot\n ?\n /** @type {ShadowRoot} */\n rootNode.elementFromPoint(originalEvent.clientX, originalEvent.clientY) :\n /** @type {Node} */\n originalEvent.target;\n\n if ( // Abort if the target is a child of the container for elements whose events are not meant\n // to be handled by map interactions.\n this.overlayContainerStopEvent_.contains(target) || // Abort if the event target is a child of the container that is no longer in the page.\n // It\'s possible for the target to no longer be in the page if it has been removed in an\n // event listener, this might happen in a Control that recreates it\'s content based on\n // user interaction either manually or via a render in something like https://reactjs.org/\n !(rootNode === doc ? doc.documentElement : rootNode).contains(target)) {\n return;\n }\n }\n\n mapBrowserEvent.frameState = this.frameState_;\n\n if (this.dispatchEvent(mapBrowserEvent) !== false) {\n var interactionsArray = this.getInteractions().getArray().slice();\n\n for (var i = interactionsArray.length - 1; i >= 0; i--) {\n var interaction = interactionsArray[i];\n\n if (interaction.getMap() !== this || !interaction.getActive() || !this.getTargetElement()) {\n continue;\n }\n\n var cont = interaction.handleEvent(mapBrowserEvent);\n\n if (!cont || mapBrowserEvent.propagationStopped) {\n break;\n }\n }\n }\n };\n /**\n * @protected\n */\n\n\n PluggableMap.prototype.handlePostRender = function () {\n var frameState = this.frameState_; // Manage the tile queue\n // Image loads are expensive and a limited resource, so try to use them\n // efficiently:\n // * When the view is static we allow a large number of parallel tile loads\n // to complete the frame as quickly as possible.\n // * When animating or interacting, image loads can cause janks, so we reduce\n // the maximum number of loads per frame and limit the number of parallel\n // tile loads to remain reactive to view changes and to reduce the chance of\n // loading tiles that will quickly disappear from view.\n\n var tileQueue = this.tileQueue_;\n\n if (!tileQueue.isEmpty()) {\n var maxTotalLoading = this.maxTilesLoading_;\n var maxNewLoads = maxTotalLoading;\n\n if (frameState) {\n var hints = frameState.viewHints;\n\n if (hints[ViewHint.ANIMATING] || hints[ViewHint.INTERACTING]) {\n var lowOnFrameBudget = !IMAGE_DECODE && Date.now() - frameState.time > 8;\n maxTotalLoading = lowOnFrameBudget ? 0 : 8;\n maxNewLoads = lowOnFrameBudget ? 0 : 2;\n }\n }\n\n if (tileQueue.getTilesLoading() < maxTotalLoading) {\n tileQueue.reprioritize(); // FIXME only call if view has changed\n\n tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);\n }\n }\n\n if (frameState && this.hasListener(render_EventType.RENDERCOMPLETE) && !frameState.animate && !this.tileQueue_.getTilesLoading() && !this.getLoading()) {\n this.renderer_.dispatchRenderEvent(render_EventType.RENDERCOMPLETE, frameState);\n }\n\n var postRenderFunctions = this.postRenderFunctions_;\n\n for (var i = 0, ii = postRenderFunctions.length; i < ii; ++i) {\n postRenderFunctions[i](this, frameState);\n }\n\n postRenderFunctions.length = 0;\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleSizeChanged_ = function () {\n if (this.getView() && !this.getView().getAnimating()) {\n this.getView().resolveConstraints(0);\n }\n\n this.render();\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleTargetChanged_ = function () {\n // target may be undefined, null, a string or an Element.\n // If it\'s a string we convert it to an Element before proceeding.\n // If it\'s not now an Element we remove the viewport from the DOM.\n // If it\'s an Element we append the viewport element to it.\n var targetElement;\n\n if (this.getTarget()) {\n targetElement = this.getTargetElement();\n }\n\n if (this.mapBrowserEventHandler_) {\n for (var i = 0, ii = this.keyHandlerKeys_.length; i < ii; ++i) {\n unlistenByKey(this.keyHandlerKeys_[i]);\n }\n\n this.keyHandlerKeys_ = null;\n this.viewport_.removeEventListener(EventType.CONTEXTMENU, this.boundHandleBrowserEvent_);\n this.viewport_.removeEventListener(EventType.WHEEL, this.boundHandleBrowserEvent_);\n\n if (this.handleResize_ !== undefined) {\n removeEventListener(EventType.RESIZE, this.handleResize_, false);\n this.handleResize_ = undefined;\n }\n\n this.mapBrowserEventHandler_.dispose();\n this.mapBrowserEventHandler_ = null;\n removeNode(this.viewport_);\n }\n\n if (!targetElement) {\n if (this.renderer_) {\n clearTimeout(this.postRenderTimeoutHandle_);\n this.postRenderTimeoutHandle_ = undefined;\n this.postRenderFunctions_.length = 0;\n this.renderer_.dispose();\n this.renderer_ = null;\n }\n\n if (this.animationDelayKey_) {\n cancelAnimationFrame(this.animationDelayKey_);\n this.animationDelayKey_ = undefined;\n }\n } else {\n targetElement.appendChild(this.viewport_);\n\n if (!this.renderer_) {\n this.renderer_ = this.createRenderer();\n }\n\n this.mapBrowserEventHandler_ = new ol_MapBrowserEventHandler(this, this.moveTolerance_);\n\n for (var key in ol_MapBrowserEventType) {\n this.mapBrowserEventHandler_.addEventListener(ol_MapBrowserEventType[key], this.handleMapBrowserEvent.bind(this));\n }\n\n this.viewport_.addEventListener(EventType.CONTEXTMENU, this.boundHandleBrowserEvent_, false);\n this.viewport_.addEventListener(EventType.WHEEL, this.boundHandleBrowserEvent_, PASSIVE_EVENT_LISTENERS ? {\n passive: false\n } : false);\n var keyboardEventTarget = !this.keyboardEventTarget_ ? targetElement : this.keyboardEventTarget_;\n this.keyHandlerKeys_ = [listen(keyboardEventTarget, EventType.KEYDOWN, this.handleBrowserEvent, this), listen(keyboardEventTarget, EventType.KEYPRESS, this.handleBrowserEvent, this)];\n\n if (!this.handleResize_) {\n this.handleResize_ = this.updateSize.bind(this);\n window.addEventListener(EventType.RESIZE, this.handleResize_, false);\n }\n }\n\n this.updateSize(); // updateSize calls setSize, so no need to call this.render\n // ourselves here.\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleTileChange_ = function () {\n this.render();\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleViewPropertyChanged_ = function () {\n this.render();\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleViewChanged_ = function () {\n if (this.viewPropertyListenerKey_) {\n unlistenByKey(this.viewPropertyListenerKey_);\n this.viewPropertyListenerKey_ = null;\n }\n\n if (this.viewChangeListenerKey_) {\n unlistenByKey(this.viewChangeListenerKey_);\n this.viewChangeListenerKey_ = null;\n }\n\n var view = this.getView();\n\n if (view) {\n this.updateViewportSize_();\n this.viewPropertyListenerKey_ = listen(view, ObjectEventType.PROPERTYCHANGE, this.handleViewPropertyChanged_, this);\n this.viewChangeListenerKey_ = listen(view, EventType.CHANGE, this.handleViewPropertyChanged_, this);\n view.resolveConstraints(0);\n }\n\n this.render();\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleLayerGroupChanged_ = function () {\n if (this.layerGroupPropertyListenerKeys_) {\n this.layerGroupPropertyListenerKeys_.forEach(unlistenByKey);\n this.layerGroupPropertyListenerKeys_ = null;\n }\n\n var layerGroup = this.getLayerGroup();\n\n if (layerGroup) {\n this.layerGroupPropertyListenerKeys_ = [listen(layerGroup, ObjectEventType.PROPERTYCHANGE, this.render, this), listen(layerGroup, EventType.CHANGE, this.render, this)];\n }\n\n this.render();\n };\n /**\n * @return {boolean} Is rendered.\n */\n\n\n PluggableMap.prototype.isRendered = function () {\n return !!this.frameState_;\n };\n /**\n * Requests an immediate render in a synchronous manner.\n * @api\n */\n\n\n PluggableMap.prototype.renderSync = function () {\n if (this.animationDelayKey_) {\n cancelAnimationFrame(this.animationDelayKey_);\n }\n\n this.animationDelay_();\n };\n /**\n * Redraws all text after new fonts have loaded\n */\n\n\n PluggableMap.prototype.redrawText = function () {\n var layerStates = this.getLayerGroup().getLayerStatesArray();\n\n for (var i = 0, ii = layerStates.length; i < ii; ++i) {\n var layer = layerStates[i].layer;\n\n if (layer.hasRenderer()) {\n layer.getRenderer().handleFontsChanged();\n }\n }\n };\n /**\n * Request a map rendering (at the next animation frame).\n * @api\n */\n\n\n PluggableMap.prototype.render = function () {\n if (this.renderer_ && this.animationDelayKey_ === undefined) {\n this.animationDelayKey_ = requestAnimationFrame(this.animationDelay_);\n }\n };\n /**\n * Remove the given control from the map.\n * @param {import("./control/Control.js").default} control Control.\n * @return {import("./control/Control.js").default|undefined} The removed control (or undefined\n * if the control was not found).\n * @api\n */\n\n\n PluggableMap.prototype.removeControl = function (control) {\n return this.getControls().remove(control);\n };\n /**\n * Remove the given interaction from the map.\n * @param {import("./interaction/Interaction.js").default} interaction Interaction to remove.\n * @return {import("./interaction/Interaction.js").default|undefined} The removed interaction (or\n * undefined if the interaction was not found).\n * @api\n */\n\n\n PluggableMap.prototype.removeInteraction = function (interaction) {\n return this.getInteractions().remove(interaction);\n };\n /**\n * Removes the given layer from the map.\n * @param {import("./layer/Base.js").default} layer Layer.\n * @return {import("./layer/Base.js").default|undefined} The removed layer (or undefined if the\n * layer was not found).\n * @api\n */\n\n\n PluggableMap.prototype.removeLayer = function (layer) {\n var layers = this.getLayerGroup().getLayers();\n return layers.remove(layer);\n };\n /**\n * Remove the given overlay from the map.\n * @param {import("./Overlay.js").default} overlay Overlay.\n * @return {import("./Overlay.js").default|undefined} The removed overlay (or undefined\n * if the overlay was not found).\n * @api\n */\n\n\n PluggableMap.prototype.removeOverlay = function (overlay) {\n return this.getOverlays().remove(overlay);\n };\n /**\n * @param {number} time Time.\n * @private\n */\n\n\n PluggableMap.prototype.renderFrame_ = function (time) {\n var _this = this;\n\n var size = this.getSize();\n var view = this.getView();\n var previousFrameState = this.frameState_;\n /** @type {?FrameState} */\n\n var frameState = null;\n\n if (size !== undefined && hasArea(size) && view && view.isDef()) {\n var viewHints = view.getHints(this.frameState_ ? this.frameState_.viewHints : undefined);\n var viewState = view.getState();\n frameState = {\n animate: false,\n coordinateToPixelTransform: this.coordinateToPixelTransform_,\n declutterTree: null,\n extent: getForViewAndSize(viewState.center, viewState.resolution, viewState.rotation, size),\n index: this.frameIndex_++,\n layerIndex: 0,\n layerStatesArray: this.getLayerGroup().getLayerStatesArray(),\n pixelRatio: this.pixelRatio_,\n pixelToCoordinateTransform: this.pixelToCoordinateTransform_,\n postRenderFunctions: [],\n size: size,\n tileQueue: this.tileQueue_,\n time: time,\n usedTiles: {},\n viewState: viewState,\n viewHints: viewHints,\n wantedTiles: {}\n };\n }\n\n this.frameState_ = frameState;\n this.renderer_.renderFrame(frameState);\n\n if (frameState) {\n if (frameState.animate) {\n this.render();\n }\n\n Array.prototype.push.apply(this.postRenderFunctions_, frameState.postRenderFunctions);\n\n if (previousFrameState) {\n var moveStart = !this.previousExtent_ || !extent_isEmpty(this.previousExtent_) && !extent_equals(frameState.extent, this.previousExtent_);\n\n if (moveStart) {\n this.dispatchEvent(new ol_MapEvent(MapEventType.MOVESTART, this, previousFrameState));\n this.previousExtent_ = createOrUpdateEmpty(this.previousExtent_);\n }\n }\n\n var idle = this.previousExtent_ && !frameState.viewHints[ViewHint.ANIMATING] && !frameState.viewHints[ViewHint.INTERACTING] && !extent_equals(frameState.extent, this.previousExtent_);\n\n if (idle) {\n this.dispatchEvent(new ol_MapEvent(MapEventType.MOVEEND, this, frameState));\n clone(frameState.extent, this.previousExtent_);\n }\n }\n\n this.dispatchEvent(new ol_MapEvent(MapEventType.POSTRENDER, this, frameState));\n\n if (!this.postRenderTimeoutHandle_) {\n this.postRenderTimeoutHandle_ = setTimeout(function () {\n _this.postRenderTimeoutHandle_ = undefined;\n\n _this.handlePostRender();\n }, 0);\n }\n };\n /**\n * Sets the layergroup of this map.\n * @param {LayerGroup} layerGroup A layer group containing the layers in this map.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.setLayerGroup = function (layerGroup) {\n this.set(MapProperty.LAYERGROUP, layerGroup);\n };\n /**\n * Set the size of this map.\n * @param {import("./size.js").Size|undefined} size The size in pixels of the map in the DOM.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.setSize = function (size) {\n this.set(MapProperty.SIZE, size);\n };\n /**\n * Set the target element to render this map into.\n * @param {HTMLElement|string|undefined} target The Element or id of the Element\n * that the map is rendered in.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.setTarget = function (target) {\n this.set(MapProperty.TARGET, target);\n };\n /**\n * Set the view for this map.\n * @param {View} view The view that controls this map.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.setView = function (view) {\n this.set(MapProperty.VIEW, view);\n };\n /**\n * Force a recalculation of the map viewport size. This should be called when\n * third-party code changes the size of the map viewport.\n * @api\n */\n\n\n PluggableMap.prototype.updateSize = function () {\n var targetElement = this.getTargetElement();\n\n if (!targetElement) {\n this.setSize(undefined);\n } else {\n var computedStyle = getComputedStyle(targetElement);\n this.setSize([targetElement.offsetWidth - parseFloat(computedStyle[\'borderLeftWidth\']) - parseFloat(computedStyle[\'paddingLeft\']) - parseFloat(computedStyle[\'paddingRight\']) - parseFloat(computedStyle[\'borderRightWidth\']), targetElement.offsetHeight - parseFloat(computedStyle[\'borderTopWidth\']) - parseFloat(computedStyle[\'paddingTop\']) - parseFloat(computedStyle[\'paddingBottom\']) - parseFloat(computedStyle[\'borderBottomWidth\'])]);\n }\n\n this.updateViewportSize_();\n };\n /**\n * Recomputes the viewport size and save it on the view object (if any)\n * @private\n */\n\n\n PluggableMap.prototype.updateViewportSize_ = function () {\n var view = this.getView();\n\n if (view) {\n var size = undefined;\n var computedStyle = getComputedStyle(this.viewport_);\n\n if (computedStyle.width && computedStyle.height) {\n size = [parseInt(computedStyle.width, 10), parseInt(computedStyle.height, 10)];\n }\n\n view.setViewportSize(size);\n }\n };\n\n return PluggableMap;\n}(ol_Object);\n/**\n * @param {MapOptions} options Map options.\n * @return {MapOptionsInternal} Internal map options.\n */\n\n\nfunction createOptionsInternal(options) {\n /**\n * @type {HTMLElement|Document}\n */\n var keyboardEventTarget = null;\n\n if (options.keyboardEventTarget !== undefined) {\n keyboardEventTarget = typeof options.keyboardEventTarget === \'string\' ? document.getElementById(options.keyboardEventTarget) : options.keyboardEventTarget;\n }\n /**\n * @type {Object<string, *>}\n */\n\n\n var values = {};\n var layerGroup = options.layers && typeof\n /** @type {?} */\n options.layers.getLayers === \'function\' ?\n /** @type {LayerGroup} */\n options.layers : new Group({\n layers:\n /** @type {Collection} */\n options.layers\n });\n values[MapProperty.LAYERGROUP] = layerGroup;\n values[MapProperty.TARGET] = options.target;\n values[MapProperty.VIEW] = options.view !== undefined ? options.view : new ol_View();\n var controls;\n\n if (options.controls !== undefined) {\n if (Array.isArray(options.controls)) {\n controls = new ol_Collection(options.controls.slice());\n } else {\n asserts_assert(typeof\n /** @type {?} */\n options.controls.getArray === \'function\', 47); // Expected `controls` to be an array or an `import("./Collection.js").Collection`\n\n controls =\n /** @type {Collection} */\n options.controls;\n }\n }\n\n var interactions;\n\n if (options.interactions !== undefined) {\n if (Array.isArray(options.interactions)) {\n interactions = new ol_Collection(options.interactions.slice());\n } else {\n asserts_assert(typeof\n /** @type {?} */\n options.interactions.getArray === \'function\', 48); // Expected `interactions` to be an array or an `import("./Collection.js").Collection`\n\n interactions =\n /** @type {Collection} */\n options.interactions;\n }\n }\n\n var overlays;\n\n if (options.overlays !== undefined) {\n if (Array.isArray(options.overlays)) {\n overlays = new ol_Collection(options.overlays.slice());\n } else {\n asserts_assert(typeof\n /** @type {?} */\n options.overlays.getArray === \'function\', 49); // Expected `overlays` to be an array or an `import("./Collection.js").Collection`\n\n overlays = options.overlays;\n }\n } else {\n overlays = new ol_Collection();\n }\n\n return {\n controls: controls,\n interactions: interactions,\n keyboardEventTarget: keyboardEventTarget,\n overlays: overlays,\n values: values\n };\n}\n\n/* harmony default export */ var ol_PluggableMap = (PluggableMap);\n;// CONCATENATED MODULE: ./node_modules/ol/control/Control.js\nvar Control_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/control/Control\n */\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {HTMLElement} [element] The element is the control\'s\n * container element. This only needs to be specified if you\'re developing\n * a custom control.\n * @property {function(import("../MapEvent.js").default):void} [render] Function called when\n * the control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n * @property {HTMLElement|string} [target] Specify a target if you want\n * the control to be rendered outside of the map\'s viewport.\n */\n\n/**\n * @classdesc\n * A control is a visible widget with a DOM element in a fixed position on the\n * screen. They can involve user input (buttons), or be informational only;\n * the position is determined using CSS. By default these are placed in the\n * container with CSS class name `ol-overlaycontainer-stopevent`, but can use\n * any outside DOM element.\n *\n * This is the base class for controls. You can use it for simple custom\n * controls by creating the element with listeners, creating an instance:\n * ```js\n * var myControl = new Control({element: myElement});\n * ```\n * and then adding this to the map.\n *\n * The main advantage of having this as a control rather than a simple separate\n * DOM element is that preventing propagation is handled for you. Controls\n * will also be objects in a {@link module:ol/Collection~Collection}, so you can use their methods.\n *\n * You can also extend this base for your own control class. See\n * examples/custom-controls for an example of how to do this.\n *\n * @api\n */\n\nvar Control =\n/** @class */\nfunction (_super) {\n Control_extends(Control, _super);\n /**\n * @param {Options} options Control options.\n */\n\n\n function Control(options) {\n var _this = _super.call(this) || this;\n\n var element = options.element;\n\n if (element && !options.target && !element.style.pointerEvents) {\n element.style.pointerEvents = \'auto\';\n }\n /**\n * @protected\n * @type {HTMLElement}\n */\n\n\n _this.element = element ? element : null;\n /**\n * @private\n * @type {HTMLElement}\n */\n\n _this.target_ = null;\n /**\n * @private\n * @type {import("../PluggableMap.js").default}\n */\n\n _this.map_ = null;\n /**\n * @protected\n * @type {!Array<import("../events.js").EventsKey>}\n */\n\n _this.listenerKeys = [];\n\n if (options.render) {\n _this.render = options.render;\n }\n\n if (options.target) {\n _this.setTarget(options.target);\n }\n\n return _this;\n }\n /**\n * Clean up.\n */\n\n\n Control.prototype.disposeInternal = function () {\n removeNode(this.element);\n\n _super.prototype.disposeInternal.call(this);\n };\n /**\n * Get the map associated with this control.\n * @return {import("../PluggableMap.js").default} Map.\n * @api\n */\n\n\n Control.prototype.getMap = function () {\n return this.map_;\n };\n /**\n * Remove the control from its current map and attach it to the new map.\n * Subclasses may set up event handlers to get notified about changes to\n * the map here.\n * @param {import("../PluggableMap.js").default} map Map.\n * @api\n */\n\n\n Control.prototype.setMap = function (map) {\n if (this.map_) {\n removeNode(this.element);\n }\n\n for (var i = 0, ii = this.listenerKeys.length; i < ii; ++i) {\n unlistenByKey(this.listenerKeys[i]);\n }\n\n this.listenerKeys.length = 0;\n this.map_ = map;\n\n if (this.map_) {\n var target = this.target_ ? this.target_ : map.getOverlayContainerStopEvent();\n target.appendChild(this.element);\n\n if (this.render !== VOID) {\n this.listenerKeys.push(listen(map, MapEventType.POSTRENDER, this.render, this));\n }\n\n map.render();\n }\n };\n /**\n * Renders the control.\n * @param {import("../MapEvent.js").default} mapEvent Map event.\n * @api\n */\n\n\n Control.prototype.render = function (mapEvent) {};\n /**\n * This function is used to set a target element for the control. It has no\n * effect if it is called after the control has been added to the map (i.e.\n * after `setMap` is called on the control). If no `target` is set in the\n * options passed to the control constructor and if `setTarget` is not called\n * then the control is added to the map\'s overlay container.\n * @param {HTMLElement|string} target Target.\n * @api\n */\n\n\n Control.prototype.setTarget = function (target) {\n this.target_ = typeof target === \'string\' ? document.getElementById(target) : target;\n };\n\n return Control;\n}(ol_Object);\n\n/* harmony default export */ var control_Control = (Control);\n;// CONCATENATED MODULE: ./node_modules/ol/control/Attribution.js\nvar Attribution_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/control/Attribution\n */\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-attribution\'] CSS class name.\n * @property {HTMLElement|string} [target] Specify a target if you\n * want the control to be rendered outside of the map\'s\n * viewport.\n * @property {boolean} [collapsible] Specify if attributions can\n * be collapsed. If not specified, sources control this behavior with their\n * `attributionsCollapsible` setting.\n * @property {boolean} [collapsed=true] Specify if attributions should\n * be collapsed at startup.\n * @property {string} [tipLabel=\'Attributions\'] Text label to use for the button tip.\n * @property {string} [label=\'i\'] Text label to use for the\n * collapsed attributions button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [expandClassName=className + \'-expand\'] CSS class name for the\n * collapsed attributions button.\n * @property {string|HTMLElement} [collapseLabel=\'»\'] Text label to use\n * for the expanded attributions button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [collapseClassName=className + \'-collapse\'] CSS class name for the\n * expanded attributions button.\n * @property {function(import("../MapEvent.js").default):void} [render] Function called when\n * the control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n */\n\n/**\n * @classdesc\n * Control to show all the attributions associated with the layer sources\n * in the map. This control is one of the default controls included in maps.\n * By default it will show in the bottom right portion of the map, but this can\n * be changed by using a css selector for `.ol-attribution`.\n *\n * @api\n */\n\nvar Attribution =\n/** @class */\nfunction (_super) {\n Attribution_extends(Attribution, _super);\n /**\n * @param {Options=} opt_options Attribution options.\n */\n\n\n function Attribution(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n element: document.createElement(\'div\'),\n render: options.render,\n target: options.target\n }) || this;\n /**\n * @private\n * @type {HTMLElement}\n */\n\n _this.ulElement_ = document.createElement(\'ul\');\n /**\n * @private\n * @type {boolean}\n */\n\n _this.collapsed_ = options.collapsed !== undefined ? options.collapsed : true;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.userCollapsed_ = _this.collapsed_;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.overrideCollapsible_ = options.collapsible !== undefined;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.collapsible_ = options.collapsible !== undefined ? options.collapsible : true;\n\n if (!_this.collapsible_) {\n _this.collapsed_ = false;\n }\n\n var className = options.className !== undefined ? options.className : \'ol-attribution\';\n var tipLabel = options.tipLabel !== undefined ? options.tipLabel : \'Attributions\';\n var expandClassName = options.expandClassName !== undefined ? options.expandClassName : className + \'-expand\';\n var collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : "\\xBB";\n var collapseClassName = options.collapseClassName !== undefined ? options.collapseClassName : className + \'-collpase\';\n\n if (typeof collapseLabel === \'string\') {\n /**\n * @private\n * @type {HTMLElement}\n */\n _this.collapseLabel_ = document.createElement(\'span\');\n _this.collapseLabel_.textContent = collapseLabel;\n _this.collapseLabel_.className = collapseClassName;\n } else {\n _this.collapseLabel_ = collapseLabel;\n }\n\n var label = options.label !== undefined ? options.label : \'i\';\n\n if (typeof label === \'string\') {\n /**\n * @private\n * @type {HTMLElement}\n */\n _this.label_ = document.createElement(\'span\');\n _this.label_.textContent = label;\n _this.label_.className = expandClassName;\n } else {\n _this.label_ = label;\n }\n\n var activeLabel = _this.collapsible_ && !_this.collapsed_ ? _this.collapseLabel_ : _this.label_;\n var button = document.createElement(\'button\');\n button.setAttribute(\'type\', \'button\');\n button.title = tipLabel;\n button.appendChild(activeLabel);\n button.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this), false);\n var cssClasses = className + \' \' + CLASS_UNSELECTABLE + \' \' + CLASS_CONTROL + (_this.collapsed_ && _this.collapsible_ ? \' \' + CLASS_COLLAPSED : \'\') + (_this.collapsible_ ? \'\' : \' ol-uncollapsible\');\n var element = _this.element;\n element.className = cssClasses;\n element.appendChild(_this.ulElement_);\n element.appendChild(button);\n /**\n * A list of currently rendered resolutions.\n * @type {Array<string>}\n * @private\n */\n\n _this.renderedAttributions_ = [];\n /**\n * @private\n * @type {boolean}\n */\n\n _this.renderedVisible_ = true;\n return _this;\n }\n /**\n * Collect a list of visible attributions and set the collapsible state.\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n * @return {Array<string>} Attributions.\n * @private\n */\n\n\n Attribution.prototype.collectSourceAttributions_ = function (frameState) {\n /**\n * Used to determine if an attribution already exists.\n * @type {!Object<string, boolean>}\n */\n var lookup = {};\n /**\n * A list of visible attributions.\n * @type {Array<string>}\n */\n\n var visibleAttributions = [];\n var collapsible = true;\n var layerStatesArray = frameState.layerStatesArray;\n\n for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n var layerState = layerStatesArray[i];\n\n if (!inView(layerState, frameState.viewState)) {\n continue;\n }\n\n var source =\n /** @type {import("../layer/Layer.js").default} */\n layerState.layer.getSource();\n\n if (!source) {\n continue;\n }\n\n var attributionGetter = source.getAttributions();\n\n if (!attributionGetter) {\n continue;\n }\n\n var attributions = attributionGetter(frameState);\n\n if (!attributions) {\n continue;\n }\n\n collapsible = collapsible && source.getAttributionsCollapsible() !== false;\n\n if (Array.isArray(attributions)) {\n for (var j = 0, jj = attributions.length; j < jj; ++j) {\n if (!(attributions[j] in lookup)) {\n visibleAttributions.push(attributions[j]);\n lookup[attributions[j]] = true;\n }\n }\n } else {\n if (!(attributions in lookup)) {\n visibleAttributions.push(attributions);\n lookup[attributions] = true;\n }\n }\n }\n\n if (!this.overrideCollapsible_) {\n this.setCollapsible(collapsible);\n }\n\n return visibleAttributions;\n };\n /**\n * @private\n * @param {?import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n Attribution.prototype.updateElement_ = function (frameState) {\n if (!frameState) {\n if (this.renderedVisible_) {\n this.element.style.display = \'none\';\n this.renderedVisible_ = false;\n }\n\n return;\n }\n\n var attributions = this.collectSourceAttributions_(frameState);\n var visible = attributions.length > 0;\n\n if (this.renderedVisible_ != visible) {\n this.element.style.display = visible ? \'\' : \'none\';\n this.renderedVisible_ = visible;\n }\n\n if (equals(attributions, this.renderedAttributions_)) {\n return;\n }\n\n removeChildren(this.ulElement_); // append the attributions\n\n for (var i = 0, ii = attributions.length; i < ii; ++i) {\n var element = document.createElement(\'li\');\n element.innerHTML = attributions[i];\n this.ulElement_.appendChild(element);\n }\n\n this.renderedAttributions_ = attributions;\n };\n /**\n * @param {MouseEvent} event The event to handle\n * @private\n */\n\n\n Attribution.prototype.handleClick_ = function (event) {\n event.preventDefault();\n this.handleToggle_();\n this.userCollapsed_ = this.collapsed_;\n };\n /**\n * @private\n */\n\n\n Attribution.prototype.handleToggle_ = function () {\n this.element.classList.toggle(CLASS_COLLAPSED);\n\n if (this.collapsed_) {\n replaceNode(this.collapseLabel_, this.label_);\n } else {\n replaceNode(this.label_, this.collapseLabel_);\n }\n\n this.collapsed_ = !this.collapsed_;\n };\n /**\n * Return `true` if the attribution is collapsible, `false` otherwise.\n * @return {boolean} True if the widget is collapsible.\n * @api\n */\n\n\n Attribution.prototype.getCollapsible = function () {\n return this.collapsible_;\n };\n /**\n * Set whether the attribution should be collapsible.\n * @param {boolean} collapsible True if the widget is collapsible.\n * @api\n */\n\n\n Attribution.prototype.setCollapsible = function (collapsible) {\n if (this.collapsible_ === collapsible) {\n return;\n }\n\n this.collapsible_ = collapsible;\n this.element.classList.toggle(\'ol-uncollapsible\');\n\n if (this.userCollapsed_) {\n this.handleToggle_();\n }\n };\n /**\n * Collapse or expand the attribution according to the passed parameter. Will\n * not do anything if the attribution isn\'t collapsible or if the current\n * collapsed state is already the one requested.\n * @param {boolean} collapsed True if the widget is collapsed.\n * @api\n */\n\n\n Attribution.prototype.setCollapsed = function (collapsed) {\n this.userCollapsed_ = collapsed;\n\n if (!this.collapsible_ || this.collapsed_ === collapsed) {\n return;\n }\n\n this.handleToggle_();\n };\n /**\n * Return `true` when the attribution is currently collapsed or `false`\n * otherwise.\n * @return {boolean} True if the widget is collapsed.\n * @api\n */\n\n\n Attribution.prototype.getCollapsed = function () {\n return this.collapsed_;\n };\n /**\n * Update the attribution element.\n * @param {import("../MapEvent.js").default} mapEvent Map event.\n * @override\n */\n\n\n Attribution.prototype.render = function (mapEvent) {\n this.updateElement_(mapEvent.frameState);\n };\n\n return Attribution;\n}(control_Control);\n\n/* harmony default export */ var control_Attribution = (Attribution);\n;// CONCATENATED MODULE: ./node_modules/ol/control/Rotate.js\nvar Rotate_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/control/Rotate\n */\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-rotate\'] CSS class name.\n * @property {string|HTMLElement} [label=\'⇧\'] Text label to use for the rotate button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [tipLabel=\'Reset rotation\'] Text label to use for the rotate tip.\n * @property {string} [compassClassName=\'ol-compass\'] CSS class name for the compass.\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {boolean} [autoHide=true] Hide the control when rotation is 0.\n * @property {function(import("../MapEvent.js").default):void} [render] Function called when the control should\n * be re-rendered. This is called in a `requestAnimationFrame` callback.\n * @property {function():void} [resetNorth] Function called when the control is clicked.\n * This will override the default `resetNorth`.\n * @property {HTMLElement|string} [target] Specify a target if you want the control to be\n * rendered outside of the map\'s viewport.\n */\n\n/**\n * @classdesc\n * A button control to reset rotation to 0.\n * To style this control use css selector `.ol-rotate`. A `.ol-hidden` css\n * selector is added to the button when the rotation is 0.\n *\n * @api\n */\n\nvar Rotate =\n/** @class */\nfunction (_super) {\n Rotate_extends(Rotate, _super);\n /**\n * @param {Options=} opt_options Rotate options.\n */\n\n\n function Rotate(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n element: document.createElement(\'div\'),\n render: options.render,\n target: options.target\n }) || this;\n var className = options.className !== undefined ? options.className : \'ol-rotate\';\n var label = options.label !== undefined ? options.label : "\\u21E7";\n var compassClassName = options.compassClassName !== undefined ? options.compassClassName : \'ol-compass\';\n /**\n * @type {HTMLElement}\n * @private\n */\n\n _this.label_ = null;\n\n if (typeof label === \'string\') {\n _this.label_ = document.createElement(\'span\');\n _this.label_.className = compassClassName;\n _this.label_.textContent = label;\n } else {\n _this.label_ = label;\n\n _this.label_.classList.add(compassClassName);\n }\n\n var tipLabel = options.tipLabel ? options.tipLabel : \'Reset rotation\';\n var button = document.createElement(\'button\');\n button.className = className + \'-reset\';\n button.setAttribute(\'type\', \'button\');\n button.title = tipLabel;\n button.appendChild(_this.label_);\n button.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this), false);\n var cssClasses = className + \' \' + CLASS_UNSELECTABLE + \' \' + CLASS_CONTROL;\n var element = _this.element;\n element.className = cssClasses;\n element.appendChild(button);\n _this.callResetNorth_ = options.resetNorth ? options.resetNorth : undefined;\n /**\n * @type {number}\n * @private\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n /**\n * @type {boolean}\n * @private\n */\n\n _this.autoHide_ = options.autoHide !== undefined ? options.autoHide : true;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.rotation_ = undefined;\n\n if (_this.autoHide_) {\n _this.element.classList.add(CLASS_HIDDEN);\n }\n\n return _this;\n }\n /**\n * @param {MouseEvent} event The event to handle\n * @private\n */\n\n\n Rotate.prototype.handleClick_ = function (event) {\n event.preventDefault();\n\n if (this.callResetNorth_ !== undefined) {\n this.callResetNorth_();\n } else {\n this.resetNorth_();\n }\n };\n /**\n * @private\n */\n\n\n Rotate.prototype.resetNorth_ = function () {\n var map = this.getMap();\n var view = map.getView();\n\n if (!view) {\n // the map does not have a view, so we can\'t act\n // upon it\n return;\n }\n\n var rotation = view.getRotation();\n\n if (rotation !== undefined) {\n if (this.duration_ > 0 && rotation % (2 * Math.PI) !== 0) {\n view.animate({\n rotation: 0,\n duration: this.duration_,\n easing: easeOut\n });\n } else {\n view.setRotation(0);\n }\n }\n };\n /**\n * Update the rotate control element.\n * @param {import("../MapEvent.js").default} mapEvent Map event.\n * @override\n */\n\n\n Rotate.prototype.render = function (mapEvent) {\n var frameState = mapEvent.frameState;\n\n if (!frameState) {\n return;\n }\n\n var rotation = frameState.viewState.rotation;\n\n if (rotation != this.rotation_) {\n var transform = \'rotate(\' + rotation + \'rad)\';\n\n if (this.autoHide_) {\n var contains = this.element.classList.contains(CLASS_HIDDEN);\n\n if (!contains && rotation === 0) {\n this.element.classList.add(CLASS_HIDDEN);\n } else if (contains && rotation !== 0) {\n this.element.classList.remove(CLASS_HIDDEN);\n }\n }\n\n this.label_.style.transform = transform;\n }\n\n this.rotation_ = rotation;\n };\n\n return Rotate;\n}(control_Control);\n\n/* harmony default export */ var control_Rotate = (Rotate);\n;// CONCATENATED MODULE: ./node_modules/ol/control/Zoom.js\nvar Zoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/control/Zoom\n */\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {string} [className=\'ol-zoom\'] CSS class name.\n * @property {string} [zoomInClassName=className + \'-in\'] CSS class name for the zoom-in button.\n * @property {string} [zoomOutClassName=className + \'-out\'] CSS class name for the zoom-out button.\n * @property {string|HTMLElement} [zoomInLabel=\'+\'] Text label to use for the zoom-in\n * button. Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string|HTMLElement} [zoomOutLabel=\'-\'] Text label to use for the zoom-out button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [zoomInTipLabel=\'Zoom in\'] Text label to use for the button tip.\n * @property {string} [zoomOutTipLabel=\'Zoom out\'] Text label to use for the button tip.\n * @property {number} [delta=1] The zoom delta applied on each click.\n * @property {HTMLElement|string} [target] Specify a target if you want the control to be\n * rendered outside of the map\'s viewport.\n */\n\n/**\n * @classdesc\n * A control with 2 buttons, one for zoom in and one for zoom out.\n * This control is one of the default controls of a map. To style this control\n * use css selectors `.ol-zoom-in` and `.ol-zoom-out`.\n *\n * @api\n */\n\nvar Zoom =\n/** @class */\nfunction (_super) {\n Zoom_extends(Zoom, _super);\n /**\n * @param {Options=} opt_options Zoom options.\n */\n\n\n function Zoom(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n element: document.createElement(\'div\'),\n target: options.target\n }) || this;\n var className = options.className !== undefined ? options.className : \'ol-zoom\';\n var delta = options.delta !== undefined ? options.delta : 1;\n var zoomInClassName = options.zoomInClassName !== undefined ? options.zoomInClassName : className + \'-in\';\n var zoomOutClassName = options.zoomOutClassName !== undefined ? options.zoomOutClassName : className + \'-out\';\n var zoomInLabel = options.zoomInLabel !== undefined ? options.zoomInLabel : \'+\';\n var zoomOutLabel = options.zoomOutLabel !== undefined ? options.zoomOutLabel : "\\u2212";\n var zoomInTipLabel = options.zoomInTipLabel !== undefined ? options.zoomInTipLabel : \'Zoom in\';\n var zoomOutTipLabel = options.zoomOutTipLabel !== undefined ? options.zoomOutTipLabel : \'Zoom out\';\n var inElement = document.createElement(\'button\');\n inElement.className = zoomInClassName;\n inElement.setAttribute(\'type\', \'button\');\n inElement.title = zoomInTipLabel;\n inElement.appendChild(typeof zoomInLabel === \'string\' ? document.createTextNode(zoomInLabel) : zoomInLabel);\n inElement.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this, delta), false);\n var outElement = document.createElement(\'button\');\n outElement.className = zoomOutClassName;\n outElement.setAttribute(\'type\', \'button\');\n outElement.title = zoomOutTipLabel;\n outElement.appendChild(typeof zoomOutLabel === \'string\' ? document.createTextNode(zoomOutLabel) : zoomOutLabel);\n outElement.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this, -delta), false);\n var cssClasses = className + \' \' + CLASS_UNSELECTABLE + \' \' + CLASS_CONTROL;\n var element = _this.element;\n element.className = cssClasses;\n element.appendChild(inElement);\n element.appendChild(outElement);\n /**\n * @type {number}\n * @private\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * @param {number} delta Zoom delta.\n * @param {MouseEvent} event The event to handle\n * @private\n */\n\n\n Zoom.prototype.handleClick_ = function (delta, event) {\n event.preventDefault();\n this.zoomByDelta_(delta);\n };\n /**\n * @param {number} delta Zoom delta.\n * @private\n */\n\n\n Zoom.prototype.zoomByDelta_ = function (delta) {\n var map = this.getMap();\n var view = map.getView();\n\n if (!view) {\n // the map does not have a view, so we can\'t act\n // upon it\n return;\n }\n\n var currentZoom = view.getZoom();\n\n if (currentZoom !== undefined) {\n var newZoom = view.getConstrainedZoom(currentZoom + delta);\n\n if (this.duration_ > 0) {\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n\n view.animate({\n zoom: newZoom,\n duration: this.duration_,\n easing: easeOut\n });\n } else {\n view.setZoom(newZoom);\n }\n }\n };\n\n return Zoom;\n}(control_Control);\n\n/* harmony default export */ var control_Zoom = (Zoom);\n;// CONCATENATED MODULE: ./node_modules/ol/control.js\n/**\n * @module ol/control\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} DefaultsOptions\n * @property {boolean} [attribution=true] Include\n * {@link module:ol/control/Attribution~Attribution}.\n * @property {import("./control/Attribution.js").Options} [attributionOptions]\n * Options for {@link module:ol/control/Attribution~Attribution}.\n * @property {boolean} [rotate=true] Include\n * {@link module:ol/control/Rotate~Rotate}.\n * @property {import("./control/Rotate.js").Options} [rotateOptions] Options\n * for {@link module:ol/control/Rotate~Rotate}.\n * @property {boolean} [zoom] Include {@link module:ol/control/Zoom~Zoom}.\n * @property {import("./control/Zoom.js").Options} [zoomOptions] Options for\n * {@link module:ol/control/Zoom~Zoom}.\n * @api\n */\n\n/**\n * Set of controls included in maps by default. Unless configured otherwise,\n * this returns a collection containing an instance of each of the following\n * controls:\n * * {@link module:ol/control/Zoom~Zoom}\n * * {@link module:ol/control/Rotate~Rotate}\n * * {@link module:ol/control/Attribution~Attribution}\n *\n * @param {DefaultsOptions=} opt_options\n * Defaults options.\n * @return {Collection<import("./control/Control.js").default>}\n * Controls.\n * @api\n */\n\nfunction defaults(opt_options) {\n var options = opt_options ? opt_options : {};\n var controls = new ol_Collection();\n var zoomControl = options.zoom !== undefined ? options.zoom : true;\n\n if (zoomControl) {\n controls.push(new control_Zoom(options.zoomOptions));\n }\n\n var rotateControl = options.rotate !== undefined ? options.rotate : true;\n\n if (rotateControl) {\n controls.push(new control_Rotate(options.rotateOptions));\n }\n\n var attributionControl = options.attribution !== undefined ? options.attribution : true;\n\n if (attributionControl) {\n controls.push(new control_Attribution(options.attributionOptions));\n }\n\n return controls;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/Property.js\n/**\n * @module ol/interaction/Property\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var interaction_Property = ({\n ACTIVE: \'active\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/Interaction.js\nvar Interaction_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/Interaction\n */\n\n\n\n\n\n/**\n * Object literal with config options for interactions.\n * @typedef {Object} InteractionOptions\n * @property {function(import("../MapBrowserEvent.js").default):boolean} handleEvent\n * Method called by the map to notify the interaction that a browser event was\n * dispatched to the map. If the function returns a falsy value, propagation of\n * the event to other interactions in the map\'s interactions chain will be\n * prevented (this includes functions with no explicit return). The interactions\n * are traversed in reverse order of the interactions collection of the map.\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * User actions that change the state of the map. Some are similar to controls,\n * but are not associated with a DOM element.\n * For example, {@link module:ol/interaction/KeyboardZoom~KeyboardZoom} is\n * functionally the same as {@link module:ol/control/Zoom~Zoom}, but triggered\n * by a keyboard event not a button element event.\n * Although interactions do not have a DOM element, some of them do render\n * vectors and so are visible on the screen.\n * @api\n */\n\nvar Interaction =\n/** @class */\nfunction (_super) {\n Interaction_extends(Interaction, _super);\n /**\n * @param {InteractionOptions=} opt_options Options.\n */\n\n\n function Interaction(opt_options) {\n var _this = _super.call(this) || this;\n\n if (opt_options && opt_options.handleEvent) {\n _this.handleEvent = opt_options.handleEvent;\n }\n /**\n * @private\n * @type {import("../PluggableMap.js").default}\n */\n\n\n _this.map_ = null;\n\n _this.setActive(true);\n\n return _this;\n }\n /**\n * Return whether the interaction is currently active.\n * @return {boolean} `true` if the interaction is active, `false` otherwise.\n * @observable\n * @api\n */\n\n\n Interaction.prototype.getActive = function () {\n return (\n /** @type {boolean} */\n this.get(interaction_Property.ACTIVE)\n );\n };\n /**\n * Get the map associated with this interaction.\n * @return {import("../PluggableMap.js").default} Map.\n * @api\n */\n\n\n Interaction.prototype.getMap = function () {\n return this.map_;\n };\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event}.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @api\n */\n\n\n Interaction.prototype.handleEvent = function (mapBrowserEvent) {\n return true;\n };\n /**\n * Activate or deactivate the interaction.\n * @param {boolean} active Active.\n * @observable\n * @api\n */\n\n\n Interaction.prototype.setActive = function (active) {\n this.set(interaction_Property.ACTIVE, active);\n };\n /**\n * Remove the interaction from its current map and attach it to the new map.\n * Subclasses may set up event handlers to get notified about changes to\n * the map here.\n * @param {import("../PluggableMap.js").default} map Map.\n */\n\n\n Interaction.prototype.setMap = function (map) {\n this.map_ = map;\n };\n\n return Interaction;\n}(ol_Object);\n/**\n * @param {import("../View.js").default} view View.\n * @param {import("../coordinate.js").Coordinate} delta Delta.\n * @param {number=} opt_duration Duration.\n */\n\n\nfunction pan(view, delta, opt_duration) {\n var currentCenter = view.getCenterInternal();\n\n if (currentCenter) {\n var center = [currentCenter[0] + delta[0], currentCenter[1] + delta[1]];\n view.animateInternal({\n duration: opt_duration !== undefined ? opt_duration : 250,\n easing: linear,\n center: view.getConstrainedCenter(center)\n });\n }\n}\n/**\n * @param {import("../View.js").default} view View.\n * @param {number} delta Delta from previous zoom level.\n * @param {import("../coordinate.js").Coordinate=} opt_anchor Anchor coordinate in the user projection.\n * @param {number=} opt_duration Duration.\n */\n\nfunction zoomByDelta(view, delta, opt_anchor, opt_duration) {\n var currentZoom = view.getZoom();\n\n if (currentZoom === undefined) {\n return;\n }\n\n var newZoom = view.getConstrainedZoom(currentZoom + delta);\n var newResolution = view.getResolutionForZoom(newZoom);\n\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n\n view.animate({\n resolution: newResolution,\n anchor: opt_anchor,\n duration: opt_duration !== undefined ? opt_duration : 250,\n easing: easeOut\n });\n}\n/* harmony default export */ var interaction_Interaction = (Interaction);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/DoubleClickZoom.js\nvar DoubleClickZoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/DoubleClickZoom\n */\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {number} [delta=1] The zoom delta applied on each double click.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom by double-clicking on the map.\n * @api\n */\n\nvar DoubleClickZoom =\n/** @class */\nfunction (_super) {\n DoubleClickZoom_extends(DoubleClickZoom, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function DoubleClickZoom(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @private\n * @type {number}\n */\n\n _this.delta_ = options.delta ? options.delta : 1;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} (if it was a\n * doubleclick) and eventually zooms the map.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n */\n\n\n DoubleClickZoom.prototype.handleEvent = function (mapBrowserEvent) {\n var stopEvent = false;\n\n if (mapBrowserEvent.type == ol_MapBrowserEventType.DBLCLICK) {\n var browserEvent =\n /** @type {MouseEvent} */\n mapBrowserEvent.originalEvent;\n var map = mapBrowserEvent.map;\n var anchor = mapBrowserEvent.coordinate;\n var delta = browserEvent.shiftKey ? -this.delta_ : this.delta_;\n var view = map.getView();\n zoomByDelta(view, delta, anchor, this.duration_);\n browserEvent.preventDefault();\n stopEvent = true;\n }\n\n return !stopEvent;\n };\n\n return DoubleClickZoom;\n}(interaction_Interaction);\n\n/* harmony default export */ var interaction_DoubleClickZoom = (DoubleClickZoom);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/Pointer.js\nvar Pointer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/Pointer\n */\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {function(import("../MapBrowserEvent.js").default):boolean} [handleDownEvent]\n * Function handling "down" events. If the function returns `true` then a drag\n * sequence is started.\n * @property {function(import("../MapBrowserEvent.js").default):void} [handleDragEvent]\n * Function handling "drag" events. This function is called on "move" events\n * during a drag sequence.\n * @property {function(import("../MapBrowserEvent.js").default):boolean} [handleEvent]\n * Method called by the map to notify the interaction that a browser event was\n * dispatched to the map. The function may return `false` to prevent the\n * propagation of the event to other interactions in the map\'s interactions\n * chain.\n * @property {function(import("../MapBrowserEvent.js").default):void} [handleMoveEvent]\n * Function handling "move" events. This function is called on "move" events.\n * This functions is also called during a drag sequence, so during a drag\n * sequence both the `handleDragEvent` function and this function are called.\n * If `handleDownEvent` is defined and it returns true this function will not\n * be called during a drag sequence.\n * @property {function(import("../MapBrowserEvent.js").default):boolean} [handleUpEvent]\n * Function handling "up" events. If the function returns `false` then the\n * current drag sequence is stopped.\n * @property {function(boolean):boolean} [stopDown]\n * Should the down event be propagated to other interactions, or should be\n * stopped?\n */\n\n/**\n * @classdesc\n * Base class that calls user-defined functions on `down`, `move` and `up`\n * events. This class also manages "drag sequences".\n *\n * When the `handleDownEvent` user function returns `true` a drag sequence is\n * started. During a drag sequence the `handleDragEvent` user function is\n * called on `move` events. The drag sequence ends when the `handleUpEvent`\n * user function is called and returns `false`.\n * @api\n */\n\nvar PointerInteraction =\n/** @class */\nfunction (_super) {\n Pointer_extends(PointerInteraction, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function PointerInteraction(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this,\n /** @type {import("./Interaction.js").InteractionOptions} */\n options) || this;\n\n if (options.handleDownEvent) {\n _this.handleDownEvent = options.handleDownEvent;\n }\n\n if (options.handleDragEvent) {\n _this.handleDragEvent = options.handleDragEvent;\n }\n\n if (options.handleMoveEvent) {\n _this.handleMoveEvent = options.handleMoveEvent;\n }\n\n if (options.handleUpEvent) {\n _this.handleUpEvent = options.handleUpEvent;\n }\n\n if (options.stopDown) {\n _this.stopDown = options.stopDown;\n }\n /**\n * @type {boolean}\n * @protected\n */\n\n\n _this.handlingDownUpSequence = false;\n /**\n * @type {!Object<string, PointerEvent>}\n * @private\n */\n\n _this.trackedPointers_ = {};\n /**\n * @type {Array<PointerEvent>}\n * @protected\n */\n\n _this.targetPointers = [];\n return _this;\n }\n /**\n * Returns the current number of pointers involved in the interaction,\n * e.g. `2` when two fingers are used.\n * @return {number} The number of pointers.\n * @api\n */\n\n\n PointerInteraction.prototype.getPointerCount = function () {\n return this.targetPointers.length;\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @protected\n */\n\n\n PointerInteraction.prototype.handleDownEvent = function (mapBrowserEvent) {\n return false;\n };\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @protected\n */\n\n\n PointerInteraction.prototype.handleDragEvent = function (mapBrowserEvent) {};\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} and may call into\n * other functions, if event sequences like e.g. \'drag\' or \'down-up\' etc. are\n * detected.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @api\n */\n\n\n PointerInteraction.prototype.handleEvent = function (mapBrowserEvent) {\n if (!mapBrowserEvent.originalEvent) {\n return true;\n }\n\n var stopEvent = false;\n this.updateTrackedPointers_(mapBrowserEvent);\n\n if (this.handlingDownUpSequence) {\n if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERDRAG) {\n this.handleDragEvent(mapBrowserEvent); // prevent page scrolling during dragging\n\n mapBrowserEvent.originalEvent.preventDefault();\n } else if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERUP) {\n var handledUp = this.handleUpEvent(mapBrowserEvent);\n this.handlingDownUpSequence = handledUp && this.targetPointers.length > 0;\n }\n } else {\n if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERDOWN) {\n var handled = this.handleDownEvent(mapBrowserEvent);\n this.handlingDownUpSequence = handled;\n stopEvent = this.stopDown(handled);\n } else if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERMOVE) {\n this.handleMoveEvent(mapBrowserEvent);\n }\n }\n\n return !stopEvent;\n };\n /**\n * Handle pointer move events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @protected\n */\n\n\n PointerInteraction.prototype.handleMoveEvent = function (mapBrowserEvent) {};\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @protected\n */\n\n\n PointerInteraction.prototype.handleUpEvent = function (mapBrowserEvent) {\n return false;\n };\n /**\n * This function is used to determine if "down" events should be propagated\n * to other interactions or should be stopped.\n * @param {boolean} handled Was the event handled by the interaction?\n * @return {boolean} Should the `down` event be stopped?\n */\n\n\n PointerInteraction.prototype.stopDown = function (handled) {\n return handled;\n };\n /**\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @private\n */\n\n\n PointerInteraction.prototype.updateTrackedPointers_ = function (mapBrowserEvent) {\n if (isPointerDraggingEvent(mapBrowserEvent)) {\n var event_1 = mapBrowserEvent.originalEvent;\n var id = event_1.pointerId.toString();\n\n if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERUP) {\n delete this.trackedPointers_[id];\n } else if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERDOWN) {\n this.trackedPointers_[id] = event_1;\n } else if (id in this.trackedPointers_) {\n // update only when there was a pointerdown event for this pointer\n this.trackedPointers_[id] = event_1;\n }\n\n this.targetPointers = getValues(this.trackedPointers_);\n }\n };\n\n return PointerInteraction;\n}(interaction_Interaction);\n/**\n * @param {Array<PointerEvent>} pointerEvents List of events.\n * @return {import("../pixel.js").Pixel} Centroid pixel.\n */\n\n\nfunction Pointer_centroid(pointerEvents) {\n var length = pointerEvents.length;\n var clientX = 0;\n var clientY = 0;\n\n for (var i = 0; i < length; i++) {\n clientX += pointerEvents[i].clientX;\n clientY += pointerEvents[i].clientY;\n }\n\n return [clientX / length, clientY / length];\n}\n/**\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} Whether the event is a pointerdown, pointerdrag\n * or pointerup event.\n */\n\nfunction isPointerDraggingEvent(mapBrowserEvent) {\n var type = mapBrowserEvent.type;\n return type === ol_MapBrowserEventType.POINTERDOWN || type === ol_MapBrowserEventType.POINTERDRAG || type === ol_MapBrowserEventType.POINTERUP;\n}\n\n/* harmony default export */ var Pointer = (PointerInteraction);\n;// CONCATENATED MODULE: ./node_modules/ol/events/condition.js\n/**\n * @module ol/events/condition\n */\n\n\n\n\n/**\n * A function that takes an {@link module:ol/MapBrowserEvent} and returns a\n * `{boolean}`. If the condition is met, true should be returned.\n *\n * @typedef {function(this: ?, import("../MapBrowserEvent.js").default): boolean} Condition\n */\n\n/**\n * Creates a condition function that passes when all provided conditions pass.\n * @param {...Condition} var_args Conditions to check.\n * @return {Condition} Condition function.\n */\n\nfunction condition_all(var_args) {\n var conditions = arguments;\n /**\n * @param {import("../MapBrowserEvent.js").default} event Event.\n * @return {boolean} All conditions passed.\n */\n\n return function (event) {\n var pass = true;\n\n for (var i = 0, ii = conditions.length; i < ii; ++i) {\n pass = pass && conditions[i](event);\n\n if (!pass) {\n break;\n }\n }\n\n return pass;\n };\n}\n/**\n * Return `true` if only the alt-key is pressed, `false` otherwise (e.g. when\n * additionally the shift-key is pressed).\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the alt key is pressed.\n * @api\n */\n\nvar altKeyOnly = function altKeyOnly(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n return originalEvent.altKey && !(originalEvent.metaKey || originalEvent.ctrlKey) && !originalEvent.shiftKey;\n};\n/**\n * Return `true` if only the alt-key and shift-key is pressed, `false` otherwise\n * (e.g. when additionally the platform-modifier-key is pressed).\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the alt and shift keys are pressed.\n * @api\n */\n\nvar altShiftKeysOnly = function altShiftKeysOnly(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n return originalEvent.altKey && !(originalEvent.metaKey || originalEvent.ctrlKey) && originalEvent.shiftKey;\n};\n/**\n * Return `true` if the map has the focus. This condition requires a map target\n * element with a `tabindex` attribute, e.g. `<div id="map" tabindex="1">`.\n *\n * @param {import("../MapBrowserEvent.js").default} event Map browser event.\n * @return {boolean} The map has the focus.\n * @api\n */\n\nvar condition_focus = function focus(event) {\n return event.target.getTargetElement().contains(document.activeElement);\n};\n/**\n * Return `true` if the map has the focus or no \'tabindex\' attribute set.\n *\n * @param {import("../MapBrowserEvent.js").default} event Map browser event.\n * @return {boolean} The map container has the focus or no \'tabindex\' attribute.\n */\n\nvar focusWithTabindex = function focusWithTabindex(event) {\n return event.map.getTargetElement().hasAttribute(\'tabindex\') ? condition_focus(event) : true;\n};\n/**\n * Return always true.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True.\n * @api\n */\n\nvar always = TRUE;\n/**\n * Return `true` if the event is a `click` event, `false` otherwise.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `click` event.\n * @api\n */\n\nvar click = function click(mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.CLICK;\n};\n/**\n * Return `true` if the event has an "action"-producing mouse button.\n *\n * By definition, this includes left-click on windows/linux, and left-click\n * without the ctrl key on Macs.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} The result.\n */\n\nvar mouseActionButton = function mouseActionButton(mapBrowserEvent) {\n var originalEvent =\n /** @type {MouseEvent} */\n mapBrowserEvent.originalEvent;\n return originalEvent.button == 0 && !(WEBKIT && has_MAC && originalEvent.ctrlKey);\n};\n/**\n * Return always false.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} False.\n * @api\n */\n\nvar never = (/* unused pure expression or super */ null && (FALSE));\n/**\n * Return `true` if the browser event is a `pointermove` event, `false`\n * otherwise.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the browser event is a `pointermove` event.\n * @api\n */\n\nvar pointerMove = function pointerMove(mapBrowserEvent) {\n return mapBrowserEvent.type == \'pointermove\';\n};\n/**\n * Return `true` if the event is a map `singleclick` event, `false` otherwise.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `singleclick` event.\n * @api\n */\n\nvar singleClick = function singleClick(mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK;\n};\n/**\n * Return `true` if the event is a map `dblclick` event, `false` otherwise.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `dblclick` event.\n * @api\n */\n\nvar doubleClick = function doubleClick(mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.DBLCLICK;\n};\n/**\n * Return `true` if no modifier key (alt-, shift- or platform-modifier-key) is\n * pressed.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True only if there no modifier keys are pressed.\n * @api\n */\n\nvar noModifierKeys = function noModifierKeys(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n return !originalEvent.altKey && !(originalEvent.metaKey || originalEvent.ctrlKey) && !originalEvent.shiftKey;\n};\n/**\n * Return `true` if only the platform-modifier-key (the meta-key on Mac,\n * ctrl-key otherwise) is pressed, `false` otherwise (e.g. when additionally\n * the shift-key is pressed).\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the platform modifier key is pressed.\n * @api\n */\n\nvar platformModifierKeyOnly = function platformModifierKeyOnly(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n return !originalEvent.altKey && (MAC ? originalEvent.metaKey : originalEvent.ctrlKey) && !originalEvent.shiftKey;\n};\n/**\n * Return `true` if only the shift-key is pressed, `false` otherwise (e.g. when\n * additionally the alt-key is pressed).\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the shift key is pressed.\n * @api\n */\n\nvar shiftKeyOnly = function shiftKeyOnly(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n return !originalEvent.altKey && !(originalEvent.metaKey || originalEvent.ctrlKey) && originalEvent.shiftKey;\n};\n/**\n * Return `true` if the target element is not editable, i.e. not a `<input>`-,\n * `<select>`- or `<textarea>`-element, `false` otherwise.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True only if the target element is not editable.\n * @api\n */\n\nvar targetNotEditable = function targetNotEditable(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n var tagName =\n /** @type {Element} */\n originalEvent.target.tagName;\n return tagName !== \'INPUT\' && tagName !== \'SELECT\' && tagName !== \'TEXTAREA\';\n};\n/**\n * Return `true` if the event originates from a mouse device.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a mouse device.\n * @api\n */\n\nvar mouseOnly = function mouseOnly(mapBrowserEvent) {\n var pointerEvent =\n /** @type {import("../MapBrowserEvent").default} */\n mapBrowserEvent.originalEvent;\n asserts_assert(pointerEvent !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n // see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n\n return pointerEvent.pointerType == \'mouse\';\n};\n/**\n * Return `true` if the event originates from a touchable device.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a touchable device.\n * @api\n */\n\nvar touchOnly = function touchOnly(mapBrowserEvent) {\n var pointerEvt =\n /** @type {import("../MapBrowserEvent").default} */\n mapBrowserEvent.originalEvent;\n assert(pointerEvt !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n // see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n\n return pointerEvt.pointerType === \'touch\';\n};\n/**\n * Return `true` if the event originates from a digital pen.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a digital pen.\n * @api\n */\n\nvar penOnly = function penOnly(mapBrowserEvent) {\n var pointerEvt =\n /** @type {import("../MapBrowserEvent").default} */\n mapBrowserEvent.originalEvent;\n assert(pointerEvt !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n // see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n\n return pointerEvt.pointerType === \'pen\';\n};\n/**\n * Return `true` if the event originates from a primary pointer in\n * contact with the surface or if the left mouse button is pressed.\n * See http://www.w3.org/TR/pointerevents/#button-states.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a primary pointer.\n * @api\n */\n\nvar primaryAction = function primaryAction(mapBrowserEvent) {\n var pointerEvent =\n /** @type {import("../MapBrowserEvent").default} */\n mapBrowserEvent.originalEvent;\n asserts_assert(pointerEvent !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n\n return pointerEvent.isPrimary && pointerEvent.button === 0;\n};\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragPan.js\nvar DragPan_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/DragPan\n */\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("../events/condition.js").Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition~noModifierKeys} and {@link module:ol/events/condition~primaryAction}.\n * @property {boolean} [onFocusOnly=false] When the map\'s target has a `tabindex` attribute set,\n * the interaction will only handle events when the map has the focus.\n * @property {import("../Kinetic.js").default} [kinetic] Kinetic inertia to apply to the pan.\n */\n\n/**\n * @classdesc\n * Allows the user to pan the map by dragging the map.\n * @api\n */\n\nvar DragPan =\n/** @class */\nfunction (_super) {\n DragPan_extends(DragPan, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function DragPan(opt_options) {\n var _this = _super.call(this, {\n stopDown: functions_FALSE\n }) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @private\n * @type {import("../Kinetic.js").default|undefined}\n */\n\n _this.kinetic_ = options.kinetic;\n /**\n * @type {import("../pixel.js").Pixel}\n */\n\n _this.lastCentroid = null;\n /**\n * @type {number}\n */\n\n _this.lastPointersCount_;\n /**\n * @type {boolean}\n */\n\n _this.panning_ = false;\n var condition = options.condition ? options.condition : condition_all(noModifierKeys, primaryAction);\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n _this.condition_ = options.onFocusOnly ? condition_all(focusWithTabindex, condition) : condition;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.noKinetic_ = false;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n */\n\n\n DragPan.prototype.handleDragEvent = function (mapBrowserEvent) {\n if (!this.panning_) {\n this.panning_ = true;\n this.getMap().getView().beginInteraction();\n }\n\n var targetPointers = this.targetPointers;\n var centroid = Pointer_centroid(targetPointers);\n\n if (targetPointers.length == this.lastPointersCount_) {\n if (this.kinetic_) {\n this.kinetic_.update(centroid[0], centroid[1]);\n }\n\n if (this.lastCentroid) {\n var delta = [this.lastCentroid[0] - centroid[0], centroid[1] - this.lastCentroid[1]];\n var map = mapBrowserEvent.map;\n var view = map.getView();\n coordinate_scale(delta, view.getResolution());\n coordinate_rotate(delta, view.getRotation());\n view.adjustCenterInternal(delta);\n }\n } else if (this.kinetic_) {\n // reset so we don\'t overestimate the kinetic energy after\n // after one finger down, tiny drag, second finger down\n this.kinetic_.begin();\n }\n\n this.lastCentroid = centroid;\n this.lastPointersCount_ = targetPointers.length;\n mapBrowserEvent.originalEvent.preventDefault();\n };\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragPan.prototype.handleUpEvent = function (mapBrowserEvent) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n\n if (this.targetPointers.length === 0) {\n if (!this.noKinetic_ && this.kinetic_ && this.kinetic_.end()) {\n var distance = this.kinetic_.getDistance();\n var angle = this.kinetic_.getAngle();\n var center = view.getCenterInternal();\n var centerpx = map.getPixelFromCoordinateInternal(center);\n var dest = map.getCoordinateFromPixelInternal([centerpx[0] - distance * Math.cos(angle), centerpx[1] - distance * Math.sin(angle)]);\n view.animateInternal({\n center: view.getConstrainedCenter(dest),\n duration: 500,\n easing: easeOut\n });\n }\n\n if (this.panning_) {\n this.panning_ = false;\n view.endInteraction();\n }\n\n return false;\n } else {\n if (this.kinetic_) {\n // reset so we don\'t overestimate the kinetic energy after\n // after one finger up, tiny drag, second finger up\n this.kinetic_.begin();\n }\n\n this.lastCentroid = null;\n return true;\n }\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragPan.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n this.lastCentroid = null; // stop any current animation\n\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n\n if (this.kinetic_) {\n this.kinetic_.begin();\n } // No kinetic as soon as more than one pointer on the screen is\n // detected. This is to prevent nasty pans after pinch.\n\n\n this.noKinetic_ = this.targetPointers.length > 1;\n return true;\n } else {\n return false;\n }\n };\n\n return DragPan;\n}(Pointer);\n\n/* harmony default export */ var interaction_DragPan = (DragPan);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragRotate.js\nvar DragRotate_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/DragRotate\n */\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("../events/condition.js").Condition} [condition] A function that takes an\n * {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition~altShiftKeysOnly}.\n * @property {number} [duration=250] Animation duration in milliseconds.\n */\n\n/**\n * @classdesc\n * Allows the user to rotate the map by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when the alt and shift keys are held down.\n *\n * This interaction is only supported for mouse devices.\n * @api\n */\n\nvar DragRotate =\n/** @class */\nfunction (_super) {\n DragRotate_extends(DragRotate, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function DragRotate(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n stopDown: functions_FALSE\n }) || this;\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n _this.condition_ = options.condition ? options.condition : altShiftKeysOnly;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.lastAngle_ = undefined;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n */\n\n\n DragRotate.prototype.handleDragEvent = function (mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return;\n }\n\n var map = mapBrowserEvent.map;\n var view = map.getView();\n\n if (view.getConstraints().rotation === disable) {\n return;\n }\n\n var size = map.getSize();\n var offset = mapBrowserEvent.pixel;\n var theta = Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);\n\n if (this.lastAngle_ !== undefined) {\n var delta = theta - this.lastAngle_;\n view.adjustRotationInternal(-delta);\n }\n\n this.lastAngle_ = theta;\n };\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragRotate.prototype.handleUpEvent = function (mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return true;\n }\n\n var map = mapBrowserEvent.map;\n var view = map.getView();\n view.endInteraction(this.duration_);\n return false;\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragRotate.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return false;\n }\n\n if (mouseActionButton(mapBrowserEvent) && this.condition_(mapBrowserEvent)) {\n var map = mapBrowserEvent.map;\n map.getView().beginInteraction();\n this.lastAngle_ = undefined;\n return true;\n } else {\n return false;\n }\n };\n\n return DragRotate;\n}(Pointer);\n\n/* harmony default export */ var interaction_DragRotate = (DragRotate);\n;// CONCATENATED MODULE: ./node_modules/ol/render/Box.js\n/**\n * @module ol/render/Box\n */\nvar Box_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\nvar RenderBox =\n/** @class */\nfunction (_super) {\n Box_extends(RenderBox, _super);\n /**\n * @param {string} className CSS class name.\n */\n\n\n function RenderBox(className) {\n var _this = _super.call(this) || this;\n /**\n * @type {import("../geom/Polygon.js").default}\n * @private\n */\n\n\n _this.geometry_ = null;\n /**\n * @type {HTMLDivElement}\n * @private\n */\n\n _this.element_ = document.createElement(\'div\');\n _this.element_.style.position = \'absolute\';\n _this.element_.style.pointerEvents = \'auto\';\n _this.element_.className = \'ol-box \' + className;\n /**\n * @private\n * @type {import("../PluggableMap.js").default}\n */\n\n _this.map_ = null;\n /**\n * @private\n * @type {import("../pixel.js").Pixel}\n */\n\n _this.startPixel_ = null;\n /**\n * @private\n * @type {import("../pixel.js").Pixel}\n */\n\n _this.endPixel_ = null;\n return _this;\n }\n /**\n * Clean up.\n */\n\n\n RenderBox.prototype.disposeInternal = function () {\n this.setMap(null);\n };\n /**\n * @private\n */\n\n\n RenderBox.prototype.render_ = function () {\n var startPixel = this.startPixel_;\n var endPixel = this.endPixel_;\n var px = \'px\';\n var style = this.element_.style;\n style.left = Math.min(startPixel[0], endPixel[0]) + px;\n style.top = Math.min(startPixel[1], endPixel[1]) + px;\n style.width = Math.abs(endPixel[0] - startPixel[0]) + px;\n style.height = Math.abs(endPixel[1] - startPixel[1]) + px;\n };\n /**\n * @param {import("../PluggableMap.js").default} map Map.\n */\n\n\n RenderBox.prototype.setMap = function (map) {\n if (this.map_) {\n this.map_.getOverlayContainer().removeChild(this.element_);\n var style = this.element_.style;\n style.left = \'inherit\';\n style.top = \'inherit\';\n style.width = \'inherit\';\n style.height = \'inherit\';\n }\n\n this.map_ = map;\n\n if (this.map_) {\n this.map_.getOverlayContainer().appendChild(this.element_);\n }\n };\n /**\n * @param {import("../pixel.js").Pixel} startPixel Start pixel.\n * @param {import("../pixel.js").Pixel} endPixel End pixel.\n */\n\n\n RenderBox.prototype.setPixels = function (startPixel, endPixel) {\n this.startPixel_ = startPixel;\n this.endPixel_ = endPixel;\n this.createOrUpdateGeometry();\n this.render_();\n };\n /**\n * Creates or updates the cached geometry.\n */\n\n\n RenderBox.prototype.createOrUpdateGeometry = function () {\n var startPixel = this.startPixel_;\n var endPixel = this.endPixel_;\n var pixels = [startPixel, [startPixel[0], endPixel[1]], endPixel, [endPixel[0], startPixel[1]]];\n var coordinates = pixels.map(this.map_.getCoordinateFromPixelInternal, this.map_); // close the polygon\n\n coordinates[4] = coordinates[0].slice();\n\n if (!this.geometry_) {\n this.geometry_ = new geom_Polygon([coordinates]);\n } else {\n this.geometry_.setCoordinates([coordinates]);\n }\n };\n /**\n * @return {import("../geom/Polygon.js").default} Geometry.\n */\n\n\n RenderBox.prototype.getGeometry = function () {\n return this.geometry_;\n };\n\n return RenderBox;\n}(ol_Disposable);\n\n/* harmony default export */ var Box = (RenderBox);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragBox.js\nvar DragBox_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/DragBox\n */\n// FIXME draw drag box\n\n\n\n\n\n\n/**\n * A function that takes a {@link module:ol/MapBrowserEvent} and two\n * {@link module:ol/pixel~Pixel}s and returns a `{boolean}`. If the condition is met,\n * true should be returned.\n * @typedef {function(this: ?, import("../MapBrowserEvent.js").default, import("../pixel.js").Pixel, import("../pixel.js").Pixel):boolean} EndCondition\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-dragbox\'] CSS class name for styling the box.\n * @property {import("../events/condition.js").Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link ol/events/condition~mouseActionButton}.\n * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the default\n * `boxEndCondition` function.\n * @property {EndCondition} [boxEndCondition] A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and two\n * {@link module:ol/pixel~Pixel}s to indicate whether a `boxend` event should be fired.\n * Default is `true` if the area of the box is bigger than the `minArea` option.\n * @property {function(this:DragBox, import("../MapBrowserEvent.js").default):void} [onBoxEnd] Code to execute just\n * before `boxend` is fired.\n */\n\n/**\n * @enum {string}\n */\n\nvar DragBoxEventType = {\n /**\n * Triggered upon drag box start.\n * @event DragBoxEvent#boxstart\n * @api\n */\n BOXSTART: \'boxstart\',\n\n /**\n * Triggered on drag when box is active.\n * @event DragBoxEvent#boxdrag\n * @api\n */\n BOXDRAG: \'boxdrag\',\n\n /**\n * Triggered upon drag box end.\n * @event DragBoxEvent#boxend\n * @api\n */\n BOXEND: \'boxend\',\n\n /**\n * Triggered upon drag box canceled.\n * @event DragBoxEvent#boxcancel\n * @api\n */\n BOXCANCEL: \'boxcancel\'\n};\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/DragBox~DragBox} instances are instances of\n * this type.\n */\n\nvar DragBoxEvent =\n/** @class */\nfunction (_super) {\n DragBox_extends(DragBoxEvent, _super);\n /**\n * @param {string} type The event type.\n * @param {import("../coordinate.js").Coordinate} coordinate The event coordinate.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Originating event.\n */\n\n\n function DragBoxEvent(type, coordinate, mapBrowserEvent) {\n var _this = _super.call(this, type) || this;\n /**\n * The coordinate of the drag event.\n * @const\n * @type {import("../coordinate.js").Coordinate}\n * @api\n */\n\n\n _this.coordinate = coordinate;\n /**\n * @const\n * @type {import("../MapBrowserEvent.js").default}\n * @api\n */\n\n _this.mapBrowserEvent = mapBrowserEvent;\n return _this;\n }\n\n return DragBoxEvent;\n}(Event);\n\n\n/**\n * @classdesc\n * Allows the user to draw a vector box by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when the shift or other key is held down. This is used, for example,\n * for zooming to a specific area of the map\n * (see {@link module:ol/interaction/DragZoom~DragZoom} and\n * {@link module:ol/interaction/DragRotateAndZoom}).\n *\n * @fires DragBoxEvent\n * @api\n */\n\nvar DragBox =\n/** @class */\nfunction (_super) {\n DragBox_extends(DragBox, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function DragBox(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @type {import("../render/Box.js").default}\n * @private\n */\n\n _this.box_ = new Box(options.className || \'ol-dragbox\');\n /**\n * @type {number}\n * @private\n */\n\n _this.minArea_ = options.minArea !== undefined ? options.minArea : 64;\n\n if (options.onBoxEnd) {\n _this.onBoxEnd = options.onBoxEnd;\n }\n /**\n * @type {import("../pixel.js").Pixel}\n * @private\n */\n\n\n _this.startPixel_ = null;\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n _this.condition_ = options.condition ? options.condition : mouseActionButton;\n /**\n * @private\n * @type {EndCondition}\n */\n\n _this.boxEndCondition_ = options.boxEndCondition ? options.boxEndCondition : _this.defaultBoxEndCondition;\n return _this;\n }\n /**\n * The default condition for determining whether the boxend event\n * should fire.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent The originating MapBrowserEvent\n * leading to the box end.\n * @param {import("../pixel.js").Pixel} startPixel The starting pixel of the box.\n * @param {import("../pixel.js").Pixel} endPixel The end pixel of the box.\n * @return {boolean} Whether or not the boxend condition should be fired.\n */\n\n\n DragBox.prototype.defaultBoxEndCondition = function (mapBrowserEvent, startPixel, endPixel) {\n var width = endPixel[0] - startPixel[0];\n var height = endPixel[1] - startPixel[1];\n return width * width + height * height >= this.minArea_;\n };\n /**\n * Returns geometry of last drawn box.\n * @return {import("../geom/Polygon.js").default} Geometry.\n * @api\n */\n\n\n DragBox.prototype.getGeometry = function () {\n return this.box_.getGeometry();\n };\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n */\n\n\n DragBox.prototype.handleDragEvent = function (mapBrowserEvent) {\n this.box_.setPixels(this.startPixel_, mapBrowserEvent.pixel);\n this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXDRAG, mapBrowserEvent.coordinate, mapBrowserEvent));\n };\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragBox.prototype.handleUpEvent = function (mapBrowserEvent) {\n this.box_.setMap(null);\n var completeBox = this.boxEndCondition_(mapBrowserEvent, this.startPixel_, mapBrowserEvent.pixel);\n\n if (completeBox) {\n this.onBoxEnd(mapBrowserEvent);\n }\n\n this.dispatchEvent(new DragBoxEvent(completeBox ? DragBoxEventType.BOXEND : DragBoxEventType.BOXCANCEL, mapBrowserEvent.coordinate, mapBrowserEvent));\n return false;\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragBox.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.condition_(mapBrowserEvent)) {\n this.startPixel_ = mapBrowserEvent.pixel;\n this.box_.setMap(mapBrowserEvent.map);\n this.box_.setPixels(this.startPixel_, this.startPixel_);\n this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXSTART, mapBrowserEvent.coordinate, mapBrowserEvent));\n return true;\n } else {\n return false;\n }\n };\n /**\n * Function to execute just before `onboxend` is fired\n * @param {import("../MapBrowserEvent.js").default} event Event.\n */\n\n\n DragBox.prototype.onBoxEnd = function (event) {};\n\n return DragBox;\n}(Pointer);\n\n/* harmony default export */ var interaction_DragBox = (DragBox);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragZoom.js\nvar DragZoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/DragZoom\n */\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-dragzoom\'] CSS class name for styling the\n * box.\n * @property {import("../events/condition.js").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition~shiftKeyOnly}.\n * @property {number} [duration=200] Animation duration in milliseconds.\n * @property {boolean} [out=false] Use interaction for zooming out.\n * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the parent default\n * `boxEndCondition` function.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when a key, shift by default, is held down.\n *\n * To change the style of the box, use CSS and the `.ol-dragzoom` selector, or\n * your custom one configured with `className`.\n * @api\n */\n\nvar DragZoom =\n/** @class */\nfunction (_super) {\n DragZoom_extends(DragZoom, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function DragZoom(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var condition = options.condition ? options.condition : shiftKeyOnly;\n _this = _super.call(this, {\n condition: condition,\n className: options.className || \'ol-dragzoom\',\n minArea: options.minArea\n }) || this;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 200;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.out_ = options.out !== undefined ? options.out : false;\n return _this;\n }\n /**\n * Function to execute just before `onboxend` is fired\n * @param {import("../MapBrowserEvent.js").default} event Event.\n */\n\n\n DragZoom.prototype.onBoxEnd = function (event) {\n var map = this.getMap();\n var view =\n /** @type {!import("../View.js").default} */\n map.getView();\n var size =\n /** @type {!import("../size.js").Size} */\n map.getSize();\n var extent = this.getGeometry().getExtent();\n\n if (this.out_) {\n var mapExtent = view.calculateExtentInternal(size);\n var boxPixelExtent = createOrUpdateFromCoordinates([map.getPixelFromCoordinateInternal(getBottomLeft(extent)), map.getPixelFromCoordinateInternal(getTopRight(extent))]);\n var factor = view.getResolutionForExtentInternal(boxPixelExtent, size);\n scaleFromCenter(mapExtent, 1 / factor);\n extent = mapExtent;\n }\n\n var resolution = view.getConstrainedResolution(view.getResolutionForExtentInternal(extent, size));\n var center = view.getConstrainedCenter(getCenter(extent), resolution);\n view.animateInternal({\n resolution: resolution,\n center: center,\n duration: this.duration_,\n easing: easeOut\n });\n };\n\n return DragZoom;\n}(interaction_DragBox);\n\n/* harmony default export */ var interaction_DragZoom = (DragZoom);\n;// CONCATENATED MODULE: ./node_modules/ol/events/KeyCode.js\n/**\n * @module ol/events/KeyCode\n */\n\n/**\n * @enum {number}\n * @const\n */\n/* harmony default export */ var KeyCode = ({\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40\n});\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/KeyboardPan.js\nvar KeyboardPan_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/KeyboardPan\n */\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("../events/condition.js").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition~noModifierKeys} and\n * {@link module:ol/events/condition~targetNotEditable}.\n * @property {number} [duration=100] Animation duration in milliseconds.\n * @property {number} [pixelDelta=128] The amount of pixels to pan on each key\n * press.\n */\n\n/**\n * @classdesc\n * Allows the user to pan the map using keyboard arrows.\n * Note that, although this interaction is by default included in maps,\n * the keys can only be used when browser focus is on the element to which\n * the keyboard events are attached. By default, this is the map div,\n * though you can change this with the `keyboardEventTarget` in\n * {@link module:ol/Map~Map}. `document` never loses focus but, for any other\n * element, focus will have to be on, and returned to, this element if the keys\n * are to function.\n * See also {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}.\n * @api\n */\n\nvar KeyboardPan =\n/** @class */\nfunction (_super) {\n KeyboardPan_extends(KeyboardPan, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function KeyboardPan(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options || {};\n /**\n * @private\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Browser event.\n * @return {boolean} Combined condition result.\n */\n\n _this.defaultCondition_ = function (mapBrowserEvent) {\n return noModifierKeys(mapBrowserEvent) && targetNotEditable(mapBrowserEvent);\n };\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n\n _this.condition_ = options.condition !== undefined ? options.condition : _this.defaultCondition_;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 100;\n /**\n * @private\n * @type {number}\n */\n\n _this.pixelDelta_ = options.pixelDelta !== undefined ? options.pixelDelta : 128;\n return _this;\n }\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} if it was a\n * `KeyEvent`, and decides the direction to pan to (if an arrow key was\n * pressed).\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {KeyboardPan}\n */\n\n\n KeyboardPan.prototype.handleEvent = function (mapBrowserEvent) {\n var stopEvent = false;\n\n if (mapBrowserEvent.type == EventType.KEYDOWN) {\n var keyEvent =\n /** @type {KeyboardEvent} */\n mapBrowserEvent.originalEvent;\n var keyCode = keyEvent.keyCode;\n\n if (this.condition_(mapBrowserEvent) && (keyCode == KeyCode.DOWN || keyCode == KeyCode.LEFT || keyCode == KeyCode.RIGHT || keyCode == KeyCode.UP)) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n var mapUnitsDelta = view.getResolution() * this.pixelDelta_;\n var deltaX = 0,\n deltaY = 0;\n\n if (keyCode == KeyCode.DOWN) {\n deltaY = -mapUnitsDelta;\n } else if (keyCode == KeyCode.LEFT) {\n deltaX = -mapUnitsDelta;\n } else if (keyCode == KeyCode.RIGHT) {\n deltaX = mapUnitsDelta;\n } else {\n deltaY = mapUnitsDelta;\n }\n\n var delta = [deltaX, deltaY];\n coordinate_rotate(delta, view.getRotation());\n pan(view, delta, this.duration_);\n keyEvent.preventDefault();\n stopEvent = true;\n }\n }\n\n return !stopEvent;\n };\n\n return KeyboardPan;\n}(interaction_Interaction);\n\n/* harmony default export */ var interaction_KeyboardPan = (KeyboardPan);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/KeyboardZoom.js\nvar KeyboardZoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/KeyboardZoom\n */\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=100] Animation duration in milliseconds.\n * @property {import("../events/condition.js").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition~targetNotEditable}.\n * @property {number} [delta=1] The zoom level delta on each key press.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map using keyboard + and -.\n * Note that, although this interaction is by default included in maps,\n * the keys can only be used when browser focus is on the element to which\n * the keyboard events are attached. By default, this is the map div,\n * though you can change this with the `keyboardEventTarget` in\n * {@link module:ol/Map~Map}. `document` never loses focus but, for any other\n * element, focus will have to be on, and returned to, this element if the keys\n * are to function.\n * See also {@link module:ol/interaction/KeyboardPan~KeyboardPan}.\n * @api\n */\n\nvar KeyboardZoom =\n/** @class */\nfunction (_super) {\n KeyboardZoom_extends(KeyboardZoom, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function KeyboardZoom(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n _this.condition_ = options.condition ? options.condition : targetNotEditable;\n /**\n * @private\n * @type {number}\n */\n\n _this.delta_ = options.delta ? options.delta : 1;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 100;\n return _this;\n }\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} if it was a\n * `KeyEvent`, and decides whether to zoom in or out (depending on whether the\n * key pressed was \'+\' or \'-\').\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {KeyboardZoom}\n */\n\n\n KeyboardZoom.prototype.handleEvent = function (mapBrowserEvent) {\n var stopEvent = false;\n\n if (mapBrowserEvent.type == EventType.KEYDOWN || mapBrowserEvent.type == EventType.KEYPRESS) {\n var keyEvent =\n /** @type {KeyboardEvent} */\n mapBrowserEvent.originalEvent;\n var charCode = keyEvent.charCode;\n\n if (this.condition_(mapBrowserEvent) && (charCode == \'+\'.charCodeAt(0) || charCode == \'-\'.charCodeAt(0))) {\n var map = mapBrowserEvent.map;\n var delta = charCode == \'+\'.charCodeAt(0) ? this.delta_ : -this.delta_;\n var view = map.getView();\n zoomByDelta(view, delta, undefined, this.duration_);\n keyEvent.preventDefault();\n stopEvent = true;\n }\n }\n\n return !stopEvent;\n };\n\n return KeyboardZoom;\n}(interaction_Interaction);\n\n/* harmony default export */ var interaction_KeyboardZoom = (KeyboardZoom);\n;// CONCATENATED MODULE: ./node_modules/ol/Kinetic.js\n/**\n * @module ol/Kinetic\n */\n\n/**\n * @classdesc\n * Implementation of inertial deceleration for map movement.\n *\n * @api\n */\nvar Kinetic =\n/** @class */\nfunction () {\n /**\n * @param {number} decay Rate of decay (must be negative).\n * @param {number} minVelocity Minimum velocity (pixels/millisecond).\n * @param {number} delay Delay to consider to calculate the kinetic\n * initial values (milliseconds).\n */\n function Kinetic(decay, minVelocity, delay) {\n /**\n * @private\n * @type {number}\n */\n this.decay_ = decay;\n /**\n * @private\n * @type {number}\n */\n\n this.minVelocity_ = minVelocity;\n /**\n * @private\n * @type {number}\n */\n\n this.delay_ = delay;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.points_ = [];\n /**\n * @private\n * @type {number}\n */\n\n this.angle_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n this.initialVelocity_ = 0;\n }\n /**\n * FIXME empty description for jsdoc\n */\n\n\n Kinetic.prototype.begin = function () {\n this.points_.length = 0;\n this.angle_ = 0;\n this.initialVelocity_ = 0;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n */\n\n\n Kinetic.prototype.update = function (x, y) {\n this.points_.push(x, y, Date.now());\n };\n /**\n * @return {boolean} Whether we should do kinetic animation.\n */\n\n\n Kinetic.prototype.end = function () {\n if (this.points_.length < 6) {\n // at least 2 points are required (i.e. there must be at least 6 elements\n // in the array)\n return false;\n }\n\n var delay = Date.now() - this.delay_;\n var lastIndex = this.points_.length - 3;\n\n if (this.points_[lastIndex + 2] < delay) {\n // the last tracked point is too old, which means that the user stopped\n // panning before releasing the map\n return false;\n } // get the first point which still falls into the delay time\n\n\n var firstIndex = lastIndex - 3;\n\n while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {\n firstIndex -= 3;\n }\n\n var duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2]; // we don\'t want a duration of 0 (divide by zero)\n // we also make sure the user panned for a duration of at least one frame\n // (1/60s) to compute sane displacement values\n\n if (duration < 1000 / 60) {\n return false;\n }\n\n var dx = this.points_[lastIndex] - this.points_[firstIndex];\n var dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];\n this.angle_ = Math.atan2(dy, dx);\n this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;\n return this.initialVelocity_ > this.minVelocity_;\n };\n /**\n * @return {number} Total distance travelled (pixels).\n */\n\n\n Kinetic.prototype.getDistance = function () {\n return (this.minVelocity_ - this.initialVelocity_) / this.decay_;\n };\n /**\n * @return {number} Angle of the kinetic panning animation (radians).\n */\n\n\n Kinetic.prototype.getAngle = function () {\n return this.angle_;\n };\n\n return Kinetic;\n}();\n\n/* harmony default export */ var ol_Kinetic = (Kinetic);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/MouseWheelZoom.js\nvar MouseWheelZoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/MouseWheelZoom\n */\n\n\n\n\n\n\n\n/**\n * @enum {string}\n */\n\nvar Mode = {\n TRACKPAD: \'trackpad\',\n WHEEL: \'wheel\'\n};\n/**\n * @typedef {Object} Options\n * @property {import("../events/condition.js").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition~always}.\n * @property {boolean} [onFocusOnly=false] When the map\'s target has a `tabindex` attribute set,\n * the interaction will only handle events when the map has the focus.\n * @property {number} [maxDelta=1] Maximum mouse wheel delta.\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {number} [timeout=80] Mouse wheel timeout duration in milliseconds.\n * @property {boolean} [useAnchor=true] Enable zooming using the mouse\'s\n * location as the anchor. When set to `false`, zooming in and out will zoom to\n * the center of the screen instead of zooming on the mouse\'s location.\n * @property {boolean} [constrainResolution=false] If true, the mouse wheel zoom\n * event will always animate to the closest zoom level after an interaction;\n * false means intermediary zoom levels are allowed.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map by scrolling the mouse wheel.\n * @api\n */\n\nvar MouseWheelZoom =\n/** @class */\nfunction (_super) {\n MouseWheelZoom_extends(MouseWheelZoom, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function MouseWheelZoom(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this,\n /** @type {import("./Interaction.js").InteractionOptions} */\n options) || this;\n /**\n * @private\n * @type {number}\n */\n\n _this.totalDelta_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.lastDelta_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDelta_ = options.maxDelta !== undefined ? options.maxDelta : 1;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n /**\n * @private\n * @type {number}\n */\n\n _this.timeout_ = options.timeout !== undefined ? options.timeout : 80;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.useAnchor_ = options.useAnchor !== undefined ? options.useAnchor : true;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.constrainResolution_ = options.constrainResolution !== undefined ? options.constrainResolution : false;\n var condition = options.condition ? options.condition : always;\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n _this.condition_ = options.onFocusOnly ? condition_all(focusWithTabindex, condition) : condition;\n /**\n * @private\n * @type {?import("../coordinate.js").Coordinate}\n */\n\n _this.lastAnchor_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.startTime_ = undefined;\n /**\n * @private\n * @type {?}\n */\n\n _this.timeoutId_;\n /**\n * @private\n * @type {Mode|undefined}\n */\n\n _this.mode_ = undefined;\n /**\n * Trackpad events separated by this delay will be considered separate\n * interactions.\n * @type {number}\n */\n\n _this.trackpadEventGap_ = 400;\n /**\n * @type {?}\n */\n\n _this.trackpadTimeoutId_;\n /**\n * The number of delta values per zoom level\n * @private\n * @type {number}\n */\n\n _this.deltaPerZoom_ = 300;\n return _this;\n }\n /**\n * @private\n */\n\n\n MouseWheelZoom.prototype.endInteraction_ = function () {\n this.trackpadTimeoutId_ = undefined;\n var view = this.getMap().getView();\n view.endInteraction(undefined, this.lastDelta_ ? this.lastDelta_ > 0 ? 1 : -1 : 0, this.lastAnchor_);\n };\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} (if it was a mousewheel-event) and eventually\n * zooms the map.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n */\n\n\n MouseWheelZoom.prototype.handleEvent = function (mapBrowserEvent) {\n if (!this.condition_(mapBrowserEvent)) {\n return true;\n }\n\n var type = mapBrowserEvent.type;\n\n if (type !== EventType.WHEEL) {\n return true;\n }\n\n var map = mapBrowserEvent.map;\n var wheelEvent =\n /** @type {WheelEvent} */\n mapBrowserEvent.originalEvent;\n wheelEvent.preventDefault();\n\n if (this.useAnchor_) {\n this.lastAnchor_ = mapBrowserEvent.coordinate;\n } // Delta normalisation inspired by\n // https://github.com/mapbox/mapbox-gl-js/blob/001c7b9/js/ui/handler/scroll_zoom.js\n\n\n var delta;\n\n if (mapBrowserEvent.type == EventType.WHEEL) {\n delta = wheelEvent.deltaY;\n\n if (FIREFOX && wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n delta /= DEVICE_PIXEL_RATIO;\n }\n\n if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n delta *= 40;\n }\n }\n\n if (delta === 0) {\n return false;\n } else {\n this.lastDelta_ = delta;\n }\n\n var now = Date.now();\n\n if (this.startTime_ === undefined) {\n this.startTime_ = now;\n }\n\n if (!this.mode_ || now - this.startTime_ > this.trackpadEventGap_) {\n this.mode_ = Math.abs(delta) < 4 ? Mode.TRACKPAD : Mode.WHEEL;\n }\n\n var view = map.getView();\n\n if (this.mode_ === Mode.TRACKPAD && !(view.getConstrainResolution() || this.constrainResolution_)) {\n if (this.trackpadTimeoutId_) {\n clearTimeout(this.trackpadTimeoutId_);\n } else {\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n\n view.beginInteraction();\n }\n\n this.trackpadTimeoutId_ = setTimeout(this.endInteraction_.bind(this), this.timeout_);\n view.adjustZoom(-delta / this.deltaPerZoom_, this.lastAnchor_);\n this.startTime_ = now;\n return false;\n }\n\n this.totalDelta_ += delta;\n var timeLeft = Math.max(this.timeout_ - (now - this.startTime_), 0);\n clearTimeout(this.timeoutId_);\n this.timeoutId_ = setTimeout(this.handleWheelZoom_.bind(this, map), timeLeft);\n return false;\n };\n /**\n * @private\n * @param {import("../PluggableMap.js").default} map Map.\n */\n\n\n MouseWheelZoom.prototype.handleWheelZoom_ = function (map) {\n var view = map.getView();\n\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n\n var delta = -math_clamp(this.totalDelta_, -this.maxDelta_ * this.deltaPerZoom_, this.maxDelta_ * this.deltaPerZoom_) / this.deltaPerZoom_;\n\n if (view.getConstrainResolution() || this.constrainResolution_) {\n // view has a zoom constraint, zoom by 1\n delta = delta ? delta > 0 ? 1 : -1 : 0;\n }\n\n zoomByDelta(view, delta, this.lastAnchor_, this.duration_);\n this.mode_ = undefined;\n this.totalDelta_ = 0;\n this.lastAnchor_ = null;\n this.startTime_ = undefined;\n this.timeoutId_ = undefined;\n };\n /**\n * Enable or disable using the mouse\'s location as an anchor when zooming\n * @param {boolean} useAnchor true to zoom to the mouse\'s location, false\n * to zoom to the center of the map\n * @api\n */\n\n\n MouseWheelZoom.prototype.setMouseAnchor = function (useAnchor) {\n this.useAnchor_ = useAnchor;\n\n if (!useAnchor) {\n this.lastAnchor_ = null;\n }\n };\n\n return MouseWheelZoom;\n}(interaction_Interaction);\n\n/* harmony default export */ var interaction_MouseWheelZoom = (MouseWheelZoom);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/PinchRotate.js\nvar PinchRotate_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/PinchRotate\n */\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] The duration of the animation in\n * milliseconds.\n * @property {number} [threshold=0.3] Minimal angle in radians to start a rotation.\n */\n\n/**\n * @classdesc\n * Allows the user to rotate the map by twisting with two fingers\n * on a touch screen.\n * @api\n */\n\nvar PinchRotate =\n/** @class */\nfunction (_super) {\n PinchRotate_extends(PinchRotate, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function PinchRotate(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var pointerOptions =\n /** @type {import("./Pointer.js").Options} */\n options;\n\n if (!pointerOptions.stopDown) {\n pointerOptions.stopDown = functions_FALSE;\n }\n\n _this = _super.call(this, pointerOptions) || this;\n /**\n * @private\n * @type {import("../coordinate.js").Coordinate}\n */\n\n _this.anchor_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.lastAngle_ = undefined;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.rotating_ = false;\n /**\n * @private\n * @type {number}\n */\n\n _this.rotationDelta_ = 0.0;\n /**\n * @private\n * @type {number}\n */\n\n _this.threshold_ = options.threshold !== undefined ? options.threshold : 0.3;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n */\n\n\n PinchRotate.prototype.handleDragEvent = function (mapBrowserEvent) {\n var rotationDelta = 0.0;\n var touch0 = this.targetPointers[0];\n var touch1 = this.targetPointers[1]; // angle between touches\n\n var angle = Math.atan2(touch1.clientY - touch0.clientY, touch1.clientX - touch0.clientX);\n\n if (this.lastAngle_ !== undefined) {\n var delta = angle - this.lastAngle_;\n this.rotationDelta_ += delta;\n\n if (!this.rotating_ && Math.abs(this.rotationDelta_) > this.threshold_) {\n this.rotating_ = true;\n }\n\n rotationDelta = delta;\n }\n\n this.lastAngle_ = angle;\n var map = mapBrowserEvent.map;\n var view = map.getView();\n\n if (view.getConstraints().rotation === disable) {\n return;\n } // rotate anchor point.\n // FIXME: should be the intersection point between the lines:\n // touch0,touch1 and previousTouch0,previousTouch1\n\n\n var viewportPosition = map.getViewport().getBoundingClientRect();\n var centroid = Pointer_centroid(this.targetPointers);\n centroid[0] -= viewportPosition.left;\n centroid[1] -= viewportPosition.top;\n this.anchor_ = map.getCoordinateFromPixelInternal(centroid); // rotate\n\n if (this.rotating_) {\n map.render();\n view.adjustRotationInternal(rotationDelta, this.anchor_);\n }\n };\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n PinchRotate.prototype.handleUpEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length < 2) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n view.endInteraction(this.duration_);\n return false;\n } else {\n return true;\n }\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n PinchRotate.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length >= 2) {\n var map = mapBrowserEvent.map;\n this.anchor_ = null;\n this.lastAngle_ = undefined;\n this.rotating_ = false;\n this.rotationDelta_ = 0.0;\n\n if (!this.handlingDownUpSequence) {\n map.getView().beginInteraction();\n }\n\n return true;\n } else {\n return false;\n }\n };\n\n return PinchRotate;\n}(Pointer);\n\n/* harmony default export */ var interaction_PinchRotate = (PinchRotate);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/PinchZoom.js\nvar PinchZoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/PinchZoom\n */\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=400] Animation duration in milliseconds.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map by pinching with two fingers\n * on a touch screen.\n * @api\n */\n\nvar PinchZoom =\n/** @class */\nfunction (_super) {\n PinchZoom_extends(PinchZoom, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function PinchZoom(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var pointerOptions =\n /** @type {import("./Pointer.js").Options} */\n options;\n\n if (!pointerOptions.stopDown) {\n pointerOptions.stopDown = functions_FALSE;\n }\n\n _this = _super.call(this, pointerOptions) || this;\n /**\n * @private\n * @type {import("../coordinate.js").Coordinate}\n */\n\n _this.anchor_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 400;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.lastDistance_ = undefined;\n /**\n * @private\n * @type {number}\n */\n\n _this.lastScaleDelta_ = 1;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n */\n\n\n PinchZoom.prototype.handleDragEvent = function (mapBrowserEvent) {\n var scaleDelta = 1.0;\n var touch0 = this.targetPointers[0];\n var touch1 = this.targetPointers[1];\n var dx = touch0.clientX - touch1.clientX;\n var dy = touch0.clientY - touch1.clientY; // distance between touches\n\n var distance = Math.sqrt(dx * dx + dy * dy);\n\n if (this.lastDistance_ !== undefined) {\n scaleDelta = this.lastDistance_ / distance;\n }\n\n this.lastDistance_ = distance;\n var map = mapBrowserEvent.map;\n var view = map.getView();\n\n if (scaleDelta != 1.0) {\n this.lastScaleDelta_ = scaleDelta;\n } // scale anchor point.\n\n\n var viewportPosition = map.getViewport().getBoundingClientRect();\n var centroid = Pointer_centroid(this.targetPointers);\n centroid[0] -= viewportPosition.left;\n centroid[1] -= viewportPosition.top;\n this.anchor_ = map.getCoordinateFromPixelInternal(centroid); // scale, bypass the resolution constraint\n\n map.render();\n view.adjustResolutionInternal(scaleDelta, this.anchor_);\n };\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n PinchZoom.prototype.handleUpEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length < 2) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n var direction = this.lastScaleDelta_ > 1 ? 1 : -1;\n view.endInteraction(this.duration_, direction);\n return false;\n } else {\n return true;\n }\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n PinchZoom.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length >= 2) {\n var map = mapBrowserEvent.map;\n this.anchor_ = null;\n this.lastDistance_ = undefined;\n this.lastScaleDelta_ = 1;\n\n if (!this.handlingDownUpSequence) {\n map.getView().beginInteraction();\n }\n\n return true;\n } else {\n return false;\n }\n };\n\n return PinchZoom;\n}(Pointer);\n\n/* harmony default export */ var interaction_PinchZoom = (PinchZoom);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction.js\n/**\n * @module ol/interaction\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} DefaultsOptions\n * @property {boolean} [altShiftDragRotate=true] Whether Alt-Shift-drag rotate is\n * desired.\n * @property {boolean} [onFocusOnly=false] Interact only when the map has the\n * focus. This affects the `MouseWheelZoom` and `DragPan` interactions and is\n * useful when page scroll is desired for maps that do not have the browser\'s\n * focus.\n * @property {boolean} [doubleClickZoom=true] Whether double click zoom is\n * desired.\n * @property {boolean} [keyboard=true] Whether keyboard interaction is desired.\n * @property {boolean} [mouseWheelZoom=true] Whether mousewheel zoom is desired.\n * @property {boolean} [shiftDragZoom=true] Whether Shift-drag zoom is desired.\n * @property {boolean} [dragPan=true] Whether drag pan is desired.\n * @property {boolean} [pinchRotate=true] Whether pinch rotate is desired.\n * @property {boolean} [pinchZoom=true] Whether pinch zoom is desired.\n * @property {number} [zoomDelta] Zoom level delta when using keyboard or double click zoom.\n * @property {number} [zoomDuration] Duration of the zoom animation in\n * milliseconds.\n */\n\n/**\n * Set of interactions included in maps by default. Specific interactions can be\n * excluded by setting the appropriate option to false in the constructor\n * options, but the order of the interactions is fixed. If you want to specify\n * a different order for interactions, you will need to create your own\n * {@link module:ol/interaction/Interaction} instances and insert\n * them into a {@link module:ol/Collection} in the order you want\n * before creating your {@link module:ol/Map~Map} instance. Changing the order can\n * be of interest if the event propagation needs to be stopped at a point.\n * The default set of interactions, in sequence, is:\n * * {@link module:ol/interaction/DragRotate~DragRotate}\n * * {@link module:ol/interaction/DoubleClickZoom~DoubleClickZoom}\n * * {@link module:ol/interaction/DragPan~DragPan}\n * * {@link module:ol/interaction/PinchRotate~PinchRotate}\n * * {@link module:ol/interaction/PinchZoom~PinchZoom}\n * * {@link module:ol/interaction/KeyboardPan~KeyboardPan}\n * * {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}\n * * {@link module:ol/interaction/MouseWheelZoom~MouseWheelZoom}\n * * {@link module:ol/interaction/DragZoom~DragZoom}\n *\n * @param {DefaultsOptions=} opt_options Defaults options.\n * @return {import("./Collection.js").default<import("./interaction/Interaction.js").default>}\n * A collection of interactions to be used with the {@link module:ol/Map~Map}\n * constructor\'s `interactions` option.\n * @api\n */\n\nfunction interaction_defaults(opt_options) {\n var options = opt_options ? opt_options : {};\n var interactions = new ol_Collection();\n var kinetic = new ol_Kinetic(-0.005, 0.05, 100);\n var altShiftDragRotate = options.altShiftDragRotate !== undefined ? options.altShiftDragRotate : true;\n\n if (altShiftDragRotate) {\n interactions.push(new interaction_DragRotate());\n }\n\n var doubleClickZoom = options.doubleClickZoom !== undefined ? options.doubleClickZoom : true;\n\n if (doubleClickZoom) {\n interactions.push(new interaction_DoubleClickZoom({\n delta: options.zoomDelta,\n duration: options.zoomDuration\n }));\n }\n\n var dragPan = options.dragPan !== undefined ? options.dragPan : true;\n\n if (dragPan) {\n interactions.push(new interaction_DragPan({\n onFocusOnly: options.onFocusOnly,\n kinetic: kinetic\n }));\n }\n\n var pinchRotate = options.pinchRotate !== undefined ? options.pinchRotate : true;\n\n if (pinchRotate) {\n interactions.push(new interaction_PinchRotate());\n }\n\n var pinchZoom = options.pinchZoom !== undefined ? options.pinchZoom : true;\n\n if (pinchZoom) {\n interactions.push(new interaction_PinchZoom({\n duration: options.zoomDuration\n }));\n }\n\n var keyboard = options.keyboard !== undefined ? options.keyboard : true;\n\n if (keyboard) {\n interactions.push(new interaction_KeyboardPan());\n interactions.push(new interaction_KeyboardZoom({\n delta: options.zoomDelta,\n duration: options.zoomDuration\n }));\n }\n\n var mouseWheelZoom = options.mouseWheelZoom !== undefined ? options.mouseWheelZoom : true;\n\n if (mouseWheelZoom) {\n interactions.push(new interaction_MouseWheelZoom({\n onFocusOnly: options.onFocusOnly,\n duration: options.zoomDuration\n }));\n }\n\n var shiftDragZoom = options.shiftDragZoom !== undefined ? options.shiftDragZoom : true;\n\n if (shiftDragZoom) {\n interactions.push(new interaction_DragZoom({\n duration: options.zoomDuration\n }));\n }\n\n return interactions;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/Map.js\nvar ol_Map_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Map\n */\n\n\n\n\n\n\n\n/**\n * @classdesc\n * The map is the core component of OpenLayers. For a map to render, a view,\n * one or more layers, and a target container are needed:\n *\n * import Map from \'ol/Map\';\n * import View from \'ol/View\';\n * import TileLayer from \'ol/layer/Tile\';\n * import OSM from \'ol/source/OSM\';\n *\n * var map = new Map({\n * view: new View({\n * center: [0, 0],\n * zoom: 1\n * }),\n * layers: [\n * new TileLayer({\n * source: new OSM()\n * })\n * ],\n * target: \'map\'\n * });\n *\n * The above snippet creates a map using a {@link module:ol/layer/Tile} to\n * display {@link module:ol/source/OSM~OSM} OSM data and render it to a DOM\n * element with the id `map`.\n *\n * The constructor places a viewport container (with CSS class name\n * `ol-viewport`) in the target element (see `getViewport()`), and then two\n * further elements within the viewport: one with CSS class name\n * `ol-overlaycontainer-stopevent` for controls and some overlays, and one with\n * CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`\n * option of {@link module:ol/Overlay~Overlay} for the difference). The map\n * itself is placed in a further element within the viewport.\n *\n * Layers are stored as a {@link module:ol/Collection~Collection} in\n * layerGroups. A top-level group is provided by the library. This is what is\n * accessed by `getLayerGroup` and `setLayerGroup`. Layers entered in the\n * options are added to this group, and `addLayer` and `removeLayer` change the\n * layer collection in the group. `getLayers` is a convenience function for\n * `getLayerGroup().getLayers()`. Note that {@link module:ol/layer/Group~Group}\n * is a subclass of {@link module:ol/layer/Base}, so layers entered in the\n * options or added with `addLayer` can be groups, which can contain further\n * groups, and so on.\n *\n * @api\n */\n\nvar Map_Map =\n/** @class */\nfunction (_super) {\n ol_Map_extends(Map, _super);\n /**\n * @param {import("./PluggableMap.js").MapOptions} options Map options.\n */\n\n\n function Map(options) {\n var _this = this;\n\n options = obj_assign({}, options);\n\n if (!options.controls) {\n options.controls = defaults();\n }\n\n if (!options.interactions) {\n options.interactions = interaction_defaults({\n onFocusOnly: true\n });\n }\n\n _this = _super.call(this, options) || this;\n return _this;\n }\n\n Map.prototype.createRenderer = function () {\n return new Composite(this);\n };\n\n return Map;\n}(ol_PluggableMap);\n\n/* harmony default export */ var ol_Map = (Map_Map);\n// EXTERNAL MODULE: ./node_modules/rbush/rbush.min.js\nvar rbush_min = __webpack_require__(5792);\nvar rbush_min_default = /*#__PURE__*/__webpack_require__.n(rbush_min);\n;// CONCATENATED MODULE: ./node_modules/ol/ImageState.js\n/**\n * @module ol/ImageState\n */\n\n/**\n * @enum {number}\n */\n/* harmony default export */ var ImageState = ({\n IDLE: 0,\n LOADING: 1,\n LOADED: 2,\n ERROR: 3,\n EMPTY: 4\n});\n;// CONCATENATED MODULE: ./node_modules/ol/style/Image.js\n/**\n * @module ol/style/Image\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {number} opacity\n * @property {boolean} rotateWithView\n * @property {number} rotation\n * @property {number|import("../size.js").Size} scale\n * @property {Array<number>} displacement\n */\n\n/**\n * @classdesc\n * A base class used for creating subclasses and not instantiated in\n * apps. Base class for {@link module:ol/style/Icon~Icon}, {@link module:ol/style/Circle~CircleStyle} and\n * {@link module:ol/style/RegularShape~RegularShape}.\n * @abstract\n * @api\n */\n\nvar ImageStyle =\n/** @class */\nfunction () {\n /**\n * @param {Options} options Options.\n */\n function ImageStyle(options) {\n /**\n * @private\n * @type {number}\n */\n this.opacity_ = options.opacity;\n /**\n * @private\n * @type {boolean}\n */\n\n this.rotateWithView_ = options.rotateWithView;\n /**\n * @private\n * @type {number}\n */\n\n this.rotation_ = options.rotation;\n /**\n * @private\n * @type {number|import("../size.js").Size}\n */\n\n this.scale_ = options.scale;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n this.scaleArray_ = toSize(options.scale);\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.displacement_ = options.displacement;\n }\n /**\n * Clones the style.\n * @return {ImageStyle} The cloned style.\n * @api\n */\n\n\n ImageStyle.prototype.clone = function () {\n var scale = this.getScale();\n return new ImageStyle({\n opacity: this.getOpacity(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n displacement: this.getDisplacement().slice()\n });\n };\n /**\n * Get the symbolizer opacity.\n * @return {number} Opacity.\n * @api\n */\n\n\n ImageStyle.prototype.getOpacity = function () {\n return this.opacity_;\n };\n /**\n * Determine whether the symbolizer rotates with the map.\n * @return {boolean} Rotate with map.\n * @api\n */\n\n\n ImageStyle.prototype.getRotateWithView = function () {\n return this.rotateWithView_;\n };\n /**\n * Get the symoblizer rotation.\n * @return {number} Rotation.\n * @api\n */\n\n\n ImageStyle.prototype.getRotation = function () {\n return this.rotation_;\n };\n /**\n * Get the symbolizer scale.\n * @return {number|import("../size.js").Size} Scale.\n * @api\n */\n\n\n ImageStyle.prototype.getScale = function () {\n return this.scale_;\n };\n /**\n * Get the symbolizer scale array.\n * @return {import("../size.js").Size} Scale array.\n */\n\n\n ImageStyle.prototype.getScaleArray = function () {\n return this.scaleArray_;\n };\n /**\n * Get the displacement of the shape\n * @return {Array<number>} Shape\'s center displacement\n * @api\n */\n\n\n ImageStyle.prototype.getDisplacement = function () {\n return this.displacement_;\n };\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @abstract\n * @return {Array<number>} Anchor.\n */\n\n\n ImageStyle.prototype.getAnchor = function () {\n return util_abstract();\n };\n /**\n * Get the image element for the symbolizer.\n * @abstract\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.\n */\n\n\n ImageStyle.prototype.getImage = function (pixelRatio) {\n return util_abstract();\n };\n /**\n * @abstract\n * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.\n */\n\n\n ImageStyle.prototype.getHitDetectionImage = function () {\n return util_abstract();\n };\n /*\n * Get the image pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * */\n\n\n ImageStyle.prototype.getPixelRatio = function (pixelRatio) {\n return 1;\n };\n /**\n * @abstract\n * @return {import("../ImageState.js").default} Image state.\n */\n\n\n ImageStyle.prototype.getImageState = function () {\n return util_abstract();\n };\n /**\n * @abstract\n * @return {import("../size.js").Size} Image size.\n */\n\n\n ImageStyle.prototype.getImageSize = function () {\n return util_abstract();\n };\n /**\n * @abstract\n * @return {import("../size.js").Size} Size of the hit-detection image.\n */\n\n\n ImageStyle.prototype.getHitDetectionImageSize = function () {\n return util_abstract();\n };\n /**\n * Get the origin of the symbolizer.\n * @abstract\n * @return {Array<number>} Origin.\n */\n\n\n ImageStyle.prototype.getOrigin = function () {\n return util_abstract();\n };\n /**\n * Get the size of the symbolizer (in pixels).\n * @abstract\n * @return {import("../size.js").Size} Size.\n */\n\n\n ImageStyle.prototype.getSize = function () {\n return util_abstract();\n };\n /**\n * Set the opacity.\n *\n * @param {number} opacity Opacity.\n * @api\n */\n\n\n ImageStyle.prototype.setOpacity = function (opacity) {\n this.opacity_ = opacity;\n };\n /**\n * Set whether to rotate the style with the view.\n *\n * @param {boolean} rotateWithView Rotate with map.\n * @api\n */\n\n\n ImageStyle.prototype.setRotateWithView = function (rotateWithView) {\n this.rotateWithView_ = rotateWithView;\n };\n /**\n * Set the rotation.\n *\n * @param {number} rotation Rotation.\n * @api\n */\n\n\n ImageStyle.prototype.setRotation = function (rotation) {\n this.rotation_ = rotation;\n };\n /**\n * Set the scale.\n *\n * @param {number|import("../size.js").Size} scale Scale.\n * @api\n */\n\n\n ImageStyle.prototype.setScale = function (scale) {\n this.scale_ = scale;\n this.scaleArray_ = toSize(scale);\n };\n /**\n * @abstract\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n ImageStyle.prototype.listenImageChange = function (listener) {\n util_abstract();\n };\n /**\n * Load not yet loaded URI.\n * @abstract\n */\n\n\n ImageStyle.prototype.load = function () {\n util_abstract();\n };\n /**\n * @abstract\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n ImageStyle.prototype.unlistenImageChange = function (listener) {\n util_abstract();\n };\n\n return ImageStyle;\n}();\n\n/* harmony default export */ var style_Image = (ImageStyle);\n;// CONCATENATED MODULE: ./node_modules/ol/colorlike.js\n/**\n * @module ol/colorlike\n */\n\n/**\n * A type accepted by CanvasRenderingContext2D.fillStyle\n * or CanvasRenderingContext2D.strokeStyle.\n * Represents a color, pattern, or gradient. The origin for patterns and\n * gradients as fill style is an increment of 512 css pixels from map coordinate\n * `[0, 0]`. For seamless repeat patterns, width and height of the pattern image\n * must be a factor of two (2, 4, 8, ..., 512).\n *\n * @typedef {string|CanvasPattern|CanvasGradient} ColorLike\n * @api\n */\n\n/**\n * @param {import("./color.js").Color|ColorLike} color Color.\n * @return {ColorLike} The color as an {@link ol/colorlike~ColorLike}.\n * @api\n */\n\nfunction asColorLike(color) {\n if (Array.isArray(color)) {\n return color_toString(color);\n } else {\n return color;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/style/RegularShape.js\n/**\n * @module ol/style/RegularShape\n */\nvar RegularShape_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n/**\n * Specify radius for regular polygons, or radius1 and radius2 for stars.\n * @typedef {Object} Options\n * @property {import("./Fill.js").default} [fill] Fill style.\n * @property {number} points Number of points for stars and regular polygons. In case of a polygon, the number of points\n * is the number of sides.\n * @property {number} [radius] Radius of a regular polygon.\n * @property {number} [radius1] Outer radius of a star.\n * @property {number} [radius2] Inner radius of a star.\n * @property {number} [angle=0] Shape\'s angle in radians. A value of 0 will have one of the shape\'s point facing up.\n * @property {Array<number>} [displacement=[0,0]] Displacement of the shape\n * @property {import("./Stroke.js").default} [stroke] Stroke style.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view.\n * @property {number|import("../size.js").Size} [scale=1] Scale. Unless two dimensional scaling is required a better\n * result may be obtained with appropriate settings for `radius`, `radius1` and `radius2`.\n */\n\n/**\n * @typedef {Object} RenderOptions\n * @property {import("../colorlike.js").ColorLike} [strokeStyle]\n * @property {number} strokeWidth\n * @property {number} size\n * @property {CanvasLineCap} lineCap\n * @property {Array<number>} lineDash\n * @property {number} lineDashOffset\n * @property {CanvasLineJoin} lineJoin\n * @property {number} miterLimit\n */\n\n/**\n * @classdesc\n * Set regular shape style for vector features. The resulting shape will be\n * a regular polygon when `radius` is provided, or a star when `radius1` and\n * `radius2` are provided.\n * @api\n */\n\nvar RegularShape =\n/** @class */\nfunction (_super) {\n RegularShape_extends(RegularShape, _super);\n /**\n * @param {Options} options Options.\n */\n\n\n function RegularShape(options) {\n var _this = this;\n /**\n * @type {boolean}\n */\n\n\n var rotateWithView = options.rotateWithView !== undefined ? options.rotateWithView : false;\n _this = _super.call(this, {\n opacity: 1,\n rotateWithView: rotateWithView,\n rotation: options.rotation !== undefined ? options.rotation : 0,\n scale: options.scale !== undefined ? options.scale : 1,\n displacement: options.displacement !== undefined ? options.displacement : [0, 0]\n }) || this;\n /**\n * @private\n * @type {Object<number, HTMLCanvasElement>}\n */\n\n _this.canvas_ = {};\n /**\n * @private\n * @type {HTMLCanvasElement}\n */\n\n _this.hitDetectionCanvas_ = null;\n /**\n * @private\n * @type {import("./Fill.js").default}\n */\n\n _this.fill_ = options.fill !== undefined ? options.fill : null;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.origin_ = [0, 0];\n /**\n * @private\n * @type {number}\n */\n\n _this.points_ = options.points;\n /**\n * @protected\n * @type {number}\n */\n\n _this.radius_ = options.radius !== undefined ? options.radius : options.radius1;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.radius2_ = options.radius2;\n /**\n * @private\n * @type {number}\n */\n\n _this.angle_ = options.angle !== undefined ? options.angle : 0;\n /**\n * @private\n * @type {import("./Stroke.js").default}\n */\n\n _this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.anchor_ = null;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n _this.size_ = null;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n _this.imageSize_ = null;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n _this.hitDetectionImageSize_ = null;\n\n _this.render();\n\n return _this;\n }\n /**\n * Clones the style.\n * @return {RegularShape} The cloned style.\n * @api\n */\n\n\n RegularShape.prototype.clone = function () {\n var scale = this.getScale();\n var style = new RegularShape({\n fill: this.getFill() ? this.getFill().clone() : undefined,\n points: this.getPoints(),\n radius: this.getRadius(),\n radius2: this.getRadius2(),\n angle: this.getAngle(),\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n displacement: this.getDisplacement().slice()\n });\n style.setOpacity(this.getOpacity());\n return style;\n };\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @return {Array<number>} Anchor.\n * @api\n */\n\n\n RegularShape.prototype.getAnchor = function () {\n return this.anchor_;\n };\n /**\n * Get the angle used in generating the shape.\n * @return {number} Shape\'s rotation in radians.\n * @api\n */\n\n\n RegularShape.prototype.getAngle = function () {\n return this.angle_;\n };\n /**\n * Get the fill style for the shape.\n * @return {import("./Fill.js").default} Fill style.\n * @api\n */\n\n\n RegularShape.prototype.getFill = function () {\n return this.fill_;\n };\n /**\n * @return {HTMLCanvasElement} Image element.\n */\n\n\n RegularShape.prototype.getHitDetectionImage = function () {\n if (!this.hitDetectionCanvas_) {\n var renderOptions = this.createRenderOptions();\n this.createHitDetectionCanvas_(renderOptions);\n }\n\n return this.hitDetectionCanvas_;\n };\n /**\n * Get the image icon.\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLCanvasElement} Image or Canvas element.\n * @api\n */\n\n\n RegularShape.prototype.getImage = function (pixelRatio) {\n if (!this.canvas_[pixelRatio || 1]) {\n var renderOptions = this.createRenderOptions();\n var context = createCanvasContext2D(renderOptions.size * pixelRatio || 1, renderOptions.size * pixelRatio || 1);\n this.draw_(renderOptions, context, 0, 0, pixelRatio || 1);\n this.canvas_[pixelRatio || 1] = context.canvas;\n }\n\n return this.canvas_[pixelRatio || 1];\n };\n /*\n * Get the image pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * */\n\n\n RegularShape.prototype.getPixelRatio = function (pixelRatio) {\n return pixelRatio;\n };\n /**\n * @return {import("../size.js").Size} Image size.\n */\n\n\n RegularShape.prototype.getImageSize = function () {\n return this.imageSize_;\n };\n /**\n * @return {import("../size.js").Size} Size of the hit-detection image.\n */\n\n\n RegularShape.prototype.getHitDetectionImageSize = function () {\n return this.hitDetectionImageSize_;\n };\n /**\n * @return {import("../ImageState.js").default} Image state.\n */\n\n\n RegularShape.prototype.getImageState = function () {\n return ImageState.LOADED;\n };\n /**\n * Get the origin of the symbolizer.\n * @return {Array<number>} Origin.\n * @api\n */\n\n\n RegularShape.prototype.getOrigin = function () {\n return this.origin_;\n };\n /**\n * Get the number of points for generating the shape.\n * @return {number} Number of points for stars and regular polygons.\n * @api\n */\n\n\n RegularShape.prototype.getPoints = function () {\n return this.points_;\n };\n /**\n * Get the (primary) radius for the shape.\n * @return {number} Radius.\n * @api\n */\n\n\n RegularShape.prototype.getRadius = function () {\n return this.radius_;\n };\n /**\n * Get the secondary radius for the shape.\n * @return {number|undefined} Radius2.\n * @api\n */\n\n\n RegularShape.prototype.getRadius2 = function () {\n return this.radius2_;\n };\n /**\n * Get the size of the symbolizer (in pixels).\n * @return {import("../size.js").Size} Size.\n * @api\n */\n\n\n RegularShape.prototype.getSize = function () {\n return this.size_;\n };\n /**\n * Get the stroke style for the shape.\n * @return {import("./Stroke.js").default} Stroke style.\n * @api\n */\n\n\n RegularShape.prototype.getStroke = function () {\n return this.stroke_;\n };\n /**\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n RegularShape.prototype.listenImageChange = function (listener) {};\n /**\n * Load not yet loaded URI.\n */\n\n\n RegularShape.prototype.load = function () {};\n /**\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n RegularShape.prototype.unlistenImageChange = function (listener) {};\n /**\n * @returns {RenderOptions} The render options\n * @protected\n */\n\n\n RegularShape.prototype.createRenderOptions = function () {\n var lineCap = defaultLineCap;\n var lineJoin = defaultLineJoin;\n var miterLimit = 0;\n var lineDash = null;\n var lineDashOffset = 0;\n var strokeStyle;\n var strokeWidth = 0;\n\n if (this.stroke_) {\n strokeStyle = this.stroke_.getColor();\n\n if (strokeStyle === null) {\n strokeStyle = defaultStrokeStyle;\n }\n\n strokeStyle = asColorLike(strokeStyle);\n strokeWidth = this.stroke_.getWidth();\n\n if (strokeWidth === undefined) {\n strokeWidth = defaultLineWidth;\n }\n\n lineDash = this.stroke_.getLineDash();\n lineDashOffset = this.stroke_.getLineDashOffset();\n lineJoin = this.stroke_.getLineJoin();\n\n if (lineJoin === undefined) {\n lineJoin = defaultLineJoin;\n }\n\n lineCap = this.stroke_.getLineCap();\n\n if (lineCap === undefined) {\n lineCap = defaultLineCap;\n }\n\n miterLimit = this.stroke_.getMiterLimit();\n\n if (miterLimit === undefined) {\n miterLimit = defaultMiterLimit;\n }\n }\n\n var size = 2 * (this.radius_ + strokeWidth) + 1;\n return {\n strokeStyle: strokeStyle,\n strokeWidth: strokeWidth,\n size: size,\n lineCap: lineCap,\n lineDash: lineDash,\n lineDashOffset: lineDashOffset,\n lineJoin: lineJoin,\n miterLimit: miterLimit\n };\n };\n /**\n * @protected\n */\n\n\n RegularShape.prototype.render = function () {\n var renderOptions = this.createRenderOptions();\n var context = createCanvasContext2D(renderOptions.size, renderOptions.size);\n this.draw_(renderOptions, context, 0, 0, 1);\n this.canvas_ = {};\n this.canvas_[1] = context.canvas; // canvas.width and height are rounded to the closest integer\n\n var size = context.canvas.width;\n var imageSize = size;\n var displacement = this.getDisplacement();\n this.hitDetectionImageSize_ = [renderOptions.size, renderOptions.size];\n this.createHitDetectionCanvas_(renderOptions);\n this.anchor_ = [size / 2 - displacement[0], size / 2 + displacement[1]];\n this.size_ = [size, size];\n this.imageSize_ = [imageSize, imageSize];\n };\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n * @param {CanvasRenderingContext2D} context The rendering context.\n * @param {number} x The origin for the symbol (x).\n * @param {number} y The origin for the symbol (y).\n * @param {number} pixelRatio The pixel ratio.\n */\n\n\n RegularShape.prototype.draw_ = function (renderOptions, context, x, y, pixelRatio) {\n var i, angle0, radiusC; // reset transform\n\n context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); // then move to (x, y)\n\n context.translate(x, y);\n context.beginPath();\n var points = this.points_;\n\n if (points === Infinity) {\n context.arc(renderOptions.size / 2, renderOptions.size / 2, this.radius_, 0, 2 * Math.PI, true);\n } else {\n var radius2 = this.radius2_ !== undefined ? this.radius2_ : this.radius_;\n\n if (radius2 !== this.radius_) {\n points = 2 * points;\n }\n\n for (i = 0; i <= points; i++) {\n angle0 = i * 2 * Math.PI / points - Math.PI / 2 + this.angle_;\n radiusC = i % 2 === 0 ? this.radius_ : radius2;\n context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0), renderOptions.size / 2 + radiusC * Math.sin(angle0));\n }\n }\n\n if (this.fill_) {\n var color = this.fill_.getColor();\n\n if (color === null) {\n color = defaultFillStyle;\n }\n\n context.fillStyle = asColorLike(color);\n context.fill();\n }\n\n if (this.stroke_) {\n context.strokeStyle = renderOptions.strokeStyle;\n context.lineWidth = renderOptions.strokeWidth;\n\n if (context.setLineDash && renderOptions.lineDash) {\n context.setLineDash(renderOptions.lineDash);\n context.lineDashOffset = renderOptions.lineDashOffset;\n }\n\n context.lineCap = renderOptions.lineCap;\n context.lineJoin = renderOptions.lineJoin;\n context.miterLimit = renderOptions.miterLimit;\n context.stroke();\n }\n\n context.closePath();\n };\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n */\n\n\n RegularShape.prototype.createHitDetectionCanvas_ = function (renderOptions) {\n this.hitDetectionCanvas_ = this.getImage(1);\n\n if (this.fill_) {\n var color = this.fill_.getColor(); // determine if fill is transparent (or pattern or gradient)\n\n var opacity = 0;\n\n if (typeof color === \'string\') {\n color = asArray(color);\n }\n\n if (color === null) {\n opacity = 1;\n } else if (Array.isArray(color)) {\n opacity = color.length === 4 ? color[3] : 1;\n }\n\n if (opacity === 0) {\n // if a transparent fill style is set, create an extra hit-detection image\n // with a default fill style\n var context = createCanvasContext2D(renderOptions.size, renderOptions.size);\n this.hitDetectionCanvas_ = context.canvas;\n this.drawHitDetectionCanvas_(renderOptions, context, 0, 0);\n }\n }\n };\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n * @param {CanvasRenderingContext2D} context The context.\n * @param {number} x The origin for the symbol (x).\n * @param {number} y The origin for the symbol (y).\n */\n\n\n RegularShape.prototype.drawHitDetectionCanvas_ = function (renderOptions, context, x, y) {\n // move to (x, y)\n context.translate(x, y);\n context.beginPath();\n var points = this.points_;\n\n if (points === Infinity) {\n context.arc(renderOptions.size / 2, renderOptions.size / 2, this.radius_, 0, 2 * Math.PI, true);\n } else {\n var radius2 = this.radius2_ !== undefined ? this.radius2_ : this.radius_;\n\n if (radius2 !== this.radius_) {\n points = 2 * points;\n }\n\n var i = void 0,\n radiusC = void 0,\n angle0 = void 0;\n\n for (i = 0; i <= points; i++) {\n angle0 = i * 2 * Math.PI / points - Math.PI / 2 + this.angle_;\n radiusC = i % 2 === 0 ? this.radius_ : radius2;\n context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0), renderOptions.size / 2 + radiusC * Math.sin(angle0));\n }\n }\n\n context.fillStyle = defaultFillStyle;\n context.fill();\n\n if (this.stroke_) {\n context.strokeStyle = renderOptions.strokeStyle;\n context.lineWidth = renderOptions.strokeWidth;\n\n if (renderOptions.lineDash) {\n context.setLineDash(renderOptions.lineDash);\n context.lineDashOffset = renderOptions.lineDashOffset;\n }\n\n context.stroke();\n }\n\n context.closePath();\n };\n\n return RegularShape;\n}(style_Image);\n\n/* harmony default export */ var style_RegularShape = (RegularShape);\n;// CONCATENATED MODULE: ./node_modules/ol/style/Circle.js\n/**\n * @module ol/style/Circle\n */\nvar Circle_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Fill.js").default} [fill] Fill style.\n * @property {number} radius Circle radius.\n * @property {import("./Stroke.js").default} [stroke] Stroke style.\n * @property {Array<number>} [displacement=[0,0]] displacement\n * @property {number|import("../size.js").Size} [scale=1] Scale. A two dimensional scale will produce an ellipse.\n * Unless two dimensional scaling is required a better result may be obtained with an appropriate setting for `radius`.\n * @property {number} [rotation=0] Rotation in radians\n * (positive rotation clockwise, meaningful only when used in conjunction with a two dimensional scale).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view\n * (meaningful only when used in conjunction with a two dimensional scale).\n */\n\n/**\n * @classdesc\n * Set circle style for vector features.\n * @api\n */\n\nvar Circle_CircleStyle =\n/** @class */\nfunction (_super) {\n Circle_extends(CircleStyle, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function CircleStyle(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n points: Infinity,\n fill: options.fill,\n radius: options.radius,\n stroke: options.stroke,\n scale: options.scale !== undefined ? options.scale : 1,\n rotation: options.rotation !== undefined ? options.rotation : 0,\n rotateWithView: options.rotateWithView !== undefined ? options.rotateWithView : false,\n displacement: options.displacement !== undefined ? options.displacement : [0, 0]\n }) || this;\n return _this;\n }\n /**\n * Clones the style.\n * @return {CircleStyle} The cloned style.\n * @api\n */\n\n\n CircleStyle.prototype.clone = function () {\n var scale = this.getScale();\n var style = new CircleStyle({\n fill: this.getFill() ? this.getFill().clone() : undefined,\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n radius: this.getRadius(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n displacement: this.getDisplacement().slice()\n });\n style.setOpacity(this.getOpacity());\n return style;\n };\n /**\n * Set the circle radius.\n *\n * @param {number} radius Circle radius.\n * @api\n */\n\n\n CircleStyle.prototype.setRadius = function (radius) {\n this.radius_ = radius;\n this.render();\n };\n\n return CircleStyle;\n}(style_RegularShape);\n\n/* harmony default export */ var Circle = (Circle_CircleStyle);\n;// CONCATENATED MODULE: ./node_modules/ol/style/Fill.js\n/**\n * @module ol/style/Fill\n */\n\n/**\n * @typedef {Object} Options\n * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [color=null] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n */\n\n/**\n * @classdesc\n * Set fill style for vector features.\n * @api\n */\nvar Fill_Fill =\n/** @class */\nfunction () {\n /**\n * @param {Options=} opt_options Options.\n */\n function Fill(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {import("../color.js").Color|import("../colorlike.js").ColorLike}\n */\n\n this.color_ = options.color !== undefined ? options.color : null;\n }\n /**\n * Clones the style. The color is not cloned if it is an {@link module:ol/colorlike~ColorLike}.\n * @return {Fill} The cloned style.\n * @api\n */\n\n\n Fill.prototype.clone = function () {\n var color = this.getColor();\n return new Fill({\n color: Array.isArray(color) ? color.slice() : color || undefined\n });\n };\n /**\n * Get the fill color.\n * @return {import("../color.js").Color|import("../colorlike.js").ColorLike} Color.\n * @api\n */\n\n\n Fill.prototype.getColor = function () {\n return this.color_;\n };\n /**\n * Set the color.\n *\n * @param {import("../color.js").Color|import("../colorlike.js").ColorLike} color Color.\n * @api\n */\n\n\n Fill.prototype.setColor = function (color) {\n this.color_ = color;\n };\n\n return Fill;\n}();\n\n/* harmony default export */ var style_Fill = (Fill_Fill);\n;// CONCATENATED MODULE: ./node_modules/ol/style/Stroke.js\n/**\n * @module ol/style/Stroke\n */\n\n/**\n * @typedef {Object} Options\n * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [color] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n * @property {CanvasLineCap} [lineCap=\'round\'] Line cap style: `butt`, `round`, or `square`.\n * @property {CanvasLineJoin} [lineJoin=\'round\'] Line join style: `bevel`, `round`, or `miter`.\n * @property {Array<number>} [lineDash] Line dash pattern. Default is `null` (no dash).\n * Please note that Internet Explorer 10 and lower do not support the `setLineDash` method on\n * the `CanvasRenderingContext2D` and therefore this option will have no visual effect in these browsers.\n * @property {number} [lineDashOffset=0] Line dash offset.\n * @property {number} [miterLimit=10] Miter limit.\n * @property {number} [width] Width.\n */\n\n/**\n * @classdesc\n * Set stroke style for vector features.\n * Note that the defaults given are the Canvas defaults, which will be used if\n * option is not defined. The `get` functions return whatever was entered in\n * the options; they will not return the default.\n * @api\n */\nvar Stroke_Stroke =\n/** @class */\nfunction () {\n /**\n * @param {Options=} opt_options Options.\n */\n function Stroke(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {import("../color.js").Color|import("../colorlike.js").ColorLike}\n */\n\n this.color_ = options.color !== undefined ? options.color : null;\n /**\n * @private\n * @type {CanvasLineCap|undefined}\n */\n\n this.lineCap_ = options.lineCap;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.lineDashOffset_ = options.lineDashOffset;\n /**\n * @private\n * @type {CanvasLineJoin|undefined}\n */\n\n this.lineJoin_ = options.lineJoin;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.miterLimit_ = options.miterLimit;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.width_ = options.width;\n }\n /**\n * Clones the style.\n * @return {Stroke} The cloned style.\n * @api\n */\n\n\n Stroke.prototype.clone = function () {\n var color = this.getColor();\n return new Stroke({\n color: Array.isArray(color) ? color.slice() : color || undefined,\n lineCap: this.getLineCap(),\n lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined,\n lineDashOffset: this.getLineDashOffset(),\n lineJoin: this.getLineJoin(),\n miterLimit: this.getMiterLimit(),\n width: this.getWidth()\n });\n };\n /**\n * Get the stroke color.\n * @return {import("../color.js").Color|import("../colorlike.js").ColorLike} Color.\n * @api\n */\n\n\n Stroke.prototype.getColor = function () {\n return this.color_;\n };\n /**\n * Get the line cap type for the stroke.\n * @return {CanvasLineCap|undefined} Line cap.\n * @api\n */\n\n\n Stroke.prototype.getLineCap = function () {\n return this.lineCap_;\n };\n /**\n * Get the line dash style for the stroke.\n * @return {Array<number>} Line dash.\n * @api\n */\n\n\n Stroke.prototype.getLineDash = function () {\n return this.lineDash_;\n };\n /**\n * Get the line dash offset for the stroke.\n * @return {number|undefined} Line dash offset.\n * @api\n */\n\n\n Stroke.prototype.getLineDashOffset = function () {\n return this.lineDashOffset_;\n };\n /**\n * Get the line join type for the stroke.\n * @return {CanvasLineJoin|undefined} Line join.\n * @api\n */\n\n\n Stroke.prototype.getLineJoin = function () {\n return this.lineJoin_;\n };\n /**\n * Get the miter limit for the stroke.\n * @return {number|undefined} Miter limit.\n * @api\n */\n\n\n Stroke.prototype.getMiterLimit = function () {\n return this.miterLimit_;\n };\n /**\n * Get the stroke width.\n * @return {number|undefined} Width.\n * @api\n */\n\n\n Stroke.prototype.getWidth = function () {\n return this.width_;\n };\n /**\n * Set the color.\n *\n * @param {import("../color.js").Color|import("../colorlike.js").ColorLike} color Color.\n * @api\n */\n\n\n Stroke.prototype.setColor = function (color) {\n this.color_ = color;\n };\n /**\n * Set the line cap.\n *\n * @param {CanvasLineCap|undefined} lineCap Line cap.\n * @api\n */\n\n\n Stroke.prototype.setLineCap = function (lineCap) {\n this.lineCap_ = lineCap;\n };\n /**\n * Set the line dash.\n *\n * Please note that Internet Explorer 10 and lower [do not support][mdn] the\n * `setLineDash` method on the `CanvasRenderingContext2D` and therefore this\n * property will have no visual effect in these browsers.\n *\n * [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility\n *\n * @param {Array<number>} lineDash Line dash.\n * @api\n */\n\n\n Stroke.prototype.setLineDash = function (lineDash) {\n this.lineDash_ = lineDash;\n };\n /**\n * Set the line dash offset.\n *\n * @param {number|undefined} lineDashOffset Line dash offset.\n * @api\n */\n\n\n Stroke.prototype.setLineDashOffset = function (lineDashOffset) {\n this.lineDashOffset_ = lineDashOffset;\n };\n /**\n * Set the line join.\n *\n * @param {CanvasLineJoin|undefined} lineJoin Line join.\n * @api\n */\n\n\n Stroke.prototype.setLineJoin = function (lineJoin) {\n this.lineJoin_ = lineJoin;\n };\n /**\n * Set the miter limit.\n *\n * @param {number|undefined} miterLimit Miter limit.\n * @api\n */\n\n\n Stroke.prototype.setMiterLimit = function (miterLimit) {\n this.miterLimit_ = miterLimit;\n };\n /**\n * Set the width.\n *\n * @param {number|undefined} width Width.\n * @api\n */\n\n\n Stroke.prototype.setWidth = function (width) {\n this.width_ = width;\n };\n\n return Stroke;\n}();\n\n/* harmony default export */ var style_Stroke = (Stroke_Stroke);\n;// CONCATENATED MODULE: ./node_modules/ol/style/Style.js\n/**\n * @module ol/style/Style\n */\n\n\n\n\n\n/**\n * A function that takes an {@link module:ol/Feature} and a `{number}`\n * representing the view\'s resolution. The function should return a\n * {@link module:ol/style/Style} or an array of them. This way e.g. a\n * vector layer can be styled. If the function returns `undefined`, the\n * feature will not be rendered.\n *\n * @typedef {function(import("../Feature.js").FeatureLike, number):(Style|Array<Style>|void)} StyleFunction\n */\n\n/**\n * A {@link Style}, an array of {@link Style}, or a {@link StyleFunction}.\n * @typedef {Style|Array<Style>|StyleFunction} StyleLike\n */\n\n/**\n * A function that takes an {@link module:ol/Feature} as argument and returns an\n * {@link module:ol/geom/Geometry} that will be rendered and styled for the feature.\n *\n * @typedef {function(import("../Feature.js").FeatureLike):\n * (import("../geom/Geometry.js").default|import("../render/Feature.js").default|undefined)} GeometryFunction\n */\n\n/**\n * Custom renderer function. Takes two arguments:\n *\n * 1. The pixel coordinates of the geometry in GeoJSON notation.\n * 2. The {@link module:ol/render~State} of the layer renderer.\n *\n * @typedef {function((import("../coordinate.js").Coordinate|Array<import("../coordinate.js").Coordinate>|Array<Array<import("../coordinate.js").Coordinate>>),import("../render.js").State): void}\n * RenderFunction\n */\n\n/**\n * @typedef {Object} Options\n * @property {string|import("../geom/Geometry.js").default|GeometryFunction} [geometry] Feature property or geometry\n * or function returning a geometry to render for this style.\n * @property {import("./Fill.js").default} [fill] Fill style.\n * @property {import("./Image.js").default} [image] Image style.\n * @property {RenderFunction} [renderer] Custom renderer. When configured, `fill`, `stroke` and `image` will be\n * ignored, and the provided function will be called with each render frame for each geometry.\n * @property {import("./Stroke.js").default} [stroke] Stroke style.\n * @property {import("./Text.js").default} [text] Text style.\n * @property {number} [zIndex] Z index.\n */\n\n/**\n * @classdesc\n * Container for vector feature rendering styles. Any changes made to the style\n * or its children through `set*()` methods will not take effect until the\n * feature or layer that uses the style is re-rendered.\n *\n * ## Feature styles\n *\n * If no style is defined, the following default style is used:\n * ```js\n * import {Fill, Stroke, Circle, Style} from \'ol/style\';\n *\n * var fill = new Fill({\n * color: \'rgba(255,255,255,0.4)\'\n * });\n * var stroke = new Stroke({\n * color: \'#3399CC\',\n * width: 1.25\n * });\n * var styles = [\n * new Style({\n * image: new Circle({\n * fill: fill,\n * stroke: stroke,\n * radius: 5\n * }),\n * fill: fill,\n * stroke: stroke\n * })\n * ];\n * ```\n *\n * A separate editing style has the following defaults:\n * ```js\n * import {Fill, Stroke, Circle, Style} from \'ol/style\';\n * import GeometryType from \'ol/geom/GeometryType\';\n *\n * var white = [255, 255, 255, 1];\n * var blue = [0, 153, 255, 1];\n * var width = 3;\n * styles[GeometryType.POLYGON] = [\n * new Style({\n * fill: new Fill({\n * color: [255, 255, 255, 0.5]\n * })\n * })\n * ];\n * styles[GeometryType.MULTI_POLYGON] =\n * styles[GeometryType.POLYGON];\n * styles[GeometryType.LINE_STRING] = [\n * new Style({\n * stroke: new Stroke({\n * color: white,\n * width: width + 2\n * })\n * }),\n * new Style({\n * stroke: new Stroke({\n * color: blue,\n * width: width\n * })\n * })\n * ];\n * styles[GeometryType.MULTI_LINE_STRING] =\n * styles[GeometryType.LINE_STRING];\n * styles[GeometryType.POINT] = [\n * new Style({\n * image: new Circle({\n * radius: width * 2,\n * fill: new Fill({\n * color: blue\n * }),\n * stroke: new Stroke({\n * color: white,\n * width: width / 2\n * })\n * }),\n * zIndex: Infinity\n * })\n * ];\n * styles[GeometryType.MULTI_POINT] =\n * styles[GeometryType.POINT];\n * styles[GeometryType.GEOMETRY_COLLECTION] =\n * styles[GeometryType.POLYGON].concat(\n * styles[GeometryType.LINE_STRING],\n * styles[GeometryType.POINT]\n * );\n * ```\n *\n * @api\n */\n\nvar Style =\n/** @class */\nfunction () {\n /**\n * @param {Options=} opt_options Style options.\n */\n function Style(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {string|import("../geom/Geometry.js").default|GeometryFunction}\n */\n\n this.geometry_ = null;\n /**\n * @private\n * @type {!GeometryFunction}\n */\n\n this.geometryFunction_ = defaultGeometryFunction;\n\n if (options.geometry !== undefined) {\n this.setGeometry(options.geometry);\n }\n /**\n * @private\n * @type {import("./Fill.js").default}\n */\n\n\n this.fill_ = options.fill !== undefined ? options.fill : null;\n /**\n * @private\n * @type {import("./Image.js").default}\n */\n\n this.image_ = options.image !== undefined ? options.image : null;\n /**\n * @private\n * @type {RenderFunction|null}\n */\n\n this.renderer_ = options.renderer !== undefined ? options.renderer : null;\n /**\n * @private\n * @type {import("./Stroke.js").default}\n */\n\n this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n /**\n * @private\n * @type {import("./Text.js").default}\n */\n\n this.text_ = options.text !== undefined ? options.text : null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.zIndex_ = options.zIndex;\n }\n /**\n * Clones the style.\n * @return {Style} The cloned style.\n * @api\n */\n\n\n Style.prototype.clone = function () {\n var geometry = this.getGeometry();\n\n if (geometry && typeof geometry === \'object\') {\n geometry =\n /** @type {import("../geom/Geometry.js").default} */\n geometry.clone();\n }\n\n return new Style({\n geometry: geometry,\n fill: this.getFill() ? this.getFill().clone() : undefined,\n image: this.getImage() ? this.getImage().clone() : undefined,\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n text: this.getText() ? this.getText().clone() : undefined,\n zIndex: this.getZIndex()\n });\n };\n /**\n * Get the custom renderer function that was configured with\n * {@link #setRenderer} or the `renderer` constructor option.\n * @return {RenderFunction|null} Custom renderer function.\n * @api\n */\n\n\n Style.prototype.getRenderer = function () {\n return this.renderer_;\n };\n /**\n * Sets a custom renderer function for this style. When set, `fill`, `stroke`\n * and `image` options of the style will be ignored.\n * @param {RenderFunction|null} renderer Custom renderer function.\n * @api\n */\n\n\n Style.prototype.setRenderer = function (renderer) {\n this.renderer_ = renderer;\n };\n /**\n * Get the geometry to be rendered.\n * @return {string|import("../geom/Geometry.js").default|GeometryFunction}\n * Feature property or geometry or function that returns the geometry that will\n * be rendered with this style.\n * @api\n */\n\n\n Style.prototype.getGeometry = function () {\n return this.geometry_;\n };\n /**\n * Get the function used to generate a geometry for rendering.\n * @return {!GeometryFunction} Function that is called with a feature\n * and returns the geometry to render instead of the feature\'s geometry.\n * @api\n */\n\n\n Style.prototype.getGeometryFunction = function () {\n return this.geometryFunction_;\n };\n /**\n * Get the fill style.\n * @return {import("./Fill.js").default} Fill style.\n * @api\n */\n\n\n Style.prototype.getFill = function () {\n return this.fill_;\n };\n /**\n * Set the fill style.\n * @param {import("./Fill.js").default} fill Fill style.\n * @api\n */\n\n\n Style.prototype.setFill = function (fill) {\n this.fill_ = fill;\n };\n /**\n * Get the image style.\n * @return {import("./Image.js").default} Image style.\n * @api\n */\n\n\n Style.prototype.getImage = function () {\n return this.image_;\n };\n /**\n * Set the image style.\n * @param {import("./Image.js").default} image Image style.\n * @api\n */\n\n\n Style.prototype.setImage = function (image) {\n this.image_ = image;\n };\n /**\n * Get the stroke style.\n * @return {import("./Stroke.js").default} Stroke style.\n * @api\n */\n\n\n Style.prototype.getStroke = function () {\n return this.stroke_;\n };\n /**\n * Set the stroke style.\n * @param {import("./Stroke.js").default} stroke Stroke style.\n * @api\n */\n\n\n Style.prototype.setStroke = function (stroke) {\n this.stroke_ = stroke;\n };\n /**\n * Get the text style.\n * @return {import("./Text.js").default} Text style.\n * @api\n */\n\n\n Style.prototype.getText = function () {\n return this.text_;\n };\n /**\n * Set the text style.\n * @param {import("./Text.js").default} text Text style.\n * @api\n */\n\n\n Style.prototype.setText = function (text) {\n this.text_ = text;\n };\n /**\n * Get the z-index for the style.\n * @return {number|undefined} ZIndex.\n * @api\n */\n\n\n Style.prototype.getZIndex = function () {\n return this.zIndex_;\n };\n /**\n * Set a geometry that is rendered instead of the feature\'s geometry.\n *\n * @param {string|import("../geom/Geometry.js").default|GeometryFunction} geometry\n * Feature property or geometry or function returning a geometry to render\n * for this style.\n * @api\n */\n\n\n Style.prototype.setGeometry = function (geometry) {\n if (typeof geometry === \'function\') {\n this.geometryFunction_ = geometry;\n } else if (typeof geometry === \'string\') {\n this.geometryFunction_ = function (feature) {\n return (\n /** @type {import("../geom/Geometry.js").default} */\n feature.get(geometry)\n );\n };\n } else if (!geometry) {\n this.geometryFunction_ = defaultGeometryFunction;\n } else if (geometry !== undefined) {\n this.geometryFunction_ = function () {\n return (\n /** @type {import("../geom/Geometry.js").default} */\n geometry\n );\n };\n }\n\n this.geometry_ = geometry;\n };\n /**\n * Set the z-index.\n *\n * @param {number|undefined} zIndex ZIndex.\n * @api\n */\n\n\n Style.prototype.setZIndex = function (zIndex) {\n this.zIndex_ = zIndex;\n };\n\n return Style;\n}();\n/**\n * Convert the provided object into a style function. Functions passed through\n * unchanged. Arrays of Style or single style objects wrapped in a\n * new style function.\n * @param {StyleFunction|Array<Style>|Style} obj\n * A style function, a single style, or an array of styles.\n * @return {StyleFunction} A style function.\n */\n\n\nfunction toFunction(obj) {\n var styleFunction;\n\n if (typeof obj === \'function\') {\n styleFunction = obj;\n } else {\n /**\n * @type {Array<Style>}\n */\n var styles_1;\n\n if (Array.isArray(obj)) {\n styles_1 = obj;\n } else {\n asserts_assert(typeof\n /** @type {?} */\n obj.getZIndex === \'function\', 41); // Expected an `Style` or an array of `Style`\n\n var style =\n /** @type {Style} */\n obj;\n styles_1 = [style];\n }\n\n styleFunction = function styleFunction() {\n return styles_1;\n };\n }\n\n return styleFunction;\n}\n/**\n * @type {Array<Style>}\n */\n\nvar defaultStyles = null;\n/**\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {number} resolution Resolution.\n * @return {Array<Style>} Style.\n */\n\nfunction createDefaultStyle(feature, resolution) {\n // We don\'t use an immediately-invoked function\n // and a closure so we don\'t get an error at script evaluation time in\n // browsers that do not support Canvas. (import("./Circle.js").CircleStyle does\n // canvas.getContext(\'2d\') at construction time, which will cause an.error\n // in such browsers.)\n if (!defaultStyles) {\n var fill = new style_Fill({\n color: \'rgba(255,255,255,0.4)\'\n });\n var stroke = new style_Stroke({\n color: \'#3399CC\',\n width: 1.25\n });\n defaultStyles = [new Style({\n image: new Circle({\n fill: fill,\n stroke: stroke,\n radius: 5\n }),\n fill: fill,\n stroke: stroke\n })];\n }\n\n return defaultStyles;\n}\n/**\n * Default styles for editing features.\n * @return {Object<import("../geom/GeometryType.js").default, Array<Style>>} Styles\n */\n\nfunction createEditingStyle() {\n /** @type {Object<import("../geom/GeometryType.js").default, Array<Style>>} */\n var styles = {};\n var white = [255, 255, 255, 1];\n var blue = [0, 153, 255, 1];\n var width = 3;\n styles[GeometryType.POLYGON] = [new Style({\n fill: new Fill({\n color: [255, 255, 255, 0.5]\n })\n })];\n styles[GeometryType.MULTI_POLYGON] = styles[GeometryType.POLYGON];\n styles[GeometryType.LINE_STRING] = [new Style({\n stroke: new Stroke({\n color: white,\n width: width + 2\n })\n }), new Style({\n stroke: new Stroke({\n color: blue,\n width: width\n })\n })];\n styles[GeometryType.MULTI_LINE_STRING] = styles[GeometryType.LINE_STRING];\n styles[GeometryType.CIRCLE] = styles[GeometryType.POLYGON].concat(styles[GeometryType.LINE_STRING]);\n styles[GeometryType.POINT] = [new Style({\n image: new CircleStyle({\n radius: width * 2,\n fill: new Fill({\n color: blue\n }),\n stroke: new Stroke({\n color: white,\n width: width / 2\n })\n }),\n zIndex: Infinity\n })];\n styles[GeometryType.MULTI_POINT] = styles[GeometryType.POINT];\n styles[GeometryType.GEOMETRY_COLLECTION] = styles[GeometryType.POLYGON].concat(styles[GeometryType.LINE_STRING], styles[GeometryType.POINT]);\n return styles;\n}\n/**\n * Function that is called with a feature and returns its default geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature to get the geometry for.\n * @return {import("../geom/Geometry.js").default|import("../render/Feature.js").default|undefined} Geometry to render.\n */\n\nfunction defaultGeometryFunction(feature) {\n return feature.getGeometry();\n}\n\n/* harmony default export */ var style_Style = (Style);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/BaseVector.js\nvar BaseVector_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/BaseVector\n */\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-layer\'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {import("../render.js").OrderFunction} [renderOrder] Render order. Function to be used when sorting\n * features before rendering. By default features are drawn in the order that they are created. Use\n * `null` to avoid the sort, but get an undefined draw order.\n * @property {number} [renderBuffer=100] The buffer in pixels around the viewport extent used by the\n * renderer when getting features from the vector source for the rendering or hit-detection.\n * Recommended value: the size of the largest symbol, line width or label.\n * @property {import("../source/Vector.js").default} [source] Source.\n * @property {import("../PluggableMap.js").default} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link module:ol/Map#addLayer}.\n * @property {boolean} [declutter=false] Declutter images and text. Decluttering is applied to all\n * image and text styles of all Vector and VectorTile layers that have set this to `true`. The priority\n * is defined by the z-index of the layer, the `zIndex` of the style and the render order of features.\n * Higher z-index means higher priority. Within the same z-index, a feature rendered before another has\n * higher priority.\n * @property {import("../style/Style.js").StyleLike|null} [style] Layer style. When set to `null`, only\n * features that have their own style will be rendered. See {@link module:ol/style} for default style\n * which will be used if this is not set.\n * @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will\n * be recreated during animations. This means that no vectors will be shown clipped, but the\n * setting will have a performance impact for large amounts of vector data. When set to `false`,\n * batches will be recreated when no animation is active.\n * @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will\n * be recreated during interactions. See also `updateWhileAnimating`.\n */\n\n/**\n * @enum {string}\n * @private\n */\n\nvar BaseVector_Property = {\n RENDER_ORDER: \'renderOrder\'\n};\n/**\n * @classdesc\n * Vector data that is rendered client-side.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: \'My Title\'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @template {import("../source/Vector.js").default|import("../source/VectorTile.js").default} VectorSourceType\n * @extends {Layer<VectorSourceType>}\n * @api\n */\n\nvar BaseVectorLayer =\n/** @class */\nfunction (_super) {\n BaseVector_extends(BaseVectorLayer, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function BaseVectorLayer(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var baseOptions = obj_assign({}, options);\n delete baseOptions.style;\n delete baseOptions.renderBuffer;\n delete baseOptions.updateWhileAnimating;\n delete baseOptions.updateWhileInteracting;\n _this = _super.call(this, baseOptions) || this;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.declutter_ = options.declutter !== undefined ? options.declutter : false;\n /**\n * @type {number}\n * @private\n */\n\n _this.renderBuffer_ = options.renderBuffer !== undefined ? options.renderBuffer : 100;\n /**\n * User provided style.\n * @type {import("../style/Style.js").StyleLike}\n * @private\n */\n\n _this.style_ = null;\n /**\n * Style function for use within the library.\n * @type {import("../style/Style.js").StyleFunction|undefined}\n * @private\n */\n\n _this.styleFunction_ = undefined;\n\n _this.setStyle(options.style);\n /**\n * @type {boolean}\n * @private\n */\n\n\n _this.updateWhileAnimating_ = options.updateWhileAnimating !== undefined ? options.updateWhileAnimating : false;\n /**\n * @type {boolean}\n * @private\n */\n\n _this.updateWhileInteracting_ = options.updateWhileInteracting !== undefined ? options.updateWhileInteracting : false;\n return _this;\n }\n /**\n * @return {boolean} Declutter.\n */\n\n\n BaseVectorLayer.prototype.getDeclutter = function () {\n return this.declutter_;\n };\n /**\n * Get the topmost feature that intersects the given pixel on the viewport. Returns a promise\n * that resolves with an array of features. The array will either contain the topmost feature\n * when a hit was detected, or it will be empty.\n *\n * The hit detection algorithm used for this method is optimized for performance, but is less\n * accurate than the one used in {@link import("../PluggableMap.js").default#getFeaturesAtPixel}: Text\n * is not considered, and icons are only represented by their bounding box instead of the exact\n * image.\n *\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with an array of features.\n * @api\n */\n\n\n BaseVectorLayer.prototype.getFeatures = function (pixel) {\n return _super.prototype.getFeatures.call(this, pixel);\n };\n /**\n * @return {number|undefined} Render buffer.\n */\n\n\n BaseVectorLayer.prototype.getRenderBuffer = function () {\n return this.renderBuffer_;\n };\n /**\n * @return {function(import("../Feature.js").default, import("../Feature.js").default): number|null|undefined} Render\n * order.\n */\n\n\n BaseVectorLayer.prototype.getRenderOrder = function () {\n return (\n /** @type {import("../render.js").OrderFunction|null|undefined} */\n this.get(BaseVector_Property.RENDER_ORDER)\n );\n };\n /**\n * Get the style for features. This returns whatever was passed to the `style`\n * option at construction or to the `setStyle` method.\n * @return {import("../style/Style.js").StyleLike|null|undefined} Layer style.\n * @api\n */\n\n\n BaseVectorLayer.prototype.getStyle = function () {\n return this.style_;\n };\n /**\n * Get the style function.\n * @return {import("../style/Style.js").StyleFunction|undefined} Layer style function.\n * @api\n */\n\n\n BaseVectorLayer.prototype.getStyleFunction = function () {\n return this.styleFunction_;\n };\n /**\n * @return {boolean} Whether the rendered layer should be updated while\n * animating.\n */\n\n\n BaseVectorLayer.prototype.getUpdateWhileAnimating = function () {\n return this.updateWhileAnimating_;\n };\n /**\n * @return {boolean} Whether the rendered layer should be updated while\n * interacting.\n */\n\n\n BaseVectorLayer.prototype.getUpdateWhileInteracting = function () {\n return this.updateWhileInteracting_;\n };\n /**\n * Render declutter items for this layer\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n BaseVectorLayer.prototype.renderDeclutter = function (frameState) {\n if (!frameState.declutterTree) {\n frameState.declutterTree = new (rbush_min_default())(9);\n }\n /** @type {*} */\n\n\n this.getRenderer().renderDeclutter(frameState);\n };\n /**\n * @param {import("../render.js").OrderFunction|null|undefined} renderOrder\n * Render order.\n */\n\n\n BaseVectorLayer.prototype.setRenderOrder = function (renderOrder) {\n this.set(BaseVector_Property.RENDER_ORDER, renderOrder);\n };\n /**\n * Set the style for features. This can be a single style object, an array\n * of styles, or a function that takes a feature and resolution and returns\n * an array of styles. If set to `null`, the layer has no style (a `null` style),\n * so only features that have their own styles will be rendered in the layer. Call\n * `setStyle()` without arguments to reset to the default style. See\n * {@link module:ol/style} for information on the default style.\n * @param {(import("../style/Style.js").StyleLike|null)=} opt_style Layer style.\n * @api\n */\n\n\n BaseVectorLayer.prototype.setStyle = function (opt_style) {\n this.style_ = opt_style !== undefined ? opt_style : createDefaultStyle;\n this.styleFunction_ = opt_style === null ? undefined : toFunction(this.style_);\n this.changed();\n };\n\n return BaseVectorLayer;\n}(layer_Layer);\n\n/* harmony default export */ var BaseVector = (BaseVectorLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Instruction.js\n/**\n * @module ol/render/canvas/Instruction\n */\n\n/**\n * @enum {number}\n */\nvar Instruction = {\n BEGIN_GEOMETRY: 0,\n BEGIN_PATH: 1,\n CIRCLE: 2,\n CLOSE_PATH: 3,\n CUSTOM: 4,\n DRAW_CHARS: 5,\n DRAW_IMAGE: 6,\n END_GEOMETRY: 7,\n FILL: 8,\n MOVE_TO_LINE_TO: 9,\n SET_FILL_STYLE: 10,\n SET_STROKE_STYLE: 11,\n STROKE: 12\n};\n/**\n * @type {Array<Instruction>}\n */\n\nvar fillInstruction = [Instruction.FILL];\n/**\n * @type {Array<Instruction>}\n */\n\nvar strokeInstruction = [Instruction.STROKE];\n/**\n * @type {Array<Instruction>}\n */\n\nvar beginPathInstruction = [Instruction.BEGIN_PATH];\n/**\n * @type {Array<Instruction>}\n */\n\nvar closePathInstruction = [Instruction.CLOSE_PATH];\n/* harmony default export */ var canvas_Instruction = (Instruction);\n;// CONCATENATED MODULE: ./node_modules/ol/render/VectorContext.js\n/**\n * @module ol/render/VectorContext\n */\n\n/**\n * @classdesc\n * Context for drawing geometries. A vector context is available on render\n * events and does not need to be constructed directly.\n * @api\n */\nvar VectorContext =\n/** @class */\nfunction () {\n function VectorContext() {}\n /**\n * Render a geometry with a custom renderer.\n *\n * @param {import("../geom/SimpleGeometry.js").default} geometry Geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {Function} renderer Renderer.\n */\n\n\n VectorContext.prototype.drawCustom = function (geometry, feature, renderer) {};\n /**\n * Render a geometry.\n *\n * @param {import("../geom/Geometry.js").default} geometry The geometry to render.\n */\n\n\n VectorContext.prototype.drawGeometry = function (geometry) {};\n /**\n * Set the rendering style.\n *\n * @param {import("../style/Style.js").default} style The rendering style.\n */\n\n\n VectorContext.prototype.setStyle = function (style) {};\n /**\n * @param {import("../geom/Circle.js").default} circleGeometry Circle geometry.\n * @param {import("../Feature.js").default} feature Feature.\n */\n\n\n VectorContext.prototype.drawCircle = function (circleGeometry, feature) {};\n /**\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("../style/Style.js").default} style Style.\n */\n\n\n VectorContext.prototype.drawFeature = function (feature, style) {};\n /**\n * @param {import("../geom/GeometryCollection.js").default} geometryCollectionGeometry Geometry collection.\n * @param {import("../Feature.js").default} feature Feature.\n */\n\n\n VectorContext.prototype.drawGeometryCollection = function (geometryCollectionGeometry, feature) {};\n /**\n * @param {import("../geom/LineString.js").default|import("./Feature.js").default} lineStringGeometry Line string geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawLineString = function (lineStringGeometry, feature) {};\n /**\n * @param {import("../geom/MultiLineString.js").default|import("./Feature.js").default} multiLineStringGeometry MultiLineString geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawMultiLineString = function (multiLineStringGeometry, feature) {};\n /**\n * @param {import("../geom/MultiPoint.js").default|import("./Feature.js").default} multiPointGeometry MultiPoint geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawMultiPoint = function (multiPointGeometry, feature) {};\n /**\n * @param {import("../geom/MultiPolygon.js").default} multiPolygonGeometry MultiPolygon geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawMultiPolygon = function (multiPolygonGeometry, feature) {};\n /**\n * @param {import("../geom/Point.js").default|import("./Feature.js").default} pointGeometry Point geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawPoint = function (pointGeometry, feature) {};\n /**\n * @param {import("../geom/Polygon.js").default|import("./Feature.js").default} polygonGeometry Polygon geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawPolygon = function (polygonGeometry, feature) {};\n /**\n * @param {import("../geom/SimpleGeometry.js").default|import("./Feature.js").default} geometry Geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawText = function (geometry, feature) {};\n /**\n * @param {import("../style/Fill.js").default} fillStyle Fill style.\n * @param {import("../style/Stroke.js").default} strokeStyle Stroke style.\n */\n\n\n VectorContext.prototype.setFillStrokeStyle = function (fillStyle, strokeStyle) {};\n /**\n * @param {import("../style/Image.js").default} imageStyle Image style.\n * @param {import("../render/canvas.js").DeclutterImageWithText=} opt_declutterImageWithText Shared data for combined decluttering with a text style.\n */\n\n\n VectorContext.prototype.setImageStyle = function (imageStyle, opt_declutterImageWithText) {};\n /**\n * @param {import("../style/Text.js").default} textStyle Text style.\n * @param {import("../render/canvas.js").DeclutterImageWithText=} opt_declutterImageWithText Shared data for combined decluttering with an image style.\n */\n\n\n VectorContext.prototype.setTextStyle = function (textStyle, opt_declutterImageWithText) {};\n\n return VectorContext;\n}();\n\n/* harmony default export */ var render_VectorContext = (VectorContext);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Builder.js\nvar Builder_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/render/canvas/Builder\n */\n\n\n\n\n\n\n\n\n\n\n\n\nvar CanvasBuilder =\n/** @class */\nfunction (_super) {\n Builder_extends(CanvasBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n\n\n function CanvasBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {number}\n */\n\n\n _this.tolerance = tolerance;\n /**\n * @protected\n * @const\n * @type {import("../../extent.js").Extent}\n */\n\n _this.maxExtent = maxExtent;\n /**\n * @protected\n * @type {number}\n */\n\n _this.pixelRatio = pixelRatio;\n /**\n * @protected\n * @type {number}\n */\n\n _this.maxLineWidth = 0;\n /**\n * @protected\n * @const\n * @type {number}\n */\n\n _this.resolution = resolution;\n /**\n * @private\n * @type {Array<*>}\n */\n\n _this.beginGeometryInstruction1_ = null;\n /**\n * @private\n * @type {Array<*>}\n */\n\n _this.beginGeometryInstruction2_ = null;\n /**\n * @private\n * @type {import("../../extent.js").Extent}\n */\n\n _this.bufferedMaxExtent_ = null;\n /**\n * @protected\n * @type {Array<*>}\n */\n\n _this.instructions = [];\n /**\n * @protected\n * @type {Array<number>}\n */\n\n _this.coordinates = [];\n /**\n * @private\n * @type {import("../../coordinate.js").Coordinate}\n */\n\n _this.tmpCoordinate_ = [];\n /**\n * @protected\n * @type {Array<*>}\n */\n\n _this.hitDetectionInstructions = [];\n /**\n * @protected\n * @type {import("../canvas.js").FillStrokeState}\n */\n\n _this.state =\n /** @type {import("../canvas.js").FillStrokeState} */\n {};\n return _this;\n }\n /**\n * @protected\n * @param {Array<number>} dashArray Dash array.\n * @return {Array<number>} Dash array with pixel ratio applied\n */\n\n\n CanvasBuilder.prototype.applyPixelRatio = function (dashArray) {\n var pixelRatio = this.pixelRatio;\n return pixelRatio == 1 ? dashArray : dashArray.map(function (dash) {\n return dash * pixelRatio;\n });\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} stride Stride.\n * @protected\n * @return {number} My end\n */\n\n\n CanvasBuilder.prototype.appendFlatPointCoordinates = function (flatCoordinates, stride) {\n var extent = this.getBufferedMaxExtent();\n var tmpCoord = this.tmpCoordinate_;\n var coordinates = this.coordinates;\n var myEnd = coordinates.length;\n\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n tmpCoord[0] = flatCoordinates[i];\n tmpCoord[1] = flatCoordinates[i + 1];\n\n if (containsCoordinate(extent, tmpCoord)) {\n coordinates[myEnd++] = tmpCoord[0];\n coordinates[myEnd++] = tmpCoord[1];\n }\n }\n\n return myEnd;\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {boolean} closed Last input coordinate equals first.\n * @param {boolean} skipFirst Skip first coordinate.\n * @protected\n * @return {number} My end.\n */\n\n\n CanvasBuilder.prototype.appendFlatLineCoordinates = function (flatCoordinates, offset, end, stride, closed, skipFirst) {\n var coordinates = this.coordinates;\n var myEnd = coordinates.length;\n var extent = this.getBufferedMaxExtent();\n\n if (skipFirst) {\n offset += stride;\n }\n\n var lastXCoord = flatCoordinates[offset];\n var lastYCoord = flatCoordinates[offset + 1];\n var nextCoord = this.tmpCoordinate_;\n var skipped = true;\n var i, lastRel, nextRel;\n\n for (i = offset + stride; i < end; i += stride) {\n nextCoord[0] = flatCoordinates[i];\n nextCoord[1] = flatCoordinates[i + 1];\n nextRel = coordinateRelationship(extent, nextCoord);\n\n if (nextRel !== lastRel) {\n if (skipped) {\n coordinates[myEnd++] = lastXCoord;\n coordinates[myEnd++] = lastYCoord;\n skipped = false;\n }\n\n coordinates[myEnd++] = nextCoord[0];\n coordinates[myEnd++] = nextCoord[1];\n } else if (nextRel === Relationship.INTERSECTING) {\n coordinates[myEnd++] = nextCoord[0];\n coordinates[myEnd++] = nextCoord[1];\n skipped = false;\n } else {\n skipped = true;\n }\n\n lastXCoord = nextCoord[0];\n lastYCoord = nextCoord[1];\n lastRel = nextRel;\n } // Last coordinate equals first or only one point to append:\n\n\n if (closed && skipped || i === offset + stride) {\n coordinates[myEnd++] = lastXCoord;\n coordinates[myEnd++] = lastYCoord;\n }\n\n return myEnd;\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array<number>} builderEnds Builder ends.\n * @return {number} Offset.\n */\n\n\n CanvasBuilder.prototype.drawCustomCoordinates_ = function (flatCoordinates, offset, ends, stride, builderEnds) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var builderEnd = this.appendFlatLineCoordinates(flatCoordinates, offset, end, stride, false, false);\n builderEnds.push(builderEnd);\n offset = end;\n }\n\n return offset;\n };\n /**\n * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @param {Function} renderer Renderer.\n */\n\n\n CanvasBuilder.prototype.drawCustom = function (geometry, feature, renderer) {\n this.beginGeometry(geometry, feature);\n var type = geometry.getType();\n var stride = geometry.getStride();\n var builderBegin = this.coordinates.length;\n var flatCoordinates, builderEnd, builderEnds, builderEndss;\n var offset;\n\n if (type == geom_GeometryType.MULTI_POLYGON) {\n flatCoordinates =\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry.getOrientedFlatCoordinates();\n builderEndss = [];\n var endss =\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry.getEndss();\n offset = 0;\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var myEnds = [];\n offset = this.drawCustomCoordinates_(flatCoordinates, offset, endss[i], stride, myEnds);\n builderEndss.push(myEnds);\n }\n\n this.instructions.push([canvas_Instruction.CUSTOM, builderBegin, builderEndss, geometry, renderer, inflateMultiCoordinatesArray]);\n } else if (type == geom_GeometryType.POLYGON || type == geom_GeometryType.MULTI_LINE_STRING) {\n builderEnds = [];\n flatCoordinates = type == geom_GeometryType.POLYGON ?\n /** @type {import("../../geom/Polygon.js").default} */\n geometry.getOrientedFlatCoordinates() : geometry.getFlatCoordinates();\n offset = this.drawCustomCoordinates_(flatCoordinates, 0,\n /** @type {import("../../geom/Polygon.js").default|import("../../geom/MultiLineString.js").default} */\n geometry.getEnds(), stride, builderEnds);\n this.instructions.push([canvas_Instruction.CUSTOM, builderBegin, builderEnds, geometry, renderer, inflateCoordinatesArray]);\n } else if (type == geom_GeometryType.LINE_STRING || type == geom_GeometryType.CIRCLE) {\n flatCoordinates = geometry.getFlatCoordinates();\n builderEnd = this.appendFlatLineCoordinates(flatCoordinates, 0, flatCoordinates.length, stride, false, false);\n this.instructions.push([canvas_Instruction.CUSTOM, builderBegin, builderEnd, geometry, renderer, inflateCoordinates]);\n } else if (type == geom_GeometryType.MULTI_POINT) {\n flatCoordinates = geometry.getFlatCoordinates();\n builderEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);\n\n if (builderEnd > builderBegin) {\n this.instructions.push([canvas_Instruction.CUSTOM, builderBegin, builderEnd, geometry, renderer, inflateCoordinates]);\n }\n } else if (type == geom_GeometryType.POINT) {\n flatCoordinates = geometry.getFlatCoordinates();\n this.coordinates.push(flatCoordinates[0], flatCoordinates[1]);\n builderEnd = this.coordinates.length;\n this.instructions.push([canvas_Instruction.CUSTOM, builderBegin, builderEnd, geometry, renderer]);\n }\n\n this.endGeometry(feature);\n };\n /**\n * @protected\n * @param {import("../../geom/Geometry").default|import("../Feature.js").default} geometry The geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasBuilder.prototype.beginGeometry = function (geometry, feature) {\n this.beginGeometryInstruction1_ = [canvas_Instruction.BEGIN_GEOMETRY, feature, 0, geometry];\n this.instructions.push(this.beginGeometryInstruction1_);\n this.beginGeometryInstruction2_ = [canvas_Instruction.BEGIN_GEOMETRY, feature, 0, geometry];\n this.hitDetectionInstructions.push(this.beginGeometryInstruction2_);\n };\n /**\n * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.\n */\n\n\n CanvasBuilder.prototype.finish = function () {\n return {\n instructions: this.instructions,\n hitDetectionInstructions: this.hitDetectionInstructions,\n coordinates: this.coordinates\n };\n };\n /**\n * Reverse the hit detection instructions.\n */\n\n\n CanvasBuilder.prototype.reverseHitDetectionInstructions = function () {\n var hitDetectionInstructions = this.hitDetectionInstructions; // step 1 - reverse array\n\n hitDetectionInstructions.reverse(); // step 2 - reverse instructions within geometry blocks\n\n var i;\n var n = hitDetectionInstructions.length;\n var instruction;\n var type;\n var begin = -1;\n\n for (i = 0; i < n; ++i) {\n instruction = hitDetectionInstructions[i];\n type =\n /** @type {import("./Instruction.js").default} */\n instruction[0];\n\n if (type == canvas_Instruction.END_GEOMETRY) {\n begin = i;\n } else if (type == canvas_Instruction.BEGIN_GEOMETRY) {\n instruction[2] = i;\n reverseSubArray(this.hitDetectionInstructions, begin, i);\n begin = -1;\n }\n }\n };\n /**\n * @param {import("../../style/Fill.js").default} fillStyle Fill style.\n * @param {import("../../style/Stroke.js").default} strokeStyle Stroke style.\n */\n\n\n CanvasBuilder.prototype.setFillStrokeStyle = function (fillStyle, strokeStyle) {\n var state = this.state;\n\n if (fillStyle) {\n var fillStyleColor = fillStyle.getColor();\n state.fillStyle = asColorLike(fillStyleColor ? fillStyleColor : defaultFillStyle);\n } else {\n state.fillStyle = undefined;\n }\n\n if (strokeStyle) {\n var strokeStyleColor = strokeStyle.getColor();\n state.strokeStyle = asColorLike(strokeStyleColor ? strokeStyleColor : defaultStrokeStyle);\n var strokeStyleLineCap = strokeStyle.getLineCap();\n state.lineCap = strokeStyleLineCap !== undefined ? strokeStyleLineCap : defaultLineCap;\n var strokeStyleLineDash = strokeStyle.getLineDash();\n state.lineDash = strokeStyleLineDash ? strokeStyleLineDash.slice() : defaultLineDash;\n var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();\n state.lineDashOffset = strokeStyleLineDashOffset ? strokeStyleLineDashOffset : defaultLineDashOffset;\n var strokeStyleLineJoin = strokeStyle.getLineJoin();\n state.lineJoin = strokeStyleLineJoin !== undefined ? strokeStyleLineJoin : defaultLineJoin;\n var strokeStyleWidth = strokeStyle.getWidth();\n state.lineWidth = strokeStyleWidth !== undefined ? strokeStyleWidth : defaultLineWidth;\n var strokeStyleMiterLimit = strokeStyle.getMiterLimit();\n state.miterLimit = strokeStyleMiterLimit !== undefined ? strokeStyleMiterLimit : defaultMiterLimit;\n\n if (state.lineWidth > this.maxLineWidth) {\n this.maxLineWidth = state.lineWidth; // invalidate the buffered max extent cache\n\n this.bufferedMaxExtent_ = null;\n }\n } else {\n state.strokeStyle = undefined;\n state.lineCap = undefined;\n state.lineDash = null;\n state.lineDashOffset = undefined;\n state.lineJoin = undefined;\n state.lineWidth = undefined;\n state.miterLimit = undefined;\n }\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n * @return {Array<*>} Fill instruction.\n */\n\n\n CanvasBuilder.prototype.createFill = function (state) {\n var fillStyle = state.fillStyle;\n /** @type {Array<*>} */\n\n var fillInstruction = [canvas_Instruction.SET_FILL_STYLE, fillStyle];\n\n if (typeof fillStyle !== \'string\') {\n // Fill is a pattern or gradient - align it!\n fillInstruction.push(true);\n }\n\n return fillInstruction;\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n */\n\n\n CanvasBuilder.prototype.applyStroke = function (state) {\n this.instructions.push(this.createStroke(state));\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n * @return {Array<*>} Stroke instruction.\n */\n\n\n CanvasBuilder.prototype.createStroke = function (state) {\n return [canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth * this.pixelRatio, state.lineCap, state.lineJoin, state.miterLimit, this.applyPixelRatio(state.lineDash), state.lineDashOffset * this.pixelRatio];\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n * @param {function(this:CanvasBuilder, import("../canvas.js").FillStrokeState):Array<*>} createFill Create fill.\n */\n\n\n CanvasBuilder.prototype.updateFillStyle = function (state, createFill) {\n var fillStyle = state.fillStyle;\n\n if (typeof fillStyle !== \'string\' || state.currentFillStyle != fillStyle) {\n if (fillStyle !== undefined) {\n this.instructions.push(createFill.call(this, state));\n }\n\n state.currentFillStyle = fillStyle;\n }\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n * @param {function(this:CanvasBuilder, import("../canvas.js").FillStrokeState): void} applyStroke Apply stroke.\n */\n\n\n CanvasBuilder.prototype.updateStrokeStyle = function (state, applyStroke) {\n var strokeStyle = state.strokeStyle;\n var lineCap = state.lineCap;\n var lineDash = state.lineDash;\n var lineDashOffset = state.lineDashOffset;\n var lineJoin = state.lineJoin;\n var lineWidth = state.lineWidth;\n var miterLimit = state.miterLimit;\n\n if (state.currentStrokeStyle != strokeStyle || state.currentLineCap != lineCap || lineDash != state.currentLineDash && !equals(state.currentLineDash, lineDash) || state.currentLineDashOffset != lineDashOffset || state.currentLineJoin != lineJoin || state.currentLineWidth != lineWidth || state.currentMiterLimit != miterLimit) {\n if (strokeStyle !== undefined) {\n applyStroke.call(this, state);\n }\n\n state.currentStrokeStyle = strokeStyle;\n state.currentLineCap = lineCap;\n state.currentLineDash = lineDash;\n state.currentLineDashOffset = lineDashOffset;\n state.currentLineJoin = lineJoin;\n state.currentLineWidth = lineWidth;\n state.currentMiterLimit = miterLimit;\n }\n };\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasBuilder.prototype.endGeometry = function (feature) {\n this.beginGeometryInstruction1_[2] = this.instructions.length;\n this.beginGeometryInstruction1_ = null;\n this.beginGeometryInstruction2_[2] = this.hitDetectionInstructions.length;\n this.beginGeometryInstruction2_ = null;\n var endGeometryInstruction = [canvas_Instruction.END_GEOMETRY, feature];\n this.instructions.push(endGeometryInstruction);\n this.hitDetectionInstructions.push(endGeometryInstruction);\n };\n /**\n * Get the buffered rendering extent. Rendering will be clipped to the extent\n * provided to the constructor. To account for symbolizers that may intersect\n * this extent, we calculate a buffered extent (e.g. based on stroke width).\n * @return {import("../../extent.js").Extent} The buffered rendering extent.\n * @protected\n */\n\n\n CanvasBuilder.prototype.getBufferedMaxExtent = function () {\n if (!this.bufferedMaxExtent_) {\n this.bufferedMaxExtent_ = clone(this.maxExtent);\n\n if (this.maxLineWidth > 0) {\n var width = this.resolution * (this.maxLineWidth + 1) / 2;\n buffer(this.bufferedMaxExtent_, width, this.bufferedMaxExtent_);\n }\n }\n\n return this.bufferedMaxExtent_;\n };\n\n return CanvasBuilder;\n}(render_VectorContext);\n\n/* harmony default export */ var Builder = (CanvasBuilder);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/ImageBuilder.js\nvar ImageBuilder_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/render/canvas/ImageBuilder\n */\n\n\n\n\n\nvar CanvasImageBuilder =\n/** @class */\nfunction (_super) {\n ImageBuilder_extends(CanvasImageBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n\n\n function CanvasImageBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n var _this = _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n */\n\n\n _this.hitDetectionImage_ = null;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n */\n\n _this.image_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.imagePixelRatio_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.anchorX_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.anchorY_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.height_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.opacity_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.originX_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.originY_ = undefined;\n /**\n * @private\n * @type {boolean|undefined}\n */\n\n _this.rotateWithView_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.rotation_ = undefined;\n /**\n * @private\n * @type {import("../../size.js").Size|undefined}\n */\n\n _this.scale_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.width_ = undefined;\n /**\n * Data shared with a text builder for combined decluttering.\n * @private\n * @type {import("../canvas.js").DeclutterImageWithText}\n */\n\n _this.declutterImageWithText_ = undefined;\n return _this;\n }\n /**\n * @param {import("../../geom/Point.js").default|import("../Feature.js").default} pointGeometry Point geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasImageBuilder.prototype.drawPoint = function (pointGeometry, feature) {\n if (!this.image_) {\n return;\n }\n\n this.beginGeometry(pointGeometry, feature);\n var flatCoordinates = pointGeometry.getFlatCoordinates();\n var stride = pointGeometry.getStride();\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);\n this.instructions.push([canvas_Instruction.DRAW_IMAGE, myBegin, myEnd, this.image_, // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_ * this.imagePixelRatio_, this.anchorY_ * this.imagePixelRatio_, Math.ceil(this.height_ * this.imagePixelRatio_), this.opacity_, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, [this.scale_[0] * this.pixelRatio / this.imagePixelRatio_, this.scale_[1] * this.pixelRatio / this.imagePixelRatio_], Math.ceil(this.width_ * this.imagePixelRatio_), this.declutterImageWithText_]);\n this.hitDetectionInstructions.push([canvas_Instruction.DRAW_IMAGE, myBegin, myEnd, this.hitDetectionImage_, // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_, this.anchorY_, this.height_, this.opacity_, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, this.scale_, this.width_, this.declutterImageWithText_]);\n this.endGeometry(feature);\n };\n /**\n * @param {import("../../geom/MultiPoint.js").default|import("../Feature.js").default} multiPointGeometry MultiPoint geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasImageBuilder.prototype.drawMultiPoint = function (multiPointGeometry, feature) {\n if (!this.image_) {\n return;\n }\n\n this.beginGeometry(multiPointGeometry, feature);\n var flatCoordinates = multiPointGeometry.getFlatCoordinates();\n var stride = multiPointGeometry.getStride();\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);\n this.instructions.push([canvas_Instruction.DRAW_IMAGE, myBegin, myEnd, this.image_, // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_ * this.imagePixelRatio_, this.anchorY_ * this.imagePixelRatio_, Math.ceil(this.height_ * this.imagePixelRatio_), this.opacity_, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, [this.scale_[0] * this.pixelRatio / this.imagePixelRatio_, this.scale_[1] * this.pixelRatio / this.imagePixelRatio_], Math.ceil(this.width_ * this.imagePixelRatio_), this.declutterImageWithText_]);\n this.hitDetectionInstructions.push([canvas_Instruction.DRAW_IMAGE, myBegin, myEnd, this.hitDetectionImage_, // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_, this.anchorY_, this.height_, this.opacity_, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, this.scale_, this.width_, this.declutterImageWithText_]);\n this.endGeometry(feature);\n };\n /**\n * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.\n */\n\n\n CanvasImageBuilder.prototype.finish = function () {\n this.reverseHitDetectionInstructions(); // FIXME this doesn\'t really protect us against further calls to draw*Geometry\n\n this.anchorX_ = undefined;\n this.anchorY_ = undefined;\n this.hitDetectionImage_ = null;\n this.image_ = null;\n this.imagePixelRatio_ = undefined;\n this.height_ = undefined;\n this.scale_ = undefined;\n this.opacity_ = undefined;\n this.originX_ = undefined;\n this.originY_ = undefined;\n this.rotateWithView_ = undefined;\n this.rotation_ = undefined;\n this.width_ = undefined;\n return _super.prototype.finish.call(this);\n };\n /**\n * @param {import("../../style/Image.js").default} imageStyle Image style.\n * @param {Object=} opt_sharedData Shared data.\n */\n\n\n CanvasImageBuilder.prototype.setImageStyle = function (imageStyle, opt_sharedData) {\n var anchor = imageStyle.getAnchor();\n var size = imageStyle.getSize();\n var hitDetectionImage = imageStyle.getHitDetectionImage();\n var image = imageStyle.getImage(this.pixelRatio);\n var origin = imageStyle.getOrigin();\n this.imagePixelRatio_ = imageStyle.getPixelRatio(this.pixelRatio);\n this.anchorX_ = anchor[0];\n this.anchorY_ = anchor[1];\n this.hitDetectionImage_ = hitDetectionImage;\n this.image_ = image;\n this.height_ = size[1];\n this.opacity_ = imageStyle.getOpacity();\n this.originX_ = origin[0];\n this.originY_ = origin[1];\n this.rotateWithView_ = imageStyle.getRotateWithView();\n this.rotation_ = imageStyle.getRotation();\n this.scale_ = imageStyle.getScaleArray();\n this.width_ = size[0];\n this.declutterImageWithText_ = opt_sharedData;\n };\n\n return CanvasImageBuilder;\n}(Builder);\n\n/* harmony default export */ var ImageBuilder = (CanvasImageBuilder);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/LineStringBuilder.js\nvar LineStringBuilder_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/render/canvas/LineStringBuilder\n */\n\n\n\n\n\nvar CanvasLineStringBuilder =\n/** @class */\nfunction (_super) {\n LineStringBuilder_extends(CanvasLineStringBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n\n\n function CanvasLineStringBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n return _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n }\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @private\n * @return {number} end.\n */\n\n\n CanvasLineStringBuilder.prototype.drawFlatCoordinates_ = function (flatCoordinates, offset, end, stride) {\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatLineCoordinates(flatCoordinates, offset, end, stride, false, false);\n var moveToLineToInstruction = [canvas_Instruction.MOVE_TO_LINE_TO, myBegin, myEnd];\n this.instructions.push(moveToLineToInstruction);\n this.hitDetectionInstructions.push(moveToLineToInstruction);\n return end;\n };\n /**\n * @param {import("../../geom/LineString.js").default|import("../Feature.js").default} lineStringGeometry Line string geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasLineStringBuilder.prototype.drawLineString = function (lineStringGeometry, feature) {\n var state = this.state;\n var strokeStyle = state.strokeStyle;\n var lineWidth = state.lineWidth;\n\n if (strokeStyle === undefined || lineWidth === undefined) {\n return;\n }\n\n this.updateStrokeStyle(state, this.applyStroke);\n this.beginGeometry(lineStringGeometry, feature);\n this.hitDetectionInstructions.push([canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash, state.lineDashOffset], beginPathInstruction);\n var flatCoordinates = lineStringGeometry.getFlatCoordinates();\n var stride = lineStringGeometry.getStride();\n this.drawFlatCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);\n this.hitDetectionInstructions.push(strokeInstruction);\n this.endGeometry(feature);\n };\n /**\n * @param {import("../../geom/MultiLineString.js").default|import("../Feature.js").default} multiLineStringGeometry MultiLineString geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasLineStringBuilder.prototype.drawMultiLineString = function (multiLineStringGeometry, feature) {\n var state = this.state;\n var strokeStyle = state.strokeStyle;\n var lineWidth = state.lineWidth;\n\n if (strokeStyle === undefined || lineWidth === undefined) {\n return;\n }\n\n this.updateStrokeStyle(state, this.applyStroke);\n this.beginGeometry(multiLineStringGeometry, feature);\n this.hitDetectionInstructions.push([canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash, state.lineDashOffset], beginPathInstruction);\n var ends = multiLineStringGeometry.getEnds();\n var flatCoordinates = multiLineStringGeometry.getFlatCoordinates();\n var stride = multiLineStringGeometry.getStride();\n var offset = 0;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n offset = this.drawFlatCoordinates_(flatCoordinates, offset,\n /** @type {number} */\n ends[i], stride);\n }\n\n this.hitDetectionInstructions.push(strokeInstruction);\n this.endGeometry(feature);\n };\n /**\n * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.\n */\n\n\n CanvasLineStringBuilder.prototype.finish = function () {\n var state = this.state;\n\n if (state.lastStroke != undefined && state.lastStroke != this.coordinates.length) {\n this.instructions.push(strokeInstruction);\n }\n\n this.reverseHitDetectionInstructions();\n this.state = null;\n return _super.prototype.finish.call(this);\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n */\n\n\n CanvasLineStringBuilder.prototype.applyStroke = function (state) {\n if (state.lastStroke != undefined && state.lastStroke != this.coordinates.length) {\n this.instructions.push(strokeInstruction);\n state.lastStroke = this.coordinates.length;\n }\n\n state.lastStroke = 0;\n\n _super.prototype.applyStroke.call(this, state);\n\n this.instructions.push(beginPathInstruction);\n };\n\n return CanvasLineStringBuilder;\n}(Builder);\n\n/* harmony default export */ var LineStringBuilder = (CanvasLineStringBuilder);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/PolygonBuilder.js\nvar PolygonBuilder_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/render/canvas/PolygonBuilder\n */\n\n\n\n\n\n\n\nvar CanvasPolygonBuilder =\n/** @class */\nfunction (_super) {\n PolygonBuilder_extends(CanvasPolygonBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n\n\n function CanvasPolygonBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n return _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n }\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @private\n * @return {number} End.\n */\n\n\n CanvasPolygonBuilder.prototype.drawFlatCoordinatess_ = function (flatCoordinates, offset, ends, stride) {\n var state = this.state;\n var fill = state.fillStyle !== undefined;\n var stroke = state.strokeStyle !== undefined;\n var numEnds = ends.length;\n this.instructions.push(beginPathInstruction);\n this.hitDetectionInstructions.push(beginPathInstruction);\n\n for (var i = 0; i < numEnds; ++i) {\n var end = ends[i];\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatLineCoordinates(flatCoordinates, offset, end, stride, true, !stroke);\n var moveToLineToInstruction = [canvas_Instruction.MOVE_TO_LINE_TO, myBegin, myEnd];\n this.instructions.push(moveToLineToInstruction);\n this.hitDetectionInstructions.push(moveToLineToInstruction);\n\n if (stroke) {\n // Performance optimization: only call closePath() when we have a stroke.\n // Otherwise the ring is closed already (see appendFlatLineCoordinates above).\n this.instructions.push(closePathInstruction);\n this.hitDetectionInstructions.push(closePathInstruction);\n }\n\n offset = end;\n }\n\n if (fill) {\n this.instructions.push(fillInstruction);\n this.hitDetectionInstructions.push(fillInstruction);\n }\n\n if (stroke) {\n this.instructions.push(strokeInstruction);\n this.hitDetectionInstructions.push(strokeInstruction);\n }\n\n return offset;\n };\n /**\n * @param {import("../../geom/Circle.js").default} circleGeometry Circle geometry.\n * @param {import("../../Feature.js").default} feature Feature.\n */\n\n\n CanvasPolygonBuilder.prototype.drawCircle = function (circleGeometry, feature) {\n var state = this.state;\n var fillStyle = state.fillStyle;\n var strokeStyle = state.strokeStyle;\n\n if (fillStyle === undefined && strokeStyle === undefined) {\n return;\n }\n\n this.setFillStrokeStyles_();\n this.beginGeometry(circleGeometry, feature);\n\n if (state.fillStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_FILL_STYLE, defaultFillStyle]);\n }\n\n if (state.strokeStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash, state.lineDashOffset]);\n }\n\n var flatCoordinates = circleGeometry.getFlatCoordinates();\n var stride = circleGeometry.getStride();\n var myBegin = this.coordinates.length;\n this.appendFlatLineCoordinates(flatCoordinates, 0, flatCoordinates.length, stride, false, false);\n var circleInstruction = [canvas_Instruction.CIRCLE, myBegin];\n this.instructions.push(beginPathInstruction, circleInstruction);\n this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction);\n\n if (state.fillStyle !== undefined) {\n this.instructions.push(fillInstruction);\n this.hitDetectionInstructions.push(fillInstruction);\n }\n\n if (state.strokeStyle !== undefined) {\n this.instructions.push(strokeInstruction);\n this.hitDetectionInstructions.push(strokeInstruction);\n }\n\n this.endGeometry(feature);\n };\n /**\n * @param {import("../../geom/Polygon.js").default|import("../Feature.js").default} polygonGeometry Polygon geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasPolygonBuilder.prototype.drawPolygon = function (polygonGeometry, feature) {\n var state = this.state;\n var fillStyle = state.fillStyle;\n var strokeStyle = state.strokeStyle;\n\n if (fillStyle === undefined && strokeStyle === undefined) {\n return;\n }\n\n this.setFillStrokeStyles_();\n this.beginGeometry(polygonGeometry, feature);\n\n if (state.fillStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_FILL_STYLE, defaultFillStyle]);\n }\n\n if (state.strokeStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash, state.lineDashOffset]);\n }\n\n var ends = polygonGeometry.getEnds();\n var flatCoordinates = polygonGeometry.getOrientedFlatCoordinates();\n var stride = polygonGeometry.getStride();\n this.drawFlatCoordinatess_(flatCoordinates, 0,\n /** @type {Array<number>} */\n ends, stride);\n this.endGeometry(feature);\n };\n /**\n * @param {import("../../geom/MultiPolygon.js").default} multiPolygonGeometry MultiPolygon geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasPolygonBuilder.prototype.drawMultiPolygon = function (multiPolygonGeometry, feature) {\n var state = this.state;\n var fillStyle = state.fillStyle;\n var strokeStyle = state.strokeStyle;\n\n if (fillStyle === undefined && strokeStyle === undefined) {\n return;\n }\n\n this.setFillStrokeStyles_();\n this.beginGeometry(multiPolygonGeometry, feature);\n\n if (state.fillStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_FILL_STYLE, defaultFillStyle]);\n }\n\n if (state.strokeStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash, state.lineDashOffset]);\n }\n\n var endss = multiPolygonGeometry.getEndss();\n var flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates();\n var stride = multiPolygonGeometry.getStride();\n var offset = 0;\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n offset = this.drawFlatCoordinatess_(flatCoordinates, offset, endss[i], stride);\n }\n\n this.endGeometry(feature);\n };\n /**\n * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.\n */\n\n\n CanvasPolygonBuilder.prototype.finish = function () {\n this.reverseHitDetectionInstructions();\n this.state = null; // We want to preserve topology when drawing polygons. Polygons are\n // simplified using quantization and point elimination. However, we might\n // have received a mix of quantized and non-quantized geometries, so ensure\n // that all are quantized by quantizing all coordinates in the batch.\n\n var tolerance = this.tolerance;\n\n if (tolerance !== 0) {\n var coordinates = this.coordinates;\n\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n coordinates[i] = snap(coordinates[i], tolerance);\n }\n }\n\n return _super.prototype.finish.call(this);\n };\n /**\n * @private\n */\n\n\n CanvasPolygonBuilder.prototype.setFillStrokeStyles_ = function () {\n var state = this.state;\n var fillStyle = state.fillStyle;\n\n if (fillStyle !== undefined) {\n this.updateFillStyle(state, this.createFill);\n }\n\n if (state.strokeStyle !== undefined) {\n this.updateStrokeStyle(state, this.applyStroke);\n }\n };\n\n return CanvasPolygonBuilder;\n}(Builder);\n\n/* harmony default export */ var PolygonBuilder = (CanvasPolygonBuilder);\n;// CONCATENATED MODULE: ./node_modules/ol/style/TextPlacement.js\n/**\n * @module ol/style/TextPlacement\n */\n\n/**\n * Text placement. One of `\'point\'`, `\'line\'`. Default is `\'point\'`. Note that\n * `\'line\'` requires the underlying geometry to be a {@link module:ol/geom/LineString~LineString},\n * {@link module:ol/geom/Polygon~Polygon}, {@link module:ol/geom/MultiLineString~MultiLineString} or\n * {@link module:ol/geom/MultiPolygon~MultiPolygon}.\n * @enum {string}\n */\n/* harmony default export */ var TextPlacement = ({\n POINT: \'point\',\n LINE: \'line\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/straightchunk.js\n/**\n * @module ol/geom/flat/straightchunk\n */\n\n/**\n * @param {number} maxAngle Maximum acceptable angle delta between segments.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {Array<number>} Start and end of the first suitable chunk of the\n * given `flatCoordinates`.\n */\nfunction matchingChunk(maxAngle, flatCoordinates, offset, end, stride) {\n var chunkStart = offset;\n var chunkEnd = offset;\n var chunkM = 0;\n var m = 0;\n var start = offset;\n var acos, i, m12, m23, x1, y1, x12, y12, x23, y23;\n\n for (i = offset; i < end; i += stride) {\n var x2 = flatCoordinates[i];\n var y2 = flatCoordinates[i + 1];\n\n if (x1 !== undefined) {\n x23 = x2 - x1;\n y23 = y2 - y1;\n m23 = Math.sqrt(x23 * x23 + y23 * y23);\n\n if (x12 !== undefined) {\n m += m12;\n acos = Math.acos((x12 * x23 + y12 * y23) / (m12 * m23));\n\n if (acos > maxAngle) {\n if (m > chunkM) {\n chunkM = m;\n chunkStart = start;\n chunkEnd = i;\n }\n\n m = 0;\n start = i - stride;\n }\n }\n\n m12 = m23;\n x12 = x23;\n y12 = y23;\n }\n\n x1 = x2;\n y1 = y2;\n }\n\n m += m23;\n return m > chunkM ? [start, i] : [chunkStart, chunkEnd];\n}\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/TextBuilder.js\nvar TextBuilder_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/render/canvas/TextBuilder\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @const\n * @enum {number}\n */\n\nvar TEXT_ALIGN = {\n \'left\': 0,\n \'end\': 0,\n \'center\': 0.5,\n \'right\': 1,\n \'start\': 1,\n \'top\': 0,\n \'middle\': 0.5,\n \'hanging\': 0.2,\n \'alphabetic\': 0.8,\n \'ideographic\': 0.8,\n \'bottom\': 1\n};\n\nvar CanvasTextBuilder =\n/** @class */\nfunction (_super) {\n TextBuilder_extends(CanvasTextBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n\n\n function CanvasTextBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n var _this = _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n /**\n * @private\n * @type {Array<HTMLCanvasElement>}\n */\n\n\n _this.labels_ = null;\n /**\n * @private\n * @type {string}\n */\n\n _this.text_ = \'\';\n /**\n * @private\n * @type {number}\n */\n\n _this.textOffsetX_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.textOffsetY_ = 0;\n /**\n * @private\n * @type {boolean|undefined}\n */\n\n _this.textRotateWithView_ = undefined;\n /**\n * @private\n * @type {number}\n */\n\n _this.textRotation_ = 0;\n /**\n * @private\n * @type {?import("../canvas.js").FillState}\n */\n\n _this.textFillState_ = null;\n /**\n * @type {!Object<string, import("../canvas.js").FillState>}\n */\n\n _this.fillStates = {};\n /**\n * @private\n * @type {?import("../canvas.js").StrokeState}\n */\n\n _this.textStrokeState_ = null;\n /**\n * @type {!Object<string, import("../canvas.js").StrokeState>}\n */\n\n _this.strokeStates = {};\n /**\n * @private\n * @type {import("../canvas.js").TextState}\n */\n\n _this.textState_ =\n /** @type {import("../canvas.js").TextState} */\n {};\n /**\n * @type {!Object<string, import("../canvas.js").TextState>}\n */\n\n _this.textStates = {};\n /**\n * @private\n * @type {string}\n */\n\n _this.textKey_ = \'\';\n /**\n * @private\n * @type {string}\n */\n\n _this.fillKey_ = \'\';\n /**\n * @private\n * @type {string}\n */\n\n _this.strokeKey_ = \'\';\n /**\n * Data shared with an image builder for combined decluttering.\n * @private\n * @type {import("../canvas.js").DeclutterImageWithText}\n */\n\n _this.declutterImageWithText_ = undefined;\n return _this;\n }\n /**\n * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.\n */\n\n\n CanvasTextBuilder.prototype.finish = function () {\n var instructions = _super.prototype.finish.call(this);\n\n instructions.textStates = this.textStates;\n instructions.fillStates = this.fillStates;\n instructions.strokeStates = this.strokeStates;\n return instructions;\n };\n /**\n * @param {import("../../geom/SimpleGeometry.js").default|import("../Feature.js").default} geometry Geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasTextBuilder.prototype.drawText = function (geometry, feature) {\n var fillState = this.textFillState_;\n var strokeState = this.textStrokeState_;\n var textState = this.textState_;\n\n if (this.text_ === \'\' || !textState || !fillState && !strokeState) {\n return;\n }\n\n var coordinates = this.coordinates;\n var begin = coordinates.length;\n var geometryType = geometry.getType();\n var flatCoordinates = null;\n var stride = geometry.getStride();\n\n if (textState.placement === TextPlacement.LINE && (geometryType == geom_GeometryType.LINE_STRING || geometryType == geom_GeometryType.MULTI_LINE_STRING || geometryType == geom_GeometryType.POLYGON || geometryType == geom_GeometryType.MULTI_POLYGON)) {\n if (!intersects(this.getBufferedMaxExtent(), geometry.getExtent())) {\n return;\n }\n\n var ends = void 0;\n flatCoordinates = geometry.getFlatCoordinates();\n\n if (geometryType == geom_GeometryType.LINE_STRING) {\n ends = [flatCoordinates.length];\n } else if (geometryType == geom_GeometryType.MULTI_LINE_STRING) {\n ends =\n /** @type {import("../../geom/MultiLineString.js").default} */\n geometry.getEnds();\n } else if (geometryType == geom_GeometryType.POLYGON) {\n ends =\n /** @type {import("../../geom/Polygon.js").default} */\n geometry.getEnds().slice(0, 1);\n } else if (geometryType == geom_GeometryType.MULTI_POLYGON) {\n var endss =\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry.getEndss();\n ends = [];\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n ends.push(endss[i][0]);\n }\n }\n\n this.beginGeometry(geometry, feature);\n var textAlign = textState.textAlign;\n var flatOffset = 0;\n var flatEnd = void 0;\n\n for (var o = 0, oo = ends.length; o < oo; ++o) {\n if (textAlign == undefined) {\n var range = matchingChunk(textState.maxAngle, flatCoordinates, flatOffset, ends[o], stride);\n flatOffset = range[0];\n flatEnd = range[1];\n } else {\n flatEnd = ends[o];\n }\n\n for (var i = flatOffset; i < flatEnd; i += stride) {\n coordinates.push(flatCoordinates[i], flatCoordinates[i + 1]);\n }\n\n var end = coordinates.length;\n flatOffset = ends[o];\n this.drawChars_(begin, end);\n begin = end;\n }\n\n this.endGeometry(feature);\n } else {\n var geometryWidths = textState.overflow ? null : [];\n\n switch (geometryType) {\n case geom_GeometryType.POINT:\n case geom_GeometryType.MULTI_POINT:\n flatCoordinates =\n /** @type {import("../../geom/MultiPoint.js").default} */\n geometry.getFlatCoordinates();\n break;\n\n case geom_GeometryType.LINE_STRING:\n flatCoordinates =\n /** @type {import("../../geom/LineString.js").default} */\n geometry.getFlatMidpoint();\n break;\n\n case geom_GeometryType.CIRCLE:\n flatCoordinates =\n /** @type {import("../../geom/Circle.js").default} */\n geometry.getCenter();\n break;\n\n case geom_GeometryType.MULTI_LINE_STRING:\n flatCoordinates =\n /** @type {import("../../geom/MultiLineString.js").default} */\n geometry.getFlatMidpoints();\n stride = 2;\n break;\n\n case geom_GeometryType.POLYGON:\n flatCoordinates =\n /** @type {import("../../geom/Polygon.js").default} */\n geometry.getFlatInteriorPoint();\n\n if (!textState.overflow) {\n geometryWidths.push(flatCoordinates[2] / this.resolution);\n }\n\n stride = 3;\n break;\n\n case geom_GeometryType.MULTI_POLYGON:\n var interiorPoints =\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry.getFlatInteriorPoints();\n flatCoordinates = [];\n\n for (var i = 0, ii = interiorPoints.length; i < ii; i += 3) {\n if (!textState.overflow) {\n geometryWidths.push(interiorPoints[i + 2] / this.resolution);\n }\n\n flatCoordinates.push(interiorPoints[i], interiorPoints[i + 1]);\n }\n\n if (flatCoordinates.length === 0) {\n return;\n }\n\n stride = 2;\n break;\n\n default:\n }\n\n var end = this.appendFlatPointCoordinates(flatCoordinates, stride);\n\n if (end === begin) {\n return;\n }\n\n this.saveTextStates_();\n\n if (textState.backgroundFill || textState.backgroundStroke) {\n this.setFillStrokeStyle(textState.backgroundFill, textState.backgroundStroke);\n\n if (textState.backgroundFill) {\n this.updateFillStyle(this.state, this.createFill);\n this.hitDetectionInstructions.push(this.createFill(this.state));\n }\n\n if (textState.backgroundStroke) {\n this.updateStrokeStyle(this.state, this.applyStroke);\n this.hitDetectionInstructions.push(this.createStroke(this.state));\n }\n }\n\n this.beginGeometry(geometry, feature); // adjust padding for negative scale\n\n var padding = textState.padding;\n\n if (padding != defaultPadding && (textState.scale[0] < 0 || textState.scale[1] < 0)) {\n var p0 = textState.padding[0];\n var p1 = textState.padding[1];\n var p2 = textState.padding[2];\n var p3 = textState.padding[3];\n\n if (textState.scale[0] < 0) {\n p1 = -p1;\n p3 = -p3;\n }\n\n if (textState.scale[1] < 0) {\n p0 = -p0;\n p2 = -p2;\n }\n\n padding = [p0, p1, p2, p3];\n } // The image is unknown at this stage so we pass null; it will be computed at render time.\n // For clarity, we pass NaN for offsetX, offsetY, width and height, which will be computed at\n // render time.\n\n\n var pixelRatio_1 = this.pixelRatio;\n this.instructions.push([canvas_Instruction.DRAW_IMAGE, begin, end, null, NaN, NaN, NaN, 1, 0, 0, this.textRotateWithView_, this.textRotation_, [1, 1], NaN, this.declutterImageWithText_, padding == defaultPadding ? defaultPadding : padding.map(function (p) {\n return p * pixelRatio_1;\n }), !!textState.backgroundFill, !!textState.backgroundStroke, this.text_, this.textKey_, this.strokeKey_, this.fillKey_, this.textOffsetX_, this.textOffsetY_, geometryWidths]);\n var scale = 1 / pixelRatio_1;\n this.hitDetectionInstructions.push([canvas_Instruction.DRAW_IMAGE, begin, end, null, NaN, NaN, NaN, 1, 0, 0, this.textRotateWithView_, this.textRotation_, [scale, scale], NaN, this.declutterImageWithText_, padding, !!textState.backgroundFill, !!textState.backgroundStroke, this.text_, this.textKey_, this.strokeKey_, this.fillKey_, this.textOffsetX_, this.textOffsetY_, geometryWidths]);\n this.endGeometry(feature);\n }\n };\n /**\n * @private\n */\n\n\n CanvasTextBuilder.prototype.saveTextStates_ = function () {\n var strokeState = this.textStrokeState_;\n var textState = this.textState_;\n var fillState = this.textFillState_;\n var strokeKey = this.strokeKey_;\n\n if (strokeState) {\n if (!(strokeKey in this.strokeStates)) {\n this.strokeStates[strokeKey] = {\n strokeStyle: strokeState.strokeStyle,\n lineCap: strokeState.lineCap,\n lineDashOffset: strokeState.lineDashOffset,\n lineWidth: strokeState.lineWidth,\n lineJoin: strokeState.lineJoin,\n miterLimit: strokeState.miterLimit,\n lineDash: strokeState.lineDash\n };\n }\n }\n\n var textKey = this.textKey_;\n\n if (!(textKey in this.textStates)) {\n this.textStates[textKey] = {\n font: textState.font,\n textAlign: textState.textAlign || defaultTextAlign,\n textBaseline: textState.textBaseline || defaultTextBaseline,\n scale: textState.scale\n };\n }\n\n var fillKey = this.fillKey_;\n\n if (fillState) {\n if (!(fillKey in this.fillStates)) {\n this.fillStates[fillKey] = {\n fillStyle: fillState.fillStyle\n };\n }\n }\n };\n /**\n * @private\n * @param {number} begin Begin.\n * @param {number} end End.\n */\n\n\n CanvasTextBuilder.prototype.drawChars_ = function (begin, end) {\n var strokeState = this.textStrokeState_;\n var textState = this.textState_;\n var strokeKey = this.strokeKey_;\n var textKey = this.textKey_;\n var fillKey = this.fillKey_;\n this.saveTextStates_();\n var pixelRatio = this.pixelRatio;\n var baseline = TEXT_ALIGN[textState.textBaseline];\n var offsetY = this.textOffsetY_ * pixelRatio;\n var text = this.text_;\n var strokeWidth = strokeState ? strokeState.lineWidth * Math.abs(textState.scale[0]) / 2 : 0;\n this.instructions.push([canvas_Instruction.DRAW_CHARS, begin, end, baseline, textState.overflow, fillKey, textState.maxAngle, pixelRatio, offsetY, strokeKey, strokeWidth * pixelRatio, text, textKey, 1]);\n this.hitDetectionInstructions.push([canvas_Instruction.DRAW_CHARS, begin, end, baseline, textState.overflow, fillKey, textState.maxAngle, 1, offsetY, strokeKey, strokeWidth, text, textKey, 1 / pixelRatio]);\n };\n /**\n * @param {import("../../style/Text.js").default} textStyle Text style.\n * @param {Object=} opt_sharedData Shared data.\n */\n\n\n CanvasTextBuilder.prototype.setTextStyle = function (textStyle, opt_sharedData) {\n var textState, fillState, strokeState;\n\n if (!textStyle) {\n this.text_ = \'\';\n } else {\n var textFillStyle = textStyle.getFill();\n\n if (!textFillStyle) {\n fillState = null;\n this.textFillState_ = fillState;\n } else {\n fillState = this.textFillState_;\n\n if (!fillState) {\n fillState =\n /** @type {import("../canvas.js").FillState} */\n {};\n this.textFillState_ = fillState;\n }\n\n fillState.fillStyle = asColorLike(textFillStyle.getColor() || defaultFillStyle);\n }\n\n var textStrokeStyle = textStyle.getStroke();\n\n if (!textStrokeStyle) {\n strokeState = null;\n this.textStrokeState_ = strokeState;\n } else {\n strokeState = this.textStrokeState_;\n\n if (!strokeState) {\n strokeState =\n /** @type {import("../canvas.js").StrokeState} */\n {};\n this.textStrokeState_ = strokeState;\n }\n\n var lineDash = textStrokeStyle.getLineDash();\n var lineDashOffset = textStrokeStyle.getLineDashOffset();\n var lineWidth = textStrokeStyle.getWidth();\n var miterLimit = textStrokeStyle.getMiterLimit();\n strokeState.lineCap = textStrokeStyle.getLineCap() || defaultLineCap;\n strokeState.lineDash = lineDash ? lineDash.slice() : defaultLineDash;\n strokeState.lineDashOffset = lineDashOffset === undefined ? defaultLineDashOffset : lineDashOffset;\n strokeState.lineJoin = textStrokeStyle.getLineJoin() || defaultLineJoin;\n strokeState.lineWidth = lineWidth === undefined ? defaultLineWidth : lineWidth;\n strokeState.miterLimit = miterLimit === undefined ? defaultMiterLimit : miterLimit;\n strokeState.strokeStyle = asColorLike(textStrokeStyle.getColor() || defaultStrokeStyle);\n }\n\n textState = this.textState_;\n var font = textStyle.getFont() || defaultFont;\n registerFont(font);\n var textScale = textStyle.getScaleArray();\n textState.overflow = textStyle.getOverflow();\n textState.font = font;\n textState.maxAngle = textStyle.getMaxAngle();\n textState.placement = textStyle.getPlacement();\n textState.textAlign = textStyle.getTextAlign();\n textState.textBaseline = textStyle.getTextBaseline() || defaultTextBaseline;\n textState.backgroundFill = textStyle.getBackgroundFill();\n textState.backgroundStroke = textStyle.getBackgroundStroke();\n textState.padding = textStyle.getPadding() || defaultPadding;\n textState.scale = textScale === undefined ? [1, 1] : textScale;\n var textOffsetX = textStyle.getOffsetX();\n var textOffsetY = textStyle.getOffsetY();\n var textRotateWithView = textStyle.getRotateWithView();\n var textRotation = textStyle.getRotation();\n this.text_ = textStyle.getText() || \'\';\n this.textOffsetX_ = textOffsetX === undefined ? 0 : textOffsetX;\n this.textOffsetY_ = textOffsetY === undefined ? 0 : textOffsetY;\n this.textRotateWithView_ = textRotateWithView === undefined ? false : textRotateWithView;\n this.textRotation_ = textRotation === undefined ? 0 : textRotation;\n this.strokeKey_ = strokeState ? (typeof strokeState.strokeStyle == \'string\' ? strokeState.strokeStyle : getUid(strokeState.strokeStyle)) + strokeState.lineCap + strokeState.lineDashOffset + \'|\' + strokeState.lineWidth + strokeState.lineJoin + strokeState.miterLimit + \'[\' + strokeState.lineDash.join() + \']\' : \'\';\n this.textKey_ = textState.font + textState.scale + (textState.textAlign || \'?\') + (textState.textBaseline || \'?\');\n this.fillKey_ = fillState ? typeof fillState.fillStyle == \'string\' ? fillState.fillStyle : \'|\' + getUid(fillState.fillStyle) : \'\';\n }\n\n this.declutterImageWithText_ = opt_sharedData;\n };\n\n return CanvasTextBuilder;\n}(Builder);\n\n/* harmony default export */ var TextBuilder = (CanvasTextBuilder);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/BuilderGroup.js\n/**\n * @module ol/render/canvas/BuilderGroup\n */\n\n\n\n\n\n/**\n * @type {Object<import("./BuilderType").default, typeof Builder>}\n */\n\nvar BATCH_CONSTRUCTORS = {\n \'Circle\': PolygonBuilder,\n \'Default\': Builder,\n \'Image\': ImageBuilder,\n \'LineString\': LineStringBuilder,\n \'Polygon\': PolygonBuilder,\n \'Text\': TextBuilder\n};\n\nvar BuilderGroup =\n/** @class */\nfunction () {\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Max extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n function BuilderGroup(tolerance, maxExtent, resolution, pixelRatio) {\n /**\n * @private\n * @type {number}\n */\n this.tolerance_ = tolerance;\n /**\n * @private\n * @type {import("../../extent.js").Extent}\n */\n\n this.maxExtent_ = maxExtent;\n /**\n * @private\n * @type {number}\n */\n\n this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {number}\n */\n\n this.resolution_ = resolution;\n /**\n * @private\n * @type {!Object<string, !Object<import("./BuilderType").default, Builder>>}\n */\n\n this.buildersByZIndex_ = {};\n }\n /**\n * @return {!Object<string, !Object<import("./BuilderType").default, import("./Builder.js").SerializableInstructions>>} The serializable instructions\n */\n\n\n BuilderGroup.prototype.finish = function () {\n var builderInstructions = {};\n\n for (var zKey in this.buildersByZIndex_) {\n builderInstructions[zKey] = builderInstructions[zKey] || {};\n var builders = this.buildersByZIndex_[zKey];\n\n for (var builderKey in builders) {\n var builderInstruction = builders[builderKey].finish();\n builderInstructions[zKey][builderKey] = builderInstruction;\n }\n }\n\n return builderInstructions;\n };\n /**\n * @param {number|undefined} zIndex Z index.\n * @param {import("./BuilderType.js").default} builderType Replay type.\n * @return {import("../VectorContext.js").default} Replay.\n */\n\n\n BuilderGroup.prototype.getBuilder = function (zIndex, builderType) {\n var zIndexKey = zIndex !== undefined ? zIndex.toString() : \'0\';\n var replays = this.buildersByZIndex_[zIndexKey];\n\n if (replays === undefined) {\n replays = {};\n this.buildersByZIndex_[zIndexKey] = replays;\n }\n\n var replay = replays[builderType];\n\n if (replay === undefined) {\n var Constructor = BATCH_CONSTRUCTORS[builderType];\n replay = new Constructor(this.tolerance_, this.maxExtent_, this.resolution_, this.pixelRatio_);\n replays[builderType] = replay;\n }\n\n return replay;\n };\n\n return BuilderGroup;\n}();\n\n/* harmony default export */ var canvas_BuilderGroup = (BuilderGroup);\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/Layer.js\nvar renderer_Layer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/Layer\n */\n\n\n\n\n\n\n\n/**\n * @template {import("../layer/Layer.js").default} LayerType\n */\n\nvar LayerRenderer =\n/** @class */\nfunction (_super) {\n renderer_Layer_extends(LayerRenderer, _super);\n /**\n * @param {LayerType} layer Layer.\n */\n\n\n function LayerRenderer(layer) {\n var _this = _super.call(this) || this;\n /** @private */\n\n\n _this.boundHandleImageChange_ = _this.handleImageChange_.bind(_this);\n /**\n * @protected\n * @type {LayerType}\n */\n\n _this.layer_ = layer;\n /**\n * @type {import("../render/canvas/ExecutorGroup").default}\n */\n\n _this.declutterExecutorGroup = null;\n return _this;\n }\n /**\n * Asynchronous layer level hit detection.\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with\n * an array of features.\n */\n\n\n LayerRenderer.prototype.getFeatures = function (pixel) {\n return util_abstract();\n };\n /**\n * Determine whether render should be called.\n * @abstract\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n\n\n LayerRenderer.prototype.prepareFrame = function (frameState) {\n return util_abstract();\n };\n /**\n * Render the layer.\n * @abstract\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n\n\n LayerRenderer.prototype.renderFrame = function (frameState, target) {\n return util_abstract();\n };\n /**\n * @param {Object<number, Object<string, import("../Tile.js").default>>} tiles Lookup of loaded tiles by zoom level.\n * @param {number} zoom Zoom level.\n * @param {import("../Tile.js").default} tile Tile.\n * @return {boolean|void} If `false`, the tile will not be considered loaded.\n */\n\n\n LayerRenderer.prototype.loadedTileCallback = function (tiles, zoom, tile) {\n if (!tiles[zoom]) {\n tiles[zoom] = {};\n }\n\n tiles[zoom][tile.tileCoord.toString()] = tile;\n return undefined;\n };\n /**\n * Create a function that adds loaded tiles to the tile lookup.\n * @param {import("../source/Tile.js").default} source Tile source.\n * @param {import("../proj/Projection.js").default} projection Projection of the tiles.\n * @param {Object<number, Object<string, import("../Tile.js").default>>} tiles Lookup of loaded tiles by zoom level.\n * @return {function(number, import("../TileRange.js").default):boolean} A function that can be\n * called with a zoom level and a tile range to add loaded tiles to the lookup.\n * @protected\n */\n\n\n LayerRenderer.prototype.createLoadedTileFinder = function (source, projection, tiles) {\n return (\n /**\n * @param {number} zoom Zoom level.\n * @param {import("../TileRange.js").default} tileRange Tile range.\n * @return {boolean} The tile range is fully loaded.\n * @this {LayerRenderer}\n */\n function (zoom, tileRange) {\n var callback = this.loadedTileCallback.bind(this, tiles, zoom);\n return source.forEachLoadedTile(projection, zoom, tileRange, callback);\n }.bind(this)\n );\n };\n /**\n * @abstract\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {import("./vector.js").FeatureCallback<T>} callback Feature callback.\n * @param {Array<import("./Map.js").HitMatch<T>>} matches The hit detected matches with tolerance.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n LayerRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, callback, matches) {\n return undefined;\n };\n /**\n * @abstract\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @return {Uint8ClampedArray|Uint8Array} The result. If there is no data at the pixel\n * location, null will be returned. If there is data, but pixel values cannot be\n * returned, and empty array will be returned.\n */\n\n\n LayerRenderer.prototype.getDataAtPixel = function (pixel, frameState, hitTolerance) {\n return util_abstract();\n };\n /**\n * @return {LayerType} Layer.\n */\n\n\n LayerRenderer.prototype.getLayer = function () {\n return this.layer_;\n };\n /**\n * Perform action necessary to get the layer rendered after new fonts have loaded\n * @abstract\n */\n\n\n LayerRenderer.prototype.handleFontsChanged = function () {};\n /**\n * Handle changes in image state.\n * @param {import("../events/Event.js").default} event Image change event.\n * @private\n */\n\n\n LayerRenderer.prototype.handleImageChange_ = function (event) {\n var image =\n /** @type {import("../Image.js").default} */\n event.target;\n\n if (image.getState() === ImageState.LOADED) {\n this.renderIfReadyAndVisible();\n }\n };\n /**\n * Load the image if not already loaded, and register the image change\n * listener if needed.\n * @param {import("../ImageBase.js").default} image Image.\n * @return {boolean} `true` if the image is already loaded, `false` otherwise.\n * @protected\n */\n\n\n LayerRenderer.prototype.loadImage = function (image) {\n var imageState = image.getState();\n\n if (imageState != ImageState.LOADED && imageState != ImageState.ERROR) {\n image.addEventListener(EventType.CHANGE, this.boundHandleImageChange_);\n }\n\n if (imageState == ImageState.IDLE) {\n image.load();\n imageState = image.getState();\n }\n\n return imageState == ImageState.LOADED;\n };\n /**\n * @protected\n */\n\n\n LayerRenderer.prototype.renderIfReadyAndVisible = function () {\n var layer = this.getLayer();\n\n if (layer.getVisible() && layer.getSourceState() == State.READY) {\n layer.changed();\n }\n };\n\n return LayerRenderer;\n}(ol_Observable);\n\n/* harmony default export */ var renderer_Layer = (LayerRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/Layer.js\nvar canvas_Layer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/canvas/Layer\n */\n\n\n\n\n\n\n\n\n\n/**\n * @abstract\n * @template {import("../../layer/Layer.js").default} LayerType\n */\n\nvar CanvasLayerRenderer =\n/** @class */\nfunction (_super) {\n canvas_Layer_extends(CanvasLayerRenderer, _super);\n /**\n * @param {LayerType} layer Layer.\n */\n\n\n function CanvasLayerRenderer(layer) {\n var _this = _super.call(this, layer) || this;\n /**\n * @protected\n * @type {HTMLElement}\n */\n\n\n _this.container = null;\n /**\n * @protected\n * @type {number}\n */\n\n _this.renderedResolution;\n /**\n * A temporary transform. The values in this transform should only be used in a\n * function that sets the values.\n * @protected\n * @type {import("../../transform.js").Transform}\n */\n\n _this.tempTransform = create();\n /**\n * The transform for rendered pixels to viewport CSS pixels. This transform must\n * be set when rendering a frame and may be used by other functions after rendering.\n * @protected\n * @type {import("../../transform.js").Transform}\n */\n\n _this.pixelTransform = create();\n /**\n * The transform for viewport CSS pixels to rendered pixels. This transform must\n * be set when rendering a frame and may be used by other functions after rendering.\n * @protected\n * @type {import("../../transform.js").Transform}\n */\n\n _this.inversePixelTransform = create();\n /**\n * @type {CanvasRenderingContext2D}\n */\n\n _this.context = null;\n /**\n * @type {boolean}\n */\n\n _this.containerReused = false;\n return _this;\n }\n /**\n * Get a rendering container from an existing target, if compatible.\n * @param {HTMLElement} target Potential render target.\n * @param {string} transform CSS Transform.\n * @param {number} opacity Opacity.\n */\n\n\n CanvasLayerRenderer.prototype.useContainer = function (target, transform, opacity) {\n var layerClassName = this.getLayer().getClassName();\n var container, context;\n\n if (target && target.style.opacity === \'\' && target.className === layerClassName) {\n var canvas = target.firstElementChild;\n\n if (canvas instanceof HTMLCanvasElement) {\n context = canvas.getContext(\'2d\');\n }\n }\n\n if (context && (context.canvas.width === 0 || context.canvas.style.transform === transform)) {\n // Container of the previous layer renderer can be used.\n this.container = target;\n this.context = context;\n this.containerReused = true;\n } else if (this.containerReused) {\n // Previously reused container cannot be used any more.\n this.container = null;\n this.context = null;\n this.containerReused = false;\n }\n\n if (!this.container) {\n container = document.createElement(\'div\');\n container.className = layerClassName;\n var style = container.style;\n style.position = \'absolute\';\n style.width = \'100%\';\n style.height = \'100%\';\n context = createCanvasContext2D();\n var canvas = context.canvas;\n container.appendChild(canvas);\n style = canvas.style;\n style.position = \'absolute\';\n style.left = \'0\';\n style.transformOrigin = \'top left\';\n this.container = container;\n this.context = context;\n }\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {import("../../extent.js").Extent} extent Clip extent.\n * @protected\n */\n\n\n CanvasLayerRenderer.prototype.clip = function (context, frameState, extent) {\n var pixelRatio = frameState.pixelRatio;\n var halfWidth = frameState.size[0] * pixelRatio / 2;\n var halfHeight = frameState.size[1] * pixelRatio / 2;\n var rotation = frameState.viewState.rotation;\n var topLeft = getTopLeft(extent);\n var topRight = getTopRight(extent);\n var bottomRight = getBottomRight(extent);\n var bottomLeft = getBottomLeft(extent);\n apply(frameState.coordinateToPixelTransform, topLeft);\n apply(frameState.coordinateToPixelTransform, topRight);\n apply(frameState.coordinateToPixelTransform, bottomRight);\n apply(frameState.coordinateToPixelTransform, bottomLeft);\n context.save();\n rotateAtOffset(context, -rotation, halfWidth, halfHeight);\n context.beginPath();\n context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio);\n context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio);\n context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio);\n context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio);\n context.clip();\n rotateAtOffset(context, rotation, halfWidth, halfHeight);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {import("../../extent.js").Extent} extent Clip extent.\n * @protected\n */\n\n\n CanvasLayerRenderer.prototype.clipUnrotated = function (context, frameState, extent) {\n var topLeft = getTopLeft(extent);\n var topRight = getTopRight(extent);\n var bottomRight = getBottomRight(extent);\n var bottomLeft = getBottomLeft(extent);\n apply(frameState.coordinateToPixelTransform, topLeft);\n apply(frameState.coordinateToPixelTransform, topRight);\n apply(frameState.coordinateToPixelTransform, bottomRight);\n apply(frameState.coordinateToPixelTransform, bottomLeft);\n var inverted = this.inversePixelTransform;\n apply(inverted, topLeft);\n apply(inverted, topRight);\n apply(inverted, bottomRight);\n apply(inverted, bottomLeft);\n context.save();\n context.beginPath();\n context.moveTo(Math.round(topLeft[0]), Math.round(topLeft[1]));\n context.lineTo(Math.round(topRight[0]), Math.round(topRight[1]));\n context.lineTo(Math.round(bottomRight[0]), Math.round(bottomRight[1]));\n context.lineTo(Math.round(bottomLeft[0]), Math.round(bottomLeft[1]));\n context.clip();\n };\n /**\n * @param {import("../../render/EventType.js").default} type Event type.\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @private\n */\n\n\n CanvasLayerRenderer.prototype.dispatchRenderEvent_ = function (type, context, frameState) {\n var layer = this.getLayer();\n\n if (layer.hasListener(type)) {\n var event_1 = new render_Event(type, this.inversePixelTransform, frameState, context);\n layer.dispatchEvent(event_1);\n }\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @protected\n */\n\n\n CanvasLayerRenderer.prototype.preRender = function (context, frameState) {\n this.dispatchRenderEvent_(render_EventType.PRERENDER, context, frameState);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @protected\n */\n\n\n CanvasLayerRenderer.prototype.postRender = function (context, frameState) {\n this.dispatchRenderEvent_(render_EventType.POSTRENDER, context, frameState);\n };\n /**\n * Creates a transform for rendering to an element that will be rotated after rendering.\n * @param {import("../../coordinate.js").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} width Width of the rendered element (in pixels).\n * @param {number} height Height of the rendered element (in pixels).\n * @param {number} offsetX Offset on the x-axis in view coordinates.\n * @protected\n * @return {!import("../../transform.js").Transform} Transform.\n */\n\n\n CanvasLayerRenderer.prototype.getRenderTransform = function (center, resolution, rotation, pixelRatio, width, height, offsetX) {\n var dx1 = width / 2;\n var dy1 = height / 2;\n var sx = pixelRatio / resolution;\n var sy = -sx;\n var dx2 = -center[0] + offsetX;\n var dy2 = -center[1];\n return compose(this.tempTransform, dx1, dy1, sx, sy, -rotation, dx2, dy2);\n };\n /**\n * @param {import("../../pixel.js").Pixel} pixel Pixel.\n * @param {import("../../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @return {Uint8ClampedArray|Uint8Array} The result. If there is no data at the pixel\n * location, null will be returned. If there is data, but pixel values cannot be\n * returned, and empty array will be returned.\n */\n\n\n CanvasLayerRenderer.prototype.getDataAtPixel = function (pixel, frameState, hitTolerance) {\n var renderPixel = apply(this.inversePixelTransform, pixel.slice());\n var context = this.context;\n var layer = this.getLayer();\n var layerExtent = layer.getExtent();\n\n if (layerExtent) {\n var renderCoordinate = apply(frameState.pixelToCoordinateTransform, pixel.slice());\n /** get only data inside of the layer extent */\n\n if (!containsCoordinate(layerExtent, renderCoordinate)) {\n return null;\n }\n }\n\n var data;\n\n try {\n var x = Math.round(renderPixel[0]);\n var y = Math.round(renderPixel[1]);\n var newCanvas = document.createElement(\'canvas\');\n var newContext = newCanvas.getContext(\'2d\');\n newCanvas.width = 1;\n newCanvas.height = 1;\n newContext.clearRect(0, 0, 1, 1);\n newContext.drawImage(context.canvas, x, y, 1, 1, 0, 0, 1, 1);\n data = newContext.getImageData(0, 0, 1, 1).data;\n } catch (err) {\n if (err.name === \'SecurityError\') {\n // tainted canvas, we assume there is data at the given pixel (although there might not be)\n return new Uint8Array();\n }\n\n return data;\n }\n\n if (data[3] === 0) {\n return null;\n }\n\n return data;\n };\n\n return CanvasLayerRenderer;\n}(renderer_Layer);\n\n/* harmony default export */ var canvas_Layer = (CanvasLayerRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/BuilderType.js\n/**\n * @module ol/render/canvas/BuilderType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var BuilderType = ({\n CIRCLE: \'Circle\',\n DEFAULT: \'Default\',\n IMAGE: \'Image\',\n LINE_STRING: \'LineString\',\n POLYGON: \'Polygon\',\n TEXT: \'Text\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/textpath.js\n/**\n * @module ol/geom/flat/textpath\n */\n\n\n/**\n * @param {Array<number>} flatCoordinates Path to put text on.\n * @param {number} offset Start offset of the `flatCoordinates`.\n * @param {number} end End offset of the `flatCoordinates`.\n * @param {number} stride Stride.\n * @param {string} text Text to place on the path.\n * @param {number} startM m along the path where the text starts.\n * @param {number} maxAngle Max angle between adjacent chars in radians.\n * @param {number} scale The product of the text scale and the device pixel ratio.\n * @param {function(string, string, Object<string, number>):number} measureAndCacheTextWidth Measure and cache text width.\n * @param {string} font The font.\n * @param {Object<string, number>} cache A cache of measured widths.\n * @param {number} rotation Rotation to apply to the flatCoordinates to determine whether text needs to be reversed.\n * @return {Array<Array<*>>} The result array (or null if `maxAngle` was\n * exceeded). Entries of the array are x, y, anchorX, angle, chunk.\n */\n\nfunction drawTextOnPath(flatCoordinates, offset, end, stride, text, startM, maxAngle, scale, measureAndCacheTextWidth, font, cache, rotation) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n var x1 = 0;\n var y1 = 0;\n var segmentLength = 0;\n var segmentM = 0;\n\n function advance() {\n x1 = x2;\n y1 = y2;\n offset += stride;\n x2 = flatCoordinates[offset];\n y2 = flatCoordinates[offset + 1];\n segmentM += segmentLength;\n segmentLength = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n }\n\n do {\n advance();\n } while (offset < end - stride && segmentM + segmentLength < startM);\n\n var interpolate = (startM - segmentM) / segmentLength;\n var beginX = lerp(x1, x2, interpolate);\n var beginY = lerp(y1, y2, interpolate);\n var startOffset = offset - stride;\n var startLength = segmentM;\n var endM = startM + scale * measureAndCacheTextWidth(font, text, cache);\n\n while (offset < end - stride && segmentM + segmentLength < endM) {\n advance();\n }\n\n interpolate = (endM - segmentM) / segmentLength;\n var endX = lerp(x1, x2, interpolate);\n var endY = lerp(y1, y2, interpolate); // Keep text upright\n\n var reverse;\n\n if (rotation) {\n var flat = [beginX, beginY, endX, endY];\n transform_rotate(flat, 0, 4, 2, rotation, flat, flat);\n reverse = flat[0] > flat[2];\n } else {\n reverse = beginX > endX;\n }\n\n var PI = Math.PI;\n var result = [];\n var singleSegment = startOffset + stride === offset;\n offset = startOffset;\n segmentLength = 0;\n segmentM = startLength;\n x2 = flatCoordinates[offset];\n y2 = flatCoordinates[offset + 1]; // All on the same segment\n\n if (singleSegment) {\n advance();\n var previousAngle_1 = Math.atan2(y2 - y1, x2 - x1);\n\n if (reverse) {\n previousAngle_1 += previousAngle_1 > 0 ? -PI : PI;\n }\n\n var x = (endX + beginX) / 2;\n var y = (endY + beginY) / 2;\n result[0] = [x, y, (endM - startM) / 2, previousAngle_1, text];\n return result;\n }\n\n var previousAngle;\n\n for (var i = 0, ii = text.length; i < ii;) {\n advance();\n var angle = Math.atan2(y2 - y1, x2 - x1);\n\n if (reverse) {\n angle += angle > 0 ? -PI : PI;\n }\n\n if (previousAngle !== undefined) {\n var delta = angle - previousAngle;\n delta += delta > PI ? -2 * PI : delta < -PI ? 2 * PI : 0;\n\n if (Math.abs(delta) > maxAngle) {\n return null;\n }\n }\n\n previousAngle = angle;\n var iStart = i;\n var charLength = 0;\n\n for (; i < ii; ++i) {\n var index = reverse ? ii - i - 1 : i;\n var len = scale * measureAndCacheTextWidth(font, text[index], cache);\n\n if (offset + stride < end && segmentM + segmentLength < startM + charLength + len / 2) {\n break;\n }\n\n charLength += len;\n }\n\n if (i === iStart) {\n continue;\n }\n\n var chars = reverse ? text.substring(ii - iStart, ii - i) : text.substring(iStart, i);\n interpolate = (startM + charLength / 2 - segmentM) / segmentLength;\n var x = lerp(x1, x2, interpolate);\n var y = lerp(y1, y2, interpolate);\n result.push([x, y, charLength / 2, angle, chars]);\n startM += charLength;\n }\n\n return result;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/length.js\n/**\n * @module ol/geom/flat/length\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Length.\n */\nfunction lineStringLength(flatCoordinates, offset, end, stride) {\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1];\n var length = 0;\n\n for (var i = offset + stride; i < end; i += stride) {\n var x2 = flatCoordinates[i];\n var y2 = flatCoordinates[i + 1];\n length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n x1 = x2;\n y1 = y2;\n }\n\n return length;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Perimeter.\n */\n\nfunction linearRingLength(flatCoordinates, offset, end, stride) {\n var perimeter = lineStringLength(flatCoordinates, offset, end, stride);\n var dx = flatCoordinates[end - stride] - flatCoordinates[offset];\n var dy = flatCoordinates[end - stride + 1] - flatCoordinates[offset + 1];\n perimeter += Math.sqrt(dx * dx + dy * dy);\n return perimeter;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Executor.js\n/**\n * @module ol/render/canvas/Executor\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} BBox\n * @property {number} minX\n * @property {number} minY\n * @property {number} maxX\n * @property {number} maxY\n * @property {*} value\n */\n\n/**\n * @typedef {Object} ImageOrLabelDimensions\n * @property {number} drawImageX\n * @property {number} drawImageY\n * @property {number} drawImageW\n * @property {number} drawImageH\n * @property {number} originX\n * @property {number} originY\n * @property {Array<number>} scale\n * @property {BBox} declutterBox\n * @property {import("../../transform.js").Transform} canvasTransform\n */\n\n/**\n * @typedef {{0: CanvasRenderingContext2D, 1: number, 2: import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement, 3: ImageOrLabelDimensions, 4: number, 5: Array<*>, 6: Array<*>}} ReplayImageOrLabelArgs\n */\n\n/**\n * @template T\n * @typedef {function(import("../../Feature.js").FeatureLike, import("../../geom/SimpleGeometry.js").default): T} FeatureCallback\n */\n\n/**\n * @type {import("../../extent.js").Extent}\n */\n\nvar tmpExtent = createEmpty();\n/** @type {import("../../coordinate.js").Coordinate} */\n\nvar p1 = [];\n/** @type {import("../../coordinate.js").Coordinate} */\n\nvar p2 = [];\n/** @type {import("../../coordinate.js").Coordinate} */\n\nvar p3 = [];\n/** @type {import("../../coordinate.js").Coordinate} */\n\nvar p4 = [];\n/**\n * @param {ReplayImageOrLabelArgs} replayImageOrLabelArgs Arguments to replayImageOrLabel\n * @return {BBox} Declutter bbox.\n */\n\nfunction getDeclutterBox(replayImageOrLabelArgs) {\n return replayImageOrLabelArgs[3].declutterBox;\n}\n\nvar rtlRegEx = new RegExp(\n/* eslint-disable prettier/prettier */\n\'[\' + String.fromCharCode(0x00591) + \'-\' + String.fromCharCode(0x008ff) + String.fromCharCode(0x0fb1d) + \'-\' + String.fromCharCode(0x0fdff) + String.fromCharCode(0x0fe70) + \'-\' + String.fromCharCode(0x0fefc) + String.fromCharCode(0x10800) + \'-\' + String.fromCharCode(0x10fff) + String.fromCharCode(0x1e800) + \'-\' + String.fromCharCode(0x1efff) + \']\'\n/* eslint-enable prettier/prettier */\n);\n/**\n * @param {string} text Text.\n * @param {string} align Alignment.\n * @return {number} Text alignment.\n */\n\nfunction horizontalTextAlign(text, align) {\n if ((align === \'start\' || align === \'end\') && !rtlRegEx.test(text)) {\n align = align === \'start\' ? \'left\' : \'right\';\n }\n\n return TEXT_ALIGN[align];\n}\n\nvar Executor =\n/** @class */\nfunction () {\n /**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {boolean} overlaps The replay can have overlapping geometries.\n * @param {import("../canvas.js").SerializableInstructions} instructions The serializable instructions\n * @param {import("../../size.js").Size} renderBuffer Render buffer (width/height) in pixels.\n */\n function Executor(resolution, pixelRatio, overlaps, instructions, renderBuffer) {\n /**\n * @protected\n * @type {boolean}\n */\n this.overlaps = overlaps;\n /**\n * @protected\n * @type {number}\n */\n\n this.pixelRatio = pixelRatio;\n /**\n * @protected\n * @const\n * @type {number}\n */\n\n this.resolution = resolution;\n /**\n * @private\n * @type {boolean}\n */\n\n this.alignFill_;\n /**\n * @protected\n * @type {Array<*>}\n */\n\n this.instructions = instructions.instructions;\n /**\n * @protected\n * @type {Array<number>}\n */\n\n this.coordinates = instructions.coordinates;\n /**\n * @private\n * @type {!Object<number,import("../../coordinate.js").Coordinate|Array<import("../../coordinate.js").Coordinate>|Array<Array<import("../../coordinate.js").Coordinate>>>}\n */\n\n this.coordinateCache_ = {};\n /**\n * @private\n * @type {import("../../size.js").Size}\n */\n\n this.renderBuffer_ = renderBuffer;\n /**\n * @private\n * @type {!import("../../transform.js").Transform}\n */\n\n this.renderedTransform_ = create();\n /**\n * @protected\n * @type {Array<*>}\n */\n\n this.hitDetectionInstructions = instructions.hitDetectionInstructions;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.pixelCoordinates_ = null;\n /**\n * @private\n * @type {number}\n */\n\n this.viewRotation_ = 0;\n /**\n * @type {!Object<string, import("../canvas.js").FillState>}\n */\n\n this.fillStates = instructions.fillStates || {};\n /**\n * @type {!Object<string, import("../canvas.js").StrokeState>}\n */\n\n this.strokeStates = instructions.strokeStates || {};\n /**\n * @type {!Object<string, import("../canvas.js").TextState>}\n */\n\n this.textStates = instructions.textStates || {};\n /**\n * @private\n * @type {Object<string, Object<string, number>>}\n */\n\n this.widths_ = {};\n /**\n * @private\n * @type {Object<string, import("../canvas.js").Label>}\n */\n\n this.labels_ = {};\n }\n /**\n * @param {string} text Text.\n * @param {string} textKey Text style key.\n * @param {string} fillKey Fill style key.\n * @param {string} strokeKey Stroke style key.\n * @return {import("../canvas.js").Label} Label.\n */\n\n\n Executor.prototype.createLabel = function (text, textKey, fillKey, strokeKey) {\n var key = text + textKey + fillKey + strokeKey;\n\n if (this.labels_[key]) {\n return this.labels_[key];\n }\n\n var strokeState = strokeKey ? this.strokeStates[strokeKey] : null;\n var fillState = fillKey ? this.fillStates[fillKey] : null;\n var textState = this.textStates[textKey];\n var pixelRatio = this.pixelRatio;\n var scale = [textState.scale[0] * pixelRatio, textState.scale[1] * pixelRatio];\n var align = horizontalTextAlign(text, textState.textAlign || defaultTextAlign);\n var strokeWidth = strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0;\n var lines = text.split(\'\\n\');\n var numLines = lines.length;\n var widths = [];\n var width = measureTextWidths(textState.font, lines, widths);\n var lineHeight = measureTextHeight(textState.font);\n var height = lineHeight * numLines;\n var renderWidth = width + strokeWidth;\n var contextInstructions = []; // make canvas 2 pixels wider to account for italic text width measurement errors\n\n var w = (renderWidth + 2) * scale[0];\n var h = (height + strokeWidth) * scale[1];\n /** @type {import("../canvas.js").Label} */\n\n var label = {\n width: w < 0 ? Math.floor(w) : Math.ceil(w),\n height: h < 0 ? Math.floor(h) : Math.ceil(h),\n contextInstructions: contextInstructions\n };\n\n if (scale[0] != 1 || scale[1] != 1) {\n contextInstructions.push(\'scale\', scale);\n }\n\n contextInstructions.push(\'font\', textState.font);\n\n if (strokeKey) {\n contextInstructions.push(\'strokeStyle\', strokeState.strokeStyle);\n contextInstructions.push(\'lineWidth\', strokeWidth);\n contextInstructions.push(\'lineCap\', strokeState.lineCap);\n contextInstructions.push(\'lineJoin\', strokeState.lineJoin);\n contextInstructions.push(\'miterLimit\', strokeState.miterLimit); // eslint-disable-next-line\n\n var Context = WORKER_OFFSCREEN_CANVAS ? OffscreenCanvasRenderingContext2D : CanvasRenderingContext2D;\n\n if (Context.prototype.setLineDash) {\n contextInstructions.push(\'setLineDash\', [strokeState.lineDash]);\n contextInstructions.push(\'lineDashOffset\', strokeState.lineDashOffset);\n }\n }\n\n if (fillKey) {\n contextInstructions.push(\'fillStyle\', fillState.fillStyle);\n }\n\n contextInstructions.push(\'textBaseline\', \'middle\');\n contextInstructions.push(\'textAlign\', \'center\');\n var leftRight = 0.5 - align;\n var x = align * renderWidth + leftRight * strokeWidth;\n var i;\n\n if (strokeKey) {\n for (i = 0; i < numLines; ++i) {\n contextInstructions.push(\'strokeText\', [lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight]);\n }\n }\n\n if (fillKey) {\n for (i = 0; i < numLines; ++i) {\n contextInstructions.push(\'fillText\', [lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight]);\n }\n }\n\n this.labels_[key] = label;\n return label;\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../coordinate.js").Coordinate} p1 1st point of the background box.\n * @param {import("../../coordinate.js").Coordinate} p2 2nd point of the background box.\n * @param {import("../../coordinate.js").Coordinate} p3 3rd point of the background box.\n * @param {import("../../coordinate.js").Coordinate} p4 4th point of the background box.\n * @param {Array<*>} fillInstruction Fill instruction.\n * @param {Array<*>} strokeInstruction Stroke instruction.\n */\n\n\n Executor.prototype.replayTextBackground_ = function (context, p1, p2, p3, p4, fillInstruction, strokeInstruction) {\n context.beginPath();\n context.moveTo.apply(context, p1);\n context.lineTo.apply(context, p2);\n context.lineTo.apply(context, p3);\n context.lineTo.apply(context, p4);\n context.lineTo.apply(context, p1);\n\n if (fillInstruction) {\n this.alignFill_ =\n /** @type {boolean} */\n fillInstruction[2];\n this.fill_(context);\n }\n\n if (strokeInstruction) {\n this.setStrokeStyle_(context,\n /** @type {Array<*>} */\n strokeInstruction);\n context.stroke();\n }\n };\n /**\n * @private\n * @param {number} sheetWidth Width of the sprite sheet.\n * @param {number} sheetHeight Height of the sprite sheet.\n * @param {number} centerX X.\n * @param {number} centerY Y.\n * @param {number} width Width.\n * @param {number} height Height.\n * @param {number} anchorX Anchor X.\n * @param {number} anchorY Anchor Y.\n * @param {number} originX Origin X.\n * @param {number} originY Origin Y.\n * @param {number} rotation Rotation.\n * @param {import("../../size.js").Size} scale Scale.\n * @param {boolean} snapToPixel Snap to pixel.\n * @param {Array<number>} padding Padding.\n * @param {boolean} fillStroke Background fill or stroke.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @return {ImageOrLabelDimensions} Dimensions for positioning and decluttering the image or label.\n */\n\n\n Executor.prototype.calculateImageOrLabelDimensions_ = function (sheetWidth, sheetHeight, centerX, centerY, width, height, anchorX, anchorY, originX, originY, rotation, scale, snapToPixel, padding, fillStroke, feature) {\n anchorX *= scale[0];\n anchorY *= scale[1];\n var x = centerX - anchorX;\n var y = centerY - anchorY;\n var w = width + originX > sheetWidth ? sheetWidth - originX : width;\n var h = height + originY > sheetHeight ? sheetHeight - originY : height;\n var boxW = padding[3] + w * scale[0] + padding[1];\n var boxH = padding[0] + h * scale[1] + padding[2];\n var boxX = x - padding[3];\n var boxY = y - padding[0];\n\n if (fillStroke || rotation !== 0) {\n p1[0] = boxX;\n p4[0] = boxX;\n p1[1] = boxY;\n p2[1] = boxY;\n p2[0] = boxX + boxW;\n p3[0] = p2[0];\n p3[1] = boxY + boxH;\n p4[1] = p3[1];\n }\n\n var transform;\n\n if (rotation !== 0) {\n transform = compose(create(), centerX, centerY, 1, 1, rotation, -centerX, -centerY);\n apply(transform, p1);\n apply(transform, p2);\n apply(transform, p3);\n apply(transform, p4);\n createOrUpdate(Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1]), tmpExtent);\n } else {\n createOrUpdate(Math.min(boxX, boxX + boxW), Math.min(boxY, boxY + boxH), Math.max(boxX, boxX + boxW), Math.max(boxY, boxY + boxH), tmpExtent);\n }\n\n if (snapToPixel) {\n x = Math.round(x);\n y = Math.round(y);\n }\n\n return {\n drawImageX: x,\n drawImageY: y,\n drawImageW: w,\n drawImageH: h,\n originX: originX,\n originY: originY,\n declutterBox: {\n minX: tmpExtent[0],\n minY: tmpExtent[1],\n maxX: tmpExtent[2],\n maxY: tmpExtent[3],\n value: feature\n },\n canvasTransform: transform,\n scale: scale\n };\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} imageOrLabel Image.\n * @param {ImageOrLabelDimensions} dimensions Dimensions.\n * @param {number} opacity Opacity.\n * @param {Array<*>} fillInstruction Fill instruction.\n * @param {Array<*>} strokeInstruction Stroke instruction.\n * @return {boolean} The image or label was rendered.\n */\n\n\n Executor.prototype.replayImageOrLabel_ = function (context, contextScale, imageOrLabel, dimensions, opacity, fillInstruction, strokeInstruction) {\n var fillStroke = !!(fillInstruction || strokeInstruction);\n var box = dimensions.declutterBox;\n var canvas = context.canvas;\n var strokePadding = strokeInstruction ? strokeInstruction[2] * dimensions.scale[0] / 2 : 0;\n var intersects = box.minX - strokePadding <= canvas.width / contextScale && box.maxX + strokePadding >= 0 && box.minY - strokePadding <= canvas.height / contextScale && box.maxY + strokePadding >= 0;\n\n if (intersects) {\n if (fillStroke) {\n this.replayTextBackground_(context, p1, p2, p3, p4,\n /** @type {Array<*>} */\n fillInstruction,\n /** @type {Array<*>} */\n strokeInstruction);\n }\n\n drawImageOrLabel(context, dimensions.canvasTransform, opacity, imageOrLabel, dimensions.originX, dimensions.originY, dimensions.drawImageW, dimensions.drawImageH, dimensions.drawImageX, dimensions.drawImageY, dimensions.scale);\n }\n\n return true;\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n */\n\n\n Executor.prototype.fill_ = function (context) {\n if (this.alignFill_) {\n var origin_1 = apply(this.renderedTransform_, [0, 0]);\n var repeatSize = 512 * this.pixelRatio;\n context.save();\n context.translate(origin_1[0] % repeatSize, origin_1[1] % repeatSize);\n context.rotate(this.viewRotation_);\n }\n\n context.fill();\n\n if (this.alignFill_) {\n context.restore();\n }\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n * @param {Array<*>} instruction Instruction.\n */\n\n\n Executor.prototype.setStrokeStyle_ = function (context, instruction) {\n context[\'strokeStyle\'] =\n /** @type {import("../../colorlike.js").ColorLike} */\n instruction[1];\n context.lineWidth =\n /** @type {number} */\n instruction[2];\n context.lineCap =\n /** @type {CanvasLineCap} */\n instruction[3];\n context.lineJoin =\n /** @type {CanvasLineJoin} */\n instruction[4];\n context.miterLimit =\n /** @type {number} */\n instruction[5];\n\n if (context.setLineDash) {\n context.lineDashOffset =\n /** @type {number} */\n instruction[7];\n context.setLineDash(\n /** @type {Array<number>} */\n instruction[6]);\n }\n };\n /**\n * @private\n * @param {string} text The text to draw.\n * @param {string} textKey The key of the text state.\n * @param {string} strokeKey The key for the stroke state.\n * @param {string} fillKey The key for the fill state.\n * @return {{label: import("../canvas.js").Label, anchorX: number, anchorY: number}} The text image and its anchor.\n */\n\n\n Executor.prototype.drawLabelWithPointPlacement_ = function (text, textKey, strokeKey, fillKey) {\n var textState = this.textStates[textKey];\n var label = this.createLabel(text, textKey, fillKey, strokeKey);\n var strokeState = this.strokeStates[strokeKey];\n var pixelRatio = this.pixelRatio;\n var align = horizontalTextAlign(text, textState.textAlign || defaultTextAlign);\n var baseline = TEXT_ALIGN[textState.textBaseline || defaultTextBaseline];\n var strokeWidth = strokeState && strokeState.lineWidth ? strokeState.lineWidth : 0; // Remove the 2 pixels we added in createLabel() for the anchor\n\n var width = label.width / pixelRatio - 2 * textState.scale[0];\n var anchorX = align * width + 2 * (0.5 - align) * strokeWidth;\n var anchorY = baseline * label.height / pixelRatio + 2 * (0.5 - baseline) * strokeWidth;\n return {\n label: label,\n anchorX: anchorX,\n anchorY: anchorY\n };\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {Array<*>} instructions Instructions array.\n * @param {boolean} snapToPixel Snap point symbols and text to integer pixels.\n * @param {FeatureCallback<T>=} opt_featureCallback Feature callback.\n * @param {import("../../extent.js").Extent=} opt_hitExtent Only check\n * features that intersect this extent.\n * @param {import("rbush").default=} opt_declutterTree Declutter tree.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n Executor.prototype.execute_ = function (context, contextScale, transform, instructions, snapToPixel, opt_featureCallback, opt_hitExtent, opt_declutterTree) {\n /** @type {Array<number>} */\n var pixelCoordinates;\n\n if (this.pixelCoordinates_ && equals(transform, this.renderedTransform_)) {\n pixelCoordinates = this.pixelCoordinates_;\n } else {\n if (!this.pixelCoordinates_) {\n this.pixelCoordinates_ = [];\n }\n\n pixelCoordinates = transform2D(this.coordinates, 0, this.coordinates.length, 2, transform, this.pixelCoordinates_);\n setFromArray(this.renderedTransform_, transform);\n }\n\n var i = 0; // instruction index\n\n var ii = instructions.length; // end of instructions\n\n var d = 0; // data index\n\n var dd; // end of per-instruction data\n\n var anchorX, anchorY, prevX, prevY, roundX, roundY, image, text, textKey, strokeKey, fillKey;\n var pendingFill = 0;\n var pendingStroke = 0;\n var lastFillInstruction = null;\n var lastStrokeInstruction = null;\n var coordinateCache = this.coordinateCache_;\n var viewRotation = this.viewRotation_;\n var viewRotationFromTransform = Math.round(Math.atan2(-transform[1], transform[0]) * 1e12) / 1e12;\n var state =\n /** @type {import("../../render.js").State} */\n {\n context: context,\n pixelRatio: this.pixelRatio,\n resolution: this.resolution,\n rotation: viewRotation\n }; // When the batch size gets too big, performance decreases. 200 is a good\n // balance between batch size and number of fill/stroke instructions.\n\n var batchSize = this.instructions != instructions || this.overlaps ? 0 : 200;\n var\n /** @type {import("../../Feature.js").FeatureLike} */\n feature;\n var x, y, currentGeometry;\n\n while (i < ii) {\n var instruction = instructions[i];\n var type =\n /** @type {import("./Instruction.js").default} */\n instruction[0];\n\n switch (type) {\n case canvas_Instruction.BEGIN_GEOMETRY:\n feature =\n /** @type {import("../../Feature.js").FeatureLike} */\n instruction[1];\n currentGeometry = instruction[3];\n\n if (!feature.getGeometry()) {\n i =\n /** @type {number} */\n instruction[2];\n } else if (opt_hitExtent !== undefined && !intersects(opt_hitExtent, currentGeometry.getExtent())) {\n i =\n /** @type {number} */\n instruction[2] + 1;\n } else {\n ++i;\n }\n\n break;\n\n case canvas_Instruction.BEGIN_PATH:\n if (pendingFill > batchSize) {\n this.fill_(context);\n pendingFill = 0;\n }\n\n if (pendingStroke > batchSize) {\n context.stroke();\n pendingStroke = 0;\n }\n\n if (!pendingFill && !pendingStroke) {\n context.beginPath();\n prevX = NaN;\n prevY = NaN;\n }\n\n ++i;\n break;\n\n case canvas_Instruction.CIRCLE:\n d =\n /** @type {number} */\n instruction[1];\n var x1 = pixelCoordinates[d];\n var y1 = pixelCoordinates[d + 1];\n var x2 = pixelCoordinates[d + 2];\n var y2 = pixelCoordinates[d + 3];\n var dx = x2 - x1;\n var dy = y2 - y1;\n var r = Math.sqrt(dx * dx + dy * dy);\n context.moveTo(x1 + r, y1);\n context.arc(x1, y1, r, 0, 2 * Math.PI, true);\n ++i;\n break;\n\n case canvas_Instruction.CLOSE_PATH:\n context.closePath();\n ++i;\n break;\n\n case canvas_Instruction.CUSTOM:\n d =\n /** @type {number} */\n instruction[1];\n dd = instruction[2];\n var geometry =\n /** @type {import("../../geom/SimpleGeometry.js").default} */\n instruction[3];\n var renderer = instruction[4];\n var fn = instruction.length == 6 ? instruction[5] : undefined;\n state.geometry = geometry;\n state.feature = feature;\n\n if (!(i in coordinateCache)) {\n coordinateCache[i] = [];\n }\n\n var coords = coordinateCache[i];\n\n if (fn) {\n fn(pixelCoordinates, d, dd, 2, coords);\n } else {\n coords[0] = pixelCoordinates[d];\n coords[1] = pixelCoordinates[d + 1];\n coords.length = 2;\n }\n\n renderer(coords, state);\n ++i;\n break;\n\n case canvas_Instruction.DRAW_IMAGE:\n d =\n /** @type {number} */\n instruction[1];\n dd =\n /** @type {number} */\n instruction[2];\n image =\n /** @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} */\n instruction[3]; // Remaining arguments in DRAW_IMAGE are in alphabetical order\n\n anchorX =\n /** @type {number} */\n instruction[4];\n anchorY =\n /** @type {number} */\n instruction[5];\n var height =\n /** @type {number} */\n instruction[6];\n var opacity =\n /** @type {number} */\n instruction[7];\n var originX =\n /** @type {number} */\n instruction[8];\n var originY =\n /** @type {number} */\n instruction[9];\n var rotateWithView =\n /** @type {boolean} */\n instruction[10];\n var rotation =\n /** @type {number} */\n instruction[11];\n var scale =\n /** @type {import("../../size.js").Size} */\n instruction[12];\n var width =\n /** @type {number} */\n instruction[13];\n var declutterImageWithText =\n /** @type {import("../canvas.js").DeclutterImageWithText} */\n instruction[14];\n\n if (!image && instruction.length >= 19) {\n // create label images\n text =\n /** @type {string} */\n instruction[18];\n textKey =\n /** @type {string} */\n instruction[19];\n strokeKey =\n /** @type {string} */\n instruction[20];\n fillKey =\n /** @type {string} */\n instruction[21];\n var labelWithAnchor = this.drawLabelWithPointPlacement_(text, textKey, strokeKey, fillKey);\n image = labelWithAnchor.label;\n instruction[3] = image;\n var textOffsetX =\n /** @type {number} */\n instruction[22];\n anchorX = (labelWithAnchor.anchorX - textOffsetX) * this.pixelRatio;\n instruction[4] = anchorX;\n var textOffsetY =\n /** @type {number} */\n instruction[23];\n anchorY = (labelWithAnchor.anchorY - textOffsetY) * this.pixelRatio;\n instruction[5] = anchorY;\n height = image.height;\n instruction[6] = height;\n width = image.width;\n instruction[13] = width;\n }\n\n var geometryWidths = void 0;\n\n if (instruction.length > 24) {\n geometryWidths =\n /** @type {number} */\n instruction[24];\n }\n\n var padding = void 0,\n backgroundFill = void 0,\n backgroundStroke = void 0;\n\n if (instruction.length > 16) {\n padding =\n /** @type {Array<number>} */\n instruction[15];\n backgroundFill =\n /** @type {boolean} */\n instruction[16];\n backgroundStroke =\n /** @type {boolean} */\n instruction[17];\n } else {\n padding = defaultPadding;\n backgroundFill = false;\n backgroundStroke = false;\n }\n\n if (rotateWithView && viewRotationFromTransform) {\n // Canvas is expected to be rotated to reverse view rotation.\n rotation += viewRotation;\n } else if (!rotateWithView && !viewRotationFromTransform) {\n // Canvas is not rotated, images need to be rotated back to be north-up.\n rotation -= viewRotation;\n }\n\n var widthIndex = 0;\n\n for (; d < dd; d += 2) {\n if (geometryWidths && geometryWidths[widthIndex++] < width / this.pixelRatio) {\n continue;\n }\n\n var dimensions = this.calculateImageOrLabelDimensions_(image.width, image.height, pixelCoordinates[d], pixelCoordinates[d + 1], width, height, anchorX, anchorY, originX, originY, rotation, scale, snapToPixel, padding, backgroundFill || backgroundStroke, feature);\n /** @type {ReplayImageOrLabelArgs} */\n\n var args = [context, contextScale, image, dimensions, opacity, backgroundFill ?\n /** @type {Array<*>} */\n lastFillInstruction : null, backgroundStroke ?\n /** @type {Array<*>} */\n lastStrokeInstruction : null];\n var imageArgs = void 0;\n var imageDeclutterBox = void 0;\n\n if (opt_declutterTree && declutterImageWithText) {\n if (!declutterImageWithText[d]) {\n // We now have the image for an image+text combination.\n declutterImageWithText[d] = args; // Don\'t render anything for now, wait for the text.\n\n continue;\n }\n\n imageArgs = declutterImageWithText[d];\n delete declutterImageWithText[d];\n imageDeclutterBox = getDeclutterBox(imageArgs);\n\n if (opt_declutterTree.collides(imageDeclutterBox)) {\n continue;\n }\n }\n\n if (opt_declutterTree && opt_declutterTree.collides(dimensions.declutterBox)) {\n continue;\n }\n\n if (imageArgs) {\n // We now have image and text for an image+text combination.\n if (opt_declutterTree) {\n opt_declutterTree.insert(imageDeclutterBox);\n } // Render the image before we render the text.\n\n\n this.replayImageOrLabel_.apply(this, imageArgs);\n }\n\n if (opt_declutterTree) {\n opt_declutterTree.insert(dimensions.declutterBox);\n }\n\n this.replayImageOrLabel_.apply(this, args);\n }\n\n ++i;\n break;\n\n case canvas_Instruction.DRAW_CHARS:\n var begin =\n /** @type {number} */\n instruction[1];\n var end =\n /** @type {number} */\n instruction[2];\n var baseline =\n /** @type {number} */\n instruction[3];\n var overflow =\n /** @type {number} */\n instruction[4];\n fillKey =\n /** @type {string} */\n instruction[5];\n var maxAngle =\n /** @type {number} */\n instruction[6];\n var measurePixelRatio =\n /** @type {number} */\n instruction[7];\n var offsetY =\n /** @type {number} */\n instruction[8];\n strokeKey =\n /** @type {string} */\n instruction[9];\n var strokeWidth =\n /** @type {number} */\n instruction[10];\n text =\n /** @type {string} */\n instruction[11];\n textKey =\n /** @type {string} */\n instruction[12];\n var pixelRatioScale = [\n /** @type {number} */\n instruction[13],\n /** @type {number} */\n instruction[13]];\n var textState = this.textStates[textKey];\n var font = textState.font;\n var textScale = [textState.scale[0] * measurePixelRatio, textState.scale[1] * measurePixelRatio];\n var cachedWidths = void 0;\n\n if (font in this.widths_) {\n cachedWidths = this.widths_[font];\n } else {\n cachedWidths = {};\n this.widths_[font] = cachedWidths;\n }\n\n var pathLength = lineStringLength(pixelCoordinates, begin, end, 2);\n var textLength = Math.abs(textScale[0]) * measureAndCacheTextWidth(font, text, cachedWidths);\n\n if (overflow || textLength <= pathLength) {\n var textAlign = this.textStates[textKey].textAlign;\n var startM = (pathLength - textLength) * TEXT_ALIGN[textAlign];\n var parts = drawTextOnPath(pixelCoordinates, begin, end, 2, text, startM, maxAngle, Math.abs(textScale[0]), measureAndCacheTextWidth, font, cachedWidths, viewRotationFromTransform ? 0 : this.viewRotation_);\n\n drawChars: if (parts) {\n /** @type {Array<ReplayImageOrLabelArgs>} */\n var replayImageOrLabelArgs = [];\n var c = void 0,\n cc = void 0,\n chars = void 0,\n label = void 0,\n part = void 0;\n\n if (strokeKey) {\n for (c = 0, cc = parts.length; c < cc; ++c) {\n part = parts[c]; // x, y, anchorX, rotation, chunk\n\n chars =\n /** @type {string} */\n part[4];\n label = this.createLabel(chars, textKey, \'\', strokeKey);\n anchorX =\n /** @type {number} */\n part[2] + (textScale[0] < 0 ? -strokeWidth : strokeWidth);\n anchorY = baseline * label.height + (0.5 - baseline) * 2 * strokeWidth * textScale[1] / textScale[0] - offsetY;\n var dimensions = this.calculateImageOrLabelDimensions_(label.width, label.height, part[0], part[1], label.width, label.height, anchorX, anchorY, 0, 0, part[3], pixelRatioScale, false, defaultPadding, false, feature);\n\n if (opt_declutterTree && opt_declutterTree.collides(dimensions.declutterBox)) {\n break drawChars;\n }\n\n replayImageOrLabelArgs.push([context, contextScale, label, dimensions, 1, null, null]);\n }\n }\n\n if (fillKey) {\n for (c = 0, cc = parts.length; c < cc; ++c) {\n part = parts[c]; // x, y, anchorX, rotation, chunk\n\n chars =\n /** @type {string} */\n part[4];\n label = this.createLabel(chars, textKey, fillKey, \'\');\n anchorX =\n /** @type {number} */\n part[2];\n anchorY = baseline * label.height - offsetY;\n var dimensions = this.calculateImageOrLabelDimensions_(label.width, label.height, part[0], part[1], label.width, label.height, anchorX, anchorY, 0, 0, part[3], pixelRatioScale, false, defaultPadding, false, feature);\n\n if (opt_declutterTree && opt_declutterTree.collides(dimensions.declutterBox)) {\n break drawChars;\n }\n\n replayImageOrLabelArgs.push([context, contextScale, label, dimensions, 1, null, null]);\n }\n }\n\n if (opt_declutterTree) {\n opt_declutterTree.load(replayImageOrLabelArgs.map(getDeclutterBox));\n }\n\n for (var i_1 = 0, ii_1 = replayImageOrLabelArgs.length; i_1 < ii_1; ++i_1) {\n this.replayImageOrLabel_.apply(this, replayImageOrLabelArgs[i_1]);\n }\n }\n }\n\n ++i;\n break;\n\n case canvas_Instruction.END_GEOMETRY:\n if (opt_featureCallback !== undefined) {\n feature =\n /** @type {import("../../Feature.js").FeatureLike} */\n instruction[1];\n var result = opt_featureCallback(feature, currentGeometry);\n\n if (result) {\n return result;\n }\n }\n\n ++i;\n break;\n\n case canvas_Instruction.FILL:\n if (batchSize) {\n pendingFill++;\n } else {\n this.fill_(context);\n }\n\n ++i;\n break;\n\n case canvas_Instruction.MOVE_TO_LINE_TO:\n d =\n /** @type {number} */\n instruction[1];\n dd =\n /** @type {number} */\n instruction[2];\n x = pixelCoordinates[d];\n y = pixelCoordinates[d + 1];\n roundX = x + 0.5 | 0;\n roundY = y + 0.5 | 0;\n\n if (roundX !== prevX || roundY !== prevY) {\n context.moveTo(x, y);\n prevX = roundX;\n prevY = roundY;\n }\n\n for (d += 2; d < dd; d += 2) {\n x = pixelCoordinates[d];\n y = pixelCoordinates[d + 1];\n roundX = x + 0.5 | 0;\n roundY = y + 0.5 | 0;\n\n if (d == dd - 2 || roundX !== prevX || roundY !== prevY) {\n context.lineTo(x, y);\n prevX = roundX;\n prevY = roundY;\n }\n }\n\n ++i;\n break;\n\n case canvas_Instruction.SET_FILL_STYLE:\n lastFillInstruction = instruction;\n this.alignFill_ = instruction[2];\n\n if (pendingFill) {\n this.fill_(context);\n pendingFill = 0;\n\n if (pendingStroke) {\n context.stroke();\n pendingStroke = 0;\n }\n }\n\n context.fillStyle =\n /** @type {import("../../colorlike.js").ColorLike} */\n instruction[1];\n ++i;\n break;\n\n case canvas_Instruction.SET_STROKE_STYLE:\n lastStrokeInstruction = instruction;\n\n if (pendingStroke) {\n context.stroke();\n pendingStroke = 0;\n }\n\n this.setStrokeStyle_(context,\n /** @type {Array<*>} */\n instruction);\n ++i;\n break;\n\n case canvas_Instruction.STROKE:\n if (batchSize) {\n pendingStroke++;\n } else {\n context.stroke();\n }\n\n ++i;\n break;\n\n default:\n ++i; // consume the instruction anyway, to avoid an infinite loop\n\n break;\n }\n }\n\n if (pendingFill) {\n this.fill_(context);\n }\n\n if (pendingStroke) {\n context.stroke();\n }\n\n return undefined;\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {boolean} snapToPixel Snap point symbols and text to integer pixels.\n * @param {import("rbush").default=} opt_declutterTree Declutter tree.\n */\n\n\n Executor.prototype.execute = function (context, contextScale, transform, viewRotation, snapToPixel, opt_declutterTree) {\n this.viewRotation_ = viewRotation;\n this.execute_(context, contextScale, transform, this.instructions, snapToPixel, undefined, undefined, opt_declutterTree);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {FeatureCallback<T>=} opt_featureCallback Feature callback.\n * @param {import("../../extent.js").Extent=} opt_hitExtent Only check\n * features that intersect this extent.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n Executor.prototype.executeHitDetection = function (context, transform, viewRotation, opt_featureCallback, opt_hitExtent) {\n this.viewRotation_ = viewRotation;\n return this.execute_(context, 1, transform, this.hitDetectionInstructions, true, opt_featureCallback, opt_hitExtent);\n };\n\n return Executor;\n}();\n\n/* harmony default export */ var canvas_Executor = (Executor);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/ExecutorGroup.js\n/**\n * @module ol/render/canvas/ExecutorGroup\n */\n\n\n\n\n\n\n\n\n/**\n * @const\n * @type {Array<import("./BuilderType.js").default>}\n */\n\nvar ORDER = [BuilderType.POLYGON, BuilderType.CIRCLE, BuilderType.LINE_STRING, BuilderType.IMAGE, BuilderType.TEXT, BuilderType.DEFAULT];\n\nvar ExecutorGroup =\n/** @class */\nfunction () {\n /**\n * @param {import("../../extent.js").Extent} maxExtent Max extent for clipping. When a\n * `maxExtent` was set on the Buillder for this executor group, the same `maxExtent`\n * should be set here, unless the target context does not exceet that extent (which\n * can be the case when rendering to tiles).\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {boolean} overlaps The executor group can have overlapping geometries.\n * @param {!Object<string, !Object<import("./BuilderType.js").default, import("../canvas.js").SerializableInstructions>>} allInstructions\n * The serializable instructions.\n * @param {number=} opt_renderBuffer Optional rendering buffer.\n */\n function ExecutorGroup(maxExtent, resolution, pixelRatio, overlaps, allInstructions, opt_renderBuffer) {\n /**\n * @private\n * @type {import("../../extent.js").Extent}\n */\n this.maxExtent_ = maxExtent;\n /**\n * @private\n * @type {boolean}\n */\n\n this.overlaps_ = overlaps;\n /**\n * @private\n * @type {number}\n */\n\n this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {number}\n */\n\n this.resolution_ = resolution;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.renderBuffer_ = opt_renderBuffer;\n /**\n * @private\n * @type {!Object<string, !Object<import("./BuilderType.js").default, import("./Executor").default>>}\n */\n\n this.executorsByZIndex_ = {};\n /**\n * @private\n * @type {CanvasRenderingContext2D}\n */\n\n this.hitDetectionContext_ = null;\n /**\n * @private\n * @type {import("../../transform.js").Transform}\n */\n\n this.hitDetectionTransform_ = create();\n this.createExecutors_(allInstructions);\n }\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../transform.js").Transform} transform Transform.\n */\n\n\n ExecutorGroup.prototype.clip = function (context, transform) {\n var flatClipCoords = this.getClipCoords(transform);\n context.beginPath();\n context.moveTo(flatClipCoords[0], flatClipCoords[1]);\n context.lineTo(flatClipCoords[2], flatClipCoords[3]);\n context.lineTo(flatClipCoords[4], flatClipCoords[5]);\n context.lineTo(flatClipCoords[6], flatClipCoords[7]);\n context.clip();\n };\n /**\n * Create executors and populate them using the provided instructions.\n * @private\n * @param {!Object<string, !Object<import("./BuilderType.js").default, import("../canvas.js").SerializableInstructions>>} allInstructions The serializable instructions\n */\n\n\n ExecutorGroup.prototype.createExecutors_ = function (allInstructions) {\n for (var zIndex in allInstructions) {\n var executors = this.executorsByZIndex_[zIndex];\n\n if (executors === undefined) {\n executors = {};\n this.executorsByZIndex_[zIndex] = executors;\n }\n\n var instructionByZindex = allInstructions[zIndex];\n var renderBuffer = [this.renderBuffer_ || 0, this.renderBuffer_ || 0];\n\n for (var builderType in instructionByZindex) {\n var instructions = instructionByZindex[builderType];\n executors[builderType] = new canvas_Executor(this.resolution_, this.pixelRatio_, this.overlaps_, instructions, renderBuffer);\n }\n }\n };\n /**\n * @param {Array<import("./BuilderType.js").default>} executors Executors.\n * @return {boolean} Has executors of the provided types.\n */\n\n\n ExecutorGroup.prototype.hasExecutors = function (executors) {\n for (var zIndex in this.executorsByZIndex_) {\n var candidates = this.executorsByZIndex_[zIndex];\n\n for (var i = 0, ii = executors.length; i < ii; ++i) {\n if (executors[i] in candidates) {\n return true;\n }\n }\n }\n\n return false;\n };\n /**\n * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {function(import("../../Feature.js").FeatureLike, import("../../geom/SimpleGeometry.js").default, number): T} callback Feature callback.\n * @param {Array<import("../../Feature.js").FeatureLike>} declutteredFeatures Decluttered features.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n ExecutorGroup.prototype.forEachFeatureAtCoordinate = function (coordinate, resolution, rotation, hitTolerance, callback, declutteredFeatures) {\n hitTolerance = Math.round(hitTolerance);\n var contextSize = hitTolerance * 2 + 1;\n var transform = compose(this.hitDetectionTransform_, hitTolerance + 0.5, hitTolerance + 0.5, 1 / resolution, -1 / resolution, -rotation, -coordinate[0], -coordinate[1]);\n var newContext = !this.hitDetectionContext_;\n\n if (newContext) {\n this.hitDetectionContext_ = createCanvasContext2D(contextSize, contextSize);\n }\n\n var context = this.hitDetectionContext_;\n\n if (context.canvas.width !== contextSize || context.canvas.height !== contextSize) {\n context.canvas.width = contextSize;\n context.canvas.height = contextSize;\n } else if (!newContext) {\n context.clearRect(0, 0, contextSize, contextSize);\n }\n /**\n * @type {import("../../extent.js").Extent}\n */\n\n\n var hitExtent;\n\n if (this.renderBuffer_ !== undefined) {\n hitExtent = createEmpty();\n extendCoordinate(hitExtent, coordinate);\n buffer(hitExtent, resolution * (this.renderBuffer_ + hitTolerance), hitExtent);\n }\n\n var indexes = getPixelIndexArray(hitTolerance);\n var builderType;\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.\n * @return {T|undefined} Callback result.\n */\n\n function featureCallback(feature, geometry) {\n var imageData = context.getImageData(0, 0, contextSize, contextSize).data;\n\n for (var i_1 = 0, ii = indexes.length; i_1 < ii; i_1++) {\n if (imageData[indexes[i_1]] > 0) {\n if (!declutteredFeatures || builderType !== BuilderType.IMAGE && builderType !== BuilderType.TEXT || declutteredFeatures.indexOf(feature) !== -1) {\n var idx = (indexes[i_1] - 3) / 4;\n var x = hitTolerance - idx % contextSize;\n var y = hitTolerance - (idx / contextSize | 0);\n var result_1 = callback(feature, geometry, x * x + y * y);\n\n if (result_1) {\n return result_1;\n }\n }\n\n context.clearRect(0, 0, contextSize, contextSize);\n break;\n }\n }\n\n return undefined;\n }\n /** @type {Array<number>} */\n\n\n var zs = Object.keys(this.executorsByZIndex_).map(Number);\n zs.sort(numberSafeCompareFunction);\n var i, j, executors, executor, result;\n\n for (i = zs.length - 1; i >= 0; --i) {\n var zIndexKey = zs[i].toString();\n executors = this.executorsByZIndex_[zIndexKey];\n\n for (j = ORDER.length - 1; j >= 0; --j) {\n builderType = ORDER[j];\n executor = executors[builderType];\n\n if (executor !== undefined) {\n result = executor.executeHitDetection(context, transform, rotation, featureCallback, hitExtent);\n\n if (result) {\n return result;\n }\n }\n }\n }\n\n return undefined;\n };\n /**\n * @param {import("../../transform.js").Transform} transform Transform.\n * @return {Array<number>} Clip coordinates.\n */\n\n\n ExecutorGroup.prototype.getClipCoords = function (transform) {\n var maxExtent = this.maxExtent_;\n\n if (!maxExtent) {\n return null;\n }\n\n var minX = maxExtent[0];\n var minY = maxExtent[1];\n var maxX = maxExtent[2];\n var maxY = maxExtent[3];\n var flatClipCoords = [minX, minY, minX, maxY, maxX, maxY, maxX, minY];\n transform2D(flatClipCoords, 0, 8, 2, transform, flatClipCoords);\n return flatClipCoords;\n };\n /**\n * @return {boolean} Is empty.\n */\n\n\n ExecutorGroup.prototype.isEmpty = function () {\n return obj_isEmpty(this.executorsByZIndex_);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {boolean} snapToPixel Snap point symbols and test to integer pixel.\n * @param {Array<import("./BuilderType.js").default>=} opt_builderTypes Ordered replay types to replay.\n * Default is {@link module:ol/render/replay~ORDER}\n * @param {import("rbush").default=} opt_declutterTree Declutter tree.\n */\n\n\n ExecutorGroup.prototype.execute = function (context, contextScale, transform, viewRotation, snapToPixel, opt_builderTypes, opt_declutterTree) {\n /** @type {Array<number>} */\n var zs = Object.keys(this.executorsByZIndex_).map(Number);\n zs.sort(numberSafeCompareFunction); // setup clipping so that the parts of over-simplified geometries are not\n // visible outside the current extent when panning\n\n if (this.maxExtent_) {\n context.save();\n this.clip(context, transform);\n }\n\n var builderTypes = opt_builderTypes ? opt_builderTypes : ORDER;\n var i, ii, j, jj, replays, replay;\n\n if (opt_declutterTree) {\n zs.reverse();\n }\n\n for (i = 0, ii = zs.length; i < ii; ++i) {\n var zIndexKey = zs[i].toString();\n replays = this.executorsByZIndex_[zIndexKey];\n\n for (j = 0, jj = builderTypes.length; j < jj; ++j) {\n var builderType = builderTypes[j];\n replay = replays[builderType];\n\n if (replay !== undefined) {\n replay.execute(context, contextScale, transform, viewRotation, snapToPixel, opt_declutterTree);\n }\n }\n }\n\n if (this.maxExtent_) {\n context.restore();\n }\n };\n\n return ExecutorGroup;\n}();\n/**\n * This cache is used to store arrays of indexes for calculated pixel circles\n * to increase performance.\n * It is a static property to allow each Replaygroup to access it.\n * @type {Object<number, Array<number>>}\n */\n\n\nvar circlePixelIndexArrayCache = {};\n/**\n * This methods creates an array with indexes of all pixels within a circle,\n * ordered by how close they are to the center.\n * A cache is used to increase performance.\n * @param {number} radius Radius.\n * @returns {Array<number>} An array with indexes within a circle.\n */\n\nfunction getPixelIndexArray(radius) {\n if (circlePixelIndexArrayCache[radius] !== undefined) {\n return circlePixelIndexArrayCache[radius];\n }\n\n var size = radius * 2 + 1;\n var maxDistanceSq = radius * radius;\n var distances = new Array(maxDistanceSq + 1);\n\n for (var i = 0; i <= radius; ++i) {\n for (var j = 0; j <= radius; ++j) {\n var distanceSq = i * i + j * j;\n\n if (distanceSq > maxDistanceSq) {\n break;\n }\n\n var distance = distances[distanceSq];\n\n if (!distance) {\n distance = [];\n distances[distanceSq] = distance;\n }\n\n distance.push(((radius + i) * size + (radius + j)) * 4 + 3);\n\n if (i > 0) {\n distance.push(((radius - i) * size + (radius + j)) * 4 + 3);\n }\n\n if (j > 0) {\n distance.push(((radius + i) * size + (radius - j)) * 4 + 3);\n\n if (i > 0) {\n distance.push(((radius - i) * size + (radius - j)) * 4 + 3);\n }\n }\n }\n }\n\n var pixelIndex = [];\n\n for (var i = 0, ii = distances.length; i < ii; ++i) {\n if (distances[i]) {\n pixelIndex.push.apply(pixelIndex, distances[i]);\n }\n }\n\n circlePixelIndexArrayCache[radius] = pixelIndex;\n return pixelIndex;\n}\n/* harmony default export */ var canvas_ExecutorGroup = (ExecutorGroup);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Immediate.js\n/**\n * @module ol/render/canvas/Immediate\n */\n// FIXME test, especially polygons with holes and multipolygons\n// FIXME need to handle large thick features (where pixel size matters)\n// FIXME add offset and end to ol/geom/flat/transform~transform2D?\nvar Immediate_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * A concrete subclass of {@link module:ol/render/VectorContext} that implements\n * direct rendering of features and geometries to an HTML5 Canvas context.\n * Instances of this class are created internally by the library and\n * provided to application code as vectorContext member of the\n * {@link module:ol/render/Event~RenderEvent} object associated with postcompose, precompose and\n * render events emitted by layers and maps.\n */\n\nvar CanvasImmediateRenderer =\n/** @class */\nfunction (_super) {\n Immediate_extends(CanvasImmediateRenderer, _super);\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {number=} opt_squaredTolerance Optional squared tolerance for simplification.\n * @param {import("../../proj.js").TransformFunction=} opt_userTransform Transform from user to view projection.\n */\n\n\n function CanvasImmediateRenderer(context, pixelRatio, extent, transform, viewRotation, opt_squaredTolerance, opt_userTransform) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {CanvasRenderingContext2D}\n */\n\n\n _this.context_ = context;\n /**\n * @private\n * @type {number}\n */\n\n _this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {import("../../extent.js").Extent}\n */\n\n _this.extent_ = extent;\n /**\n * @private\n * @type {import("../../transform.js").Transform}\n */\n\n _this.transform_ = transform;\n /**\n * @private\n * @type {number}\n */\n\n _this.viewRotation_ = viewRotation;\n /**\n * @private\n * @type {number}\n */\n\n _this.squaredTolerance_ = opt_squaredTolerance;\n /**\n * @private\n * @type {import("../../proj.js").TransformFunction}\n */\n\n _this.userTransform_ = opt_userTransform;\n /**\n * @private\n * @type {?import("../canvas.js").FillState}\n */\n\n _this.contextFillState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").StrokeState}\n */\n\n _this.contextStrokeState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").TextState}\n */\n\n _this.contextTextState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").FillState}\n */\n\n _this.fillState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").StrokeState}\n */\n\n _this.strokeState_ = null;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n */\n\n _this.image_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageAnchorX_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageAnchorY_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageHeight_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageOpacity_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageOriginX_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageOriginY_ = 0;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.imageRotateWithView_ = false;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageRotation_ = 0;\n /**\n * @private\n * @type {import("../../size.js").Size}\n */\n\n _this.imageScale_ = [0, 0];\n /**\n * @private\n * @type {number}\n */\n\n _this.imageWidth_ = 0;\n /**\n * @private\n * @type {string}\n */\n\n _this.text_ = \'\';\n /**\n * @private\n * @type {number}\n */\n\n _this.textOffsetX_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.textOffsetY_ = 0;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.textRotateWithView_ = false;\n /**\n * @private\n * @type {number}\n */\n\n _this.textRotation_ = 0;\n /**\n * @private\n * @type {import("../../size.js").Size}\n */\n\n _this.textScale_ = [0, 0];\n /**\n * @private\n * @type {?import("../canvas.js").FillState}\n */\n\n _this.textFillState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").StrokeState}\n */\n\n _this.textStrokeState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").TextState}\n */\n\n _this.textState_ = null;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.pixelCoordinates_ = [];\n /**\n * @private\n * @type {import("../../transform.js").Transform}\n */\n\n _this.tmpLocalTransform_ = create();\n return _this;\n }\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @private\n */\n\n\n CanvasImmediateRenderer.prototype.drawImages_ = function (flatCoordinates, offset, end, stride) {\n if (!this.image_) {\n return;\n }\n\n var pixelCoordinates = transform2D(flatCoordinates, offset, end, 2, this.transform_, this.pixelCoordinates_);\n var context = this.context_;\n var localTransform = this.tmpLocalTransform_;\n var alpha = context.globalAlpha;\n\n if (this.imageOpacity_ != 1) {\n context.globalAlpha = alpha * this.imageOpacity_;\n }\n\n var rotation = this.imageRotation_;\n\n if (this.imageRotateWithView_) {\n rotation += this.viewRotation_;\n }\n\n for (var i = 0, ii = pixelCoordinates.length; i < ii; i += 2) {\n var x = pixelCoordinates[i] - this.imageAnchorX_;\n var y = pixelCoordinates[i + 1] - this.imageAnchorY_;\n\n if (rotation !== 0 || this.imageScale_[0] != 1 || this.imageScale_[1] != 1) {\n var centerX = x + this.imageAnchorX_;\n var centerY = y + this.imageAnchorY_;\n compose(localTransform, centerX, centerY, 1, 1, rotation, -centerX, -centerY);\n context.setTransform.apply(context, localTransform);\n context.translate(centerX, centerY);\n context.scale(this.imageScale_[0], this.imageScale_[1]);\n context.drawImage(this.image_, this.imageOriginX_, this.imageOriginY_, this.imageWidth_, this.imageHeight_, -this.imageAnchorX_, -this.imageAnchorY_, this.imageWidth_, this.imageHeight_);\n context.setTransform(1, 0, 0, 1, 0, 0);\n } else {\n context.drawImage(this.image_, this.imageOriginX_, this.imageOriginY_, this.imageWidth_, this.imageHeight_, x, y, this.imageWidth_, this.imageHeight_);\n }\n }\n\n if (this.imageOpacity_ != 1) {\n context.globalAlpha = alpha;\n }\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @private\n */\n\n\n CanvasImmediateRenderer.prototype.drawText_ = function (flatCoordinates, offset, end, stride) {\n if (!this.textState_ || this.text_ === \'\') {\n return;\n }\n\n if (this.textFillState_) {\n this.setContextFillState_(this.textFillState_);\n }\n\n if (this.textStrokeState_) {\n this.setContextStrokeState_(this.textStrokeState_);\n }\n\n this.setContextTextState_(this.textState_);\n var pixelCoordinates = transform2D(flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_);\n var context = this.context_;\n var rotation = this.textRotation_;\n\n if (this.textRotateWithView_) {\n rotation += this.viewRotation_;\n }\n\n for (; offset < end; offset += stride) {\n var x = pixelCoordinates[offset] + this.textOffsetX_;\n var y = pixelCoordinates[offset + 1] + this.textOffsetY_;\n\n if (rotation !== 0 || this.textScale_[0] != 1 || this.textScale_[1] != 1) {\n var localTransform = compose(this.tmpLocalTransform_, x, y, 1, 1, rotation, -x, -y);\n context.setTransform.apply(context, localTransform);\n context.translate(x, y);\n context.scale(this.textScale_[0], this.textScale_[1]);\n\n if (this.textStrokeState_) {\n context.strokeText(this.text_, 0, 0);\n }\n\n if (this.textFillState_) {\n context.fillText(this.text_, 0, 0);\n }\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n } else {\n if (this.textStrokeState_) {\n context.strokeText(this.text_, x, y);\n }\n\n if (this.textFillState_) {\n context.fillText(this.text_, x, y);\n }\n }\n }\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {boolean} close Close.\n * @private\n * @return {number} end End.\n */\n\n\n CanvasImmediateRenderer.prototype.moveToLineTo_ = function (flatCoordinates, offset, end, stride, close) {\n var context = this.context_;\n var pixelCoordinates = transform2D(flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_);\n context.moveTo(pixelCoordinates[0], pixelCoordinates[1]);\n var length = pixelCoordinates.length;\n\n if (close) {\n length -= 2;\n }\n\n for (var i = 2; i < length; i += 2) {\n context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]);\n }\n\n if (close) {\n context.closePath();\n }\n\n return end;\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @private\n * @return {number} End.\n */\n\n\n CanvasImmediateRenderer.prototype.drawRings_ = function (flatCoordinates, offset, ends, stride) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n offset = this.moveToLineTo_(flatCoordinates, offset, ends[i], stride, true);\n }\n\n return offset;\n };\n /**\n * Render a circle geometry into the canvas. Rendering is immediate and uses\n * the current fill and stroke styles.\n *\n * @param {import("../../geom/Circle.js").default} geometry Circle geometry.\n * @api\n */\n\n\n CanvasImmediateRenderer.prototype.drawCircle = function (geometry) {\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n\n if (this.fillState_ || this.strokeState_) {\n if (this.fillState_) {\n this.setContextFillState_(this.fillState_);\n }\n\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n }\n\n var pixelCoordinates = transformGeom2D(geometry, this.transform_, this.pixelCoordinates_);\n var dx = pixelCoordinates[2] - pixelCoordinates[0];\n var dy = pixelCoordinates[3] - pixelCoordinates[1];\n var radius = Math.sqrt(dx * dx + dy * dy);\n var context = this.context_;\n context.beginPath();\n context.arc(pixelCoordinates[0], pixelCoordinates[1], radius, 0, 2 * Math.PI);\n\n if (this.fillState_) {\n context.fill();\n }\n\n if (this.strokeState_) {\n context.stroke();\n }\n }\n\n if (this.text_ !== \'\') {\n this.drawText_(geometry.getCenter(), 0, 2, 2);\n }\n };\n /**\n * Set the rendering style. Note that since this is an immediate rendering API,\n * any `zIndex` on the provided style will be ignored.\n *\n * @param {import("../../style/Style.js").default} style The rendering style.\n * @api\n */\n\n\n CanvasImmediateRenderer.prototype.setStyle = function (style) {\n this.setFillStrokeStyle(style.getFill(), style.getStroke());\n this.setImageStyle(style.getImage());\n this.setTextStyle(style.getText());\n };\n /**\n * @param {import("../../transform.js").Transform} transform Transform.\n */\n\n\n CanvasImmediateRenderer.prototype.setTransform = function (transform) {\n this.transform_ = transform;\n };\n /**\n * Render a geometry into the canvas. Call\n * {@link module:ol/render/canvas/Immediate#setStyle} first to set the rendering style.\n *\n * @param {import("../../geom/Geometry.js").default|import("../Feature.js").default} geometry The geometry to render.\n * @api\n */\n\n\n CanvasImmediateRenderer.prototype.drawGeometry = function (geometry) {\n var type = geometry.getType();\n\n switch (type) {\n case geom_GeometryType.POINT:\n this.drawPoint(\n /** @type {import("../../geom/Point.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.LINE_STRING:\n this.drawLineString(\n /** @type {import("../../geom/LineString.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.POLYGON:\n this.drawPolygon(\n /** @type {import("../../geom/Polygon.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.MULTI_POINT:\n this.drawMultiPoint(\n /** @type {import("../../geom/MultiPoint.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.MULTI_LINE_STRING:\n this.drawMultiLineString(\n /** @type {import("../../geom/MultiLineString.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.MULTI_POLYGON:\n this.drawMultiPolygon(\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.GEOMETRY_COLLECTION:\n this.drawGeometryCollection(\n /** @type {import("../../geom/GeometryCollection.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.CIRCLE:\n this.drawCircle(\n /** @type {import("../../geom/Circle.js").default} */\n geometry);\n break;\n\n default:\n }\n };\n /**\n * Render a feature into the canvas. Note that any `zIndex` on the provided\n * style will be ignored - features are rendered immediately in the order that\n * this method is called. If you need `zIndex` support, you should be using an\n * {@link module:ol/layer/Vector~VectorLayer} instead.\n *\n * @param {import("../../Feature.js").default} feature Feature.\n * @param {import("../../style/Style.js").default} style Style.\n * @api\n */\n\n\n CanvasImmediateRenderer.prototype.drawFeature = function (feature, style) {\n var geometry = style.getGeometryFunction()(feature);\n\n if (!geometry || !intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n\n this.setStyle(style);\n this.drawGeometry(geometry);\n };\n /**\n * Render a GeometryCollection to the canvas. Rendering is immediate and\n * uses the current styles appropriate for each geometry in the collection.\n *\n * @param {import("../../geom/GeometryCollection.js").default} geometry Geometry collection.\n */\n\n\n CanvasImmediateRenderer.prototype.drawGeometryCollection = function (geometry) {\n var geometries = geometry.getGeometriesArray();\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n this.drawGeometry(geometries[i]);\n }\n };\n /**\n * Render a Point geometry into the canvas. Rendering is immediate and uses\n * the current style.\n *\n * @param {import("../../geom/Point.js").default|import("../Feature.js").default} geometry Point geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawPoint = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/Point.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n var flatCoordinates = geometry.getFlatCoordinates();\n var stride = geometry.getStride();\n\n if (this.image_) {\n this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n\n if (this.text_ !== \'\') {\n this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n };\n /**\n * Render a MultiPoint geometry into the canvas. Rendering is immediate and\n * uses the current style.\n *\n * @param {import("../../geom/MultiPoint.js").default|import("../Feature.js").default} geometry MultiPoint geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawMultiPoint = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/MultiPoint.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n var flatCoordinates = geometry.getFlatCoordinates();\n var stride = geometry.getStride();\n\n if (this.image_) {\n this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n\n if (this.text_ !== \'\') {\n this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n };\n /**\n * Render a LineString into the canvas. Rendering is immediate and uses\n * the current style.\n *\n * @param {import("../../geom/LineString.js").default|import("../Feature.js").default} geometry LineString geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawLineString = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/LineString.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n var context = this.context_;\n var flatCoordinates = geometry.getFlatCoordinates();\n context.beginPath();\n this.moveToLineTo_(flatCoordinates, 0, flatCoordinates.length, geometry.getStride(), false);\n context.stroke();\n }\n\n if (this.text_ !== \'\') {\n var flatMidpoint = geometry.getFlatMidpoint();\n this.drawText_(flatMidpoint, 0, 2, 2);\n }\n };\n /**\n * Render a MultiLineString geometry into the canvas. Rendering is immediate\n * and uses the current style.\n *\n * @param {import("../../geom/MultiLineString.js").default|import("../Feature.js").default} geometry MultiLineString geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawMultiLineString = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/MultiLineString.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n var geometryExtent = geometry.getExtent();\n\n if (!intersects(this.extent_, geometryExtent)) {\n return;\n }\n\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n var context = this.context_;\n var flatCoordinates = geometry.getFlatCoordinates();\n var offset = 0;\n var ends =\n /** @type {Array<number>} */\n geometry.getEnds();\n var stride = geometry.getStride();\n context.beginPath();\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n offset = this.moveToLineTo_(flatCoordinates, offset, ends[i], stride, false);\n }\n\n context.stroke();\n }\n\n if (this.text_ !== \'\') {\n var flatMidpoints = geometry.getFlatMidpoints();\n this.drawText_(flatMidpoints, 0, flatMidpoints.length, 2);\n }\n };\n /**\n * Render a Polygon geometry into the canvas. Rendering is immediate and uses\n * the current style.\n *\n * @param {import("../../geom/Polygon.js").default|import("../Feature.js").default} geometry Polygon geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawPolygon = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/Polygon.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n\n if (this.strokeState_ || this.fillState_) {\n if (this.fillState_) {\n this.setContextFillState_(this.fillState_);\n }\n\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n }\n\n var context = this.context_;\n context.beginPath();\n this.drawRings_(geometry.getOrientedFlatCoordinates(), 0,\n /** @type {Array<number>} */\n geometry.getEnds(), geometry.getStride());\n\n if (this.fillState_) {\n context.fill();\n }\n\n if (this.strokeState_) {\n context.stroke();\n }\n }\n\n if (this.text_ !== \'\') {\n var flatInteriorPoint = geometry.getFlatInteriorPoint();\n this.drawText_(flatInteriorPoint, 0, 2, 2);\n }\n };\n /**\n * Render MultiPolygon geometry into the canvas. Rendering is immediate and\n * uses the current style.\n * @param {import("../../geom/MultiPolygon.js").default} geometry MultiPolygon geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawMultiPolygon = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n\n if (this.strokeState_ || this.fillState_) {\n if (this.fillState_) {\n this.setContextFillState_(this.fillState_);\n }\n\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n }\n\n var context = this.context_;\n var flatCoordinates = geometry.getOrientedFlatCoordinates();\n var offset = 0;\n var endss = geometry.getEndss();\n var stride = geometry.getStride();\n context.beginPath();\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n offset = this.drawRings_(flatCoordinates, offset, ends, stride);\n }\n\n if (this.fillState_) {\n context.fill();\n }\n\n if (this.strokeState_) {\n context.stroke();\n }\n }\n\n if (this.text_ !== \'\') {\n var flatInteriorPoints = geometry.getFlatInteriorPoints();\n this.drawText_(flatInteriorPoints, 0, flatInteriorPoints.length, 2);\n }\n };\n /**\n * @param {import("../canvas.js").FillState} fillState Fill state.\n * @private\n */\n\n\n CanvasImmediateRenderer.prototype.setContextFillState_ = function (fillState) {\n var context = this.context_;\n var contextFillState = this.contextFillState_;\n\n if (!contextFillState) {\n context.fillStyle = fillState.fillStyle;\n this.contextFillState_ = {\n fillStyle: fillState.fillStyle\n };\n } else {\n if (contextFillState.fillStyle != fillState.fillStyle) {\n contextFillState.fillStyle = fillState.fillStyle;\n context.fillStyle = fillState.fillStyle;\n }\n }\n };\n /**\n * @param {import("../canvas.js").StrokeState} strokeState Stroke state.\n * @private\n */\n\n\n CanvasImmediateRenderer.prototype.setContextStrokeState_ = function (strokeState) {\n var context = this.context_;\n var contextStrokeState = this.contextStrokeState_;\n\n if (!contextStrokeState) {\n context.lineCap = strokeState.lineCap;\n\n if (context.setLineDash) {\n context.setLineDash(strokeState.lineDash);\n context.lineDashOffset = strokeState.lineDashOffset;\n }\n\n context.lineJoin = strokeState.lineJoin;\n context.lineWidth = strokeState.lineWidth;\n context.miterLimit = strokeState.miterLimit;\n context.strokeStyle = strokeState.strokeStyle;\n this.contextStrokeState_ = {\n lineCap: strokeState.lineCap,\n lineDash: strokeState.lineDash,\n lineDashOffset: strokeState.lineDashOffset,\n lineJoin: strokeState.lineJoin,\n lineWidth: strokeState.lineWidth,\n miterLimit: strokeState.miterLimit,\n strokeStyle: strokeState.strokeStyle\n };\n } else {\n if (contextStrokeState.lineCap != strokeState.lineCap) {\n contextStrokeState.lineCap = strokeState.lineCap;\n context.lineCap = strokeState.lineCap;\n }\n\n if (context.setLineDash) {\n if (!equals(contextStrokeState.lineDash, strokeState.lineDash)) {\n context.setLineDash(contextStrokeState.lineDash = strokeState.lineDash);\n }\n\n if (contextStrokeState.lineDashOffset != strokeState.lineDashOffset) {\n contextStrokeState.lineDashOffset = strokeState.lineDashOffset;\n context.lineDashOffset = strokeState.lineDashOffset;\n }\n }\n\n if (contextStrokeState.lineJoin != strokeState.lineJoin) {\n contextStrokeState.lineJoin = strokeState.lineJoin;\n context.lineJoin = strokeState.lineJoin;\n }\n\n if (contextStrokeState.lineWidth != strokeState.lineWidth) {\n contextStrokeState.lineWidth = strokeState.lineWidth;\n context.lineWidth = strokeState.lineWidth;\n }\n\n if (contextStrokeState.miterLimit != strokeState.miterLimit) {\n contextStrokeState.miterLimit = strokeState.miterLimit;\n context.miterLimit = strokeState.miterLimit;\n }\n\n if (contextStrokeState.strokeStyle != strokeState.strokeStyle) {\n contextStrokeState.strokeStyle = strokeState.strokeStyle;\n context.strokeStyle = strokeState.strokeStyle;\n }\n }\n };\n /**\n * @param {import("../canvas.js").TextState} textState Text state.\n * @private\n */\n\n\n CanvasImmediateRenderer.prototype.setContextTextState_ = function (textState) {\n var context = this.context_;\n var contextTextState = this.contextTextState_;\n var textAlign = textState.textAlign ? textState.textAlign : defaultTextAlign;\n\n if (!contextTextState) {\n context.font = textState.font;\n context.textAlign =\n /** @type {CanvasTextAlign} */\n textAlign;\n context.textBaseline =\n /** @type {CanvasTextBaseline} */\n textState.textBaseline;\n this.contextTextState_ = {\n font: textState.font,\n textAlign: textAlign,\n textBaseline: textState.textBaseline\n };\n } else {\n if (contextTextState.font != textState.font) {\n contextTextState.font = textState.font;\n context.font = textState.font;\n }\n\n if (contextTextState.textAlign != textAlign) {\n contextTextState.textAlign =\n /** @type {CanvasTextAlign} */\n textAlign;\n context.textAlign =\n /** @type {CanvasTextAlign} */\n textAlign;\n }\n\n if (contextTextState.textBaseline != textState.textBaseline) {\n contextTextState.textBaseline =\n /** @type {CanvasTextBaseline} */\n textState.textBaseline;\n context.textBaseline =\n /** @type {CanvasTextBaseline} */\n textState.textBaseline;\n }\n }\n };\n /**\n * Set the fill and stroke style for subsequent draw operations. To clear\n * either fill or stroke styles, pass null for the appropriate parameter.\n *\n * @param {import("../../style/Fill.js").default} fillStyle Fill style.\n * @param {import("../../style/Stroke.js").default} strokeStyle Stroke style.\n */\n\n\n CanvasImmediateRenderer.prototype.setFillStrokeStyle = function (fillStyle, strokeStyle) {\n if (!fillStyle) {\n this.fillState_ = null;\n } else {\n var fillStyleColor = fillStyle.getColor();\n this.fillState_ = {\n fillStyle: asColorLike(fillStyleColor ? fillStyleColor : defaultFillStyle)\n };\n }\n\n if (!strokeStyle) {\n this.strokeState_ = null;\n } else {\n var strokeStyleColor = strokeStyle.getColor();\n var strokeStyleLineCap = strokeStyle.getLineCap();\n var strokeStyleLineDash = strokeStyle.getLineDash();\n var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();\n var strokeStyleLineJoin = strokeStyle.getLineJoin();\n var strokeStyleWidth = strokeStyle.getWidth();\n var strokeStyleMiterLimit = strokeStyle.getMiterLimit();\n this.strokeState_ = {\n lineCap: strokeStyleLineCap !== undefined ? strokeStyleLineCap : defaultLineCap,\n lineDash: strokeStyleLineDash ? strokeStyleLineDash : defaultLineDash,\n lineDashOffset: strokeStyleLineDashOffset ? strokeStyleLineDashOffset : defaultLineDashOffset,\n lineJoin: strokeStyleLineJoin !== undefined ? strokeStyleLineJoin : defaultLineJoin,\n lineWidth: this.pixelRatio_ * (strokeStyleWidth !== undefined ? strokeStyleWidth : defaultLineWidth),\n miterLimit: strokeStyleMiterLimit !== undefined ? strokeStyleMiterLimit : defaultMiterLimit,\n strokeStyle: asColorLike(strokeStyleColor ? strokeStyleColor : defaultStrokeStyle)\n };\n }\n };\n /**\n * Set the image style for subsequent draw operations. Pass null to remove\n * the image style.\n *\n * @param {import("../../style/Image.js").default} imageStyle Image style.\n */\n\n\n CanvasImmediateRenderer.prototype.setImageStyle = function (imageStyle) {\n if (!imageStyle) {\n this.image_ = null;\n } else {\n var imageSize = imageStyle.getSize();\n\n if (!imageSize) {\n this.image_ = null;\n } else {\n var imageAnchor = imageStyle.getAnchor(); // FIXME pixel ratio\n\n var imageImage = imageStyle.getImage(1);\n var imageOrigin = imageStyle.getOrigin();\n var imageScale = imageStyle.getScaleArray();\n this.imageAnchorX_ = imageAnchor[0];\n this.imageAnchorY_ = imageAnchor[1];\n this.imageHeight_ = imageSize[1];\n this.image_ = imageImage;\n this.imageOpacity_ = imageStyle.getOpacity();\n this.imageOriginX_ = imageOrigin[0];\n this.imageOriginY_ = imageOrigin[1];\n this.imageRotateWithView_ = imageStyle.getRotateWithView();\n this.imageRotation_ = imageStyle.getRotation();\n this.imageScale_ = [this.pixelRatio_ * imageScale[0], this.pixelRatio_ * imageScale[1]];\n this.imageWidth_ = imageSize[0];\n }\n }\n };\n /**\n * Set the text style for subsequent draw operations. Pass null to\n * remove the text style.\n *\n * @param {import("../../style/Text.js").default} textStyle Text style.\n */\n\n\n CanvasImmediateRenderer.prototype.setTextStyle = function (textStyle) {\n if (!textStyle) {\n this.text_ = \'\';\n } else {\n var textFillStyle = textStyle.getFill();\n\n if (!textFillStyle) {\n this.textFillState_ = null;\n } else {\n var textFillStyleColor = textFillStyle.getColor();\n this.textFillState_ = {\n fillStyle: asColorLike(textFillStyleColor ? textFillStyleColor : defaultFillStyle)\n };\n }\n\n var textStrokeStyle = textStyle.getStroke();\n\n if (!textStrokeStyle) {\n this.textStrokeState_ = null;\n } else {\n var textStrokeStyleColor = textStrokeStyle.getColor();\n var textStrokeStyleLineCap = textStrokeStyle.getLineCap();\n var textStrokeStyleLineDash = textStrokeStyle.getLineDash();\n var textStrokeStyleLineDashOffset = textStrokeStyle.getLineDashOffset();\n var textStrokeStyleLineJoin = textStrokeStyle.getLineJoin();\n var textStrokeStyleWidth = textStrokeStyle.getWidth();\n var textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit();\n this.textStrokeState_ = {\n lineCap: textStrokeStyleLineCap !== undefined ? textStrokeStyleLineCap : defaultLineCap,\n lineDash: textStrokeStyleLineDash ? textStrokeStyleLineDash : defaultLineDash,\n lineDashOffset: textStrokeStyleLineDashOffset ? textStrokeStyleLineDashOffset : defaultLineDashOffset,\n lineJoin: textStrokeStyleLineJoin !== undefined ? textStrokeStyleLineJoin : defaultLineJoin,\n lineWidth: textStrokeStyleWidth !== undefined ? textStrokeStyleWidth : defaultLineWidth,\n miterLimit: textStrokeStyleMiterLimit !== undefined ? textStrokeStyleMiterLimit : defaultMiterLimit,\n strokeStyle: asColorLike(textStrokeStyleColor ? textStrokeStyleColor : defaultStrokeStyle)\n };\n }\n\n var textFont = textStyle.getFont();\n var textOffsetX = textStyle.getOffsetX();\n var textOffsetY = textStyle.getOffsetY();\n var textRotateWithView = textStyle.getRotateWithView();\n var textRotation = textStyle.getRotation();\n var textScale = textStyle.getScaleArray();\n var textText = textStyle.getText();\n var textTextAlign = textStyle.getTextAlign();\n var textTextBaseline = textStyle.getTextBaseline();\n this.textState_ = {\n font: textFont !== undefined ? textFont : defaultFont,\n textAlign: textTextAlign !== undefined ? textTextAlign : defaultTextAlign,\n textBaseline: textTextBaseline !== undefined ? textTextBaseline : defaultTextBaseline\n };\n this.text_ = textText !== undefined ? textText : \'\';\n this.textOffsetX_ = textOffsetX !== undefined ? this.pixelRatio_ * textOffsetX : 0;\n this.textOffsetY_ = textOffsetY !== undefined ? this.pixelRatio_ * textOffsetY : 0;\n this.textRotateWithView_ = textRotateWithView !== undefined ? textRotateWithView : false;\n this.textRotation_ = textRotation !== undefined ? textRotation : 0;\n this.textScale_ = [this.pixelRatio_ * textScale[0], this.pixelRatio_ * textScale[1]];\n }\n };\n\n return CanvasImmediateRenderer;\n}(render_VectorContext);\n\n/* harmony default export */ var Immediate = (CanvasImmediateRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/style/IconAnchorUnits.js\n/**\n * @module ol/style/IconAnchorUnits\n */\n\n/**\n * Icon anchor units. One of \'fraction\', \'pixels\'.\n * @enum {string}\n */\n/* harmony default export */ var IconAnchorUnits = ({\n /**\n * Anchor is a fraction\n * @api\n */\n FRACTION: \'fraction\',\n\n /**\n * Anchor is in pixels\n * @api\n */\n PIXELS: \'pixels\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/style/IconOrigin.js\n/**\n * @module ol/style/IconOrigin\n */\n\n/**\n * Icon origin. One of \'bottom-left\', \'bottom-right\', \'top-left\', \'top-right\'.\n * @enum {string}\n */\n/* harmony default export */ var IconOrigin = ({\n /**\n * Origin is at bottom left\n * @api\n */\n BOTTOM_LEFT: \'bottom-left\',\n\n /**\n * Origin is at bottom right\n * @api\n */\n BOTTOM_RIGHT: \'bottom-right\',\n\n /**\n * Origin is at top left\n * @api\n */\n TOP_LEFT: \'top-left\',\n\n /**\n * Origin is at top right\n * @api\n */\n TOP_RIGHT: \'top-right\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/ImageBase.js\nvar ImageBase_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/ImageBase\n */\n\n\n\n\n\n/**\n * @abstract\n */\n\nvar ImageBase =\n/** @class */\nfunction (_super) {\n ImageBase_extends(ImageBase, _super);\n /**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number|undefined} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("./ImageState.js").default} state State.\n */\n\n\n function ImageBase(extent, resolution, pixelRatio, state) {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {import("./extent.js").Extent}\n */\n\n\n _this.extent = extent;\n /**\n * @private\n * @type {number}\n */\n\n _this.pixelRatio_ = pixelRatio;\n /**\n * @protected\n * @type {number|undefined}\n */\n\n _this.resolution = resolution;\n /**\n * @protected\n * @type {import("./ImageState.js").default}\n */\n\n _this.state = state;\n return _this;\n }\n /**\n * @protected\n */\n\n\n ImageBase.prototype.changed = function () {\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * @return {import("./extent.js").Extent} Extent.\n */\n\n\n ImageBase.prototype.getExtent = function () {\n return this.extent;\n };\n /**\n * @abstract\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n */\n\n\n ImageBase.prototype.getImage = function () {\n return util_abstract();\n };\n /**\n * @return {number} PixelRatio.\n */\n\n\n ImageBase.prototype.getPixelRatio = function () {\n return this.pixelRatio_;\n };\n /**\n * @return {number} Resolution.\n */\n\n\n ImageBase.prototype.getResolution = function () {\n return (\n /** @type {number} */\n this.resolution\n );\n };\n /**\n * @return {import("./ImageState.js").default} State.\n */\n\n\n ImageBase.prototype.getState = function () {\n return this.state;\n };\n /**\n * Load not yet loaded URI.\n * @abstract\n */\n\n\n ImageBase.prototype.load = function () {\n util_abstract();\n };\n\n return ImageBase;\n}(events_Target);\n\n/* harmony default export */ var ol_ImageBase = (ImageBase);\n;// CONCATENATED MODULE: ./node_modules/ol/Image.js\nvar Image_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Image\n */\n\n\n\n\n\n\n\n\n/**\n * A function that takes an {@link module:ol/Image~Image} for the image and a\n * `{string}` for the src as arguments. It is supposed to make it so the\n * underlying image {@link module:ol/Image~Image#getImage} is assigned the\n * content specified by the src. If not specified, the default is\n *\n * function(image, src) {\n * image.getImage().src = src;\n * }\n *\n * Providing a custom `imageLoadFunction` can be useful to load images with\n * post requests or - in general - through XHR requests, where the src of the\n * image element would be set to a data URI when the content is loaded.\n *\n * @typedef {function(ImageWrapper, string): void} LoadFunction\n * @api\n */\n\nvar ImageWrapper =\n/** @class */\nfunction (_super) {\n Image_extends(ImageWrapper, _super);\n /**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number|undefined} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {string} src Image source URI.\n * @param {?string} crossOrigin Cross origin.\n * @param {LoadFunction} imageLoadFunction Image load function.\n */\n\n\n function ImageWrapper(extent, resolution, pixelRatio, src, crossOrigin, imageLoadFunction) {\n var _this = _super.call(this, extent, resolution, pixelRatio, ImageState.IDLE) || this;\n /**\n * @private\n * @type {string}\n */\n\n\n _this.src_ = src;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}\n */\n\n _this.image_ = new Image();\n\n if (crossOrigin !== null) {\n _this.image_.crossOrigin = crossOrigin;\n }\n /**\n * @private\n * @type {?function():void}\n */\n\n\n _this.unlisten_ = null;\n /**\n * @protected\n * @type {import("./ImageState.js").default}\n */\n\n _this.state = ImageState.IDLE;\n /**\n * @private\n * @type {LoadFunction}\n */\n\n _this.imageLoadFunction_ = imageLoadFunction;\n return _this;\n }\n /**\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n * @api\n */\n\n\n ImageWrapper.prototype.getImage = function () {\n return this.image_;\n };\n /**\n * Tracks loading or read errors.\n *\n * @private\n */\n\n\n ImageWrapper.prototype.handleImageError_ = function () {\n this.state = ImageState.ERROR;\n this.unlistenImage_();\n this.changed();\n };\n /**\n * Tracks successful image load.\n *\n * @private\n */\n\n\n ImageWrapper.prototype.handleImageLoad_ = function () {\n if (this.resolution === undefined) {\n this.resolution = getHeight(this.extent) / this.image_.height;\n }\n\n this.state = ImageState.LOADED;\n this.unlistenImage_();\n this.changed();\n };\n /**\n * Load the image or retry if loading previously failed.\n * Loading is taken care of by the tile queue, and calling this method is\n * only needed for preloading or for reloading in case of an error.\n * @api\n */\n\n\n ImageWrapper.prototype.load = function () {\n if (this.state == ImageState.IDLE || this.state == ImageState.ERROR) {\n this.state = ImageState.LOADING;\n this.changed();\n this.imageLoadFunction_(this, this.src_);\n this.unlisten_ = listenImage(this.image_, this.handleImageLoad_.bind(this), this.handleImageError_.bind(this));\n }\n };\n /**\n * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.\n */\n\n\n ImageWrapper.prototype.setImage = function (image) {\n this.image_ = image;\n };\n /**\n * Discards event handlers which listen for load completion or errors.\n *\n * @private\n */\n\n\n ImageWrapper.prototype.unlistenImage_ = function () {\n if (this.unlisten_) {\n this.unlisten_();\n this.unlisten_ = null;\n }\n };\n\n return ImageWrapper;\n}(ol_ImageBase);\n/**\n * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image element.\n * @param {function():any} loadHandler Load callback function.\n * @param {function():any} errorHandler Error callback function.\n * @return {function():void} Callback to stop listening.\n */\n\n\nfunction listenImage(image, loadHandler, errorHandler) {\n var img =\n /** @type {HTMLImageElement} */\n image;\n\n if (img.src && IMAGE_DECODE) {\n var promise = img.decode();\n var listening_1 = true;\n\n var unlisten = function unlisten() {\n listening_1 = false;\n };\n\n promise.then(function () {\n if (listening_1) {\n loadHandler();\n }\n }).catch(function (error) {\n if (listening_1) {\n // FIXME: Unconditionally call errorHandler() when this bug is fixed upstream:\n // https://bugs.webkit.org/show_bug.cgi?id=198527\n if (error.name === \'EncodingError\' && error.message === \'Invalid image type.\') {\n loadHandler();\n } else {\n errorHandler();\n }\n }\n });\n return unlisten;\n }\n\n var listenerKeys = [listenOnce(img, EventType.LOAD, loadHandler), listenOnce(img, EventType.ERROR, errorHandler)];\n return function unlisten() {\n listenerKeys.forEach(unlistenByKey);\n };\n}\n/* harmony default export */ var ol_Image = ((/* unused pure expression or super */ null && (ImageWrapper)));\n;// CONCATENATED MODULE: ./node_modules/ol/style/IconImage.js\n/**\n * @module ol/style/IconImage\n */\nvar IconImage_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n/**\n * @type {CanvasRenderingContext2D}\n */\n\nvar taintedTestContext = null;\n\nvar IconImage =\n/** @class */\nfunction (_super) {\n IconImage_extends(IconImage, _super);\n /**\n * @param {HTMLImageElement|HTMLCanvasElement} image Image.\n * @param {string|undefined} src Src.\n * @param {import("../size.js").Size} size Size.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("../ImageState.js").default} imageState Image state.\n * @param {import("../color.js").Color} color Color.\n */\n\n\n function IconImage(image, src, size, crossOrigin, imageState, color) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n\n\n _this.hitDetectionImage_ = null;\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n\n _this.image_ = !image ? new Image() : image;\n\n if (crossOrigin !== null) {\n /** @type {HTMLImageElement} */\n _this.image_.crossOrigin = crossOrigin;\n }\n /**\n * @private\n * @type {Object<number, HTMLCanvasElement>}\n */\n\n\n _this.canvas_ = {};\n /**\n * @private\n * @type {import("../color.js").Color}\n */\n\n _this.color_ = color;\n /**\n * @private\n * @type {?function():void}\n */\n\n _this.unlisten_ = null;\n /**\n * @private\n * @type {import("../ImageState.js").default}\n */\n\n _this.imageState_ = imageState;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n _this.size_ = size;\n /**\n * @private\n * @type {string|undefined}\n */\n\n _this.src_ = src;\n /**\n * @private\n */\n\n _this.tainted_;\n return _this;\n }\n /**\n * @private\n * @return {boolean} The image canvas is tainted.\n */\n\n\n IconImage.prototype.isTainted_ = function () {\n if (this.tainted_ === undefined && this.imageState_ === ImageState.LOADED) {\n if (!taintedTestContext) {\n taintedTestContext = createCanvasContext2D(1, 1);\n }\n\n taintedTestContext.drawImage(this.image_, 0, 0);\n\n try {\n taintedTestContext.getImageData(0, 0, 1, 1);\n this.tainted_ = false;\n } catch (e) {\n taintedTestContext = null;\n this.tainted_ = true;\n }\n }\n\n return this.tainted_ === true;\n };\n /**\n * @private\n */\n\n\n IconImage.prototype.dispatchChangeEvent_ = function () {\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * @private\n */\n\n\n IconImage.prototype.handleImageError_ = function () {\n this.imageState_ = ImageState.ERROR;\n this.unlistenImage_();\n this.dispatchChangeEvent_();\n };\n /**\n * @private\n */\n\n\n IconImage.prototype.handleImageLoad_ = function () {\n this.imageState_ = ImageState.LOADED;\n\n if (this.size_) {\n this.image_.width = this.size_[0];\n this.image_.height = this.size_[1];\n } else {\n this.size_ = [this.image_.width, this.image_.height];\n }\n\n this.unlistenImage_();\n this.dispatchChangeEvent_();\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.\n */\n\n\n IconImage.prototype.getImage = function (pixelRatio) {\n this.replaceColor_(pixelRatio);\n return this.canvas_[pixelRatio] ? this.canvas_[pixelRatio] : this.image_;\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Image or Canvas element.\n */\n\n\n IconImage.prototype.getPixelRatio = function (pixelRatio) {\n this.replaceColor_(pixelRatio);\n return this.canvas_[pixelRatio] ? pixelRatio : 1;\n };\n /**\n * @return {import("../ImageState.js").default} Image state.\n */\n\n\n IconImage.prototype.getImageState = function () {\n return this.imageState_;\n };\n /**\n * @return {HTMLImageElement|HTMLCanvasElement} Image element.\n */\n\n\n IconImage.prototype.getHitDetectionImage = function () {\n if (!this.hitDetectionImage_) {\n if (this.isTainted_()) {\n var width = this.size_[0];\n var height = this.size_[1];\n var context = createCanvasContext2D(width, height);\n context.fillRect(0, 0, width, height);\n this.hitDetectionImage_ = context.canvas;\n } else {\n this.hitDetectionImage_ = this.image_;\n }\n }\n\n return this.hitDetectionImage_;\n };\n /**\n * Get the size of the icon (in pixels).\n * @return {import("../size.js").Size} Image size.\n */\n\n\n IconImage.prototype.getSize = function () {\n return this.size_;\n };\n /**\n * @return {string|undefined} Image src.\n */\n\n\n IconImage.prototype.getSrc = function () {\n return this.src_;\n };\n /**\n * Load not yet loaded URI.\n */\n\n\n IconImage.prototype.load = function () {\n if (this.imageState_ == ImageState.IDLE) {\n this.imageState_ = ImageState.LOADING;\n\n try {\n /** @type {HTMLImageElement} */\n this.image_.src = this.src_;\n } catch (e) {\n this.handleImageError_();\n }\n\n this.unlisten_ = listenImage(this.image_, this.handleImageLoad_.bind(this), this.handleImageError_.bind(this));\n }\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @private\n */\n\n\n IconImage.prototype.replaceColor_ = function (pixelRatio) {\n if (!this.color_ || this.canvas_[pixelRatio]) {\n return;\n }\n\n var canvas = document.createElement(\'canvas\');\n this.canvas_[pixelRatio] = canvas;\n canvas.width = Math.ceil(this.image_.width * pixelRatio);\n canvas.height = Math.ceil(this.image_.height * pixelRatio);\n var ctx = canvas.getContext(\'2d\');\n ctx.scale(pixelRatio, pixelRatio);\n ctx.drawImage(this.image_, 0, 0);\n ctx.globalCompositeOperation = \'multiply\'; // Internet Explorer 11 does not support the multiply operation.\n // If the canvas is tainted in Internet Explorer this still produces\n // a solid color image with the shape of the icon.\n\n if (ctx.globalCompositeOperation === \'multiply\' || this.isTainted_()) {\n ctx.fillStyle = asString(this.color_);\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.globalCompositeOperation = \'destination-in\';\n ctx.drawImage(this.image_, 0, 0);\n } else {\n var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n var data = imgData.data;\n var r = this.color_[0] / 255.0;\n var g = this.color_[1] / 255.0;\n var b = this.color_[2] / 255.0;\n var a = this.color_[3];\n\n for (var i = 0, ii = data.length; i < ii; i += 4) {\n data[i] *= r;\n data[i + 1] *= g;\n data[i + 2] *= b;\n data[i + 3] *= a;\n }\n\n ctx.putImageData(imgData, 0, 0);\n }\n };\n /**\n * Discards event handlers which listen for load completion or errors.\n *\n * @private\n */\n\n\n IconImage.prototype.unlistenImage_ = function () {\n if (this.unlisten_) {\n this.unlisten_();\n this.unlisten_ = null;\n }\n };\n\n return IconImage;\n}(events_Target);\n/**\n * @param {HTMLImageElement|HTMLCanvasElement} image Image.\n * @param {string} src Src.\n * @param {import("../size.js").Size} size Size.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("../ImageState.js").default} imageState Image state.\n * @param {import("../color.js").Color} color Color.\n * @return {IconImage} Icon image.\n */\n\n\nfunction IconImage_get(image, src, size, crossOrigin, imageState, color) {\n var iconImage = shared.get(src, crossOrigin, color);\n\n if (!iconImage) {\n iconImage = new IconImage(image, src, size, crossOrigin, imageState, color);\n shared.set(src, crossOrigin, color, iconImage);\n }\n\n return iconImage;\n}\n/* harmony default export */ var style_IconImage = ((/* unused pure expression or super */ null && (IconImage)));\n;// CONCATENATED MODULE: ./node_modules/ol/style/Icon.js\nvar Icon_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/style/Icon\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {Array<number>} [anchor=[0.5, 0.5]] Anchor. Default value is the icon center.\n * @property {import("./IconOrigin.js").default} [anchorOrigin=\'top-left\'] Origin of the anchor: `bottom-left`, `bottom-right`,\n * `top-left` or `top-right`.\n * @property {import("./IconAnchorUnits.js").default} [anchorXUnits=\'fraction\'] Units in which the anchor x value is\n * specified. A value of `\'fraction\'` indicates the x value is a fraction of the icon. A value of `\'pixels\'` indicates\n * the x value in pixels.\n * @property {import("./IconAnchorUnits.js").default} [anchorYUnits=\'fraction\'] Units in which the anchor y value is\n * specified. A value of `\'fraction\'` indicates the y value is a fraction of the icon. A value of `\'pixels\'` indicates\n * the y value in pixels.\n * @property {import("../color.js").Color|string} [color] Color to tint the icon. If not specified,\n * the icon will be left as is.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that you must provide a\n * `crossOrigin` value if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {HTMLImageElement|HTMLCanvasElement} [img] Image object for the icon. If the `src` option is not provided then the\n * provided image must already be loaded. And in that case, it is required\n * to provide the size of the image, with the `imgSize` option.\n * @property {Array<number>} [offset=[0, 0]] Offset, which, together with the size and the offset origin, define the\n * sub-rectangle to use from the original icon image.\n * @property {Array<number>} [displacement=[0,0]] Displacement the icon\n * @property {import("./IconOrigin.js").default} [offsetOrigin=\'top-left\'] Origin of the offset: `bottom-left`, `bottom-right`,\n * `top-left` or `top-right`.\n * @property {number} [opacity=1] Opacity of the icon.\n * @property {number|import("../size.js").Size} [scale=1] Scale.\n * @property {boolean} [rotateWithView=false] Whether to rotate the icon with the view.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {import("../size.js").Size} [size] Icon size in pixel. Can be used together with `offset` to define the\n * sub-rectangle to use from the origin (sprite) icon image.\n * @property {import("../size.js").Size} [imgSize] Image size in pixels. Only required if `img` is set and `src` is not, and\n * for SVG images in Internet Explorer 11. The provided `imgSize` needs to match the actual size of the image.\n * @property {string} [src] Image source URI.\n */\n\n/**\n * @classdesc\n * Set icon style for vector features.\n * @api\n */\n\nvar Icon =\n/** @class */\nfunction (_super) {\n Icon_extends(Icon, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function Icon(opt_options) {\n var _this = this;\n\n var options = opt_options || {};\n /**\n * @type {number}\n */\n\n var opacity = options.opacity !== undefined ? options.opacity : 1;\n /**\n * @type {number}\n */\n\n var rotation = options.rotation !== undefined ? options.rotation : 0;\n /**\n * @type {number|import("../size.js").Size}\n */\n\n var scale = options.scale !== undefined ? options.scale : 1;\n /**\n * @type {boolean}\n */\n\n var rotateWithView = options.rotateWithView !== undefined ? options.rotateWithView : false;\n _this = _super.call(this, {\n opacity: opacity,\n rotation: rotation,\n scale: scale,\n displacement: options.displacement !== undefined ? options.displacement : [0, 0],\n rotateWithView: rotateWithView\n }) || this;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.anchor_ = options.anchor !== undefined ? options.anchor : [0.5, 0.5];\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.normalizedAnchor_ = null;\n /**\n * @private\n * @type {import("./IconOrigin.js").default}\n */\n\n _this.anchorOrigin_ = options.anchorOrigin !== undefined ? options.anchorOrigin : IconOrigin.TOP_LEFT;\n /**\n * @private\n * @type {import("./IconAnchorUnits.js").default}\n */\n\n _this.anchorXUnits_ = options.anchorXUnits !== undefined ? options.anchorXUnits : IconAnchorUnits.FRACTION;\n /**\n * @private\n * @type {import("./IconAnchorUnits.js").default}\n */\n\n _this.anchorYUnits_ = options.anchorYUnits !== undefined ? options.anchorYUnits : IconAnchorUnits.FRACTION;\n /**\n * @private\n * @type {?string}\n */\n\n _this.crossOrigin_ = options.crossOrigin !== undefined ? options.crossOrigin : null;\n /**\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n\n var image = options.img !== undefined ? options.img : null;\n /**\n * @type {import("../size.js").Size}\n */\n\n var imgSize = options.imgSize !== undefined ? options.imgSize : null;\n /**\n * @type {string|undefined}\n */\n\n var src = options.src;\n asserts_assert(!(src !== undefined && image), 4); // `image` and `src` cannot be provided at the same time\n\n asserts_assert(!image || image && imgSize, 5); // `imgSize` must be set when `image` is provided\n\n if ((src === undefined || src.length === 0) && image) {\n src =\n /** @type {HTMLImageElement} */\n image.src || getUid(image);\n }\n\n asserts_assert(src !== undefined && src.length > 0, 6); // A defined and non-empty `src` or `image` must be provided\n\n /**\n * @type {import("../ImageState.js").default}\n */\n\n var imageState = options.src !== undefined ? ImageState.IDLE : ImageState.LOADED;\n /**\n * @private\n * @type {import("../color.js").Color}\n */\n\n _this.color_ = options.color !== undefined ? asArray(options.color) : null;\n /**\n * @private\n * @type {import("./IconImage.js").default}\n */\n\n _this.iconImage_ = IconImage_get(image,\n /** @type {string} */\n src, imgSize, _this.crossOrigin_, imageState, _this.color_);\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.offset_ = options.offset !== undefined ? options.offset : [0, 0];\n /**\n * @private\n * @type {import("./IconOrigin.js").default}\n */\n\n _this.offsetOrigin_ = options.offsetOrigin !== undefined ? options.offsetOrigin : IconOrigin.TOP_LEFT;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.origin_ = null;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n _this.size_ = options.size !== undefined ? options.size : null;\n return _this;\n }\n /**\n * Clones the style. The underlying Image/HTMLCanvasElement is not cloned.\n * @return {Icon} The cloned style.\n * @api\n */\n\n\n Icon.prototype.clone = function () {\n var scale = this.getScale();\n return new Icon({\n anchor: this.anchor_.slice(),\n anchorOrigin: this.anchorOrigin_,\n anchorXUnits: this.anchorXUnits_,\n anchorYUnits: this.anchorYUnits_,\n crossOrigin: this.crossOrigin_,\n color: this.color_ && this.color_.slice ? this.color_.slice() : this.color_ || undefined,\n src: this.getSrc(),\n offset: this.offset_.slice(),\n offsetOrigin: this.offsetOrigin_,\n size: this.size_ !== null ? this.size_.slice() : undefined,\n opacity: this.getOpacity(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView()\n });\n };\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @return {Array<number>} Anchor.\n * @api\n */\n\n\n Icon.prototype.getAnchor = function () {\n if (this.normalizedAnchor_) {\n return this.normalizedAnchor_;\n }\n\n var anchor = this.anchor_;\n var size = this.getSize();\n\n if (this.anchorXUnits_ == IconAnchorUnits.FRACTION || this.anchorYUnits_ == IconAnchorUnits.FRACTION) {\n if (!size) {\n return null;\n }\n\n anchor = this.anchor_.slice();\n\n if (this.anchorXUnits_ == IconAnchorUnits.FRACTION) {\n anchor[0] *= size[0];\n }\n\n if (this.anchorYUnits_ == IconAnchorUnits.FRACTION) {\n anchor[1] *= size[1];\n }\n }\n\n if (this.anchorOrigin_ != IconOrigin.TOP_LEFT) {\n if (!size) {\n return null;\n }\n\n if (anchor === this.anchor_) {\n anchor = this.anchor_.slice();\n }\n\n if (this.anchorOrigin_ == IconOrigin.TOP_RIGHT || this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n anchor[0] = -anchor[0] + size[0];\n }\n\n if (this.anchorOrigin_ == IconOrigin.BOTTOM_LEFT || this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n anchor[1] = -anchor[1] + size[1];\n }\n }\n\n this.normalizedAnchor_ = anchor;\n return this.normalizedAnchor_;\n };\n /**\n * Set the anchor point. The anchor determines the center point for the\n * symbolizer.\n *\n * @param {Array<number>} anchor Anchor.\n * @api\n */\n\n\n Icon.prototype.setAnchor = function (anchor) {\n this.anchor_ = anchor;\n this.normalizedAnchor_ = null;\n };\n /**\n * Get the icon color.\n * @return {import("../color.js").Color} Color.\n * @api\n */\n\n\n Icon.prototype.getColor = function () {\n return this.color_;\n };\n /**\n * Get the image icon.\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.\n * @api\n */\n\n\n Icon.prototype.getImage = function (pixelRatio) {\n return this.iconImage_.getImage(pixelRatio);\n };\n /**\n * Get the pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} The pixel ration of the image.\n * @api\n */\n\n\n Icon.prototype.getPixelRatio = function (pixelRatio) {\n return this.iconImage_.getPixelRatio(pixelRatio);\n };\n /**\n * @return {import("../size.js").Size} Image size.\n */\n\n\n Icon.prototype.getImageSize = function () {\n return this.iconImage_.getSize();\n };\n /**\n * @return {import("../size.js").Size} Size of the hit-detection image.\n */\n\n\n Icon.prototype.getHitDetectionImageSize = function () {\n return this.getImageSize();\n };\n /**\n * @return {import("../ImageState.js").default} Image state.\n */\n\n\n Icon.prototype.getImageState = function () {\n return this.iconImage_.getImageState();\n };\n /**\n * @return {HTMLImageElement|HTMLCanvasElement} Image element.\n */\n\n\n Icon.prototype.getHitDetectionImage = function () {\n return this.iconImage_.getHitDetectionImage();\n };\n /**\n * Get the origin of the symbolizer.\n * @return {Array<number>} Origin.\n * @api\n */\n\n\n Icon.prototype.getOrigin = function () {\n if (this.origin_) {\n return this.origin_;\n }\n\n var offset = this.offset_;\n var displacement = this.getDisplacement();\n\n if (this.offsetOrigin_ != IconOrigin.TOP_LEFT) {\n var size = this.getSize();\n var iconImageSize = this.iconImage_.getSize();\n\n if (!size || !iconImageSize) {\n return null;\n }\n\n offset = offset.slice();\n\n if (this.offsetOrigin_ == IconOrigin.TOP_RIGHT || this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n offset[0] = iconImageSize[0] - size[0] - offset[0];\n }\n\n if (this.offsetOrigin_ == IconOrigin.BOTTOM_LEFT || this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n offset[1] = iconImageSize[1] - size[1] - offset[1];\n }\n }\n\n offset[0] += displacement[0];\n offset[1] += displacement[1];\n this.origin_ = offset;\n return this.origin_;\n };\n /**\n * Get the image URL.\n * @return {string|undefined} Image src.\n * @api\n */\n\n\n Icon.prototype.getSrc = function () {\n return this.iconImage_.getSrc();\n };\n /**\n * Get the size of the icon (in pixels).\n * @return {import("../size.js").Size} Image size.\n * @api\n */\n\n\n Icon.prototype.getSize = function () {\n return !this.size_ ? this.iconImage_.getSize() : this.size_;\n };\n /**\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n Icon.prototype.listenImageChange = function (listener) {\n this.iconImage_.addEventListener(EventType.CHANGE, listener);\n };\n /**\n * Load not yet loaded URI.\n * When rendering a feature with an icon style, the vector renderer will\n * automatically call this method. However, you might want to call this\n * method yourself for preloading or other purposes.\n * @api\n */\n\n\n Icon.prototype.load = function () {\n this.iconImage_.load();\n };\n /**\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n Icon.prototype.unlistenImageChange = function (listener) {\n this.iconImage_.removeEventListener(EventType.CHANGE, listener);\n };\n\n return Icon;\n}(style_Image);\n\n/* harmony default export */ var style_Icon = (Icon);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/hitdetect.js\n/**\n * @module ol/render/canvas/hitdetect\n */\n\n\n\n\n\n\n\n/**\n * @param {import("../../size.js").Size} size Canvas size in css pixels.\n * @param {Array<import("../../transform.js").Transform>} transforms Transforms\n * for rendering features to all worlds of the viewport, from coordinates to css\n * pixels.\n * @param {Array<import("../../Feature.js").FeatureLike>} features\n * Features to consider for hit detection.\n * @param {import("../../style/Style.js").StyleFunction|undefined} styleFunction\n * Layer style function.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @return {ImageData} Hit detection image data.\n */\n\nfunction createHitDetectionImageData(size, transforms, features, styleFunction, extent, resolution, rotation) {\n var width = size[0] / 2;\n var height = size[1] / 2;\n var context = createCanvasContext2D(width, height);\n context.imageSmoothingEnabled = false;\n var canvas = context.canvas;\n var renderer = new Immediate(context, 0.5, extent, null, rotation);\n var featureCount = features.length; // Stretch hit detection index to use the whole available color range\n\n var indexFactor = Math.floor((256 * 256 * 256 - 1) / featureCount);\n var featuresByZIndex = {};\n\n for (var i = 1; i <= featureCount; ++i) {\n var feature = features[i - 1];\n var featureStyleFunction = feature.getStyleFunction() || styleFunction;\n\n if (!styleFunction) {\n continue;\n }\n\n var styles = featureStyleFunction(feature, resolution);\n\n if (!styles) {\n continue;\n }\n\n if (!Array.isArray(styles)) {\n styles = [styles];\n }\n\n var index = i * indexFactor;\n var color = \'#\' + (\'000000\' + index.toString(16)).slice(-6);\n\n for (var j = 0, jj = styles.length; j < jj; ++j) {\n var originalStyle = styles[j];\n var style = originalStyle.clone();\n var fill = style.getFill();\n\n if (fill) {\n fill.setColor(color);\n }\n\n var stroke = style.getStroke();\n\n if (stroke) {\n stroke.setColor(color);\n }\n\n style.setText(undefined);\n var image = originalStyle.getImage();\n\n if (image) {\n var imgSize = image.getImageSize();\n\n if (!imgSize) {\n continue;\n }\n\n var canvas_1 = document.createElement(\'canvas\');\n canvas_1.width = imgSize[0];\n canvas_1.height = imgSize[1];\n var imgContext = canvas_1.getContext(\'2d\', {\n alpha: false\n });\n imgContext.fillStyle = color;\n var img = imgContext.canvas;\n imgContext.fillRect(0, 0, img.width, img.height);\n var width_1 = imgSize ? imgSize[0] : img.width;\n var height_1 = imgSize ? imgSize[1] : img.height;\n var iconContext = createCanvasContext2D(width_1, height_1);\n iconContext.drawImage(img, 0, 0);\n style.setImage(new style_Icon({\n img: img,\n imgSize: imgSize,\n anchor: image.getAnchor(),\n anchorXUnits: IconAnchorUnits.PIXELS,\n anchorYUnits: IconAnchorUnits.PIXELS,\n offset: image.getOrigin(),\n size: image.getSize(),\n opacity: image.getOpacity(),\n scale: image.getScale(),\n rotation: image.getRotation(),\n rotateWithView: image.getRotateWithView()\n }));\n }\n\n var zIndex = Number(style.getZIndex());\n var byGeometryType = featuresByZIndex[zIndex];\n\n if (!byGeometryType) {\n byGeometryType = {};\n featuresByZIndex[zIndex] = byGeometryType;\n byGeometryType[geom_GeometryType.POLYGON] = [];\n byGeometryType[geom_GeometryType.CIRCLE] = [];\n byGeometryType[geom_GeometryType.LINE_STRING] = [];\n byGeometryType[geom_GeometryType.POINT] = [];\n }\n\n var geometry = style.getGeometryFunction()(feature);\n\n if (geometry && intersects(extent, geometry.getExtent())) {\n byGeometryType[geometry.getType().replace(\'Multi\', \'\')].push(geometry, style);\n }\n }\n }\n\n var zIndexKeys = Object.keys(featuresByZIndex).map(Number).sort(numberSafeCompareFunction);\n\n for (var i = 0, ii = zIndexKeys.length; i < ii; ++i) {\n var byGeometryType = featuresByZIndex[zIndexKeys[i]];\n\n for (var type in byGeometryType) {\n var geomAndStyle = byGeometryType[type];\n\n for (var j = 0, jj = geomAndStyle.length; j < jj; j += 2) {\n renderer.setStyle(geomAndStyle[j + 1]);\n\n for (var k = 0, kk = transforms.length; k < kk; ++k) {\n renderer.setTransform(transforms[k]);\n renderer.drawGeometry(geomAndStyle[j]);\n }\n }\n }\n }\n\n return context.getImageData(0, 0, canvas.width, canvas.height);\n}\n/**\n * @param {import("../../pixel").Pixel} pixel Pixel coordinate on the hit\n * detection canvas in css pixels.\n * @param {Array<import("../../Feature").FeatureLike>} features Features. Has to\n * match the `features` array that was passed to `createHitDetectionImageData()`.\n * @param {ImageData} imageData Hit detection image data generated by\n * `createHitDetectionImageData()`.\n * @return {Array<import("../../Feature").FeatureLike>} features Features.\n */\n\nfunction hitDetect(pixel, features, imageData) {\n var resultFeatures = [];\n\n if (imageData) {\n var index = (Math.round(pixel[0] / 2) + Math.round(pixel[1] / 2) * imageData.width) * 4;\n var r = imageData.data[index];\n var g = imageData.data[index + 1];\n var b = imageData.data[index + 2];\n var i = b + 256 * (g + 256 * r);\n var indexFactor = Math.floor((256 * 256 * 256 - 1) / features.length);\n\n if (i && i % indexFactor === 0) {\n resultFeatures.push(features[i / indexFactor - 1]);\n }\n }\n\n return resultFeatures;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/vector.js\n/**\n * @module ol/renderer/vector\n */\n\n\n\n\n/**\n * Feature callback. The callback will be called with three arguments. The first\n * argument is one {@link module:ol/Feature feature} or {@link module:ol/render/Feature render feature}\n * at the pixel, the second is the {@link module:ol/layer/Layer layer} of the feature and will be null for\n * unmanaged layers. The third is the {@link module:ol/geom/SimpleGeometry} of the feature. For features\n * with a GeometryCollection geometry, it will be the first detected geometry from the collection.\n * @template T\n * @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default, import("../geom/SimpleGeometry.js").default): T} FeatureCallback\n */\n\n/**\n * Tolerance for geometry simplification in device pixels.\n * @type {number}\n */\n\nvar SIMPLIFY_TOLERANCE = 0.5;\n/**\n * @const\n * @type {Object<import("../geom/GeometryType.js").default,\n * function(import("../render/canvas/BuilderGroup.js").default, import("../geom/Geometry.js").default,\n * import("../style/Style.js").default, Object): void>}\n */\n\nvar GEOMETRY_RENDERERS = {\n \'Point\': renderPointGeometry,\n \'LineString\': renderLineStringGeometry,\n \'Polygon\': renderPolygonGeometry,\n \'MultiPoint\': renderMultiPointGeometry,\n \'MultiLineString\': renderMultiLineStringGeometry,\n \'MultiPolygon\': renderMultiPolygonGeometry,\n \'GeometryCollection\': renderGeometryCollectionGeometry,\n \'Circle\': renderCircleGeometry\n};\n/**\n * @param {import("../Feature.js").FeatureLike} feature1 Feature 1.\n * @param {import("../Feature.js").FeatureLike} feature2 Feature 2.\n * @return {number} Order.\n */\n\nfunction defaultOrder(feature1, feature2) {\n return parseInt(getUid(feature1), 10) - parseInt(getUid(feature2), 10);\n}\n/**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Squared pixel tolerance.\n */\n\nfunction getSquaredTolerance(resolution, pixelRatio) {\n var tolerance = getTolerance(resolution, pixelRatio);\n return tolerance * tolerance;\n}\n/**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Pixel tolerance.\n */\n\nfunction getTolerance(resolution, pixelRatio) {\n return SIMPLIFY_TOLERANCE * resolution / pixelRatio;\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Builder group.\n * @param {import("../geom/Circle.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\nfunction renderCircleGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var fillStyle = style.getFill();\n var strokeStyle = style.getStroke();\n\n if (fillStyle || strokeStyle) {\n var circleReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.CIRCLE);\n circleReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n circleReplay.drawCircle(geometry, feature);\n }\n\n var textStyle = style.getText();\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../style/Style.js").default} style Style.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n * @param {import("../proj.js").TransformFunction} [opt_transform] Transform from user to view projection.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n * @return {boolean} `true` if style is loading.\n */\n\n\nfunction renderFeature(replayGroup, feature, style, squaredTolerance, listener, opt_transform, opt_declutterBuilderGroup) {\n var loading = false;\n var imageStyle = style.getImage();\n\n if (imageStyle) {\n var imageState = imageStyle.getImageState();\n\n if (imageState == ImageState.LOADED || imageState == ImageState.ERROR) {\n imageStyle.unlistenImageChange(listener);\n } else {\n if (imageState == ImageState.IDLE) {\n imageStyle.load();\n }\n\n imageState = imageStyle.getImageState();\n imageStyle.listenImageChange(listener);\n loading = true;\n }\n }\n\n renderFeatureInternal(replayGroup, feature, style, squaredTolerance, opt_transform, opt_declutterBuilderGroup);\n return loading;\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../style/Style.js").default} style Style.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import("../proj.js").TransformFunction} [opt_transform] Optional transform function.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\nfunction renderFeatureInternal(replayGroup, feature, style, squaredTolerance, opt_transform, opt_declutterBuilderGroup) {\n var geometry = style.getGeometryFunction()(feature);\n\n if (!geometry) {\n return;\n }\n\n var simplifiedGeometry = geometry.simplifyTransformed(squaredTolerance, opt_transform);\n var renderer = style.getRenderer();\n\n if (renderer) {\n renderGeometry(replayGroup, simplifiedGeometry, style, feature);\n } else {\n var geometryRenderer = GEOMETRY_RENDERERS[simplifiedGeometry.getType()];\n geometryRenderer(replayGroup, simplifiedGeometry, style, feature, opt_declutterBuilderGroup);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.\n * @param {import("../geom/Geometry.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\nfunction renderGeometry(replayGroup, geometry, style, feature) {\n if (geometry.getType() == geom_GeometryType.GEOMETRY_COLLECTION) {\n var geometries =\n /** @type {import("../geom/GeometryCollection.js").default} */\n geometry.getGeometries();\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n renderGeometry(replayGroup, geometries[i], style, feature);\n }\n\n return;\n }\n\n var replay = replayGroup.getBuilder(style.getZIndex(), BuilderType.DEFAULT);\n replay.drawCustom(\n /** @type {import("../geom/SimpleGeometry.js").default} */\n geometry, feature, style.getRenderer());\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.\n * @param {import("../geom/GeometryCollection.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderGeometryCollectionGeometry(replayGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var geometries = geometry.getGeometriesArray();\n var i, ii;\n\n for (i = 0, ii = geometries.length; i < ii; ++i) {\n var geometryRenderer = GEOMETRY_RENDERERS[geometries[i].getType()];\n geometryRenderer(replayGroup, geometries[i], style, feature, opt_declutterBuilderGroup);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/LineString.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderLineStringGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var strokeStyle = style.getStroke();\n\n if (strokeStyle) {\n var lineStringReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.LINE_STRING);\n lineStringReplay.setFillStrokeStyle(null, strokeStyle);\n lineStringReplay.drawLineString(geometry, feature);\n }\n\n var textStyle = style.getText();\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/MultiLineString.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderMultiLineStringGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var strokeStyle = style.getStroke();\n\n if (strokeStyle) {\n var lineStringReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.LINE_STRING);\n lineStringReplay.setFillStrokeStyle(null, strokeStyle);\n lineStringReplay.drawMultiLineString(geometry, feature);\n }\n\n var textStyle = style.getText();\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/MultiPolygon.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderMultiPolygonGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var fillStyle = style.getFill();\n var strokeStyle = style.getStroke();\n\n if (strokeStyle || fillStyle) {\n var polygonReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.POLYGON);\n polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n polygonReplay.drawMultiPolygon(geometry, feature);\n }\n\n var textStyle = style.getText();\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/Point.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderPointGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var imageStyle = style.getImage();\n var textStyle = style.getText();\n /** @type {import("../render/canvas.js").DeclutterImageWithText} */\n\n var declutterImageWithText;\n\n if (opt_declutterBuilderGroup) {\n builderGroup = opt_declutterBuilderGroup;\n declutterImageWithText = imageStyle && textStyle && textStyle.getText() ? {} : undefined;\n }\n\n if (imageStyle) {\n if (imageStyle.getImageState() != ImageState.LOADED) {\n return;\n }\n\n var imageReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.IMAGE);\n imageReplay.setImageStyle(imageStyle, declutterImageWithText);\n imageReplay.drawPoint(geometry, feature);\n }\n\n if (textStyle && textStyle.getText()) {\n var textReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle, declutterImageWithText);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/MultiPoint.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderMultiPointGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var imageStyle = style.getImage();\n var textStyle = style.getText();\n /** @type {import("../render/canvas.js").DeclutterImageWithText} */\n\n var declutterImageWithText;\n\n if (opt_declutterBuilderGroup) {\n builderGroup = opt_declutterBuilderGroup;\n declutterImageWithText = imageStyle && textStyle && textStyle.getText() ? {} : undefined;\n }\n\n if (imageStyle) {\n if (imageStyle.getImageState() != ImageState.LOADED) {\n return;\n }\n\n var imageReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.IMAGE);\n imageReplay.setImageStyle(imageStyle, declutterImageWithText);\n imageReplay.drawMultiPoint(geometry, feature);\n }\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle, declutterImageWithText);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/Polygon.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderPolygonGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var fillStyle = style.getFill();\n var strokeStyle = style.getStroke();\n\n if (fillStyle || strokeStyle) {\n var polygonReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.POLYGON);\n polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n polygonReplay.drawPolygon(geometry, feature);\n }\n\n var textStyle = style.getText();\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/VectorLayer.js\nvar VectorLayer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/canvas/VectorLayer\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Canvas renderer for vector layers.\n * @api\n */\n\nvar CanvasVectorLayerRenderer =\n/** @class */\nfunction (_super) {\n VectorLayer_extends(CanvasVectorLayerRenderer, _super);\n /**\n * @param {import("../../layer/Vector.js").default} vectorLayer Vector layer.\n */\n\n\n function CanvasVectorLayerRenderer(vectorLayer) {\n var _this = _super.call(this, vectorLayer) || this;\n /** @private */\n\n\n _this.boundHandleStyleImageChange_ = _this.handleStyleImageChange_.bind(_this);\n /**\n * @type {boolean}\n */\n\n _this.animatingOrInteracting_;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.dirty_ = false;\n /**\n * @type {ImageData}\n */\n\n _this.hitDetectionImageData_ = null;\n /**\n * @type {Array<import("../../Feature.js").default>}\n */\n\n _this.renderedFeatures_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.renderedRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.renderedResolution_ = NaN;\n /**\n * @private\n * @type {import("../../extent.js").Extent}\n */\n\n _this.renderedExtent_ = createEmpty();\n /**\n * @private\n * @type {number}\n */\n\n _this.renderedRotation_;\n /**\n * @private\n * @type {import("../../coordinate").Coordinate}\n */\n\n _this.renderedCenter_ = null;\n /**\n * @private\n * @type {import("../../proj/Projection").default}\n */\n\n _this.renderedProjection_ = null;\n /**\n * @private\n * @type {function(import("../../Feature.js").default, import("../../Feature.js").default): number|null}\n */\n\n _this.renderedRenderOrder_ = null;\n /**\n * @private\n * @type {import("../../render/canvas/ExecutorGroup").default}\n */\n\n _this.replayGroup_ = null;\n /**\n * A new replay group had to be created by `prepareFrame()`\n * @type {boolean}\n */\n\n _this.replayGroupChanged = true;\n /**\n * @type {import("../../render/canvas/ExecutorGroup").default}\n */\n\n _this.declutterExecutorGroup = null;\n /**\n * Clipping to be performed by `renderFrame()`\n * @type {boolean}\n */\n\n _this.clipping = true;\n return _this;\n }\n /**\n * Get a rendering container from an existing target, if compatible.\n * @param {HTMLElement} target Potential render target.\n * @param {string} transform CSS Transform.\n * @param {number} opacity Opacity.\n */\n\n\n CanvasVectorLayerRenderer.prototype.useContainer = function (target, transform, opacity) {\n if (opacity < 1) {\n target = null;\n }\n\n _super.prototype.useContainer.call(this, target, transform, opacity);\n };\n /**\n * @param {ExecutorGroup} executorGroup Executor group.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {import("rbush").default=} opt_declutterTree Declutter tree.\n */\n\n\n CanvasVectorLayerRenderer.prototype.renderWorlds = function (executorGroup, frameState, opt_declutterTree) {\n var extent = frameState.extent;\n var viewState = frameState.viewState;\n var center = viewState.center;\n var resolution = viewState.resolution;\n var projection = viewState.projection;\n var rotation = viewState.rotation;\n var projectionExtent = projection.getExtent();\n var vectorSource = this.getLayer().getSource();\n var pixelRatio = frameState.pixelRatio;\n var viewHints = frameState.viewHints;\n var snapToPixel = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);\n var context = this.context;\n var width = Math.round(frameState.size[0] * pixelRatio);\n var height = Math.round(frameState.size[1] * pixelRatio);\n var multiWorld = vectorSource.getWrapX() && projection.canWrapX();\n var worldWidth = multiWorld ? extent_getWidth(projectionExtent) : null;\n var endWorld = multiWorld ? Math.ceil((extent[2] - projectionExtent[2]) / worldWidth) + 1 : 1;\n var world = multiWorld ? Math.floor((extent[0] - projectionExtent[0]) / worldWidth) : 0;\n\n do {\n var transform = this.getRenderTransform(center, resolution, rotation, pixelRatio, width, height, world * worldWidth);\n executorGroup.execute(context, 1, transform, rotation, snapToPixel, undefined, opt_declutterTree);\n } while (++world < endWorld);\n };\n /**\n * Render declutter items for this layer\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n CanvasVectorLayerRenderer.prototype.renderDeclutter = function (frameState) {\n if (this.declutterExecutorGroup) {\n this.renderWorlds(this.declutterExecutorGroup, frameState, frameState.declutterTree);\n }\n };\n /**\n * Render the layer.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n\n\n CanvasVectorLayerRenderer.prototype.renderFrame = function (frameState, target) {\n var pixelRatio = frameState.pixelRatio;\n var layerState = frameState.layerStatesArray[frameState.layerIndex]; // set forward and inverse pixel transforms\n\n makeScale(this.pixelTransform, 1 / pixelRatio, 1 / pixelRatio);\n makeInverse(this.inversePixelTransform, this.pixelTransform);\n var canvasTransform = transform_toString(this.pixelTransform);\n this.useContainer(target, canvasTransform, layerState.opacity);\n var context = this.context;\n var canvas = context.canvas;\n var replayGroup = this.replayGroup_;\n var declutterExecutorGroup = this.declutterExecutorGroup;\n\n if ((!replayGroup || replayGroup.isEmpty()) && (!declutterExecutorGroup || declutterExecutorGroup.isEmpty())) {\n if (!this.containerReused && canvas.width > 0) {\n canvas.width = 0;\n }\n\n return this.container;\n } // resize and clear\n\n\n var width = Math.round(frameState.size[0] * pixelRatio);\n var height = Math.round(frameState.size[1] * pixelRatio);\n\n if (canvas.width != width || canvas.height != height) {\n canvas.width = width;\n canvas.height = height;\n\n if (canvas.style.transform !== canvasTransform) {\n canvas.style.transform = canvasTransform;\n }\n } else if (!this.containerReused) {\n context.clearRect(0, 0, width, height);\n }\n\n this.preRender(context, frameState);\n var viewState = frameState.viewState;\n var projection = viewState.projection; // clipped rendering if layer extent is set\n\n var clipped = false;\n\n if (layerState.extent && this.clipping) {\n var layerExtent = fromUserExtent(layerState.extent, projection);\n clipped = !containsExtent(layerExtent, frameState.extent) && intersects(layerExtent, frameState.extent);\n\n if (clipped) {\n this.clipUnrotated(context, frameState, layerExtent);\n }\n }\n\n this.renderWorlds(replayGroup, frameState);\n\n if (clipped) {\n context.restore();\n }\n\n this.postRender(context, frameState);\n var opacity = layerState.opacity;\n var container = this.container;\n\n if (opacity !== parseFloat(container.style.opacity)) {\n container.style.opacity = opacity === 1 ? \'\' : String(opacity);\n }\n\n if (this.renderedRotation_ !== viewState.rotation) {\n this.renderedRotation_ = viewState.rotation;\n this.hitDetectionImageData_ = null;\n }\n\n return this.container;\n };\n /**\n * Asynchronous layer level hit detection.\n * @param {import("../../pixel.js").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../../Feature").default>>} Promise that resolves with an array of features.\n */\n\n\n CanvasVectorLayerRenderer.prototype.getFeatures = function (pixel) {\n return new Promise(\n /**\n * @param {function(Array<import("../../Feature").default|import("../../render/Feature").default>): void} resolve Resolver function.\n * @this {CanvasVectorLayerRenderer}\n */\n function (resolve) {\n if (!this.hitDetectionImageData_ && !this.animatingOrInteracting_) {\n var size = [this.context.canvas.width, this.context.canvas.height];\n apply(this.pixelTransform, size);\n var center = this.renderedCenter_;\n var resolution = this.renderedResolution_;\n var rotation = this.renderedRotation_;\n var projection = this.renderedProjection_;\n var extent = this.renderedExtent_;\n var layer = this.getLayer();\n var transforms = [];\n var width = size[0] / 2;\n var height = size[1] / 2;\n transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, 0).slice());\n var source = layer.getSource();\n var projectionExtent = projection.getExtent();\n\n if (source.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, extent)) {\n var startX = extent[0];\n var worldWidth = extent_getWidth(projectionExtent);\n var world = 0;\n var offsetX = void 0;\n\n while (startX < projectionExtent[0]) {\n --world;\n offsetX = worldWidth * world;\n transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, offsetX).slice());\n startX += worldWidth;\n }\n\n world = 0;\n startX = extent[2];\n\n while (startX > projectionExtent[2]) {\n ++world;\n offsetX = worldWidth * world;\n transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, offsetX).slice());\n startX -= worldWidth;\n }\n }\n\n this.hitDetectionImageData_ = createHitDetectionImageData(size, transforms, this.renderedFeatures_, layer.getStyleFunction(), extent, resolution, rotation);\n }\n\n resolve(hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_));\n }.bind(this));\n };\n /**\n * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {import("../vector.js").FeatureCallback<T>} callback Feature callback.\n * @param {Array<import("../Map.js").HitMatch<T>>} matches The hit detected matches with tolerance.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n CanvasVectorLayerRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, callback, matches) {\n var _this = this;\n\n if (!this.replayGroup_) {\n return undefined;\n }\n\n var resolution = frameState.viewState.resolution;\n var rotation = frameState.viewState.rotation;\n var layer = this.getLayer();\n /** @type {!Object<string, import("../Map.js").HitMatch<T>|true>} */\n\n var features = {};\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.\n * @param {number} distanceSq The squared distance to the click position\n * @return {T|undefined} Callback result.\n */\n\n var featureCallback = function featureCallback(feature, geometry, distanceSq) {\n var key = getUid(feature);\n var match = features[key];\n\n if (!match) {\n if (distanceSq === 0) {\n features[key] = true;\n return callback(feature, layer, geometry);\n }\n\n matches.push(features[key] = {\n feature: feature,\n layer: layer,\n geometry: geometry,\n distanceSq: distanceSq,\n callback: callback\n });\n } else if (match !== true && distanceSq < match.distanceSq) {\n if (distanceSq === 0) {\n features[key] = true;\n matches.splice(matches.lastIndexOf(match), 1);\n return callback(feature, layer, geometry);\n }\n\n match.geometry = geometry;\n match.distanceSq = distanceSq;\n }\n\n return undefined;\n };\n\n var result;\n var executorGroups = [this.replayGroup_];\n\n if (this.declutterExecutorGroup) {\n executorGroups.push(this.declutterExecutorGroup);\n }\n\n executorGroups.some(function (executorGroup) {\n return result = executorGroup.forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, featureCallback, executorGroup === _this.declutterExecutorGroup ? frameState.declutterTree.all().map(function (item) {\n return item.value;\n }) : null);\n });\n return result;\n };\n /**\n * Perform action necessary to get the layer rendered after new fonts have loaded\n */\n\n\n CanvasVectorLayerRenderer.prototype.handleFontsChanged = function () {\n var layer = this.getLayer();\n\n if (layer.getVisible() && this.replayGroup_) {\n layer.changed();\n }\n };\n /**\n * Handle changes in image style state.\n * @param {import("../../events/Event.js").default} event Image style change event.\n * @private\n */\n\n\n CanvasVectorLayerRenderer.prototype.handleStyleImageChange_ = function (event) {\n this.renderIfReadyAndVisible();\n };\n /**\n * Determine whether render should be called.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n\n\n CanvasVectorLayerRenderer.prototype.prepareFrame = function (frameState) {\n var vectorLayer = this.getLayer();\n var vectorSource = vectorLayer.getSource();\n\n if (!vectorSource) {\n return false;\n }\n\n var animating = frameState.viewHints[ViewHint.ANIMATING];\n var interacting = frameState.viewHints[ViewHint.INTERACTING];\n var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();\n var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();\n\n if (!this.dirty_ && !updateWhileAnimating && animating || !updateWhileInteracting && interacting) {\n this.animatingOrInteracting_ = true;\n return true;\n }\n\n this.animatingOrInteracting_ = false;\n var frameStateExtent = frameState.extent;\n var viewState = frameState.viewState;\n var projection = viewState.projection;\n var resolution = viewState.resolution;\n var pixelRatio = frameState.pixelRatio;\n var vectorLayerRevision = vectorLayer.getRevision();\n var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();\n var vectorLayerRenderOrder = vectorLayer.getRenderOrder();\n\n if (vectorLayerRenderOrder === undefined) {\n vectorLayerRenderOrder = defaultOrder;\n }\n\n var center = viewState.center.slice();\n var extent = buffer(frameStateExtent, vectorLayerRenderBuffer * resolution);\n var loadExtents = [extent.slice()];\n var projectionExtent = projection.getExtent();\n\n if (vectorSource.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, frameState.extent)) {\n // For the replay group, we need an extent that intersects the real world\n // (-180° to +180°). To support geometries in a coordinate range from -540°\n // to +540°, we add at least 1 world width on each side of the projection\n // extent. If the viewport is wider than the world, we need to add half of\n // the viewport width to make sure we cover the whole viewport.\n var worldWidth = extent_getWidth(projectionExtent);\n var gutter = Math.max(extent_getWidth(extent) / 2, worldWidth);\n extent[0] = projectionExtent[0] - gutter;\n extent[2] = projectionExtent[2] + gutter;\n coordinate_wrapX(center, projection);\n var loadExtent = wrapX(loadExtents[0], projection); // If the extent crosses the date line, we load data for both edges of the worlds\n\n if (loadExtent[0] < projectionExtent[0] && loadExtent[2] < projectionExtent[2]) {\n loadExtents.push([loadExtent[0] + worldWidth, loadExtent[1], loadExtent[2] + worldWidth, loadExtent[3]]);\n } else if (loadExtent[0] > projectionExtent[0] && loadExtent[2] > projectionExtent[2]) {\n loadExtents.push([loadExtent[0] - worldWidth, loadExtent[1], loadExtent[2] - worldWidth, loadExtent[3]]);\n }\n }\n\n if (!this.dirty_ && this.renderedResolution_ == resolution && this.renderedRevision_ == vectorLayerRevision && this.renderedRenderOrder_ == vectorLayerRenderOrder && containsExtent(this.renderedExtent_, extent)) {\n this.replayGroupChanged = false;\n return true;\n }\n\n this.replayGroup_ = null;\n this.dirty_ = false;\n var replayGroup = new canvas_BuilderGroup(getTolerance(resolution, pixelRatio), extent, resolution, pixelRatio);\n var declutterBuilderGroup;\n\n if (this.getLayer().getDeclutter()) {\n declutterBuilderGroup = new canvas_BuilderGroup(getTolerance(resolution, pixelRatio), extent, resolution, pixelRatio);\n }\n\n var userProjection = getUserProjection();\n var userTransform;\n\n if (userProjection) {\n for (var i = 0, ii = loadExtents.length; i < ii; ++i) {\n vectorSource.loadFeatures(toUserExtent(loadExtents[i], projection), resolution, userProjection);\n }\n\n userTransform = getTransformFromProjections(userProjection, projection);\n } else {\n for (var i = 0, ii = loadExtents.length; i < ii; ++i) {\n vectorSource.loadFeatures(loadExtents[i], resolution, projection);\n }\n }\n\n var squaredTolerance = getSquaredTolerance(resolution, pixelRatio);\n\n var render =\n /**\n * @param {import("../../Feature.js").default} feature Feature.\n * @this {CanvasVectorLayerRenderer}\n */\n function (feature) {\n var styles;\n var styleFunction = feature.getStyleFunction() || vectorLayer.getStyleFunction();\n\n if (styleFunction) {\n styles = styleFunction(feature, resolution);\n }\n\n if (styles) {\n var dirty = this.renderFeature(feature, squaredTolerance, styles, replayGroup, userTransform, declutterBuilderGroup);\n this.dirty_ = this.dirty_ || dirty;\n }\n }.bind(this);\n\n var userExtent = toUserExtent(extent, projection);\n /** @type {Array<import("../../Feature.js").default>} */\n\n var features = vectorSource.getFeaturesInExtent(userExtent);\n\n if (vectorLayerRenderOrder) {\n features.sort(vectorLayerRenderOrder);\n }\n\n for (var i = 0, ii = features.length; i < ii; ++i) {\n render(features[i]);\n }\n\n this.renderedFeatures_ = features;\n var replayGroupInstructions = replayGroup.finish();\n var executorGroup = new canvas_ExecutorGroup(extent, resolution, pixelRatio, vectorSource.getOverlaps(), replayGroupInstructions, vectorLayer.getRenderBuffer());\n\n if (declutterBuilderGroup) {\n this.declutterExecutorGroup = new canvas_ExecutorGroup(extent, resolution, pixelRatio, vectorSource.getOverlaps(), declutterBuilderGroup.finish(), vectorLayer.getRenderBuffer());\n }\n\n this.renderedResolution_ = resolution;\n this.renderedRevision_ = vectorLayerRevision;\n this.renderedRenderOrder_ = vectorLayerRenderOrder;\n this.renderedExtent_ = extent;\n this.renderedCenter_ = center;\n this.renderedProjection_ = projection;\n this.replayGroup_ = executorGroup;\n this.hitDetectionImageData_ = null;\n this.replayGroupChanged = true;\n return true;\n };\n /**\n * @param {import("../../Feature.js").default} feature Feature.\n * @param {number} squaredTolerance Squared render tolerance.\n * @param {import("../../style/Style.js").default|Array<import("../../style/Style.js").default>} styles The style or array of styles.\n * @param {import("../../render/canvas/BuilderGroup.js").default} builderGroup Builder group.\n * @param {import("../../proj.js").TransformFunction=} opt_transform Transform from user to view projection.\n * @param {import("../../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n * @return {boolean} `true` if an image is loading.\n */\n\n\n CanvasVectorLayerRenderer.prototype.renderFeature = function (feature, squaredTolerance, styles, builderGroup, opt_transform, opt_declutterBuilderGroup) {\n if (!styles) {\n return false;\n }\n\n var loading = false;\n\n if (Array.isArray(styles)) {\n for (var i = 0, ii = styles.length; i < ii; ++i) {\n loading = renderFeature(builderGroup, feature, styles[i], squaredTolerance, this.boundHandleStyleImageChange_, opt_transform, opt_declutterBuilderGroup) || loading;\n }\n } else {\n loading = renderFeature(builderGroup, feature, styles, squaredTolerance, this.boundHandleStyleImageChange_, opt_transform, opt_declutterBuilderGroup);\n }\n\n return loading;\n };\n\n return CanvasVectorLayerRenderer;\n}(canvas_Layer);\n\n/* harmony default export */ var canvas_VectorLayer = (CanvasVectorLayerRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Vector.js\nvar Vector_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/Vector\n */\n\n\n\n\n/**\n * @classdesc\n * Vector data that is rendered client-side.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: \'My Title\'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @extends {BaseVectorLayer<import("../source/Vector.js").default>}\n * @api\n */\n\nvar VectorLayer =\n/** @class */\nfunction (_super) {\n Vector_extends(VectorLayer, _super);\n /**\n * @param {import("./BaseVector.js").Options=} opt_options Options.\n */\n\n\n function VectorLayer(opt_options) {\n return _super.call(this, opt_options) || this;\n }\n /**\n * Create a renderer for this layer.\n * @return {import("../renderer/Layer.js").default} A layer renderer.\n */\n\n\n VectorLayer.prototype.createRenderer = function () {\n return new canvas_VectorLayer(this);\n };\n\n return VectorLayer;\n}(BaseVector);\n\n/* harmony default export */ var Vector = (VectorLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/structs/RBush.js\n/**\n * @module ol/structs/RBush\n */\n\n\n\n\n/**\n * @typedef {Object} Entry\n * @property {number} minX\n * @property {number} minY\n * @property {number} maxX\n * @property {number} maxY\n * @property {Object} [value]\n */\n\n/**\n * @classdesc\n * Wrapper around the RBush by Vladimir Agafonkin.\n * See https://github.com/mourner/rbush.\n *\n * @template T\n */\n\nvar RBush =\n/** @class */\nfunction () {\n /**\n * @param {number=} opt_maxEntries Max entries.\n */\n function RBush(opt_maxEntries) {\n /**\n * @private\n */\n this.rbush_ = new (rbush_min_default())(opt_maxEntries);\n /**\n * A mapping between the objects added to this rbush wrapper\n * and the objects that are actually added to the internal rbush.\n * @private\n * @type {Object<string, Entry>}\n */\n\n this.items_ = {};\n }\n /**\n * Insert a value into the RBush.\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {T} value Value.\n */\n\n\n RBush.prototype.insert = function (extent, value) {\n /** @type {Entry} */\n var item = {\n minX: extent[0],\n minY: extent[1],\n maxX: extent[2],\n maxY: extent[3],\n value: value\n };\n this.rbush_.insert(item);\n this.items_[getUid(value)] = item;\n };\n /**\n * Bulk-insert values into the RBush.\n * @param {Array<import("../extent.js").Extent>} extents Extents.\n * @param {Array<T>} values Values.\n */\n\n\n RBush.prototype.load = function (extents, values) {\n var items = new Array(values.length);\n\n for (var i = 0, l = values.length; i < l; i++) {\n var extent = extents[i];\n var value = values[i];\n /** @type {Entry} */\n\n var item = {\n minX: extent[0],\n minY: extent[1],\n maxX: extent[2],\n maxY: extent[3],\n value: value\n };\n items[i] = item;\n this.items_[getUid(value)] = item;\n }\n\n this.rbush_.load(items);\n };\n /**\n * Remove a value from the RBush.\n * @param {T} value Value.\n * @return {boolean} Removed.\n */\n\n\n RBush.prototype.remove = function (value) {\n var uid = getUid(value); // get the object in which the value was wrapped when adding to the\n // internal rbush. then use that object to do the removal.\n\n var item = this.items_[uid];\n delete this.items_[uid];\n return this.rbush_.remove(item) !== null;\n };\n /**\n * Update the extent of a value in the RBush.\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {T} value Value.\n */\n\n\n RBush.prototype.update = function (extent, value) {\n var item = this.items_[getUid(value)];\n var bbox = [item.minX, item.minY, item.maxX, item.maxY];\n\n if (!extent_equals(bbox, extent)) {\n this.remove(value);\n this.insert(extent, value);\n }\n };\n /**\n * Return all values in the RBush.\n * @return {Array<T>} All.\n */\n\n\n RBush.prototype.getAll = function () {\n var items = this.rbush_.all();\n return items.map(function (item) {\n return item.value;\n });\n };\n /**\n * Return all values in the given extent.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {Array<T>} All in extent.\n */\n\n\n RBush.prototype.getInExtent = function (extent) {\n /** @type {Entry} */\n var bbox = {\n minX: extent[0],\n minY: extent[1],\n maxX: extent[2],\n maxY: extent[3]\n };\n var items = this.rbush_.search(bbox);\n return items.map(function (item) {\n return item.value;\n });\n };\n /**\n * Calls a callback function with each value in the tree.\n * If the callback returns a truthy value, this value is returned without\n * checking the rest of the tree.\n * @param {function(T): *} callback Callback.\n * @return {*} Callback return value.\n */\n\n\n RBush.prototype.forEach = function (callback) {\n return this.forEach_(this.getAll(), callback);\n };\n /**\n * Calls a callback function with each value in the provided extent.\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {function(T): *} callback Callback.\n * @return {*} Callback return value.\n */\n\n\n RBush.prototype.forEachInExtent = function (extent, callback) {\n return this.forEach_(this.getInExtent(extent), callback);\n };\n /**\n * @param {Array<T>} values Values.\n * @param {function(T): *} callback Callback.\n * @private\n * @return {*} Callback return value.\n */\n\n\n RBush.prototype.forEach_ = function (values, callback) {\n var result;\n\n for (var i = 0, l = values.length; i < l; i++) {\n result = callback(values[i]);\n\n if (result) {\n return result;\n }\n }\n\n return result;\n };\n /**\n * @return {boolean} Is empty.\n */\n\n\n RBush.prototype.isEmpty = function () {\n return obj_isEmpty(this.items_);\n };\n /**\n * Remove all values from the RBush.\n */\n\n\n RBush.prototype.clear = function () {\n this.rbush_.clear();\n this.items_ = {};\n };\n /**\n * @param {import("../extent.js").Extent=} opt_extent Extent.\n * @return {import("../extent.js").Extent} Extent.\n */\n\n\n RBush.prototype.getExtent = function (opt_extent) {\n var data = this.rbush_.toJSON();\n return createOrUpdate(data.minX, data.minY, data.maxX, data.maxY, opt_extent);\n };\n /**\n * @param {RBush} rbush R-Tree.\n */\n\n\n RBush.prototype.concat = function (rbush) {\n this.rbush_.load(rbush.rbush_.all());\n\n for (var i in rbush.items_) {\n this.items_[i] = rbush.items_[i];\n }\n };\n\n return RBush;\n}();\n\n/* harmony default export */ var structs_RBush = (RBush);\n;// CONCATENATED MODULE: ./node_modules/ol/source/Source.js\nvar Source_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/source/Source\n */\n\n\n\n\n\n\n/**\n * A function that returns a string or an array of strings representing source\n * attributions.\n *\n * @typedef {function(import("../PluggableMap.js").FrameState): (string|Array<string>)} Attribution\n */\n\n/**\n * A type that can be used to provide attribution information for data sources.\n *\n * It represents either\n * * a simple string (e.g. `\'© Acme Inc.\'`)\n * * an array of simple strings (e.g. `[\'© Acme Inc.\', \'© Bacme Inc.\']`)\n * * a function that returns a string or array of strings ({@link module:ol/source/Source~Attribution})\n *\n * @typedef {string|Array<string>|Attribution} AttributionLike\n */\n\n/**\n * @typedef {Object} Options\n * @property {AttributionLike} [attributions]\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.\n * @property {import("./State.js").default} [state=\'ready\']\n * @property {boolean} [wrapX=false]\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for {@link module:ol/layer/Layer~Layer} sources.\n *\n * A generic `change` event is triggered when the state of the source changes.\n * @abstract\n * @api\n */\n\nvar Source =\n/** @class */\nfunction (_super) {\n Source_extends(Source, _super);\n /**\n * @param {Options} options Source options.\n */\n\n\n function Source(options) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import("../proj/Projection.js").default}\n */\n\n\n _this.projection_ = proj_get(options.projection);\n /**\n * @private\n * @type {?Attribution}\n */\n\n _this.attributions_ = adaptAttributions(options.attributions);\n /**\n * @private\n * @type {boolean}\n */\n\n _this.attributionsCollapsible_ = options.attributionsCollapsible !== undefined ? options.attributionsCollapsible : true;\n /**\n * This source is currently loading data. Sources that defer loading to the\n * map\'s tile queue never set this to `true`.\n * @type {boolean}\n */\n\n _this.loading = false;\n /**\n * @private\n * @type {import("./State.js").default}\n */\n\n _this.state_ = options.state !== undefined ? options.state : State.READY;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.wrapX_ = options.wrapX !== undefined ? options.wrapX : false;\n return _this;\n }\n /**\n * Get the attribution function for the source.\n * @return {?Attribution} Attribution function.\n */\n\n\n Source.prototype.getAttributions = function () {\n return this.attributions_;\n };\n /**\n * @return {boolean} Attributions are collapsible.\n */\n\n\n Source.prototype.getAttributionsCollapsible = function () {\n return this.attributionsCollapsible_;\n };\n /**\n * Get the projection of the source.\n * @return {import("../proj/Projection.js").default} Projection.\n * @api\n */\n\n\n Source.prototype.getProjection = function () {\n return this.projection_;\n };\n /**\n * @abstract\n * @return {Array<number>|undefined} Resolutions.\n */\n\n\n Source.prototype.getResolutions = function () {\n return util_abstract();\n };\n /**\n * Get the state of the source, see {@link module:ol/source/State~State} for possible states.\n * @return {import("./State.js").default} State.\n * @api\n */\n\n\n Source.prototype.getState = function () {\n return this.state_;\n };\n /**\n * @return {boolean|undefined} Wrap X.\n */\n\n\n Source.prototype.getWrapX = function () {\n return this.wrapX_;\n };\n /**\n * @return {Object|undefined} Context options.\n */\n\n\n Source.prototype.getContextOptions = function () {\n return undefined;\n };\n /**\n * Refreshes the source. The source will be cleared, and data from the server will be reloaded.\n * @api\n */\n\n\n Source.prototype.refresh = function () {\n this.changed();\n };\n /**\n * Set the attributions of the source.\n * @param {AttributionLike|undefined} attributions Attributions.\n * Can be passed as `string`, `Array<string>`, {@link module:ol/source/Source~Attribution},\n * or `undefined`.\n * @api\n */\n\n\n Source.prototype.setAttributions = function (attributions) {\n this.attributions_ = adaptAttributions(attributions);\n this.changed();\n };\n /**\n * Set the state of the source.\n * @param {import("./State.js").default} state State.\n */\n\n\n Source.prototype.setState = function (state) {\n this.state_ = state;\n this.changed();\n };\n\n return Source;\n}(ol_Object);\n/**\n * Turns the attributions option into an attributions function.\n * @param {AttributionLike|undefined} attributionLike The attribution option.\n * @return {?Attribution} An attribution function (or null).\n */\n\n\nfunction adaptAttributions(attributionLike) {\n if (!attributionLike) {\n return null;\n }\n\n if (Array.isArray(attributionLike)) {\n return function (frameState) {\n return attributionLike;\n };\n }\n\n if (typeof attributionLike === \'function\') {\n return attributionLike;\n }\n\n return function (frameState) {\n return [attributionLike];\n };\n}\n\n/* harmony default export */ var source_Source = (Source);\n;// CONCATENATED MODULE: ./node_modules/ol/source/VectorEventType.js\n/**\n * @module ol/source/VectorEventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var VectorEventType = ({\n /**\n * Triggered when a feature is added to the source.\n * @event module:ol/source/Vector.VectorSourceEvent#addfeature\n * @api\n */\n ADDFEATURE: \'addfeature\',\n\n /**\n * Triggered when a feature is updated.\n * @event module:ol/source/Vector.VectorSourceEvent#changefeature\n * @api\n */\n CHANGEFEATURE: \'changefeature\',\n\n /**\n * Triggered when the clear method is called on the source.\n * @event module:ol/source/Vector.VectorSourceEvent#clear\n * @api\n */\n CLEAR: \'clear\',\n\n /**\n * Triggered when a feature is removed from the source.\n * See {@link module:ol/source/Vector#clear source.clear()} for exceptions.\n * @event module:ol/source/Vector.VectorSourceEvent#removefeature\n * @api\n */\n REMOVEFEATURE: \'removefeature\',\n\n /**\n * Triggered when features starts loading.\n * @event module:ol/source/Vector.VectorSourceEvent#featuresloadstart\n * @api\n */\n FEATURESLOADSTART: \'featuresloadstart\',\n\n /**\n * Triggered when features finishes loading.\n * @event module:ol/source/Vector.VectorSourceEvent#featuresloadend\n * @api\n */\n FEATURESLOADEND: \'featuresloadend\',\n\n /**\n * Triggered if feature loading results in an error.\n * @event module:ol/source/Vector.VectorSourceEvent#featuresloaderror\n * @api\n */\n FEATURESLOADERROR: \'featuresloaderror\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/loadingstrategy.js\n/**\n * @module ol/loadingstrategy\n */\n\n/**\n * Strategy function for loading all features with a single request.\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array<import("./extent.js").Extent>} Extents.\n * @api\n */\nfunction loadingstrategy_all(extent, resolution) {\n return [[-Infinity, -Infinity, Infinity, Infinity]];\n}\n/**\n * Strategy function for loading features based on the view\'s extent and\n * resolution.\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array<import("./extent.js").Extent>} Extents.\n * @api\n */\n\nfunction bbox(extent, resolution) {\n return [extent];\n}\n/**\n * Creates a strategy function for loading features based on a tile grid.\n * @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.\n * @return {function(import("./extent.js").Extent, number): Array<import("./extent.js").Extent>} Loading strategy.\n * @api\n */\n\nfunction tile(tileGrid) {\n return (\n /**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array<import("./extent.js").Extent>} Extents.\n */\n function (extent, resolution) {\n var z = tileGrid.getZForResolution(resolution);\n var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);\n /** @type {Array<import("./extent.js").Extent>} */\n\n var extents = [];\n /** @type {import("./tilecoord.js").TileCoord} */\n\n var tileCoord = [z, 0, 0];\n\n for (tileCoord[1] = tileRange.minX; tileCoord[1] <= tileRange.maxX; ++tileCoord[1]) {\n for (tileCoord[2] = tileRange.minY; tileCoord[2] <= tileRange.maxY; ++tileCoord[2]) {\n extents.push(tileGrid.getTileCoordExtent(tileCoord));\n }\n }\n\n return extents;\n }\n );\n}\n;// CONCATENATED MODULE: ./node_modules/ol/format/FormatType.js\n/**\n * @module ol/format/FormatType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var FormatType = ({\n ARRAY_BUFFER: \'arraybuffer\',\n JSON: \'json\',\n TEXT: \'text\',\n XML: \'xml\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/featureloader.js\n/**\n * @module ol/featureloader\n */\n\n\n/**\n *\n * @type {boolean}\n * @private\n */\n\nvar withCredentials = false;\n/**\n * {@link module:ol/source/Vector} sources use a function of this type to\n * load features.\n *\n * This function takes an {@link module:ol/extent~Extent} representing the area to be loaded,\n * a `{number}` representing the resolution (map units per pixel), an\n * {@link module:ol/proj/Projection} for the projection and success and failure callbacks as\n * arguments. `this` within the function is bound to the\n * {@link module:ol/source/Vector} it\'s called from.\n *\n * The function is responsible for loading the features and adding them to the\n * source.\n * @typedef {function(this:(import("./source/Vector").default|import("./VectorTile.js").default),\n * import("./extent.js").Extent,\n * number,\n * import("./proj/Projection.js").default,\n * function(Array<import("./Feature.js").default>): void=,\n * function(): void=): void} FeatureLoader\n * @api\n */\n\n/**\n * {@link module:ol/source/Vector} sources use a function of this type to\n * get the url to load features from.\n *\n * This function takes an {@link module:ol/extent~Extent} representing the area\n * to be loaded, a `{number}` representing the resolution (map units per pixel)\n * and an {@link module:ol/proj/Projection} for the projection as\n * arguments and returns a `{string}` representing the URL.\n * @typedef {function(import("./extent.js").Extent, number, import("./proj/Projection.js").default): string} FeatureUrlFunction\n * @api\n */\n\n/**\n * @param {string|FeatureUrlFunction} url Feature URL service.\n * @param {import("./format/Feature.js").default} format Feature format.\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @param {function(Array<import("./Feature.js").default>, import("./proj/Projection.js").default): void} success Success\n * Function called with the loaded features and optionally with the data projection.\n * @param {function(): void} failure Failure\n * Function called when loading failed.\n */\n\nfunction loadFeaturesXhr(url, format, extent, resolution, projection, success, failure) {\n var xhr = new XMLHttpRequest();\n xhr.open(\'GET\', typeof url === \'function\' ? url(extent, resolution, projection) : url, true);\n\n if (format.getType() == FormatType.ARRAY_BUFFER) {\n xhr.responseType = \'arraybuffer\';\n }\n\n xhr.withCredentials = withCredentials;\n /**\n * @param {Event} event Event.\n * @private\n */\n\n xhr.onload = function (event) {\n // status will be 0 for file:// urls\n if (!xhr.status || xhr.status >= 200 && xhr.status < 300) {\n var type = format.getType();\n /** @type {Document|Node|Object|string|undefined} */\n\n var source = void 0;\n\n if (type == FormatType.JSON || type == FormatType.TEXT) {\n source = xhr.responseText;\n } else if (type == FormatType.XML) {\n source = xhr.responseXML;\n\n if (!source) {\n source = new DOMParser().parseFromString(xhr.responseText, \'application/xml\');\n }\n } else if (type == FormatType.ARRAY_BUFFER) {\n source =\n /** @type {ArrayBuffer} */\n xhr.response;\n }\n\n if (source) {\n success(\n /** @type {Array<import("./Feature.js").default>} */\n format.readFeatures(source, {\n extent: extent,\n featureProjection: projection\n }), format.readProjection(source));\n } else {\n failure();\n }\n } else {\n failure();\n }\n };\n /**\n * @private\n */\n\n\n xhr.onerror = failure;\n xhr.send();\n}\n/**\n * Create an XHR feature loader for a `url` and `format`. The feature loader\n * loads features (with XHR), parses the features, and adds them to the\n * vector source.\n * @param {string|FeatureUrlFunction} url Feature URL service.\n * @param {import("./format/Feature.js").default} format Feature format.\n * @return {FeatureLoader} The feature loader.\n * @api\n */\n\nfunction xhr(url, format) {\n /**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @param {function(): void=} success Success\n * Function called when loading succeeded.\n * @param {function(): void=} failure Failure\n * Function called when loading failed.\n * @this {import("./source/Vector").default}\n */\n return function (extent, resolution, projection, success, failure) {\n var source =\n /** @type {import("./source/Vector").default} */\n this;\n loadFeaturesXhr(url, format, extent, resolution, projection,\n /**\n * @param {Array<import("./Feature.js").default>} features The loaded features.\n * @param {import("./proj/Projection.js").default} dataProjection Data\n * projection.\n */\n function (features, dataProjection) {\n if (success !== undefined) {\n success(features);\n }\n\n source.addFeatures(features);\n },\n /* FIXME handle error */\n failure ? failure : VOID);\n };\n}\n/**\n * Setter for the withCredentials configuration for the XHR.\n *\n * @param {boolean} xhrWithCredentials The value of withCredentials to set.\n * Compare https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/\n * @api\n */\n\nfunction setWithCredentials(xhrWithCredentials) {\n withCredentials = xhrWithCredentials;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/source/Vector.js\n/**\n * @module ol/source/Vector\n */\nvar source_Vector_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * A function that takes an {@link module:ol/extent~Extent} and a resolution as arguments, and\n * returns an array of {@link module:ol/extent~Extent} with the extents to load. Usually this\n * is one of the standard {@link module:ol/loadingstrategy} strategies.\n *\n * @typedef {function(import("../extent.js").Extent, number): Array<import("../extent.js").Extent>} LoadingStrategy\n * @api\n */\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/source/Vector} instances are instances of this\n * type.\n * @template {import("../geom/Geometry.js").default} Geometry\n */\n\nvar VectorSourceEvent =\n/** @class */\nfunction (_super) {\n source_Vector_extends(VectorSourceEvent, _super);\n /**\n * @param {string} type Type.\n * @param {import("../Feature.js").default<Geometry>=} opt_feature Feature.\n * @param {Array<import("../Feature.js").default<Geometry>>=} opt_features Features.\n */\n\n\n function VectorSourceEvent(type, opt_feature, opt_features) {\n var _this = _super.call(this, type) || this;\n /**\n * The added or removed feature for the `ADDFEATURE` and `REMOVEFEATURE` events, `undefined` otherwise.\n * @type {import("../Feature.js").default<Geometry>|undefined}\n * @api\n */\n\n\n _this.feature = opt_feature;\n /**\n * The loaded features for the `FEATURESLOADED` event, `undefined` otherwise.\n * @type {Array<import("../Feature.js").default<Geometry>>|undefined}\n * @api\n */\n\n _this.features = opt_features;\n return _this;\n }\n\n return VectorSourceEvent;\n}(Event);\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions] Attributions.\n * @property {Array<import("../Feature.js").default>|Collection<import("../Feature.js").default>} [features]\n * Features. If provided as {@link module:ol/Collection}, the features in the source\n * and the collection will stay in sync.\n * @property {import("../format/Feature.js").default} [format] The feature format used by the XHR\n * feature loader when `url` is set. Required if `url` is set, otherwise ignored.\n * @property {import("../featureloader.js").FeatureLoader} [loader]\n * The loader function used to load features, from a remote source for example.\n * If this is not set and `url` is set, the source will create and use an XHR\n * feature loader.\n *\n * Example:\n *\n * ```js\n * import {Vector} from \'ol/source\';\n * import {GeoJSON} from \'ol/format\';\n * import {bbox} from \'ol/loadingstrategy\';\n *\n * var vectorSource = new Vector({\n * format: new GeoJSON(),\n * loader: function(extent, resolution, projection) {\n * var proj = projection.getCode();\n * var url = \'https://ahocevar.com/geoserver/wfs?service=WFS&\' +\n * \'version=1.1.0&request=GetFeature&typename=osm:water_areas&\' +\n * \'outputFormat=application/json&srsname=\' + proj + \'&\' +\n * \'bbox=\' + extent.join(\',\') + \',\' + proj;\n * var xhr = new XMLHttpRequest();\n * xhr.open(\'GET\', url);\n * var onError = function() {\n * vectorSource.removeLoadedExtent(extent);\n * }\n * xhr.onerror = onError;\n * xhr.onload = function() {\n * if (xhr.status == 200) {\n * vectorSource.addFeatures(\n * vectorSource.getFormat().readFeatures(xhr.responseText));\n * } else {\n * onError();\n * }\n * }\n * xhr.send();\n * },\n * strategy: bbox\n * });\n * ```\n * @property {boolean} [overlaps=true] This source may have overlapping geometries.\n * Setting this to `false` (e.g. for sources with polygons that represent administrative\n * boundaries or TopoJSON sources) allows the renderer to optimise fill and\n * stroke operations.\n * @property {LoadingStrategy} [strategy] The loading strategy to use.\n * By default an {@link module:ol/loadingstrategy~all}\n * strategy is used, a one-off strategy which loads all features at once.\n * @property {string|import("../featureloader.js").FeatureUrlFunction} [url]\n * Setting this option instructs the source to load features using an XHR loader\n * (see {@link module:ol/featureloader~xhr}). Use a `string` and an\n * {@link module:ol/loadingstrategy~all} for a one-off download of all features from\n * the given URL. Use a {@link module:ol/featureloader~FeatureUrlFunction} to generate the url with\n * other loading strategies.\n * Requires `format` to be set as well.\n * When default XHR feature loader is provided, the features will\n * be transformed from the data projection to the view projection\n * during parsing. If your remote data source does not advertise its projection\n * properly, this transformation will be incorrect. For some formats, the\n * default projection (usually EPSG:4326) can be overridden by setting the\n * dataProjection constructor option on the format.\n * Note that if a source contains non-feature data, such as a GeoJSON geometry\n * or a KML NetworkLink, these will be ignored. Use a custom loader to load these.\n * @property {boolean} [useSpatialIndex=true]\n * By default, an RTree is used as spatial index. When features are removed and\n * added frequently, and the total number of features is low, setting this to\n * `false` may improve performance.\n *\n * Note that\n * {@link module:ol/source/Vector~VectorSource#getFeaturesInExtent},\n * {@link module:ol/source/Vector~VectorSource#getClosestFeatureToCoordinate} and\n * {@link module:ol/source/Vector~VectorSource#getExtent} cannot be used when `useSpatialIndex` is\n * set to `false`, and {@link module:ol/source/Vector~VectorSource#forEachFeatureInExtent} will loop\n * through all features.\n *\n * When set to `false`, the features will be maintained in an\n * {@link module:ol/Collection}, which can be retrieved through\n * {@link module:ol/source/Vector~VectorSource#getFeaturesCollection}.\n * @property {boolean} [wrapX=true] Wrap the world horizontally. For vector editing across the\n * -180° and 180° meridians to work properly, this should be set to `false`. The\n * resulting geometry coordinates will then exceed the world bounds.\n */\n\n/**\n * @classdesc\n * Provides a source of features for vector layers. Vector features provided\n * by this source are suitable for editing. See {@link module:ol/source/VectorTile~VectorTile} for\n * vector data that is optimized for rendering.\n *\n * @fires VectorSourceEvent\n * @api\n * @template {import("../geom/Geometry.js").default} Geometry\n */\n\nvar VectorSource =\n/** @class */\nfunction (_super) {\n source_Vector_extends(VectorSource, _super);\n /**\n * @param {Options=} opt_options Vector source options.\n */\n\n\n function VectorSource(opt_options) {\n var _this = this;\n\n var options = opt_options || {};\n _this = _super.call(this, {\n attributions: options.attributions,\n projection: undefined,\n state: State.READY,\n wrapX: options.wrapX !== undefined ? options.wrapX : true\n }) || this;\n /**\n * @private\n * @type {import("../featureloader.js").FeatureLoader}\n */\n\n _this.loader_ = VOID;\n /**\n * @private\n * @type {import("../format/Feature.js").default|undefined}\n */\n\n _this.format_ = options.format;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.overlaps_ = options.overlaps === undefined ? true : options.overlaps;\n /**\n * @private\n * @type {string|import("../featureloader.js").FeatureUrlFunction|undefined}\n */\n\n _this.url_ = options.url;\n\n if (options.loader !== undefined) {\n _this.loader_ = options.loader;\n } else if (_this.url_ !== undefined) {\n asserts_assert(_this.format_, 7); // `format` must be set when `url` is set\n // create a XHR feature loader for "url" and "format"\n\n _this.loader_ = xhr(_this.url_,\n /** @type {import("../format/Feature.js").default} */\n _this.format_);\n }\n /**\n * @private\n * @type {LoadingStrategy}\n */\n\n\n _this.strategy_ = options.strategy !== undefined ? options.strategy : loadingstrategy_all;\n var useSpatialIndex = options.useSpatialIndex !== undefined ? options.useSpatialIndex : true;\n /**\n * @private\n * @type {RBush<import("../Feature.js").default<Geometry>>}\n */\n\n _this.featuresRtree_ = useSpatialIndex ? new structs_RBush() : null;\n /**\n * @private\n * @type {RBush<{extent: import("../extent.js").Extent}>}\n */\n\n _this.loadedExtentsRtree_ = new structs_RBush();\n /**\n * @private\n * @type {!Object<string, import("../Feature.js").default<Geometry>>}\n */\n\n _this.nullGeometryFeatures_ = {};\n /**\n * A lookup of features by id (the return from feature.getId()).\n * @private\n * @type {!Object<string, import("../Feature.js").default<Geometry>>}\n */\n\n _this.idIndex_ = {};\n /**\n * A lookup of features by uid (using getUid(feature)).\n * @private\n * @type {!Object<string, import("../Feature.js").default<Geometry>>}\n */\n\n _this.uidIndex_ = {};\n /**\n * @private\n * @type {Object<string, Array<import("../events.js").EventsKey>>}\n */\n\n _this.featureChangeKeys_ = {};\n /**\n * @private\n * @type {Collection<import("../Feature.js").default<Geometry>>}\n */\n\n _this.featuresCollection_ = null;\n var collection, features;\n\n if (Array.isArray(options.features)) {\n features = options.features;\n } else if (options.features) {\n collection = options.features;\n features = collection.getArray();\n }\n\n if (!useSpatialIndex && collection === undefined) {\n collection = new ol_Collection(features);\n }\n\n if (features !== undefined) {\n _this.addFeaturesInternal(features);\n }\n\n if (collection !== undefined) {\n _this.bindFeaturesCollection_(collection);\n }\n\n return _this;\n }\n /**\n * Add a single feature to the source. If you want to add a batch of features\n * at once, call {@link module:ol/source/Vector~VectorSource#addFeatures #addFeatures()}\n * instead. A feature will not be added to the source if feature with\n * the same id is already there. The reason for this behavior is to avoid\n * feature duplication when using bbox or tile loading strategies.\n * Note: this also applies if an {@link module:ol/Collection} is used for features,\n * meaning that if a feature with a duplicate id is added in the collection, it will\n * be removed from it right away.\n * @param {import("../Feature.js").default<Geometry>} feature Feature to add.\n * @api\n */\n\n\n VectorSource.prototype.addFeature = function (feature) {\n this.addFeatureInternal(feature);\n this.changed();\n };\n /**\n * Add a feature without firing a `change` event.\n * @param {import("../Feature.js").default<Geometry>} feature Feature.\n * @protected\n */\n\n\n VectorSource.prototype.addFeatureInternal = function (feature) {\n var featureKey = getUid(feature);\n\n if (!this.addToIndex_(featureKey, feature)) {\n if (this.featuresCollection_) {\n this.featuresCollection_.remove(feature);\n }\n\n return;\n }\n\n this.setupChangeEvents_(featureKey, feature);\n var geometry = feature.getGeometry();\n\n if (geometry) {\n var extent = geometry.getExtent();\n\n if (this.featuresRtree_) {\n this.featuresRtree_.insert(extent, feature);\n }\n } else {\n this.nullGeometryFeatures_[featureKey] = feature;\n }\n\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.ADDFEATURE, feature));\n };\n /**\n * @param {string} featureKey Unique identifier for the feature.\n * @param {import("../Feature.js").default<Geometry>} feature The feature.\n * @private\n */\n\n\n VectorSource.prototype.setupChangeEvents_ = function (featureKey, feature) {\n this.featureChangeKeys_[featureKey] = [listen(feature, EventType.CHANGE, this.handleFeatureChange_, this), listen(feature, ObjectEventType.PROPERTYCHANGE, this.handleFeatureChange_, this)];\n };\n /**\n * @param {string} featureKey Unique identifier for the feature.\n * @param {import("../Feature.js").default<Geometry>} feature The feature.\n * @return {boolean} The feature is "valid", in the sense that it is also a\n * candidate for insertion into the Rtree.\n * @private\n */\n\n\n VectorSource.prototype.addToIndex_ = function (featureKey, feature) {\n var valid = true;\n var id = feature.getId();\n\n if (id !== undefined) {\n if (!(id.toString() in this.idIndex_)) {\n this.idIndex_[id.toString()] = feature;\n } else {\n valid = false;\n }\n }\n\n if (valid) {\n asserts_assert(!(featureKey in this.uidIndex_), 30); // The passed `feature` was already added to the source\n\n this.uidIndex_[featureKey] = feature;\n }\n\n return valid;\n };\n /**\n * Add a batch of features to the source.\n * @param {Array<import("../Feature.js").default<Geometry>>} features Features to add.\n * @api\n */\n\n\n VectorSource.prototype.addFeatures = function (features) {\n this.addFeaturesInternal(features);\n this.changed();\n };\n /**\n * Add features without firing a `change` event.\n * @param {Array<import("../Feature.js").default<Geometry>>} features Features.\n * @protected\n */\n\n\n VectorSource.prototype.addFeaturesInternal = function (features) {\n var extents = [];\n var newFeatures = [];\n var geometryFeatures = [];\n\n for (var i = 0, length_1 = features.length; i < length_1; i++) {\n var feature = features[i];\n var featureKey = getUid(feature);\n\n if (this.addToIndex_(featureKey, feature)) {\n newFeatures.push(feature);\n }\n }\n\n for (var i = 0, length_2 = newFeatures.length; i < length_2; i++) {\n var feature = newFeatures[i];\n var featureKey = getUid(feature);\n this.setupChangeEvents_(featureKey, feature);\n var geometry = feature.getGeometry();\n\n if (geometry) {\n var extent = geometry.getExtent();\n extents.push(extent);\n geometryFeatures.push(feature);\n } else {\n this.nullGeometryFeatures_[featureKey] = feature;\n }\n }\n\n if (this.featuresRtree_) {\n this.featuresRtree_.load(extents, geometryFeatures);\n }\n\n for (var i = 0, length_3 = newFeatures.length; i < length_3; i++) {\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.ADDFEATURE, newFeatures[i]));\n }\n };\n /**\n * @param {!Collection<import("../Feature.js").default<Geometry>>} collection Collection.\n * @private\n */\n\n\n VectorSource.prototype.bindFeaturesCollection_ = function (collection) {\n var modifyingCollection = false;\n this.addEventListener(VectorEventType.ADDFEATURE,\n /**\n * @param {VectorSourceEvent<Geometry>} evt The vector source event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n collection.push(evt.feature);\n modifyingCollection = false;\n }\n });\n this.addEventListener(VectorEventType.REMOVEFEATURE,\n /**\n * @param {VectorSourceEvent<Geometry>} evt The vector source event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n collection.remove(evt.feature);\n modifyingCollection = false;\n }\n });\n collection.addEventListener(CollectionEventType.ADD,\n /**\n * @param {import("../Collection.js").CollectionEvent} evt The collection event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n this.addFeature(\n /** @type {import("../Feature.js").default<Geometry>} */\n evt.element);\n modifyingCollection = false;\n }\n }.bind(this));\n collection.addEventListener(CollectionEventType.REMOVE,\n /**\n * @param {import("../Collection.js").CollectionEvent} evt The collection event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n this.removeFeature(\n /** @type {import("../Feature.js").default<Geometry>} */\n evt.element);\n modifyingCollection = false;\n }\n }.bind(this));\n this.featuresCollection_ = collection;\n };\n /**\n * Remove all features from the source.\n * @param {boolean=} opt_fast Skip dispatching of {@link module:ol/source/Vector.VectorSourceEvent#removefeature} events.\n * @api\n */\n\n\n VectorSource.prototype.clear = function (opt_fast) {\n if (opt_fast) {\n for (var featureId in this.featureChangeKeys_) {\n var keys = this.featureChangeKeys_[featureId];\n keys.forEach(unlistenByKey);\n }\n\n if (!this.featuresCollection_) {\n this.featureChangeKeys_ = {};\n this.idIndex_ = {};\n this.uidIndex_ = {};\n }\n } else {\n if (this.featuresRtree_) {\n this.featuresRtree_.forEach(this.removeFeatureInternal.bind(this));\n\n for (var id in this.nullGeometryFeatures_) {\n this.removeFeatureInternal(this.nullGeometryFeatures_[id]);\n }\n }\n }\n\n if (this.featuresCollection_) {\n this.featuresCollection_.clear();\n }\n\n if (this.featuresRtree_) {\n this.featuresRtree_.clear();\n }\n\n this.nullGeometryFeatures_ = {};\n var clearEvent = new VectorSourceEvent(VectorEventType.CLEAR);\n this.dispatchEvent(clearEvent);\n this.changed();\n };\n /**\n * Iterate through all features on the source, calling the provided callback\n * with each one. If the callback returns any "truthy" value, iteration will\n * stop and the function will return the same value.\n * Note: this function only iterate through the feature that have a defined geometry.\n *\n * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature\n * on the source. Return a truthy value to stop iteration.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\n\n\n VectorSource.prototype.forEachFeature = function (callback) {\n if (this.featuresRtree_) {\n return this.featuresRtree_.forEach(callback);\n } else if (this.featuresCollection_) {\n this.featuresCollection_.forEach(callback);\n }\n };\n /**\n * Iterate through all features whose geometries contain the provided\n * coordinate, calling the callback with each feature. If the callback returns\n * a "truthy" value, iteration will stop and the function will return the same\n * value.\n *\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature\n * whose goemetry contains the provided coordinate.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n */\n\n\n VectorSource.prototype.forEachFeatureAtCoordinateDirect = function (coordinate, callback) {\n var extent = [coordinate[0], coordinate[1], coordinate[0], coordinate[1]];\n return this.forEachFeatureInExtent(extent, function (feature) {\n var geometry = feature.getGeometry();\n\n if (geometry.intersectsCoordinate(coordinate)) {\n return callback(feature);\n } else {\n return undefined;\n }\n });\n };\n /**\n * Iterate through all features whose bounding box intersects the provided\n * extent (note that the feature\'s geometry may not intersect the extent),\n * calling the callback with each feature. If the callback returns a "truthy"\n * value, iteration will stop and the function will return the same value.\n *\n * If you are interested in features whose geometry intersects an extent, call\n * the {@link module:ol/source/Vector~VectorSource#forEachFeatureIntersectingExtent #forEachFeatureIntersectingExtent()} method instead.\n *\n * When `useSpatialIndex` is set to false, this method will loop through all\n * features, equivalent to {@link module:ol/source/Vector~VectorSource#forEachFeature #forEachFeature()}.\n *\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature\n * whose bounding box intersects the provided extent.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\n\n\n VectorSource.prototype.forEachFeatureInExtent = function (extent, callback) {\n if (this.featuresRtree_) {\n return this.featuresRtree_.forEachInExtent(extent, callback);\n } else if (this.featuresCollection_) {\n this.featuresCollection_.forEach(callback);\n }\n };\n /**\n * Iterate through all features whose geometry intersects the provided extent,\n * calling the callback with each feature. If the callback returns a "truthy"\n * value, iteration will stop and the function will return the same value.\n *\n * If you only want to test for bounding box intersection, call the\n * {@link module:ol/source/Vector~VectorSource#forEachFeatureInExtent #forEachFeatureInExtent()} method instead.\n *\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature\n * whose geometry intersects the provided extent.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\n\n\n VectorSource.prototype.forEachFeatureIntersectingExtent = function (extent, callback) {\n return this.forEachFeatureInExtent(extent,\n /**\n * @param {import("../Feature.js").default<Geometry>} feature Feature.\n * @return {T|undefined} The return value from the last call to the callback.\n */\n function (feature) {\n var geometry = feature.getGeometry();\n\n if (geometry.intersectsExtent(extent)) {\n var result = callback(feature);\n\n if (result) {\n return result;\n }\n }\n });\n };\n /**\n * Get the features collection associated with this source. Will be `null`\n * unless the source was configured with `useSpatialIndex` set to `false`, or\n * with an {@link module:ol/Collection} as `features`.\n * @return {Collection<import("../Feature.js").default<Geometry>>} The collection of features.\n * @api\n */\n\n\n VectorSource.prototype.getFeaturesCollection = function () {\n return this.featuresCollection_;\n };\n /**\n * Get all features on the source in random order.\n * @return {Array<import("../Feature.js").default<Geometry>>} Features.\n * @api\n */\n\n\n VectorSource.prototype.getFeatures = function () {\n var features;\n\n if (this.featuresCollection_) {\n features = this.featuresCollection_.getArray();\n } else if (this.featuresRtree_) {\n features = this.featuresRtree_.getAll();\n\n if (!obj_isEmpty(this.nullGeometryFeatures_)) {\n array_extend(features, getValues(this.nullGeometryFeatures_));\n }\n }\n\n return (\n /** @type {Array<import("../Feature.js").default<Geometry>>} */\n features\n );\n };\n /**\n * Get all features whose geometry intersects the provided coordinate.\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @return {Array<import("../Feature.js").default<Geometry>>} Features.\n * @api\n */\n\n\n VectorSource.prototype.getFeaturesAtCoordinate = function (coordinate) {\n var features = [];\n this.forEachFeatureAtCoordinateDirect(coordinate, function (feature) {\n features.push(feature);\n });\n return features;\n };\n /**\n * Get all features whose bounding box intersects the provided extent. Note that this returns an array of\n * all features intersecting the given extent in random order (so it may include\n * features whose geometries do not intersect the extent).\n *\n * When `useSpatialIndex` is set to false, this method will return all\n * features.\n *\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {Array<import("../Feature.js").default<Geometry>>} Features.\n * @api\n */\n\n\n VectorSource.prototype.getFeaturesInExtent = function (extent) {\n if (this.featuresRtree_) {\n return this.featuresRtree_.getInExtent(extent);\n } else if (this.featuresCollection_) {\n return this.featuresCollection_.getArray();\n } else {\n return [];\n }\n };\n /**\n * Get the closest feature to the provided coordinate.\n *\n * This method is not available when the source is configured with\n * `useSpatialIndex` set to `false`.\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {function(import("../Feature.js").default<Geometry>):boolean=} opt_filter Feature filter function.\n * The filter function will receive one argument, the {@link module:ol/Feature feature}\n * and it should return a boolean value. By default, no filtering is made.\n * @return {import("../Feature.js").default<Geometry>} Closest feature.\n * @api\n */\n\n\n VectorSource.prototype.getClosestFeatureToCoordinate = function (coordinate, opt_filter) {\n // Find the closest feature using branch and bound. We start searching an\n // infinite extent, and find the distance from the first feature found. This\n // becomes the closest feature. We then compute a smaller extent which any\n // closer feature must intersect. We continue searching with this smaller\n // extent, trying to find a closer feature. Every time we find a closer\n // feature, we update the extent being searched so that any even closer\n // feature must intersect it. We continue until we run out of features.\n var x = coordinate[0];\n var y = coordinate[1];\n var closestFeature = null;\n var closestPoint = [NaN, NaN];\n var minSquaredDistance = Infinity;\n var extent = [-Infinity, -Infinity, Infinity, Infinity];\n var filter = opt_filter ? opt_filter : TRUE;\n this.featuresRtree_.forEachInExtent(extent,\n /**\n * @param {import("../Feature.js").default<Geometry>} feature Feature.\n */\n function (feature) {\n if (filter(feature)) {\n var geometry = feature.getGeometry();\n var previousMinSquaredDistance = minSquaredDistance;\n minSquaredDistance = geometry.closestPointXY(x, y, closestPoint, minSquaredDistance);\n\n if (minSquaredDistance < previousMinSquaredDistance) {\n closestFeature = feature; // This is sneaky. Reduce the extent that it is currently being\n // searched while the R-Tree traversal using this same extent object\n // is still in progress. This is safe because the new extent is\n // strictly contained by the old extent.\n\n var minDistance = Math.sqrt(minSquaredDistance);\n extent[0] = x - minDistance;\n extent[1] = y - minDistance;\n extent[2] = x + minDistance;\n extent[3] = y + minDistance;\n }\n }\n });\n return closestFeature;\n };\n /**\n * Get the extent of the features currently in the source.\n *\n * This method is not available when the source is configured with\n * `useSpatialIndex` set to `false`.\n * @param {import("../extent.js").Extent=} opt_extent Destination extent. If provided, no new extent\n * will be created. Instead, that extent\'s coordinates will be overwritten.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n VectorSource.prototype.getExtent = function (opt_extent) {\n return this.featuresRtree_.getExtent(opt_extent);\n };\n /**\n * Get a feature by its identifier (the value returned by feature.getId()).\n * Note that the index treats string and numeric identifiers as the same. So\n * `source.getFeatureById(2)` will return a feature with id `\'2\'` or `2`.\n *\n * @param {string|number} id Feature identifier.\n * @return {import("../Feature.js").default<Geometry>} The feature (or `null` if not found).\n * @api\n */\n\n\n VectorSource.prototype.getFeatureById = function (id) {\n var feature = this.idIndex_[id.toString()];\n return feature !== undefined ? feature : null;\n };\n /**\n * Get a feature by its internal unique identifier (using `getUid`).\n *\n * @param {string} uid Feature identifier.\n * @return {import("../Feature.js").default<Geometry>} The feature (or `null` if not found).\n */\n\n\n VectorSource.prototype.getFeatureByUid = function (uid) {\n var feature = this.uidIndex_[uid];\n return feature !== undefined ? feature : null;\n };\n /**\n * Get the format associated with this source.\n *\n * @return {import("../format/Feature.js").default|undefined} The feature format.\n * @api\n */\n\n\n VectorSource.prototype.getFormat = function () {\n return this.format_;\n };\n /**\n * @return {boolean} The source can have overlapping geometries.\n */\n\n\n VectorSource.prototype.getOverlaps = function () {\n return this.overlaps_;\n };\n /**\n * Get the url associated with this source.\n *\n * @return {string|import("../featureloader.js").FeatureUrlFunction|undefined} The url.\n * @api\n */\n\n\n VectorSource.prototype.getUrl = function () {\n return this.url_;\n };\n /**\n * @param {Event} event Event.\n * @private\n */\n\n\n VectorSource.prototype.handleFeatureChange_ = function (event) {\n var feature =\n /** @type {import("../Feature.js").default<Geometry>} */\n event.target;\n var featureKey = getUid(feature);\n var geometry = feature.getGeometry();\n\n if (!geometry) {\n if (!(featureKey in this.nullGeometryFeatures_)) {\n if (this.featuresRtree_) {\n this.featuresRtree_.remove(feature);\n }\n\n this.nullGeometryFeatures_[featureKey] = feature;\n }\n } else {\n var extent = geometry.getExtent();\n\n if (featureKey in this.nullGeometryFeatures_) {\n delete this.nullGeometryFeatures_[featureKey];\n\n if (this.featuresRtree_) {\n this.featuresRtree_.insert(extent, feature);\n }\n } else {\n if (this.featuresRtree_) {\n this.featuresRtree_.update(extent, feature);\n }\n }\n }\n\n var id = feature.getId();\n\n if (id !== undefined) {\n var sid = id.toString();\n\n if (this.idIndex_[sid] !== feature) {\n this.removeFromIdIndex_(feature);\n this.idIndex_[sid] = feature;\n }\n } else {\n this.removeFromIdIndex_(feature);\n this.uidIndex_[featureKey] = feature;\n }\n\n this.changed();\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.CHANGEFEATURE, feature));\n };\n /**\n * Returns true if the feature is contained within the source.\n * @param {import("../Feature.js").default<Geometry>} feature Feature.\n * @return {boolean} Has feature.\n * @api\n */\n\n\n VectorSource.prototype.hasFeature = function (feature) {\n var id = feature.getId();\n\n if (id !== undefined) {\n return id in this.idIndex_;\n } else {\n return getUid(feature) in this.uidIndex_;\n }\n };\n /**\n * @return {boolean} Is empty.\n */\n\n\n VectorSource.prototype.isEmpty = function () {\n return this.featuresRtree_.isEmpty() && obj_isEmpty(this.nullGeometryFeatures_);\n };\n /**\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import("../proj/Projection.js").default} projection Projection.\n */\n\n\n VectorSource.prototype.loadFeatures = function (extent, resolution, projection) {\n var loadedExtentsRtree = this.loadedExtentsRtree_;\n var extentsToLoad = this.strategy_(extent, resolution);\n this.loading = false;\n\n var _loop_1 = function _loop_1(i, ii) {\n var extentToLoad = extentsToLoad[i];\n var alreadyLoaded = loadedExtentsRtree.forEachInExtent(extentToLoad,\n /**\n * @param {{extent: import("../extent.js").Extent}} object Object.\n * @return {boolean} Contains.\n */\n function (object) {\n return containsExtent(object.extent, extentToLoad);\n });\n\n if (!alreadyLoaded) {\n this_1.dispatchEvent(new VectorSourceEvent(VectorEventType.FEATURESLOADSTART));\n this_1.loader_.call(this_1, extentToLoad, resolution, projection, function (features) {\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.FEATURESLOADEND, undefined, features));\n }.bind(this_1), function () {\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.FEATURESLOADERROR));\n }.bind(this_1));\n loadedExtentsRtree.insert(extentToLoad, {\n extent: extentToLoad.slice()\n });\n this_1.loading = this_1.loader_ !== VOID;\n }\n };\n\n var this_1 = this;\n\n for (var i = 0, ii = extentsToLoad.length; i < ii; ++i) {\n _loop_1(i, ii);\n }\n };\n\n VectorSource.prototype.refresh = function () {\n this.clear(true);\n this.loadedExtentsRtree_.clear();\n\n _super.prototype.refresh.call(this);\n };\n /**\n * Remove an extent from the list of loaded extents.\n * @param {import("../extent.js").Extent} extent Extent.\n * @api\n */\n\n\n VectorSource.prototype.removeLoadedExtent = function (extent) {\n var loadedExtentsRtree = this.loadedExtentsRtree_;\n var obj;\n loadedExtentsRtree.forEachInExtent(extent, function (object) {\n if (extent_equals(object.extent, extent)) {\n obj = object;\n return true;\n }\n });\n\n if (obj) {\n loadedExtentsRtree.remove(obj);\n }\n };\n /**\n * Remove a single feature from the source. If you want to remove all features\n * at once, use the {@link module:ol/source/Vector~VectorSource#clear #clear()} method\n * instead.\n * @param {import("../Feature.js").default<Geometry>} feature Feature to remove.\n * @api\n */\n\n\n VectorSource.prototype.removeFeature = function (feature) {\n var featureKey = getUid(feature);\n\n if (featureKey in this.nullGeometryFeatures_) {\n delete this.nullGeometryFeatures_[featureKey];\n } else {\n if (this.featuresRtree_) {\n this.featuresRtree_.remove(feature);\n }\n }\n\n this.removeFeatureInternal(feature);\n this.changed();\n };\n /**\n * Remove feature without firing a `change` event.\n * @param {import("../Feature.js").default<Geometry>} feature Feature.\n * @protected\n */\n\n\n VectorSource.prototype.removeFeatureInternal = function (feature) {\n var featureKey = getUid(feature);\n this.featureChangeKeys_[featureKey].forEach(unlistenByKey);\n delete this.featureChangeKeys_[featureKey];\n var id = feature.getId();\n\n if (id !== undefined) {\n delete this.idIndex_[id.toString()];\n }\n\n delete this.uidIndex_[featureKey];\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.REMOVEFEATURE, feature));\n };\n /**\n * Remove a feature from the id index. Called internally when the feature id\n * may have changed.\n * @param {import("../Feature.js").default<Geometry>} feature The feature.\n * @return {boolean} Removed the feature from the index.\n * @private\n */\n\n\n VectorSource.prototype.removeFromIdIndex_ = function (feature) {\n var removed = false;\n\n for (var id in this.idIndex_) {\n if (this.idIndex_[id] === feature) {\n delete this.idIndex_[id];\n removed = true;\n break;\n }\n }\n\n return removed;\n };\n /**\n * Set the new loader of the source. The next render cycle will use the\n * new loader.\n * @param {import("../featureloader.js").FeatureLoader} loader The loader to set.\n * @api\n */\n\n\n VectorSource.prototype.setLoader = function (loader) {\n this.loader_ = loader;\n };\n /**\n * Points the source to a new url. The next render cycle will use the new url.\n * @param {string|import("../featureloader.js").FeatureUrlFunction} url Url.\n * @api\n */\n\n\n VectorSource.prototype.setUrl = function (url) {\n asserts_assert(this.format_, 7); // `format` must be set when `url` is set\n\n this.setLoader(xhr(url, this.format_));\n };\n\n return VectorSource;\n}(source_Source);\n\n/* harmony default export */ var source_Vector = (VectorSource);\n;// CONCATENATED MODULE: ./src/components/map.module.scss\n// extracted by mini-css-extract-plugin\nvar mapContainer = "map-module--mapContainer--3zBiu";\nvar map_module_popupContainer = "map-module--popupContainer--2KE8h";\nvar map_module_popupCloser = "map-module--popupCloser--5XwUX";\n;// CONCATENATED MODULE: ./node_modules/ol/layer/TileProperty.js\n/**\n * @module ol/layer/TileProperty\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var TileProperty = ({\n PRELOAD: \'preload\',\n USE_INTERIM_TILES_ON_ERROR: \'useInterimTilesOnError\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/layer/BaseTile.js\nvar BaseTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/BaseTile\n */\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-layer\'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {number} [preload=0] Preload. Load low-resolution tiles up to `preload` levels. `0`\n * means no preloading.\n * @property {import("../source/Tile.js").default} [source] Source for this layer.\n * @property {import("../PluggableMap.js").default} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link module:ol/Map#addLayer}.\n * @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.\n */\n\n/**\n * @classdesc\n * For layer sources that provide pre-rendered, tiled images in grids that are\n * organized by zoom levels for specific resolutions.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: \'My Title\'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @extends {Layer<import("../source/Tile.js").default>}\n * @api\n */\n\nvar BaseTileLayer =\n/** @class */\nfunction (_super) {\n BaseTile_extends(BaseTileLayer, _super);\n /**\n * @param {Options=} opt_options Tile layer options.\n */\n\n\n function BaseTileLayer(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var baseOptions = obj_assign({}, options);\n delete baseOptions.preload;\n delete baseOptions.useInterimTilesOnError;\n _this = _super.call(this, baseOptions) || this;\n\n _this.setPreload(options.preload !== undefined ? options.preload : 0);\n\n _this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined ? options.useInterimTilesOnError : true);\n\n return _this;\n }\n /**\n * Return the level as number to which we will preload tiles up to.\n * @return {number} The level to preload tiles up to.\n * @observable\n * @api\n */\n\n\n BaseTileLayer.prototype.getPreload = function () {\n return (\n /** @type {number} */\n this.get(TileProperty.PRELOAD)\n );\n };\n /**\n * Set the level as number to which we will preload tiles up to.\n * @param {number} preload The level to preload tiles up to.\n * @observable\n * @api\n */\n\n\n BaseTileLayer.prototype.setPreload = function (preload) {\n this.set(TileProperty.PRELOAD, preload);\n };\n /**\n * Whether we use interim tiles on error.\n * @return {boolean} Use interim tiles on error.\n * @observable\n * @api\n */\n\n\n BaseTileLayer.prototype.getUseInterimTilesOnError = function () {\n return (\n /** @type {boolean} */\n this.get(TileProperty.USE_INTERIM_TILES_ON_ERROR)\n );\n };\n /**\n * Set whether we use interim tiles on error.\n * @param {boolean} useInterimTilesOnError Use interim tiles on error.\n * @observable\n * @api\n */\n\n\n BaseTileLayer.prototype.setUseInterimTilesOnError = function (useInterimTilesOnError) {\n this.set(TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError);\n };\n\n return BaseTileLayer;\n}(layer_Layer);\n\n/* harmony default export */ var BaseTile = (BaseTileLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/TileRange.js\n/**\n * @module ol/TileRange\n */\n\n/**\n * A representation of a contiguous block of tiles. A tile range is specified\n * by its min/max tile coordinates and is inclusive of coordinates.\n */\nvar TileRange =\n/** @class */\nfunction () {\n /**\n * @param {number} minX Minimum X.\n * @param {number} maxX Maximum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxY Maximum Y.\n */\n function TileRange(minX, maxX, minY, maxY) {\n /**\n * @type {number}\n */\n this.minX = minX;\n /**\n * @type {number}\n */\n\n this.maxX = maxX;\n /**\n * @type {number}\n */\n\n this.minY = minY;\n /**\n * @type {number}\n */\n\n this.maxY = maxY;\n }\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @return {boolean} Contains tile coordinate.\n */\n\n\n TileRange.prototype.contains = function (tileCoord) {\n return this.containsXY(tileCoord[1], tileCoord[2]);\n };\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Contains.\n */\n\n\n TileRange.prototype.containsTileRange = function (tileRange) {\n return this.minX <= tileRange.minX && tileRange.maxX <= this.maxX && this.minY <= tileRange.minY && tileRange.maxY <= this.maxY;\n };\n /**\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @return {boolean} Contains coordinate.\n */\n\n\n TileRange.prototype.containsXY = function (x, y) {\n return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;\n };\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Equals.\n */\n\n\n TileRange.prototype.equals = function (tileRange) {\n return this.minX == tileRange.minX && this.minY == tileRange.minY && this.maxX == tileRange.maxX && this.maxY == tileRange.maxY;\n };\n /**\n * @param {TileRange} tileRange Tile range.\n */\n\n\n TileRange.prototype.extend = function (tileRange) {\n if (tileRange.minX < this.minX) {\n this.minX = tileRange.minX;\n }\n\n if (tileRange.maxX > this.maxX) {\n this.maxX = tileRange.maxX;\n }\n\n if (tileRange.minY < this.minY) {\n this.minY = tileRange.minY;\n }\n\n if (tileRange.maxY > this.maxY) {\n this.maxY = tileRange.maxY;\n }\n };\n /**\n * @return {number} Height.\n */\n\n\n TileRange.prototype.getHeight = function () {\n return this.maxY - this.minY + 1;\n };\n /**\n * @return {import("./size.js").Size} Size.\n */\n\n\n TileRange.prototype.getSize = function () {\n return [this.getWidth(), this.getHeight()];\n };\n /**\n * @return {number} Width.\n */\n\n\n TileRange.prototype.getWidth = function () {\n return this.maxX - this.minX + 1;\n };\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Intersects.\n */\n\n\n TileRange.prototype.intersects = function (tileRange) {\n return this.minX <= tileRange.maxX && this.maxX >= tileRange.minX && this.minY <= tileRange.maxY && this.maxY >= tileRange.minY;\n };\n\n return TileRange;\n}();\n/**\n * @param {number} minX Minimum X.\n * @param {number} maxX Maximum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxY Maximum Y.\n * @param {TileRange=} tileRange TileRange.\n * @return {TileRange} Tile range.\n */\n\n\nfunction TileRange_createOrUpdate(minX, maxX, minY, maxY, tileRange) {\n if (tileRange !== undefined) {\n tileRange.minX = minX;\n tileRange.maxX = maxX;\n tileRange.minY = minY;\n tileRange.maxY = maxY;\n return tileRange;\n } else {\n return new TileRange(minX, maxX, minY, maxY);\n }\n}\n/* harmony default export */ var ol_TileRange = (TileRange);\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/TileLayer.js\nvar TileLayer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/canvas/TileLayer\n */\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Canvas renderer for tile layers.\n * @api\n */\n\nvar CanvasTileLayerRenderer =\n/** @class */\nfunction (_super) {\n TileLayer_extends(CanvasTileLayerRenderer, _super);\n /**\n * @param {import("../../layer/Tile.js").default|import("../../layer/VectorTile.js").default} tileLayer Tile layer.\n */\n\n\n function CanvasTileLayerRenderer(tileLayer) {\n var _this = _super.call(this, tileLayer) || this;\n /**\n * Rendered extent has changed since the previous `renderFrame()` call\n * @type {boolean}\n */\n\n\n _this.extentChanged = true;\n /**\n * @private\n * @type {?import("../../extent.js").Extent}\n */\n\n _this.renderedExtent_ = null;\n /**\n * @protected\n * @type {number}\n */\n\n _this.renderedPixelRatio;\n /**\n * @protected\n * @type {import("../../proj/Projection.js").default}\n */\n\n _this.renderedProjection = null;\n /**\n * @protected\n * @type {number}\n */\n\n _this.renderedRevision;\n /**\n * @protected\n * @type {!Array<import("../../Tile.js").default>}\n */\n\n _this.renderedTiles = [];\n /**\n * @private\n * @type {boolean}\n */\n\n _this.newTiles_ = false;\n /**\n * @protected\n * @type {import("../../extent.js").Extent}\n */\n\n _this.tmpExtent = createEmpty();\n /**\n * @private\n * @type {import("../../TileRange.js").default}\n */\n\n _this.tmpTileRange_ = new ol_TileRange(0, 0, 0, 0);\n return _this;\n }\n /**\n * @protected\n * @param {import("../../Tile.js").default} tile Tile.\n * @return {boolean} Tile is drawable.\n */\n\n\n CanvasTileLayerRenderer.prototype.isDrawableTile = function (tile) {\n var tileLayer = this.getLayer();\n var tileState = tile.getState();\n var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();\n return tileState == TileState.LOADED || tileState == TileState.EMPTY || tileState == TileState.ERROR && !useInterimTilesOnError;\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @return {!import("../../Tile.js").default} Tile.\n */\n\n\n CanvasTileLayerRenderer.prototype.getTile = function (z, x, y, frameState) {\n var pixelRatio = frameState.pixelRatio;\n var projection = frameState.viewState.projection;\n var tileLayer = this.getLayer();\n var tileSource = tileLayer.getSource();\n var tile = tileSource.getTile(z, x, y, pixelRatio, projection);\n\n if (tile.getState() == TileState.ERROR) {\n if (!tileLayer.getUseInterimTilesOnError()) {\n // When useInterimTilesOnError is false, we consider the error tile as loaded.\n tile.setState(TileState.LOADED);\n } else if (tileLayer.getPreload() > 0) {\n // Preloaded tiles for lower resolutions might have finished loading.\n this.newTiles_ = true;\n }\n }\n\n if (!this.isDrawableTile(tile)) {\n tile = tile.getInterimTile();\n }\n\n return tile;\n };\n /**\n * @param {Object<number, Object<string, import("../../Tile.js").default>>} tiles Lookup of loaded tiles by zoom level.\n * @param {number} zoom Zoom level.\n * @param {import("../../Tile.js").default} tile Tile.\n * @return {boolean|void} If `false`, the tile will not be considered loaded.\n */\n\n\n CanvasTileLayerRenderer.prototype.loadedTileCallback = function (tiles, zoom, tile) {\n if (this.isDrawableTile(tile)) {\n return _super.prototype.loadedTileCallback.call(this, tiles, zoom, tile);\n }\n\n return false;\n };\n /**\n * Determine whether render should be called.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n\n\n CanvasTileLayerRenderer.prototype.prepareFrame = function (frameState) {\n return !!this.getLayer().getSource();\n };\n /**\n * Render the layer.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n\n\n CanvasTileLayerRenderer.prototype.renderFrame = function (frameState, target) {\n var layerState = frameState.layerStatesArray[frameState.layerIndex];\n var viewState = frameState.viewState;\n var projection = viewState.projection;\n var viewResolution = viewState.resolution;\n var viewCenter = viewState.center;\n var rotation = viewState.rotation;\n var pixelRatio = frameState.pixelRatio;\n var tileLayer = this.getLayer();\n var tileSource = tileLayer.getSource();\n var sourceRevision = tileSource.getRevision();\n var tileGrid = tileSource.getTileGridForProjection(projection);\n var z = tileGrid.getZForResolution(viewResolution, tileSource.zDirection);\n var tileResolution = tileGrid.getResolution(z);\n var extent = frameState.extent;\n var layerExtent = layerState.extent && fromUserExtent(layerState.extent, projection);\n\n if (layerExtent) {\n extent = getIntersection(extent, fromUserExtent(layerState.extent, projection));\n }\n\n var tilePixelRatio = tileSource.getTilePixelRatio(pixelRatio); // desired dimensions of the canvas in pixels\n\n var width = Math.round(frameState.size[0] * tilePixelRatio);\n var height = Math.round(frameState.size[1] * tilePixelRatio);\n\n if (rotation) {\n var size = Math.round(Math.sqrt(width * width + height * height));\n width = size;\n height = size;\n }\n\n var dx = tileResolution * width / 2 / tilePixelRatio;\n var dy = tileResolution * height / 2 / tilePixelRatio;\n var canvasExtent = [viewCenter[0] - dx, viewCenter[1] - dy, viewCenter[0] + dx, viewCenter[1] + dy];\n var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);\n /**\n * @type {Object<number, Object<string, import("../../Tile.js").default>>}\n */\n\n var tilesToDrawByZ = {};\n tilesToDrawByZ[z] = {};\n var findLoadedTiles = this.createLoadedTileFinder(tileSource, projection, tilesToDrawByZ);\n var tmpExtent = this.tmpExtent;\n var tmpTileRange = this.tmpTileRange_;\n this.newTiles_ = false;\n\n for (var x = tileRange.minX; x <= tileRange.maxX; ++x) {\n for (var y = tileRange.minY; y <= tileRange.maxY; ++y) {\n var tile = this.getTile(z, x, y, frameState);\n\n if (this.isDrawableTile(tile)) {\n var uid = getUid(this);\n\n if (tile.getState() == TileState.LOADED) {\n tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;\n var inTransition = tile.inTransition(uid);\n\n if (!this.newTiles_ && (inTransition || this.renderedTiles.indexOf(tile) === -1)) {\n this.newTiles_ = true;\n }\n }\n\n if (tile.getAlpha(uid, frameState.time) === 1) {\n // don\'t look for alt tiles if alpha is 1\n continue;\n }\n }\n\n var childTileRange = tileGrid.getTileCoordChildTileRange(tile.tileCoord, tmpTileRange, tmpExtent);\n var covered = false;\n\n if (childTileRange) {\n covered = findLoadedTiles(z + 1, childTileRange);\n }\n\n if (!covered) {\n tileGrid.forEachTileCoordParentTileRange(tile.tileCoord, findLoadedTiles, tmpTileRange, tmpExtent);\n }\n }\n }\n\n var canvasScale = tileResolution / viewResolution; // set forward and inverse pixel transforms\n\n compose(this.pixelTransform, frameState.size[0] / 2, frameState.size[1] / 2, 1 / tilePixelRatio, 1 / tilePixelRatio, rotation, -width / 2, -height / 2);\n var canvasTransform = createTransformString(this.pixelTransform);\n this.useContainer(target, canvasTransform, layerState.opacity);\n var context = this.context;\n var canvas = context.canvas;\n makeInverse(this.inversePixelTransform, this.pixelTransform); // set scale transform for calculating tile positions on the canvas\n\n compose(this.tempTransform, width / 2, height / 2, canvasScale, canvasScale, 0, -width / 2, -height / 2);\n\n if (canvas.width != width || canvas.height != height) {\n canvas.width = width;\n canvas.height = height;\n } else if (!this.containerReused) {\n context.clearRect(0, 0, width, height);\n }\n\n if (layerExtent) {\n this.clipUnrotated(context, frameState, layerExtent);\n }\n\n obj_assign(context, tileSource.getContextOptions());\n this.preRender(context, frameState);\n this.renderedTiles.length = 0;\n /** @type {Array<number>} */\n\n var zs = Object.keys(tilesToDrawByZ).map(Number);\n zs.sort(numberSafeCompareFunction);\n var clips, clipZs, currentClip;\n\n if (layerState.opacity === 1 && (!this.containerReused || tileSource.getOpaque(frameState.viewState.projection))) {\n zs = zs.reverse();\n } else {\n clips = [];\n clipZs = [];\n }\n\n for (var i = zs.length - 1; i >= 0; --i) {\n var currentZ = zs[i];\n var currentTilePixelSize = tileSource.getTilePixelSize(currentZ, pixelRatio, projection);\n var currentResolution = tileGrid.getResolution(currentZ);\n var currentScale = currentResolution / tileResolution;\n var dx_1 = currentTilePixelSize[0] * currentScale * canvasScale;\n var dy_1 = currentTilePixelSize[1] * currentScale * canvasScale;\n var originTileCoord = tileGrid.getTileCoordForCoordAndZ(getTopLeft(canvasExtent), currentZ);\n var originTileExtent = tileGrid.getTileCoordExtent(originTileCoord);\n var origin_1 = apply(this.tempTransform, [tilePixelRatio * (originTileExtent[0] - canvasExtent[0]) / tileResolution, tilePixelRatio * (canvasExtent[3] - originTileExtent[3]) / tileResolution]);\n var tileGutter = tilePixelRatio * tileSource.getGutterForProjection(projection);\n var tilesToDraw = tilesToDrawByZ[currentZ];\n\n for (var tileCoordKey in tilesToDraw) {\n var tile =\n /** @type {import("../../ImageTile.js").default} */\n tilesToDraw[tileCoordKey];\n var tileCoord = tile.tileCoord; // Calculate integer positions and sizes so that tiles align\n\n var floatX = origin_1[0] - (originTileCoord[1] - tileCoord[1]) * dx_1;\n var nextX = Math.round(floatX + dx_1);\n var floatY = origin_1[1] - (originTileCoord[2] - tileCoord[2]) * dy_1;\n var nextY = Math.round(floatY + dy_1);\n var x = Math.round(floatX);\n var y = Math.round(floatY);\n var w = nextX - x;\n var h = nextY - y;\n var transition = z === currentZ;\n var inTransition = transition && tile.getAlpha(getUid(this), frameState.time) !== 1;\n\n if (!inTransition) {\n if (clips) {\n // Clip mask for regions in this tile that already filled by a higher z tile\n context.save();\n currentClip = [x, y, x + w, y, x + w, y + h, x, y + h];\n\n for (var i_1 = 0, ii = clips.length; i_1 < ii; ++i_1) {\n if (z !== currentZ && currentZ < clipZs[i_1]) {\n var clip = clips[i_1];\n context.beginPath(); // counter-clockwise (outer ring) for current tile\n\n context.moveTo(currentClip[0], currentClip[1]);\n context.lineTo(currentClip[2], currentClip[3]);\n context.lineTo(currentClip[4], currentClip[5]);\n context.lineTo(currentClip[6], currentClip[7]); // clockwise (inner ring) for higher z tile\n\n context.moveTo(clip[6], clip[7]);\n context.lineTo(clip[4], clip[5]);\n context.lineTo(clip[2], clip[3]);\n context.lineTo(clip[0], clip[1]);\n context.clip();\n }\n }\n\n clips.push(currentClip);\n clipZs.push(currentZ);\n } else {\n context.clearRect(x, y, w, h);\n }\n }\n\n this.drawTileImage(tile, frameState, x, y, w, h, tileGutter, transition, layerState.opacity);\n\n if (clips && !inTransition) {\n context.restore();\n }\n\n this.renderedTiles.push(tile);\n this.updateUsedTiles(frameState.usedTiles, tileSource, tile);\n }\n }\n\n this.renderedRevision = sourceRevision;\n this.renderedResolution = tileResolution;\n this.extentChanged = !this.renderedExtent_ || !extent_equals(this.renderedExtent_, canvasExtent);\n this.renderedExtent_ = canvasExtent;\n this.renderedPixelRatio = pixelRatio;\n this.renderedProjection = projection;\n this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio, projection, extent, z, tileLayer.getPreload());\n this.scheduleExpireCache(frameState, tileSource);\n this.postRender(context, frameState);\n\n if (layerState.extent) {\n context.restore();\n }\n\n if (canvasTransform !== canvas.style.transform) {\n canvas.style.transform = canvasTransform;\n }\n\n return this.container;\n };\n /**\n * @param {import("../../ImageTile.js").default} tile Tile.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {number} x Left of the tile.\n * @param {number} y Top of the tile.\n * @param {number} w Width of the tile.\n * @param {number} h Height of the tile.\n * @param {number} gutter Tile gutter.\n * @param {boolean} transition Apply an alpha transition.\n * @param {number} opacity Opacity.\n */\n\n\n CanvasTileLayerRenderer.prototype.drawTileImage = function (tile, frameState, x, y, w, h, gutter, transition, opacity) {\n var image = this.getTileImage(tile);\n\n if (!image) {\n return;\n }\n\n var uid = getUid(this);\n var tileAlpha = transition ? tile.getAlpha(uid, frameState.time) : 1;\n var alpha = opacity * tileAlpha;\n var alphaChanged = alpha !== this.context.globalAlpha;\n\n if (alphaChanged) {\n this.context.save();\n this.context.globalAlpha = alpha;\n }\n\n this.context.drawImage(image, gutter, gutter, image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h);\n\n if (alphaChanged) {\n this.context.restore();\n }\n\n if (tileAlpha !== 1) {\n frameState.animate = true;\n } else if (transition) {\n tile.endTransition(uid);\n }\n };\n /**\n * @return {HTMLCanvasElement} Image\n */\n\n\n CanvasTileLayerRenderer.prototype.getImage = function () {\n var context = this.context;\n return context ? context.canvas : null;\n };\n /**\n * Get the image from a tile.\n * @param {import("../../ImageTile.js").default} tile Tile.\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n * @protected\n */\n\n\n CanvasTileLayerRenderer.prototype.getTileImage = function (tile) {\n return tile.getImage();\n };\n /**\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {import("../../source/Tile.js").default} tileSource Tile source.\n * @protected\n */\n\n\n CanvasTileLayerRenderer.prototype.scheduleExpireCache = function (frameState, tileSource) {\n if (tileSource.canExpireCache()) {\n /**\n * @param {import("../../source/Tile.js").default} tileSource Tile source.\n * @param {import("../../PluggableMap.js").default} map Map.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n */\n var postRenderFunction = function (tileSource, map, frameState) {\n var tileSourceKey = getUid(tileSource);\n\n if (tileSourceKey in frameState.usedTiles) {\n tileSource.expireCache(frameState.viewState.projection, frameState.usedTiles[tileSourceKey]);\n }\n }.bind(null, tileSource);\n\n frameState.postRenderFunctions.push(\n /** @type {import("../../PluggableMap.js").PostRenderFunction} */\n postRenderFunction);\n }\n };\n /**\n * @param {!Object<string, !Object<string, boolean>>} usedTiles Used tiles.\n * @param {import("../../source/Tile.js").default} tileSource Tile source.\n * @param {import(\'../../Tile.js\').default} tile Tile.\n * @protected\n */\n\n\n CanvasTileLayerRenderer.prototype.updateUsedTiles = function (usedTiles, tileSource, tile) {\n // FIXME should we use tilesToDrawByZ instead?\n var tileSourceKey = getUid(tileSource);\n\n if (!(tileSourceKey in usedTiles)) {\n usedTiles[tileSourceKey] = {};\n }\n\n usedTiles[tileSourceKey][tile.getKey()] = true;\n };\n /**\n * Manage tile pyramid.\n * This function performs a number of functions related to the tiles at the\n * current zoom and lower zoom levels:\n * - registers idle tiles in frameState.wantedTiles so that they are not\n * discarded by the tile queue\n * - enqueues missing tiles\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {import("../../source/Tile.js").default} tileSource Tile source.\n * @param {import("../../tilegrid/TileGrid.js").default} tileGrid Tile grid.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../../proj/Projection.js").default} projection Projection.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @param {number} currentZ Current Z.\n * @param {number} preload Load low resolution tiles up to \'preload\' levels.\n * @param {function(import("../../Tile.js").default)=} opt_tileCallback Tile callback.\n * @protected\n */\n\n\n CanvasTileLayerRenderer.prototype.manageTilePyramid = function (frameState, tileSource, tileGrid, pixelRatio, projection, extent, currentZ, preload, opt_tileCallback) {\n var tileSourceKey = getUid(tileSource);\n\n if (!(tileSourceKey in frameState.wantedTiles)) {\n frameState.wantedTiles[tileSourceKey] = {};\n }\n\n var wantedTiles = frameState.wantedTiles[tileSourceKey];\n var tileQueue = frameState.tileQueue;\n var minZoom = tileGrid.getMinZoom();\n var tileCount = 0;\n var tile, tileRange, tileResolution, x, y, z;\n\n for (z = minZoom; z <= currentZ; ++z) {\n tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z, tileRange);\n tileResolution = tileGrid.getResolution(z);\n\n for (x = tileRange.minX; x <= tileRange.maxX; ++x) {\n for (y = tileRange.minY; y <= tileRange.maxY; ++y) {\n if (currentZ - z <= preload) {\n ++tileCount;\n tile = tileSource.getTile(z, x, y, pixelRatio, projection);\n\n if (tile.getState() == TileState.IDLE) {\n wantedTiles[tile.getKey()] = true;\n\n if (!tileQueue.isKeyQueued(tile.getKey())) {\n tileQueue.enqueue([tile, tileSourceKey, tileGrid.getTileCoordCenter(tile.tileCoord), tileResolution]);\n }\n }\n\n if (opt_tileCallback !== undefined) {\n opt_tileCallback(tile);\n }\n } else {\n tileSource.useTile(z, x, y, projection);\n }\n }\n }\n }\n\n tileSource.updateCacheSize(tileCount, projection);\n };\n\n return CanvasTileLayerRenderer;\n}(canvas_Layer);\n/**\n * @function\n * @return {import("../../layer/Tile.js").default|import("../../layer/VectorTile.js").default}\n */\n\n\nCanvasTileLayerRenderer.prototype.getLayer;\n/* harmony default export */ var canvas_TileLayer = (CanvasTileLayerRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Tile.js\nvar Tile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/Tile\n */\n\n\n\n\n/**\n * @classdesc\n * For layer sources that provide pre-rendered, tiled images in grids that are\n * organized by zoom levels for specific resolutions.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: \'My Title\'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @api\n */\n\nvar TileLayer =\n/** @class */\nfunction (_super) {\n Tile_extends(TileLayer, _super);\n /**\n * @param {import("./BaseTile.js").Options=} opt_options Tile layer options.\n */\n\n\n function TileLayer(opt_options) {\n return _super.call(this, opt_options) || this;\n }\n /**\n * Create a renderer for this layer.\n * @return {import("../renderer/Layer.js").default} A layer renderer.\n * @protected\n */\n\n\n TileLayer.prototype.createRenderer = function () {\n return new canvas_TileLayer(this);\n };\n\n return TileLayer;\n}(BaseTile);\n\n/* harmony default export */ var Tile = (TileLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/VectorTileRenderType.js\n/**\n * @module ol/layer/VectorTileRenderType\n */\n\n/**\n * @enum {string}\n * Render mode for vector tiles:\n * * `\'image\'`: Vector tiles are rendered as images. Great performance, but\n * point symbols and texts are always rotated with the view and pixels are\n * scaled during zoom animations.\n * * `\'hybrid\'`: Polygon and line elements are rendered as images, so pixels\n * are scaled during zoom animations. Point symbols and texts are accurately\n * rendered as vectors and can stay upright on rotated views.\n * * `\'vector\'`: Everything is rendered as vectors. Use this mode for improved\n * performance on vector tile layers with only a few rendered features (e.g.\n * for highlighting a subset of features of another layer with the same\n * source).\n * @api\n */\n/* harmony default export */ var VectorTileRenderType = ({\n IMAGE: \'image\',\n HYBRID: \'hybrid\',\n VECTOR: \'vector\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/VectorTileLayer.js\nvar VectorTileLayer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/canvas/VectorTileLayer\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @type {!Object<string, Array<import("../../render/canvas/BuilderType.js").default>>}\n */\n\nvar IMAGE_REPLAYS = {\n \'image\': [BuilderType.POLYGON, BuilderType.CIRCLE, BuilderType.LINE_STRING, BuilderType.IMAGE, BuilderType.TEXT],\n \'hybrid\': [BuilderType.POLYGON, BuilderType.LINE_STRING],\n \'vector\': []\n};\n/**\n * @type {!Object<string, Array<import("../../render/canvas/BuilderType.js").default>>}\n */\n\nvar VECTOR_REPLAYS = {\n \'image\': [BuilderType.DEFAULT],\n \'hybrid\': [BuilderType.IMAGE, BuilderType.TEXT, BuilderType.DEFAULT],\n \'vector\': [BuilderType.POLYGON, BuilderType.CIRCLE, BuilderType.LINE_STRING, BuilderType.IMAGE, BuilderType.TEXT, BuilderType.DEFAULT]\n};\n/**\n * @classdesc\n * Canvas renderer for vector tile layers.\n * @api\n */\n\nvar CanvasVectorTileLayerRenderer =\n/** @class */\nfunction (_super) {\n VectorTileLayer_extends(CanvasVectorTileLayerRenderer, _super);\n /**\n * @param {import("../../layer/VectorTile.js").default} layer VectorTile layer.\n */\n\n\n function CanvasVectorTileLayerRenderer(layer) {\n var _this = _super.call(this, layer) || this;\n /** @private */\n\n\n _this.boundHandleStyleImageChange_ = _this.handleStyleImageChange_.bind(_this);\n /**\n * @private\n * @type {boolean}\n */\n\n _this.dirty_ = false;\n /**\n * @private\n * @type {number}\n */\n\n _this.renderedLayerRevision_;\n /**\n * @private\n * @type {import("../../transform").Transform}\n */\n\n _this.renderedPixelToCoordinateTransform_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.renderedRotation_;\n /**\n * @private\n * @type {!Object<string, import("../../VectorRenderTile.js").default>}\n */\n\n _this.renderTileImageQueue_ = {};\n /**\n * @type {Object<string, import("../../events.js").EventsKey>}\n */\n\n _this.tileListenerKeys_ = {};\n /**\n * @private\n * @type {import("../../transform.js").Transform}\n */\n\n _this.tmpTransform_ = create();\n return _this;\n }\n /**\n * @param {import("../../VectorRenderTile.js").default} tile Tile.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../../proj/Projection").default} projection Projection.\n * @param {boolean} queue Queue tile for rendering.\n * @return {boolean|undefined} Tile needs to be rendered.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.prepareTile = function (tile, pixelRatio, projection, queue) {\n var render;\n var tileUid = getUid(tile);\n var state = tile.getState();\n\n if ((state === TileState.LOADED && tile.hifi || state === TileState.ERROR) && tileUid in this.tileListenerKeys_) {\n unlistenByKey(this.tileListenerKeys_[tileUid]);\n delete this.tileListenerKeys_[tileUid];\n }\n\n if (state === TileState.LOADED || state === TileState.ERROR) {\n this.updateExecutorGroup_(tile, pixelRatio, projection);\n\n if (this.tileImageNeedsRender_(tile, pixelRatio, projection)) {\n render = true;\n\n if (queue) {\n this.renderTileImageQueue_[tileUid] = tile;\n }\n }\n }\n\n return render;\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @return {!import("../../Tile.js").default} Tile.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.getTile = function (z, x, y, frameState) {\n var pixelRatio = frameState.pixelRatio;\n var viewState = frameState.viewState;\n var resolution = viewState.resolution;\n var projection = viewState.projection;\n var layer = this.getLayer();\n var tile = layer.getSource().getTile(z, x, y, pixelRatio, projection);\n\n if (tile.getState() < TileState.LOADED) {\n tile.wantedResolution = resolution;\n var tileUid = getUid(tile);\n\n if (!(tileUid in this.tileListenerKeys_)) {\n var listenerKey = listen(tile, EventType.CHANGE, this.prepareTile.bind(this, tile, pixelRatio, projection, true));\n this.tileListenerKeys_[tileUid] = listenerKey;\n }\n } else {\n var viewHints = frameState.viewHints;\n var hifi = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);\n\n if (hifi || !tile.wantedResolution) {\n tile.wantedResolution = resolution;\n }\n\n var render = this.prepareTile(tile, pixelRatio, projection, false);\n\n if (render && layer.getRenderMode() !== VectorTileRenderType.VECTOR) {\n this.renderTileImage_(tile, frameState);\n }\n }\n\n return _super.prototype.getTile.call(this, z, x, y, frameState);\n };\n /**\n * @param {import("../../VectorRenderTile.js").default} tile Tile.\n * @return {boolean} Tile is drawable.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.isDrawableTile = function (tile) {\n var layer = this.getLayer();\n return _super.prototype.isDrawableTile.call(this, tile) && (layer.getRenderMode() === VectorTileRenderType.VECTOR ? getUid(layer) in tile.executorGroups : tile.hasContext(layer));\n };\n /**\n * @inheritDoc\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.getTileImage = function (tile) {\n return tile.getImage(this.getLayer());\n };\n /**\n * Determine whether render should be called.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.prepareFrame = function (frameState) {\n var layerRevision = this.getLayer().getRevision();\n\n if (this.renderedLayerRevision_ != layerRevision) {\n this.renderedTiles.length = 0;\n }\n\n this.renderedLayerRevision_ = layerRevision;\n return _super.prototype.prepareFrame.call(this, frameState);\n };\n /**\n * @param {import("../../VectorRenderTile.js").default} tile Tile.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../../proj/Projection.js").default} projection Projection.\n * @private\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.updateExecutorGroup_ = function (tile, pixelRatio, projection) {\n var layer =\n /** @type {import("../../layer/VectorTile.js").default} */\n this.getLayer();\n var revision = layer.getRevision();\n var renderOrder = layer.getRenderOrder() || null;\n var resolution = tile.wantedResolution;\n var builderState = tile.getReplayState(layer);\n\n if (!builderState.dirty && builderState.renderedResolution === resolution && builderState.renderedRevision == revision && builderState.renderedRenderOrder == renderOrder && builderState.renderedZ === tile.sourceZ) {\n return;\n }\n\n var source = layer.getSource();\n var declutter = layer.getDeclutter();\n var sourceTileGrid = source.getTileGrid();\n var tileGrid = source.getTileGridForProjection(projection);\n var tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);\n var sourceTiles = source.getSourceTiles(pixelRatio, projection, tile);\n var layerUid = getUid(layer);\n delete tile.hitDetectionImageData[layerUid];\n tile.executorGroups[layerUid] = [];\n\n if (declutter) {\n tile.declutterExecutorGroups[layerUid] = [];\n }\n\n var _loop_1 = function _loop_1(t, tt) {\n var sourceTile = sourceTiles[t];\n\n if (sourceTile.getState() != TileState.LOADED) {\n return "continue";\n }\n\n var sourceTileCoord = sourceTile.tileCoord;\n var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);\n var sharedExtent = getIntersection(tileExtent, sourceTileExtent);\n var bufferedExtent = extent_equals(sourceTileExtent, sharedExtent) ? null : buffer(sharedExtent, layer.getRenderBuffer() * resolution, this_1.tmpExtent);\n builderState.dirty = false;\n var builderGroup = new canvas_BuilderGroup(0, sharedExtent, resolution, pixelRatio);\n var declutterBuilderGroup = declutter ? new canvas_BuilderGroup(0, sharedExtent, resolution, pixelRatio) : undefined;\n var squaredTolerance = getSquaredTolerance(resolution, pixelRatio);\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @this {CanvasVectorTileLayerRenderer}\n */\n\n var render = function render(feature) {\n var styles;\n var styleFunction = feature.getStyleFunction() || layer.getStyleFunction();\n\n if (styleFunction) {\n styles = styleFunction(feature, resolution);\n }\n\n if (styles) {\n var dirty = this.renderFeature(feature, squaredTolerance, styles, builderGroup, declutterBuilderGroup);\n this.dirty_ = this.dirty_ || dirty;\n builderState.dirty = builderState.dirty || dirty;\n }\n };\n\n var features = sourceTile.getFeatures();\n\n if (renderOrder && renderOrder !== builderState.renderedRenderOrder) {\n features.sort(renderOrder);\n }\n\n for (var i = 0, ii = features.length; i < ii; ++i) {\n var feature = features[i];\n\n if (!bufferedExtent || intersects(bufferedExtent, feature.getGeometry().getExtent())) {\n render.call(this_1, feature);\n }\n }\n\n var executorGroupInstructions = builderGroup.finish(); // no need to clip when the render tile is covered by a single source tile\n\n var replayExtent = layer.getRenderMode() !== VectorTileRenderType.VECTOR && declutter && sourceTiles.length === 1 ? null : sharedExtent;\n var renderingReplayGroup = new canvas_ExecutorGroup(replayExtent, resolution, pixelRatio, source.getOverlaps(), executorGroupInstructions, layer.getRenderBuffer());\n tile.executorGroups[layerUid].push(renderingReplayGroup);\n\n if (declutterBuilderGroup) {\n var declutterExecutorGroup = new canvas_ExecutorGroup(replayExtent, resolution, pixelRatio, source.getOverlaps(), declutterBuilderGroup.finish(), layer.getRenderBuffer());\n tile.declutterExecutorGroups[layerUid].push(declutterExecutorGroup);\n }\n };\n\n var this_1 = this;\n\n for (var t = 0, tt = sourceTiles.length; t < tt; ++t) {\n _loop_1(t, tt);\n }\n\n builderState.renderedRevision = revision;\n builderState.renderedZ = tile.sourceZ;\n builderState.renderedRenderOrder = renderOrder;\n builderState.renderedResolution = resolution;\n };\n /**\n * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {import("../vector.js").FeatureCallback<T>} callback Feature callback.\n * @param {Array<import("../Map.js").HitMatch<T>>} matches The hit detected matches with tolerance.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, callback, matches) {\n var resolution = frameState.viewState.resolution;\n var rotation = frameState.viewState.rotation;\n hitTolerance = hitTolerance == undefined ? 0 : hitTolerance;\n var layer = this.getLayer();\n var source = layer.getSource();\n var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);\n var hitExtent = boundingExtent([coordinate]);\n buffer(hitExtent, resolution * hitTolerance, hitExtent);\n /** @type {!Object<string, import("../Map.js").HitMatch<T>|true>} */\n\n var features = {};\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.\n * @param {number} distanceSq The squared distance to the click position.\n * @return {T|undefined} Callback result.\n */\n\n var featureCallback = function featureCallback(feature, geometry, distanceSq) {\n var key = feature.getId();\n\n if (key === undefined) {\n key = getUid(feature);\n }\n\n var match = features[key];\n\n if (!match) {\n if (distanceSq === 0) {\n features[key] = true;\n return callback(feature, layer, geometry);\n }\n\n matches.push(features[key] = {\n feature: feature,\n layer: layer,\n geometry: geometry,\n distanceSq: distanceSq,\n callback: callback\n });\n } else if (match !== true && distanceSq < match.distanceSq) {\n if (distanceSq === 0) {\n features[key] = true;\n matches.splice(matches.lastIndexOf(match), 1);\n return callback(feature, layer, geometry);\n }\n\n match.geometry = geometry;\n match.distanceSq = distanceSq;\n }\n\n return undefined;\n };\n\n var renderedTiles =\n /** @type {Array<import("../../VectorRenderTile.js").default>} */\n this.renderedTiles;\n var found;\n\n var _loop_2 = function _loop_2(i, ii) {\n var tile = renderedTiles[i];\n var tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);\n\n if (!intersects(tileExtent, hitExtent)) {\n return "continue";\n }\n\n var layerUid = getUid(layer);\n var executorGroups = [tile.executorGroups[layerUid]];\n var declutterExecutorGroups = tile.declutterExecutorGroups[layerUid];\n\n if (declutterExecutorGroups) {\n executorGroups.push(declutterExecutorGroups);\n }\n\n executorGroups.some(function (executorGroups) {\n var declutteredFeatures = executorGroups === declutterExecutorGroups ? frameState.declutterTree.all().map(function (item) {\n return item.value;\n }) : null;\n\n for (var t = 0, tt = executorGroups.length; t < tt; ++t) {\n var executorGroup = executorGroups[t];\n found = executorGroup.forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, featureCallback, declutteredFeatures);\n\n if (found) {\n return true;\n }\n }\n });\n };\n\n for (var i = 0, ii = renderedTiles.length; !found && i < ii; ++i) {\n _loop_2(i, ii);\n }\n\n return found;\n };\n /**\n * Asynchronous layer level hit detection.\n * @param {import("../../pixel.js").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../../Feature").default>>} Promise that resolves with an array of features.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.getFeatures = function (pixel) {\n return new Promise(function (resolve, reject) {\n var layer =\n /** @type {import("../../layer/VectorTile.js").default} */\n this.getLayer();\n var layerUid = getUid(layer);\n var source = layer.getSource();\n var projection = this.renderedProjection;\n var projectionExtent = projection.getExtent();\n var resolution = this.renderedResolution;\n var tileGrid = source.getTileGridForProjection(projection);\n var coordinate = apply(this.renderedPixelToCoordinateTransform_, pixel.slice());\n var tileCoord = tileGrid.getTileCoordForCoordAndResolution(coordinate, resolution);\n var tile;\n\n for (var i = 0, ii = this.renderedTiles.length; i < ii; ++i) {\n if (tileCoord.toString() === this.renderedTiles[i].tileCoord.toString()) {\n tile = this.renderedTiles[i];\n\n if (tile.getState() === TileState.LOADED && tile.hifi) {\n var extent_1 = tileGrid.getTileCoordExtent(tile.tileCoord);\n\n if (source.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, extent_1)) {\n coordinate_wrapX(coordinate, projection);\n }\n\n break;\n }\n\n tile = undefined;\n }\n }\n\n if (!tile || tile.loadingSourceTiles > 0) {\n resolve([]);\n return;\n }\n\n var extent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);\n var corner = getTopLeft(extent);\n var tilePixel = [(coordinate[0] - corner[0]) / resolution, (corner[1] - coordinate[1]) / resolution];\n var features = tile.getSourceTiles().reduce(function (accumulator, sourceTile) {\n return accumulator.concat(sourceTile.getFeatures());\n }, []);\n var hitDetectionImageData = tile.hitDetectionImageData[layerUid];\n\n if (!hitDetectionImageData && !this.animatingOrInteracting_) {\n var tileSize = toSize(tileGrid.getTileSize(tileGrid.getZForResolution(resolution)));\n var size = [tileSize[0] / 2, tileSize[1] / 2];\n var rotation = this.renderedRotation_;\n var transforms = [this.getRenderTransform(tileGrid.getTileCoordCenter(tile.wrappedTileCoord), resolution, 0, 0.5, size[0], size[1], 0)];\n hitDetectionImageData = createHitDetectionImageData(tileSize, transforms, features, layer.getStyleFunction(), tileGrid.getTileCoordExtent(tile.wrappedTileCoord), tile.getReplayState(layer).renderedResolution, rotation);\n tile.hitDetectionImageData[layerUid] = hitDetectionImageData;\n }\n\n resolve(hitDetect(tilePixel, features, hitDetectionImageData));\n }.bind(this));\n };\n /**\n * Perform action necessary to get the layer rendered after new fonts have loaded\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.handleFontsChanged = function () {\n clear(this.renderTileImageQueue_);\n var layer = this.getLayer();\n\n if (layer.getVisible() && this.renderedLayerRevision_ !== undefined) {\n layer.changed();\n }\n };\n /**\n * Handle changes in image style state.\n * @param {import("../../events/Event.js").default} event Image style change event.\n * @private\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.handleStyleImageChange_ = function (event) {\n this.renderIfReadyAndVisible();\n };\n /**\n * Render declutter items for this layer\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.renderDeclutter = function (frameState) {\n var viewHints = frameState.viewHints;\n var hifi = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);\n var tiles =\n /** @type {Array<import("../../VectorRenderTile.js").default>} */\n this.renderedTiles;\n\n for (var i = 0, ii = tiles.length; i < ii; ++i) {\n var tile = tiles[i];\n var declutterExecutorGroups = tile.declutterExecutorGroups[getUid(this.getLayer())];\n\n if (declutterExecutorGroups) {\n for (var j = declutterExecutorGroups.length - 1; j >= 0; --j) {\n declutterExecutorGroups[j].execute(this.context, 1, this.getTileRenderTransform(tile, frameState), frameState.viewState.rotation, hifi, undefined, frameState.declutterTree);\n }\n }\n }\n };\n\n CanvasVectorTileLayerRenderer.prototype.getTileRenderTransform = function (tile, frameState) {\n var pixelRatio = frameState.pixelRatio;\n var viewState = frameState.viewState;\n var center = viewState.center;\n var resolution = viewState.resolution;\n var rotation = viewState.rotation;\n var size = frameState.size;\n var width = Math.round(size[0] * pixelRatio);\n var height = Math.round(size[1] * pixelRatio);\n var source = this.getLayer().getSource();\n var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);\n var tileCoord = tile.tileCoord;\n var tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);\n var worldOffset = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent)[0] - tileExtent[0];\n var transform = multiply(scale(this.inversePixelTransform.slice(), 1 / pixelRatio, 1 / pixelRatio), this.getRenderTransform(center, resolution, rotation, pixelRatio, width, height, worldOffset));\n return transform;\n };\n /**\n * Render the layer.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.renderFrame = function (frameState, target) {\n var viewHints = frameState.viewHints;\n var hifi = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);\n this.renderQueuedTileImages_(hifi, frameState);\n\n _super.prototype.renderFrame.call(this, frameState, target);\n\n this.renderedPixelToCoordinateTransform_ = frameState.pixelToCoordinateTransform.slice();\n this.renderedRotation_ = frameState.viewState.rotation;\n var layer =\n /** @type {import("../../layer/VectorTile.js").default} */\n this.getLayer();\n var renderMode = layer.getRenderMode();\n\n if (renderMode === VectorTileRenderType.IMAGE) {\n return this.container;\n }\n\n var source = layer.getSource(); // Unqueue tiles from the image queue when we don\'t need any more\n\n var usedTiles = frameState.usedTiles[getUid(source)];\n\n for (var tileUid in this.renderTileImageQueue_) {\n if (!usedTiles || !(tileUid in usedTiles)) {\n delete this.renderTileImageQueue_[tileUid];\n }\n }\n\n var context = this.context;\n var replayTypes = VECTOR_REPLAYS[renderMode];\n var viewState = frameState.viewState;\n var rotation = viewState.rotation;\n var tiles = this.renderedTiles;\n var clips = [];\n var clipZs = [];\n\n for (var i = tiles.length - 1; i >= 0; --i) {\n var tile =\n /** @type {import("../../VectorRenderTile.js").default} */\n tiles[i];\n var transform = this.getTileRenderTransform(tile, frameState);\n var executorGroups = tile.executorGroups[getUid(layer)];\n var clipped = false;\n\n for (var t = 0, tt = executorGroups.length; t < tt; ++t) {\n var executorGroup = executorGroups[t];\n\n if (!executorGroup.hasExecutors(replayTypes)) {\n // sourceTile has no instructions of the types we want to render\n continue;\n }\n\n var currentZ = tile.tileCoord[0];\n var currentClip = void 0;\n\n if (!clipped) {\n currentClip = executorGroup.getClipCoords(transform);\n\n if (currentClip) {\n context.save(); // Create a clip mask for regions in this low resolution tile that are\n // already filled by a higher resolution tile\n\n for (var j = 0, jj = clips.length; j < jj; ++j) {\n var clip = clips[j];\n\n if (currentZ < clipZs[j]) {\n context.beginPath(); // counter-clockwise (outer ring) for current tile\n\n context.moveTo(currentClip[0], currentClip[1]);\n context.lineTo(currentClip[2], currentClip[3]);\n context.lineTo(currentClip[4], currentClip[5]);\n context.lineTo(currentClip[6], currentClip[7]); // clockwise (inner ring) for higher resolution tile\n\n context.moveTo(clip[6], clip[7]);\n context.lineTo(clip[4], clip[5]);\n context.lineTo(clip[2], clip[3]);\n context.lineTo(clip[0], clip[1]);\n context.clip();\n }\n }\n }\n }\n\n executorGroup.execute(context, 1, transform, rotation, hifi, replayTypes);\n\n if (!clipped && currentClip) {\n context.restore();\n clips.push(currentClip);\n clipZs.push(currentZ);\n clipped = true;\n }\n }\n }\n\n return this.container;\n };\n /**\n * @param {boolean} hifi We have time to render a high fidelity map image.\n * @param {import(\'../../PluggableMap.js\').FrameState} frameState Frame state.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.renderQueuedTileImages_ = function (hifi, frameState) {\n // When we don\'t have time to render hifi, only render tiles until we have used up\n // half of the frame budget of 16 ms\n for (var uid in this.renderTileImageQueue_) {\n if (!hifi && Date.now() - frameState.time > 8) {\n frameState.animate = true;\n break;\n }\n\n var tile = this.renderTileImageQueue_[uid];\n delete this.renderTileImageQueue_[uid];\n this.renderTileImage_(tile, frameState);\n }\n };\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import("../../style/Style.js").default|Array<import("../../style/Style.js").default>} styles The style or array of styles.\n * @param {import("../../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder group for decluttering.\n * @return {boolean} `true` if an image is loading.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.renderFeature = function (feature, squaredTolerance, styles, builderGroup, opt_declutterBuilderGroup) {\n if (!styles) {\n return false;\n }\n\n var loading = false;\n\n if (Array.isArray(styles)) {\n for (var i = 0, ii = styles.length; i < ii; ++i) {\n loading = renderFeature(builderGroup, feature, styles[i], squaredTolerance, this.boundHandleStyleImageChange_, undefined, opt_declutterBuilderGroup) || loading;\n }\n } else {\n loading = renderFeature(builderGroup, feature, styles, squaredTolerance, this.boundHandleStyleImageChange_, undefined, opt_declutterBuilderGroup);\n }\n\n return loading;\n };\n /**\n * @param {import("../../VectorRenderTile.js").default} tile Tile.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../../proj/Projection.js").default} projection Projection.\n * @return {boolean} A new tile image was rendered.\n * @private\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.tileImageNeedsRender_ = function (tile, pixelRatio, projection) {\n var layer =\n /** @type {import("../../layer/VectorTile.js").default} */\n this.getLayer();\n var replayState = tile.getReplayState(layer);\n var revision = layer.getRevision();\n var sourceZ = tile.sourceZ;\n var resolution = tile.wantedResolution;\n return replayState.renderedTileResolution !== resolution || replayState.renderedTileRevision !== revision || replayState.renderedTileZ !== sourceZ;\n };\n /**\n * @param {import("../../VectorRenderTile.js").default} tile Tile.\n * @param {import("../../PluggableMap").FrameState} frameState Frame state.\n * @private\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.renderTileImage_ = function (tile, frameState) {\n var layer =\n /** @type {import("../../layer/VectorTile.js").default} */\n this.getLayer();\n var replayState = tile.getReplayState(layer);\n var revision = layer.getRevision();\n var executorGroups = tile.executorGroups[getUid(layer)];\n replayState.renderedTileRevision = revision;\n replayState.renderedTileZ = tile.sourceZ;\n var tileCoord = tile.wrappedTileCoord;\n var z = tileCoord[0];\n var source = layer.getSource();\n var pixelRatio = frameState.pixelRatio;\n var viewState = frameState.viewState;\n var projection = viewState.projection;\n var tileGrid = source.getTileGridForProjection(projection);\n var tileResolution = tileGrid.getResolution(tile.tileCoord[0]);\n var renderPixelRatio = frameState.pixelRatio / tile.wantedResolution * tileResolution;\n var resolution = tileGrid.getResolution(z);\n var context = tile.getContext(layer); // Increase tile size when overzooming for low pixel ratio, to avoid blurry tiles\n\n pixelRatio = Math.round(Math.max(pixelRatio, renderPixelRatio / pixelRatio));\n var size = source.getTilePixelSize(z, pixelRatio, projection);\n context.canvas.width = size[0];\n context.canvas.height = size[1];\n var renderScale = pixelRatio / renderPixelRatio;\n\n if (renderScale !== 1) {\n var canvasTransform = transform_reset(this.tmpTransform_);\n scale(canvasTransform, renderScale, renderScale);\n context.setTransform.apply(context, canvasTransform);\n }\n\n var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);\n var pixelScale = renderPixelRatio / resolution;\n var transform = transform_reset(this.tmpTransform_);\n scale(transform, pixelScale, -pixelScale);\n translate(transform, -tileExtent[0], -tileExtent[3]);\n\n for (var i = 0, ii = executorGroups.length; i < ii; ++i) {\n var executorGroup = executorGroups[i];\n executorGroup.execute(context, renderScale, transform, 0, true, IMAGE_REPLAYS[layer.getRenderMode()]);\n }\n\n replayState.renderedTileResolution = tile.wantedResolution;\n };\n\n return CanvasVectorTileLayerRenderer;\n}(canvas_TileLayer);\n\n/* harmony default export */ var canvas_VectorTileLayer = (CanvasVectorTileLayerRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/VectorTile.js\nvar VectorTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/VectorTile\n */\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-layer\'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {import("../render.js").OrderFunction} [renderOrder] Render order. Function to be used when sorting\n * features before rendering. By default features are drawn in the order that they are created. Use\n * `null` to avoid the sort, but get an undefined draw order.\n * @property {number} [renderBuffer=100] The buffer in pixels around the tile extent used by the\n * renderer when getting features from the vector tile for the rendering or hit-detection.\n * Recommended value: Vector tiles are usually generated with a buffer, so this value should match\n * the largest possible buffer of the used tiles. It should be at least the size of the largest\n * point symbol or line width.\n * @property {import("./VectorTileRenderType.js").default|string} [renderMode=\'hybrid\'] Render mode for vector tiles:\n * * `\'image\'`: Vector tiles are rendered as images. Only available when `declutter` is set to `false` (default).\n * Otherwise, `\'hybrid\'` mode will used instead. Great performance, but point symbols and texts\n * are always rotated with the view and pixels are scaled during zoom animations. Labels and point symbols will\n * get cut off at tile boundaries.\n * * `\'hybrid\'`: Polygon and line elements are rendered as images, so pixels are scaled during zoom\n * animations. Point symbols and texts are accurately rendered as vectors and can stay upright on\n * rotated views.\n * * `\'vector\'`: Everything is rendered as vectors. Use this mode for improved performance on vector\n * tile layers with only a few rendered features (e.g. for highlighting a subset of features of\n * another layer with the same source).\n * @property {import("../source/VectorTile.js").default} [source] Source.\n * @property {import("../PluggableMap.js").default} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link module:ol/Map#addLayer}.\n * @property {boolean} [declutter=false] Declutter images and text. Decluttering is applied to all\n * image and text styles of all Vector and VectorTile layers that have set this to `true`. The priority\n * is defined by the z-index of the layer, the `zIndex` of the style and the render order of features.\n * Higher z-index means higher priority. Within the same z-index, a feature rendered before another has\n * higher priority.\n * @property {import("../style/Style.js").StyleLike} [style] Layer style. See\n * {@link module:ol/style} for default style which will be used if this is not defined.\n * @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will be\n * recreated during animations. This means that no vectors will be shown clipped, but the setting\n * will have a performance impact for large amounts of vector data. When set to `false`, batches\n * will be recreated when no animation is active.\n * @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will be\n * recreated during interactions. See also `updateWhileAnimating`.\n * @property {number} [preload=0] Preload. Load low-resolution tiles up to `preload` levels. `0`\n * means no preloading.\n * @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.\n */\n\n/**\n * @classdesc\n * Layer for vector tile data that is rendered client-side.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: \'My Title\'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @param {Options=} opt_options Options.\n * @extends {BaseVectorLayer<import("../source/VectorTile.js").default>}\n * @api\n */\n\nvar VectorTileLayer =\n/** @class */\nfunction (_super) {\n VectorTile_extends(VectorTileLayer, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function VectorTileLayer(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var baseOptions =\n /** @type {Object} */\n obj_assign({}, options);\n delete baseOptions.preload;\n delete baseOptions.useInterimTilesOnError;\n _this = _super.call(this,\n /** @type {import("./BaseVector.js").Options} */\n baseOptions) || this;\n var renderMode = options.renderMode || VectorTileRenderType.HYBRID;\n asserts_assert(renderMode == undefined || renderMode == VectorTileRenderType.IMAGE || renderMode == VectorTileRenderType.HYBRID || renderMode == VectorTileRenderType.VECTOR, 28); // `renderMode` must be `\'image\'`, `\'hybrid\'` or `\'vector\'`.\n\n /**\n * @private\n * @type {import("./VectorTileRenderType.js").default}\n */\n\n _this.renderMode_ = renderMode;\n\n _this.setPreload(options.preload ? options.preload : 0);\n\n _this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined ? options.useInterimTilesOnError : true);\n\n return _this;\n }\n /**\n * Create a renderer for this layer.\n * @return {import("../renderer/Layer.js").default} A layer renderer.\n * @protected\n */\n\n\n VectorTileLayer.prototype.createRenderer = function () {\n return new canvas_VectorTileLayer(this);\n };\n /**\n * Get the topmost feature that intersects the given pixel on the viewport. Returns a promise\n * that resolves with an array of features. The array will either contain the topmost feature\n * when a hit was detected, or it will be empty.\n *\n * The hit detection algorithm used for this method is optimized for performance, but is less\n * accurate than the one used in {@link import("../PluggableMap.js").default#getFeaturesAtPixel}: Text\n * is not considered, and icons are only represented by their bounding box instead of the exact\n * image.\n *\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with an array of features.\n * @api\n */\n\n\n VectorTileLayer.prototype.getFeatures = function (pixel) {\n return _super.prototype.getFeatures.call(this, pixel);\n };\n /**\n * @return {import("./VectorTileRenderType.js").default} The render mode.\n */\n\n\n VectorTileLayer.prototype.getRenderMode = function () {\n return this.renderMode_;\n };\n /**\n * Return the level as number to which we will preload tiles up to.\n * @return {number} The level to preload tiles up to.\n * @observable\n * @api\n */\n\n\n VectorTileLayer.prototype.getPreload = function () {\n return (\n /** @type {number} */\n this.get(TileProperty.PRELOAD)\n );\n };\n /**\n * Whether we use interim tiles on error.\n * @return {boolean} Use interim tiles on error.\n * @observable\n * @api\n */\n\n\n VectorTileLayer.prototype.getUseInterimTilesOnError = function () {\n return (\n /** @type {boolean} */\n this.get(TileProperty.USE_INTERIM_TILES_ON_ERROR)\n );\n };\n /**\n * Set the level as number to which we will preload tiles up to.\n * @param {number} preload The level to preload tiles up to.\n * @observable\n * @api\n */\n\n\n VectorTileLayer.prototype.setPreload = function (preload) {\n this.set(TileProperty.PRELOAD, preload);\n };\n /**\n * Set whether we use interim tiles on error.\n * @param {boolean} useInterimTilesOnError Use interim tiles on error.\n * @observable\n * @api\n */\n\n\n VectorTileLayer.prototype.setUseInterimTilesOnError = function (useInterimTilesOnError) {\n this.set(TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError);\n };\n\n return VectorTileLayer;\n}(BaseVector);\n\n/* harmony default export */ var VectorTile = (VectorTileLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/Tile.js\nvar ol_Tile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Tile\n */\n\n\n\n\n\n\n\n/**\n * A function that takes an {@link module:ol/Tile} for the tile and a\n * `{string}` for the url as arguments. The default is\n * ```js\n * source.setTileLoadFunction(function(tile, src) {\n * tile.getImage().src = src;\n * });\n * ```\n * For more fine grained control, the load function can use fetch or XMLHttpRequest and involve\n * error handling:\n *\n * ```js\n * import TileState from \'ol/TileState\';\n *\n * source.setTileLoadFunction(function(tile, src) {\n * var xhr = new XMLHttpRequest();\n * xhr.responseType = \'blob\';\n * xhr.addEventListener(\'loadend\', function (evt) {\n * var data = this.response;\n * if (data !== undefined) {\n * tile.getImage().src = URL.createObjectURL(data);\n * } else {\n * tile.setState(TileState.ERROR);\n * }\n * });\n * xhr.addEventListener(\'error\', function () {\n * tile.setState(TileState.ERROR);\n * });\n * xhr.open(\'GET\', src);\n * xhr.send();\n * });\n * ```\n *\n * @typedef {function(Tile, string): void} LoadFunction\n * @api\n */\n\n/**\n * {@link module:ol/source/Tile~Tile} sources use a function of this type to get\n * the url that provides a tile for a given tile coordinate.\n *\n * This function takes an {@link module:ol/tilecoord~TileCoord} for the tile\n * coordinate, a `{number}` representing the pixel ratio and a\n * {@link module:ol/proj/Projection} for the projection as arguments\n * and returns a `{string}` representing the tile URL, or undefined if no tile\n * should be requested for the passed tile coordinate.\n *\n * @typedef {function(import("./tilecoord.js").TileCoord, number,\n * import("./proj/Projection.js").default): (string|undefined)} UrlFunction\n * @api\n */\n\n/**\n * @typedef {Object} Options\n * @property {number} [transition=250] A duration for tile opacity\n * transitions in milliseconds. A duration of 0 disables the opacity transition.\n * @api\n */\n\n/**\n * @classdesc\n * Base class for tiles.\n *\n * @abstract\n */\n\nvar Tile_Tile =\n/** @class */\nfunction (_super) {\n ol_Tile_extends(Tile, _super);\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("./TileState.js").default} state State.\n * @param {Options=} opt_options Tile options.\n */\n\n\n function Tile(tileCoord, state, opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @type {import("./tilecoord.js").TileCoord}\n */\n\n _this.tileCoord = tileCoord;\n /**\n * @protected\n * @type {import("./TileState.js").default}\n */\n\n _this.state = state;\n /**\n * An "interim" tile for this tile. The interim tile may be used while this\n * one is loading, for "smooth" transitions when changing params/dimensions\n * on the source.\n * @type {Tile}\n */\n\n _this.interimTile = null;\n /**\n * The tile is available at the highest possible resolution. Subclasses can\n * set this to `false` initially. Tile load listeners will not be\n * unregistered before this is set to `true` and a `#changed()` is called.\n * @type {boolean}\n */\n\n _this.hifi = true;\n /**\n * A key assigned to the tile. This is used by the tile source to determine\n * if this tile can effectively be used, or if a new tile should be created\n * and this one be used as an interim tile for this new tile.\n * @type {string}\n */\n\n _this.key = \'\';\n /**\n * The duration for the opacity transition.\n * @type {number}\n */\n\n _this.transition_ = options.transition === undefined ? 250 : options.transition;\n /**\n * Lookup of start times for rendering transitions. If the start time is\n * equal to -1, the transition is complete.\n * @type {Object<string, number>}\n */\n\n _this.transitionStarts_ = {};\n return _this;\n }\n /**\n * @protected\n */\n\n\n Tile.prototype.changed = function () {\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * Called by the tile cache when the tile is removed from the cache due to expiry\n */\n\n\n Tile.prototype.release = function () {};\n /**\n * @return {string} Key.\n */\n\n\n Tile.prototype.getKey = function () {\n return this.key + \'/\' + this.tileCoord;\n };\n /**\n * Get the interim tile most suitable for rendering using the chain of interim\n * tiles. This corresponds to the most recent tile that has been loaded, if no\n * such tile exists, the original tile is returned.\n * @return {!Tile} Best tile for rendering.\n */\n\n\n Tile.prototype.getInterimTile = function () {\n if (!this.interimTile) {\n //empty chain\n return this;\n }\n\n var tile = this.interimTile; // find the first loaded tile and return it. Since the chain is sorted in\n // decreasing order of creation time, there is no need to search the remainder\n // of the list (all those tiles correspond to older requests and will be\n // cleaned up by refreshInterimChain)\n\n do {\n if (tile.getState() == TileState.LOADED) {\n // Show tile immediately instead of fading it in after loading, because\n // the interim tile is in place already\n this.transition_ = 0;\n return tile;\n }\n\n tile = tile.interimTile;\n } while (tile); // we can not find a better tile\n\n\n return this;\n };\n /**\n * Goes through the chain of interim tiles and discards sections of the chain\n * that are no longer relevant.\n */\n\n\n Tile.prototype.refreshInterimChain = function () {\n if (!this.interimTile) {\n return;\n }\n\n var tile = this.interimTile;\n var prev =\n /** @type {Tile} */\n this;\n\n do {\n if (tile.getState() == TileState.LOADED) {\n //we have a loaded tile, we can discard the rest of the list\n //we would could abort any LOADING tile request\n //older than this tile (i.e. any LOADING tile following this entry in the chain)\n tile.interimTile = null;\n break;\n } else if (tile.getState() == TileState.LOADING) {\n //keep this LOADING tile any loaded tiles later in the chain are\n //older than this tile, so we\'re still interested in the request\n prev = tile;\n } else if (tile.getState() == TileState.IDLE) {\n //the head of the list is the most current tile, we don\'t need\n //to start any other requests for this chain\n prev.interimTile = tile.interimTile;\n } else {\n prev = tile;\n }\n\n tile = prev.interimTile;\n } while (tile);\n };\n /**\n * Get the tile coordinate for this tile.\n * @return {import("./tilecoord.js").TileCoord} The tile coordinate.\n * @api\n */\n\n\n Tile.prototype.getTileCoord = function () {\n return this.tileCoord;\n };\n /**\n * @return {import("./TileState.js").default} State.\n */\n\n\n Tile.prototype.getState = function () {\n return this.state;\n };\n /**\n * Sets the state of this tile. If you write your own {@link module:ol/Tile~LoadFunction tileLoadFunction} ,\n * it is important to set the state correctly to {@link module:ol/TileState~ERROR}\n * when the tile cannot be loaded. Otherwise the tile cannot be removed from\n * the tile queue and will block other requests.\n * @param {import("./TileState.js").default} state State.\n * @api\n */\n\n\n Tile.prototype.setState = function (state) {\n if (this.state !== TileState.ERROR && this.state > state) {\n throw new Error(\'Tile load sequence violation\');\n }\n\n this.state = state;\n this.changed();\n };\n /**\n * Load the image or retry if loading previously failed.\n * Loading is taken care of by the tile queue, and calling this method is\n * only needed for preloading or for reloading in case of an error.\n * @abstract\n * @api\n */\n\n\n Tile.prototype.load = function () {\n util_abstract();\n };\n /**\n * Get the alpha value for rendering.\n * @param {string} id An id for the renderer.\n * @param {number} time The render frame time.\n * @return {number} A number between 0 and 1.\n */\n\n\n Tile.prototype.getAlpha = function (id, time) {\n if (!this.transition_) {\n return 1;\n }\n\n var start = this.transitionStarts_[id];\n\n if (!start) {\n start = time;\n this.transitionStarts_[id] = start;\n } else if (start === -1) {\n return 1;\n }\n\n var delta = time - start + 1000 / 60; // avoid rendering at 0\n\n if (delta >= this.transition_) {\n return 1;\n }\n\n return easeIn(delta / this.transition_);\n };\n /**\n * Determine if a tile is in an alpha transition. A tile is considered in\n * transition if tile.getAlpha() has not yet been called or has been called\n * and returned 1.\n * @param {string} id An id for the renderer.\n * @return {boolean} The tile is in transition.\n */\n\n\n Tile.prototype.inTransition = function (id) {\n if (!this.transition_) {\n return false;\n }\n\n return this.transitionStarts_[id] !== -1;\n };\n /**\n * Mark a transition as complete.\n * @param {string} id An id for the renderer.\n */\n\n\n Tile.prototype.endTransition = function (id) {\n if (this.transition_) {\n this.transitionStarts_[id] = -1;\n }\n };\n\n return Tile;\n}(events_Target);\n\n/* harmony default export */ var ol_Tile = (Tile_Tile);\n;// CONCATENATED MODULE: ./node_modules/ol/VectorTile.js\nvar ol_VectorTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/VectorTile\n */\n\n\n\n\n\nvar VectorTile_VectorTile =\n/** @class */\nfunction (_super) {\n ol_VectorTile_extends(VectorTile, _super);\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("./TileState.js").default} state State.\n * @param {string} src Data source url.\n * @param {import("./format/Feature.js").default} format Feature format.\n * @param {import("./Tile.js").LoadFunction} tileLoadFunction Tile load function.\n * @param {import("./Tile.js").Options=} opt_options Tile options.\n */\n\n\n function VectorTile(tileCoord, state, src, format, tileLoadFunction, opt_options) {\n var _this = _super.call(this, tileCoord, state, opt_options) || this;\n /**\n * Extent of this tile; set by the source.\n * @type {import("./extent.js").Extent}\n */\n\n\n _this.extent = null;\n /**\n * @private\n * @type {import("./format/Feature.js").default}\n */\n\n _this.format_ = format;\n /**\n * @private\n * @type {Array<import("./Feature.js").default>}\n */\n\n _this.features_ = null;\n /**\n * @private\n * @type {import("./featureloader.js").FeatureLoader}\n */\n\n _this.loader_;\n /**\n * Feature projection of this tile; set by the source.\n * @type {import("./proj/Projection.js").default}\n */\n\n _this.projection = null;\n /**\n * Resolution of this tile; set by the source.\n * @type {number}\n */\n\n _this.resolution;\n /**\n * @private\n * @type {import("./Tile.js").LoadFunction}\n */\n\n _this.tileLoadFunction_ = tileLoadFunction;\n /**\n * @private\n * @type {string}\n */\n\n _this.url_ = src;\n _this.key = src;\n return _this;\n }\n /**\n * Get the feature format assigned for reading this tile\'s features.\n * @return {import("./format/Feature.js").default} Feature format.\n * @api\n */\n\n\n VectorTile.prototype.getFormat = function () {\n return this.format_;\n };\n /**\n * Get the features for this tile. Geometries will be in the view projection.\n * @return {Array<import("./Feature.js").FeatureLike>} Features.\n * @api\n */\n\n\n VectorTile.prototype.getFeatures = function () {\n return this.features_;\n };\n /**\n * Load not yet loaded URI.\n */\n\n\n VectorTile.prototype.load = function () {\n if (this.state == TileState.IDLE) {\n this.setState(TileState.LOADING);\n this.tileLoadFunction_(this, this.url_);\n\n if (this.loader_) {\n this.loader_(this.extent, this.resolution, this.projection);\n }\n }\n };\n /**\n * Handler for successful tile load.\n * @param {Array<import("./Feature.js").default>} features The loaded features.\n * @param {import("./proj/Projection.js").default} dataProjection Data projection.\n */\n\n\n VectorTile.prototype.onLoad = function (features, dataProjection) {\n this.setFeatures(features);\n };\n /**\n * Handler for tile load errors.\n */\n\n\n VectorTile.prototype.onError = function () {\n this.setState(TileState.ERROR);\n };\n /**\n * Function for use in an {@link module:ol/source/VectorTile~VectorTile}\'s `tileLoadFunction`.\n * Sets the features for the tile.\n * @param {Array<import("./Feature.js").default>} features Features.\n * @api\n */\n\n\n VectorTile.prototype.setFeatures = function (features) {\n this.features_ = features;\n this.setState(TileState.LOADED);\n };\n /**\n * Set the feature loader for reading this tile\'s features.\n * @param {import("./featureloader.js").FeatureLoader} loader Feature loader.\n * @api\n */\n\n\n VectorTile.prototype.setLoader = function (loader) {\n this.loader_ = loader;\n };\n\n return VectorTile;\n}(ol_Tile);\n\n/* harmony default export */ var ol_VectorTile = (VectorTile_VectorTile);\n;// CONCATENATED MODULE: ./node_modules/ol/structs/LRUCache.js\n/**\n * @module ol/structs/LRUCache\n */\n\n/**\n * @typedef {Object} Entry\n * @property {string} key_\n * @property {Object} newer\n * @property {Object} older\n * @property {*} value_\n */\n\n/**\n * @classdesc\n * Implements a Least-Recently-Used cache where the keys do not conflict with\n * Object\'s properties (e.g. \'hasOwnProperty\' is not allowed as a key). Expiring\n * items from the cache is the responsibility of the user.\n *\n * @fires import("../events/Event.js").default\n * @template T\n */\n\nvar LRUCache =\n/** @class */\nfunction () {\n /**\n * @param {number=} opt_highWaterMark High water mark.\n */\n function LRUCache(opt_highWaterMark) {\n /**\n * Desired max cache size after expireCache(). If set to 0, no cache entries\n * will be pruned at all.\n * @type {number}\n */\n this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048;\n /**\n * @private\n * @type {number}\n */\n\n this.count_ = 0;\n /**\n * @private\n * @type {!Object<string, Entry>}\n */\n\n this.entries_ = {};\n /**\n * @private\n * @type {?Entry}\n */\n\n this.oldest_ = null;\n /**\n * @private\n * @type {?Entry}\n */\n\n this.newest_ = null;\n }\n /**\n * @return {boolean} Can expire cache.\n */\n\n\n LRUCache.prototype.canExpireCache = function () {\n return this.highWaterMark > 0 && this.getCount() > this.highWaterMark;\n };\n /**\n * FIXME empty description for jsdoc\n */\n\n\n LRUCache.prototype.clear = function () {\n this.count_ = 0;\n this.entries_ = {};\n this.oldest_ = null;\n this.newest_ = null;\n };\n /**\n * @param {string} key Key.\n * @return {boolean} Contains key.\n */\n\n\n LRUCache.prototype.containsKey = function (key) {\n return this.entries_.hasOwnProperty(key);\n };\n /**\n * @param {function(T, string, LRUCache<T>): ?} f The function\n * to call for every entry from the oldest to the newer. This function takes\n * 3 arguments (the entry value, the entry key and the LRUCache object).\n * The return value is ignored.\n */\n\n\n LRUCache.prototype.forEach = function (f) {\n var entry = this.oldest_;\n\n while (entry) {\n f(entry.value_, entry.key_, this);\n entry = entry.newer;\n }\n };\n /**\n * @param {string} key Key.\n * @param {*=} opt_options Options (reserverd for subclasses).\n * @return {T} Value.\n */\n\n\n LRUCache.prototype.get = function (key, opt_options) {\n var entry = this.entries_[key];\n asserts_assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache\n\n if (entry === this.newest_) {\n return entry.value_;\n } else if (entry === this.oldest_) {\n this.oldest_ =\n /** @type {Entry} */\n this.oldest_.newer;\n this.oldest_.older = null;\n } else {\n entry.newer.older = entry.older;\n entry.older.newer = entry.newer;\n }\n\n entry.newer = null;\n entry.older = this.newest_;\n this.newest_.newer = entry;\n this.newest_ = entry;\n return entry.value_;\n };\n /**\n * Remove an entry from the cache.\n * @param {string} key The entry key.\n * @return {T} The removed entry.\n */\n\n\n LRUCache.prototype.remove = function (key) {\n var entry = this.entries_[key];\n asserts_assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache\n\n if (entry === this.newest_) {\n this.newest_ =\n /** @type {Entry} */\n entry.older;\n\n if (this.newest_) {\n this.newest_.newer = null;\n }\n } else if (entry === this.oldest_) {\n this.oldest_ =\n /** @type {Entry} */\n entry.newer;\n\n if (this.oldest_) {\n this.oldest_.older = null;\n }\n } else {\n entry.newer.older = entry.older;\n entry.older.newer = entry.newer;\n }\n\n delete this.entries_[key];\n --this.count_;\n return entry.value_;\n };\n /**\n * @return {number} Count.\n */\n\n\n LRUCache.prototype.getCount = function () {\n return this.count_;\n };\n /**\n * @return {Array<string>} Keys.\n */\n\n\n LRUCache.prototype.getKeys = function () {\n var keys = new Array(this.count_);\n var i = 0;\n var entry;\n\n for (entry = this.newest_; entry; entry = entry.older) {\n keys[i++] = entry.key_;\n }\n\n return keys;\n };\n /**\n * @return {Array<T>} Values.\n */\n\n\n LRUCache.prototype.getValues = function () {\n var values = new Array(this.count_);\n var i = 0;\n var entry;\n\n for (entry = this.newest_; entry; entry = entry.older) {\n values[i++] = entry.value_;\n }\n\n return values;\n };\n /**\n * @return {T} Last value.\n */\n\n\n LRUCache.prototype.peekLast = function () {\n return this.oldest_.value_;\n };\n /**\n * @return {string} Last key.\n */\n\n\n LRUCache.prototype.peekLastKey = function () {\n return this.oldest_.key_;\n };\n /**\n * Get the key of the newest item in the cache. Throws if the cache is empty.\n * @return {string} The newest key.\n */\n\n\n LRUCache.prototype.peekFirstKey = function () {\n return this.newest_.key_;\n };\n /**\n * @return {T} value Value.\n */\n\n\n LRUCache.prototype.pop = function () {\n var entry = this.oldest_;\n delete this.entries_[entry.key_];\n\n if (entry.newer) {\n entry.newer.older = null;\n }\n\n this.oldest_ =\n /** @type {Entry} */\n entry.newer;\n\n if (!this.oldest_) {\n this.newest_ = null;\n }\n\n --this.count_;\n return entry.value_;\n };\n /**\n * @param {string} key Key.\n * @param {T} value Value.\n */\n\n\n LRUCache.prototype.replace = function (key, value) {\n this.get(key); // update `newest_`\n\n this.entries_[key].value_ = value;\n };\n /**\n * @param {string} key Key.\n * @param {T} value Value.\n */\n\n\n LRUCache.prototype.set = function (key, value) {\n asserts_assert(!(key in this.entries_), 16); // Tried to set a value for a key that is used already\n\n var entry = {\n key_: key,\n newer: null,\n older: this.newest_,\n value_: value\n };\n\n if (!this.newest_) {\n this.oldest_ = entry;\n } else {\n this.newest_.newer = entry;\n }\n\n this.newest_ = entry;\n this.entries_[key] = entry;\n ++this.count_;\n };\n /**\n * Set a maximum number of entries for the cache.\n * @param {number} size Cache size.\n * @api\n */\n\n\n LRUCache.prototype.setSize = function (size) {\n this.highWaterMark = size;\n };\n\n return LRUCache;\n}();\n\n/* harmony default export */ var structs_LRUCache = (LRUCache);\n;// CONCATENATED MODULE: ./node_modules/ol/tilecoord.js\n/**\n * @module ol/tilecoord\n */\n\n/**\n * An array of three numbers representing the location of a tile in a tile\n * grid. The order is `z` (zoom level), `x` (column), and `y` (row).\n * @typedef {Array<number>} TileCoord\n * @api\n */\n\n/**\n * @param {number} z Z.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {TileCoord=} opt_tileCoord Tile coordinate.\n * @return {TileCoord} Tile coordinate.\n */\nfunction tilecoord_createOrUpdate(z, x, y, opt_tileCoord) {\n if (opt_tileCoord !== undefined) {\n opt_tileCoord[0] = z;\n opt_tileCoord[1] = x;\n opt_tileCoord[2] = y;\n return opt_tileCoord;\n } else {\n return [z, x, y];\n }\n}\n/**\n * @param {number} z Z.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {string} Key.\n */\n\nfunction getKeyZXY(z, x, y) {\n return z + \'/\' + x + \'/\' + y;\n}\n/**\n * Get the key for a tile coord.\n * @param {TileCoord} tileCoord The tile coord.\n * @return {string} Key.\n */\n\nfunction tilecoord_getKey(tileCoord) {\n return getKeyZXY(tileCoord[0], tileCoord[1], tileCoord[2]);\n}\n/**\n * Get a tile coord given a key.\n * @param {string} key The tile coord key.\n * @return {TileCoord} The tile coord.\n */\n\nfunction fromKey(key) {\n return key.split(\'/\').map(Number);\n}\n/**\n * @param {TileCoord} tileCoord Tile coord.\n * @return {number} Hash.\n */\n\nfunction hash(tileCoord) {\n return (tileCoord[1] << tileCoord[0]) + tileCoord[2];\n}\n/**\n * @param {TileCoord} tileCoord Tile coordinate.\n * @param {!import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.\n * @return {boolean} Tile coordinate is within extent and zoom level range.\n */\n\nfunction withinExtentAndZ(tileCoord, tileGrid) {\n var z = tileCoord[0];\n var x = tileCoord[1];\n var y = tileCoord[2];\n\n if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) {\n return false;\n }\n\n var tileRange = tileGrid.getFullTileRange(z);\n\n if (!tileRange) {\n return true;\n } else {\n return tileRange.containsXY(x, y);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/TileCache.js\nvar TileCache_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/TileCache\n */\n\n\n\n\n\nvar TileCache =\n/** @class */\nfunction (_super) {\n TileCache_extends(TileCache, _super);\n\n function TileCache() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n /**\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n\n\n TileCache.prototype.expireCache = function (usedTiles) {\n while (this.canExpireCache()) {\n var tile = this.peekLast();\n\n if (tile.getKey() in usedTiles) {\n break;\n } else {\n this.pop().release();\n }\n }\n };\n /**\n * Prune all tiles from the cache that don\'t have the same z as the newest tile.\n */\n\n\n TileCache.prototype.pruneExceptNewestZ = function () {\n if (this.getCount() === 0) {\n return;\n }\n\n var key = this.peekFirstKey();\n var tileCoord = fromKey(key);\n var z = tileCoord[0];\n this.forEach(function (tile) {\n if (tile.tileCoord[0] !== z) {\n this.remove(tilecoord_getKey(tile.tileCoord));\n tile.release();\n }\n }.bind(this));\n };\n\n return TileCache;\n}(structs_LRUCache);\n\n/* harmony default export */ var ol_TileCache = (TileCache);\n;// CONCATENATED MODULE: ./node_modules/ol/source/TileEventType.js\n/**\n * @module ol/source/TileEventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var TileEventType = ({\n /**\n * Triggered when a tile starts loading.\n * @event module:ol/source/Tile.TileSourceEvent#tileloadstart\n * @api\n */\n TILELOADSTART: \'tileloadstart\',\n\n /**\n * Triggered when a tile finishes loading, either when its data is loaded,\n * or when loading was aborted because the tile is no longer needed.\n * @event module:ol/source/Tile.TileSourceEvent#tileloadend\n * @api\n */\n TILELOADEND: \'tileloadend\',\n\n /**\n * Triggered if tile loading results in an error.\n * @event module:ol/source/Tile.TileSourceEvent#tileloaderror\n * @api\n */\n TILELOADERROR: \'tileloaderror\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/tilegrid/TileGrid.js\n/**\n * @module ol/tilegrid/TileGrid\n */\n\n\n\n\n\n\n\n\n/**\n * @private\n * @type {import("../tilecoord.js").TileCoord}\n */\n\nvar tmpTileCoord = [0, 0, 0];\n/**\n * @typedef {Object} Options\n * @property {import("../extent.js").Extent} [extent] Extent for the tile grid. No tiles outside this\n * extent will be requested by {@link module:ol/source/Tile} sources. When no `origin` or\n * `origins` are configured, the `origin` will be set to the top-left corner of the extent.\n * @property {number} [minZoom=0] Minimum zoom.\n * @property {import("../coordinate.js").Coordinate} [origin] The tile grid origin, i.e. where the `x`\n * and `y` axes meet (`[z, 0, 0]`). Tile coordinates increase left to right and downwards. If not\n * specified, `extent` or `origins` must be provided.\n * @property {Array<import("../coordinate.js").Coordinate>} [origins] Tile grid origins, i.e. where\n * the `x` and `y` axes meet (`[z, 0, 0]`), for each zoom level. If given, the array length\n * should match the length of the `resolutions` array, i.e. each resolution can have a different\n * origin. Tile coordinates increase left to right and downwards. If not specified, `extent` or\n * `origin` must be provided.\n * @property {!Array<number>} resolutions Resolutions. The array index of each resolution needs\n * to match the zoom level. This means that even if a `minZoom` is configured, the resolutions\n * array will have a length of `maxZoom + 1`.\n * @property {Array<import("../size.js").Size>} [sizes] Number of tile rows and columns\n * of the grid for each zoom level. If specified the values\n * define each zoom level\'s extent together with the `origin` or `origins`.\n * A grid `extent` can be configured in addition, and will further limit the extent\n * for which tile requests are made by sources. If the bottom-left corner of\n * an extent is used as `origin` or `origins`, then the `y` value must be\n * negative because OpenLayers tile coordinates use the top left as the origin.\n * @property {number|import("../size.js").Size} [tileSize] Tile size.\n * Default is `[256, 256]`.\n * @property {Array<import("../size.js").Size>} [tileSizes] Tile sizes. If given, the array length\n * should match the length of the `resolutions` array, i.e. each resolution can have a different\n * tile size.\n */\n\n/**\n * @classdesc\n * Base class for setting the grid pattern for sources accessing tiled-image\n * servers.\n * @api\n */\n\nvar TileGrid =\n/** @class */\nfunction () {\n /**\n * @param {Options} options Tile grid options.\n */\n function TileGrid(options) {\n /**\n * @protected\n * @type {number}\n */\n this.minZoom = options.minZoom !== undefined ? options.minZoom : 0;\n /**\n * @private\n * @type {!Array<number>}\n */\n\n this.resolutions_ = options.resolutions;\n asserts_assert(isSorted(this.resolutions_, function (a, b) {\n return b - a;\n }, true), 17); // `resolutions` must be sorted in descending order\n // check if we\'ve got a consistent zoom factor and origin\n\n var zoomFactor;\n\n if (!options.origins) {\n for (var i = 0, ii = this.resolutions_.length - 1; i < ii; ++i) {\n if (!zoomFactor) {\n zoomFactor = this.resolutions_[i] / this.resolutions_[i + 1];\n } else {\n if (this.resolutions_[i] / this.resolutions_[i + 1] !== zoomFactor) {\n zoomFactor = undefined;\n break;\n }\n }\n }\n }\n /**\n * @private\n * @type {number|undefined}\n */\n\n\n this.zoomFactor_ = zoomFactor;\n /**\n * @protected\n * @type {number}\n */\n\n this.maxZoom = this.resolutions_.length - 1;\n /**\n * @private\n * @type {import("../coordinate.js").Coordinate}\n */\n\n this.origin_ = options.origin !== undefined ? options.origin : null;\n /**\n * @private\n * @type {Array<import("../coordinate.js").Coordinate>}\n */\n\n this.origins_ = null;\n\n if (options.origins !== undefined) {\n this.origins_ = options.origins;\n asserts_assert(this.origins_.length == this.resolutions_.length, 20); // Number of `origins` and `resolutions` must be equal\n }\n\n var extent = options.extent;\n\n if (extent !== undefined && !this.origin_ && !this.origins_) {\n this.origin_ = getTopLeft(extent);\n }\n\n asserts_assert(!this.origin_ && this.origins_ || this.origin_ && !this.origins_, 18); // Either `origin` or `origins` must be configured, never both\n\n /**\n * @private\n * @type {Array<number|import("../size.js").Size>}\n */\n\n this.tileSizes_ = null;\n\n if (options.tileSizes !== undefined) {\n this.tileSizes_ = options.tileSizes;\n asserts_assert(this.tileSizes_.length == this.resolutions_.length, 19); // Number of `tileSizes` and `resolutions` must be equal\n }\n /**\n * @private\n * @type {number|import("../size.js").Size}\n */\n\n\n this.tileSize_ = options.tileSize !== undefined ? options.tileSize : !this.tileSizes_ ? DEFAULT_TILE_SIZE : null;\n asserts_assert(!this.tileSize_ && this.tileSizes_ || this.tileSize_ && !this.tileSizes_, 22); // Either `tileSize` or `tileSizes` must be configured, never both\n\n /**\n * @private\n * @type {import("../extent.js").Extent}\n */\n\n this.extent_ = extent !== undefined ? extent : null;\n /**\n * @private\n * @type {Array<import("../TileRange.js").default>}\n */\n\n this.fullTileRanges_ = null;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n this.tmpSize_ = [0, 0];\n\n if (options.sizes !== undefined) {\n this.fullTileRanges_ = options.sizes.map(function (size, z) {\n var tileRange = new ol_TileRange(Math.min(0, size[0]), Math.max(size[0] - 1, -1), Math.min(0, size[1]), Math.max(size[1] - 1, -1));\n\n if (extent) {\n var restrictedTileRange = this.getTileRangeForExtentAndZ(extent, z);\n tileRange.minX = Math.max(restrictedTileRange.minX, tileRange.minX);\n tileRange.maxX = Math.min(restrictedTileRange.maxX, tileRange.maxX);\n tileRange.minY = Math.max(restrictedTileRange.minY, tileRange.minY);\n tileRange.maxY = Math.min(restrictedTileRange.maxY, tileRange.maxY);\n }\n\n return tileRange;\n }, this);\n } else if (extent) {\n this.calculateTileRanges_(extent);\n }\n }\n /**\n * Call a function with each tile coordinate for a given extent and zoom level.\n *\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {number} zoom Integer zoom level.\n * @param {function(import("../tilecoord.js").TileCoord): void} callback Function called with each tile coordinate.\n * @api\n */\n\n\n TileGrid.prototype.forEachTileCoord = function (extent, zoom, callback) {\n var tileRange = this.getTileRangeForExtentAndZ(extent, zoom);\n\n for (var i = tileRange.minX, ii = tileRange.maxX; i <= ii; ++i) {\n for (var j = tileRange.minY, jj = tileRange.maxY; j <= jj; ++j) {\n callback([zoom, i, j]);\n }\n }\n };\n /**\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {function(number, import("../TileRange.js").default): boolean} callback Callback.\n * @param {import("../TileRange.js").default=} opt_tileRange Temporary import("../TileRange.js").default object.\n * @param {import("../extent.js").Extent=} opt_extent Temporary import("../extent.js").Extent object.\n * @return {boolean} Callback succeeded.\n */\n\n\n TileGrid.prototype.forEachTileCoordParentTileRange = function (tileCoord, callback, opt_tileRange, opt_extent) {\n var tileRange, x, y;\n var tileCoordExtent = null;\n var z = tileCoord[0] - 1;\n\n if (this.zoomFactor_ === 2) {\n x = tileCoord[1];\n y = tileCoord[2];\n } else {\n tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);\n }\n\n while (z >= this.minZoom) {\n if (this.zoomFactor_ === 2) {\n x = Math.floor(x / 2);\n y = Math.floor(y / 2);\n tileRange = TileRange_createOrUpdate(x, x, y, y, opt_tileRange);\n } else {\n tileRange = this.getTileRangeForExtentAndZ(tileCoordExtent, z, opt_tileRange);\n }\n\n if (callback(z, tileRange)) {\n return true;\n }\n\n --z;\n }\n\n return false;\n };\n /**\n * Get the extent for this tile grid, if it was configured.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n TileGrid.prototype.getExtent = function () {\n return this.extent_;\n };\n /**\n * Get the maximum zoom level for the grid.\n * @return {number} Max zoom.\n * @api\n */\n\n\n TileGrid.prototype.getMaxZoom = function () {\n return this.maxZoom;\n };\n /**\n * Get the minimum zoom level for the grid.\n * @return {number} Min zoom.\n * @api\n */\n\n\n TileGrid.prototype.getMinZoom = function () {\n return this.minZoom;\n };\n /**\n * Get the origin for the grid at the given zoom level.\n * @param {number} z Integer zoom level.\n * @return {import("../coordinate.js").Coordinate} Origin.\n * @api\n */\n\n\n TileGrid.prototype.getOrigin = function (z) {\n if (this.origin_) {\n return this.origin_;\n } else {\n return this.origins_[z];\n }\n };\n /**\n * Get the resolution for the given zoom level.\n * @param {number} z Integer zoom level.\n * @return {number} Resolution.\n * @api\n */\n\n\n TileGrid.prototype.getResolution = function (z) {\n return this.resolutions_[z];\n };\n /**\n * Get the list of resolutions for the tile grid.\n * @return {Array<number>} Resolutions.\n * @api\n */\n\n\n TileGrid.prototype.getResolutions = function () {\n return this.resolutions_;\n };\n /**\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("../TileRange.js").default=} opt_tileRange Temporary import("../TileRange.js").default object.\n * @param {import("../extent.js").Extent=} opt_extent Temporary import("../extent.js").Extent object.\n * @return {import("../TileRange.js").default} Tile range.\n */\n\n\n TileGrid.prototype.getTileCoordChildTileRange = function (tileCoord, opt_tileRange, opt_extent) {\n if (tileCoord[0] < this.maxZoom) {\n if (this.zoomFactor_ === 2) {\n var minX = tileCoord[1] * 2;\n var minY = tileCoord[2] * 2;\n return TileRange_createOrUpdate(minX, minX + 1, minY, minY + 1, opt_tileRange);\n }\n\n var tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);\n return this.getTileRangeForExtentAndZ(tileCoordExtent, tileCoord[0] + 1, opt_tileRange);\n }\n\n return null;\n };\n /**\n * Get the extent for a tile range.\n * @param {number} z Integer zoom level.\n * @param {import("../TileRange.js").default} tileRange Tile range.\n * @param {import("../extent.js").Extent=} opt_extent Temporary import("../extent.js").Extent object.\n * @return {import("../extent.js").Extent} Extent.\n */\n\n\n TileGrid.prototype.getTileRangeExtent = function (z, tileRange, opt_extent) {\n var origin = this.getOrigin(z);\n var resolution = this.getResolution(z);\n var tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n var minX = origin[0] + tileRange.minX * tileSize[0] * resolution;\n var maxX = origin[0] + (tileRange.maxX + 1) * tileSize[0] * resolution;\n var minY = origin[1] + tileRange.minY * tileSize[1] * resolution;\n var maxY = origin[1] + (tileRange.maxY + 1) * tileSize[1] * resolution;\n return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n };\n /**\n * Get a tile range for the given extent and integer zoom level.\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {number} z Integer zoom level.\n * @param {import("../TileRange.js").default=} opt_tileRange Temporary tile range object.\n * @return {import("../TileRange.js").default} Tile range.\n */\n\n\n TileGrid.prototype.getTileRangeForExtentAndZ = function (extent, z, opt_tileRange) {\n var tileCoord = tmpTileCoord;\n this.getTileCoordForXYAndZ_(extent[0], extent[3], z, false, tileCoord);\n var minX = tileCoord[1];\n var minY = tileCoord[2];\n this.getTileCoordForXYAndZ_(extent[2], extent[1], z, true, tileCoord);\n return TileRange_createOrUpdate(minX, tileCoord[1], minY, tileCoord[2], opt_tileRange);\n };\n /**\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @return {import("../coordinate.js").Coordinate} Tile center.\n */\n\n\n TileGrid.prototype.getTileCoordCenter = function (tileCoord) {\n var origin = this.getOrigin(tileCoord[0]);\n var resolution = this.getResolution(tileCoord[0]);\n var tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);\n return [origin[0] + (tileCoord[1] + 0.5) * tileSize[0] * resolution, origin[1] - (tileCoord[2] + 0.5) * tileSize[1] * resolution];\n };\n /**\n * Get the extent of a tile coordinate.\n *\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("../extent.js").Extent=} opt_extent Temporary extent object.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n TileGrid.prototype.getTileCoordExtent = function (tileCoord, opt_extent) {\n var origin = this.getOrigin(tileCoord[0]);\n var resolution = this.getResolution(tileCoord[0]);\n var tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);\n var minX = origin[0] + tileCoord[1] * tileSize[0] * resolution;\n var minY = origin[1] - (tileCoord[2] + 1) * tileSize[1] * resolution;\n var maxX = minX + tileSize[0] * resolution;\n var maxY = minY + tileSize[1] * resolution;\n return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n };\n /**\n * Get the tile coordinate for the given map coordinate and resolution. This\n * method considers that coordinates that intersect tile boundaries should be\n * assigned the higher tile coordinate.\n *\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {number} resolution Resolution.\n * @param {import("../tilecoord.js").TileCoord=} opt_tileCoord Destination import("../tilecoord.js").TileCoord object.\n * @return {import("../tilecoord.js").TileCoord} Tile coordinate.\n * @api\n */\n\n\n TileGrid.prototype.getTileCoordForCoordAndResolution = function (coordinate, resolution, opt_tileCoord) {\n return this.getTileCoordForXYAndResolution_(coordinate[0], coordinate[1], resolution, false, opt_tileCoord);\n };\n /**\n * Note that this method should not be called for resolutions that correspond\n * to an integer zoom level. Instead call the `getTileCoordForXYAndZ_` method.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} resolution Resolution (for a non-integer zoom level).\n * @param {boolean} reverseIntersectionPolicy Instead of letting edge\n * intersections go to the higher tile coordinate, let edge intersections\n * go to the lower tile coordinate.\n * @param {import("../tilecoord.js").TileCoord=} opt_tileCoord Temporary import("../tilecoord.js").TileCoord object.\n * @return {import("../tilecoord.js").TileCoord} Tile coordinate.\n * @private\n */\n\n\n TileGrid.prototype.getTileCoordForXYAndResolution_ = function (x, y, resolution, reverseIntersectionPolicy, opt_tileCoord) {\n var z = this.getZForResolution(resolution);\n var scale = resolution / this.getResolution(z);\n var origin = this.getOrigin(z);\n var tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n var adjustX = reverseIntersectionPolicy ? 0.5 : 0;\n var adjustY = reverseIntersectionPolicy ? 0.5 : 0;\n var xFromOrigin = Math.floor((x - origin[0]) / resolution + adjustX);\n var yFromOrigin = Math.floor((origin[1] - y) / resolution + adjustY);\n var tileCoordX = scale * xFromOrigin / tileSize[0];\n var tileCoordY = scale * yFromOrigin / tileSize[1];\n\n if (reverseIntersectionPolicy) {\n tileCoordX = Math.ceil(tileCoordX) - 1;\n tileCoordY = Math.ceil(tileCoordY) - 1;\n } else {\n tileCoordX = Math.floor(tileCoordX);\n tileCoordY = Math.floor(tileCoordY);\n }\n\n return tilecoord_createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord);\n };\n /**\n * Although there is repetition between this method and `getTileCoordForXYAndResolution_`,\n * they should have separate implementations. This method is for integer zoom\n * levels. The other method should only be called for resolutions corresponding\n * to non-integer zoom levels.\n * @param {number} x Map x coordinate.\n * @param {number} y Map y coordinate.\n * @param {number} z Integer zoom level.\n * @param {boolean} reverseIntersectionPolicy Instead of letting edge\n * intersections go to the higher tile coordinate, let edge intersections\n * go to the lower tile coordinate.\n * @param {import("../tilecoord.js").TileCoord=} opt_tileCoord Temporary import("../tilecoord.js").TileCoord object.\n * @return {import("../tilecoord.js").TileCoord} Tile coordinate.\n * @private\n */\n\n\n TileGrid.prototype.getTileCoordForXYAndZ_ = function (x, y, z, reverseIntersectionPolicy, opt_tileCoord) {\n var origin = this.getOrigin(z);\n var resolution = this.getResolution(z);\n var tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n var adjustX = reverseIntersectionPolicy ? 0.5 : 0;\n var adjustY = reverseIntersectionPolicy ? 0.5 : 0;\n var xFromOrigin = Math.floor((x - origin[0]) / resolution + adjustX);\n var yFromOrigin = Math.floor((origin[1] - y) / resolution + adjustY);\n var tileCoordX = xFromOrigin / tileSize[0];\n var tileCoordY = yFromOrigin / tileSize[1];\n\n if (reverseIntersectionPolicy) {\n tileCoordX = Math.ceil(tileCoordX) - 1;\n tileCoordY = Math.ceil(tileCoordY) - 1;\n } else {\n tileCoordX = Math.floor(tileCoordX);\n tileCoordY = Math.floor(tileCoordY);\n }\n\n return tilecoord_createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord);\n };\n /**\n * Get a tile coordinate given a map coordinate and zoom level.\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {number} z Zoom level.\n * @param {import("../tilecoord.js").TileCoord=} opt_tileCoord Destination import("../tilecoord.js").TileCoord object.\n * @return {import("../tilecoord.js").TileCoord} Tile coordinate.\n * @api\n */\n\n\n TileGrid.prototype.getTileCoordForCoordAndZ = function (coordinate, z, opt_tileCoord) {\n return this.getTileCoordForXYAndZ_(coordinate[0], coordinate[1], z, false, opt_tileCoord);\n };\n /**\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @return {number} Tile resolution.\n */\n\n\n TileGrid.prototype.getTileCoordResolution = function (tileCoord) {\n return this.resolutions_[tileCoord[0]];\n };\n /**\n * Get the tile size for a zoom level. The type of the return value matches the\n * `tileSize` or `tileSizes` that the tile grid was configured with. To always\n * get an `import("../size.js").Size`, run the result through `import("../size.js").Size.toSize()`.\n * @param {number} z Z.\n * @return {number|import("../size.js").Size} Tile size.\n * @api\n */\n\n\n TileGrid.prototype.getTileSize = function (z) {\n if (this.tileSize_) {\n return this.tileSize_;\n } else {\n return this.tileSizes_[z];\n }\n };\n /**\n * @param {number} z Zoom level.\n * @return {import("../TileRange.js").default} Extent tile range for the specified zoom level.\n */\n\n\n TileGrid.prototype.getFullTileRange = function (z) {\n if (!this.fullTileRanges_) {\n return this.extent_ ? this.getTileRangeForExtentAndZ(this.extent_, z) : null;\n } else {\n return this.fullTileRanges_[z];\n }\n };\n /**\n * @param {number} resolution Resolution.\n * @param {number=} opt_direction If 0, the nearest resolution will be used.\n * If 1, the nearest lower resolution will be used. If -1, the nearest\n * higher resolution will be used. Default is 0.\n * @return {number} Z.\n * @api\n */\n\n\n TileGrid.prototype.getZForResolution = function (resolution, opt_direction) {\n var z = linearFindNearest(this.resolutions_, resolution, opt_direction || 0);\n return math_clamp(z, this.minZoom, this.maxZoom);\n };\n /**\n * @param {!import("../extent.js").Extent} extent Extent for this tile grid.\n * @private\n */\n\n\n TileGrid.prototype.calculateTileRanges_ = function (extent) {\n var length = this.resolutions_.length;\n var fullTileRanges = new Array(length);\n\n for (var z = this.minZoom; z < length; ++z) {\n fullTileRanges[z] = this.getTileRangeForExtentAndZ(extent, z);\n }\n\n this.fullTileRanges_ = fullTileRanges;\n };\n\n return TileGrid;\n}();\n\n/* harmony default export */ var tilegrid_TileGrid = (TileGrid);\n;// CONCATENATED MODULE: ./node_modules/ol/tilegrid.js\n/**\n * @module ol/tilegrid\n */\n\n\n\n\n\n\n\n/**\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {!TileGrid} Default tile grid for the\n * passed projection.\n */\n\nfunction getForProjection(projection) {\n var tileGrid = projection.getDefaultTileGrid();\n\n if (!tileGrid) {\n tileGrid = createForProjection(projection);\n projection.setDefaultTileGrid(tileGrid);\n }\n\n return tileGrid;\n}\n/**\n * @param {TileGrid} tileGrid Tile grid.\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {import("./tilecoord.js").TileCoord} Tile coordinate.\n */\n\nfunction tilegrid_wrapX(tileGrid, tileCoord, projection) {\n var z = tileCoord[0];\n var center = tileGrid.getTileCoordCenter(tileCoord);\n var projectionExtent = extentFromProjection(projection);\n\n if (!containsCoordinate(projectionExtent, center)) {\n var worldWidth = extent_getWidth(projectionExtent);\n var worldsAway = Math.ceil((projectionExtent[0] - center[0]) / worldWidth);\n center[0] += worldWidth * worldsAway;\n return tileGrid.getTileCoordForCoordAndZ(center, z);\n } else {\n return tileCoord;\n }\n}\n/**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number=} opt_maxZoom Maximum zoom level (default is\n * DEFAULT_MAX_ZOOM).\n * @param {number|import("./size.js").Size=} opt_tileSize Tile size (default uses\n * DEFAULT_TILE_SIZE).\n * @param {import("./extent/Corner.js").default=} opt_corner Extent corner (default is `\'top-left\'`).\n * @return {!TileGrid} TileGrid instance.\n */\n\nfunction createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner) {\n var corner = opt_corner !== undefined ? opt_corner : Corner.TOP_LEFT;\n var resolutions = resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize);\n return new tilegrid_TileGrid({\n extent: extent,\n origin: getCorner(extent, corner),\n resolutions: resolutions,\n tileSize: opt_tileSize\n });\n}\n/**\n * @typedef {Object} XYZOptions\n * @property {import("./extent.js").Extent} [extent] Extent for the tile grid. The origin for an XYZ tile grid is the\n * top-left corner of the extent. If `maxResolution` is not provided the zero level of the grid is defined by the resolution\n * at which one tile fits in the provided extent. If not provided, the extent of the EPSG:3857 projection is used.\n * @property {number} [maxResolution] Resolution at level zero.\n * @property {number} [maxZoom] Maximum zoom. The default is `42`. This determines the number of levels\n * in the grid set. For example, a `maxZoom` of 21 means there are 22 levels in the grid set.\n * @property {number} [minZoom=0] Minimum zoom.\n * @property {number|import("./size.js").Size} [tileSize=[256, 256]] Tile size in pixels.\n */\n\n/**\n * Creates a tile grid with a standard XYZ tiling scheme.\n * @param {XYZOptions=} opt_options Tile grid options.\n * @return {!TileGrid} Tile grid instance.\n * @api\n */\n\nfunction createXYZ(opt_options) {\n var xyzOptions = opt_options || {};\n var extent = xyzOptions.extent || proj_get(\'EPSG:3857\').getExtent();\n var gridOptions = {\n extent: extent,\n minZoom: xyzOptions.minZoom,\n tileSize: xyzOptions.tileSize,\n resolutions: resolutionsFromExtent(extent, xyzOptions.maxZoom, xyzOptions.tileSize, xyzOptions.maxResolution)\n };\n return new tilegrid_TileGrid(gridOptions);\n}\n/**\n * Create a resolutions array from an extent. A zoom factor of 2 is assumed.\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number=} opt_maxZoom Maximum zoom level (default is\n * DEFAULT_MAX_ZOOM).\n * @param {number|import("./size.js").Size=} opt_tileSize Tile size (default uses\n * DEFAULT_TILE_SIZE).\n * @param {number=} opt_maxResolution Resolution at level zero.\n * @return {!Array<number>} Resolutions array.\n */\n\nfunction resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize, opt_maxResolution) {\n var maxZoom = opt_maxZoom !== undefined ? opt_maxZoom : DEFAULT_MAX_ZOOM;\n var height = getHeight(extent);\n var width = extent_getWidth(extent);\n var tileSize = toSize(opt_tileSize !== undefined ? opt_tileSize : DEFAULT_TILE_SIZE);\n var maxResolution = opt_maxResolution > 0 ? opt_maxResolution : Math.max(width / tileSize[0], height / tileSize[1]);\n var length = maxZoom + 1;\n var resolutions = new Array(length);\n\n for (var z = 0; z < length; ++z) {\n resolutions[z] = maxResolution / Math.pow(2, z);\n }\n\n return resolutions;\n}\n/**\n * @param {import("./proj.js").ProjectionLike} projection Projection.\n * @param {number=} opt_maxZoom Maximum zoom level (default is\n * DEFAULT_MAX_ZOOM).\n * @param {number|import("./size.js").Size=} opt_tileSize Tile size (default uses\n * DEFAULT_TILE_SIZE).\n * @param {import("./extent/Corner.js").default=} opt_corner Extent corner (default is `\'top-left\'`).\n * @return {!TileGrid} TileGrid instance.\n */\n\n\nfunction createForProjection(projection, opt_maxZoom, opt_tileSize, opt_corner) {\n var extent = extentFromProjection(projection);\n return createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner);\n}\n/**\n * Generate a tile grid extent from a projection. If the projection has an\n * extent, it is used. If not, a global extent is assumed.\n * @param {import("./proj.js").ProjectionLike} projection Projection.\n * @return {import("./extent.js").Extent} Extent.\n */\n\nfunction extentFromProjection(projection) {\n projection = proj_get(projection);\n var extent = projection.getExtent();\n\n if (!extent) {\n var half = 180 * METERS_PER_UNIT[proj_Units.DEGREES] / projection.getMetersPerUnit();\n extent = createOrUpdate(-half, -half, half, half);\n }\n\n return extent;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/source/Tile.js\nvar source_Tile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/source/Tile\n */\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions]\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize]\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {number} [tilePixelRatio]\n * @property {import("../proj.js").ProjectionLike} [projection]\n * @property {import("./State.js").default} [state]\n * @property {import("../tilegrid/TileGrid.js").default} [tileGrid]\n * @property {boolean} [wrapX=true]\n * @property {number} [transition]\n * @property {string} [key]\n * @property {number} [zDirection=0]\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for sources providing images divided into a tile grid.\n * @abstract\n * @api\n */\n\nvar TileSource =\n/** @class */\nfunction (_super) {\n source_Tile_extends(TileSource, _super);\n /**\n * @param {Options} options SourceTile source options.\n */\n\n\n function TileSource(options) {\n var _this = _super.call(this, {\n attributions: options.attributions,\n attributionsCollapsible: options.attributionsCollapsible,\n projection: options.projection,\n state: options.state,\n wrapX: options.wrapX\n }) || this;\n /**\n * @private\n * @type {boolean}\n */\n\n\n _this.opaque_ = options.opaque !== undefined ? options.opaque : false;\n /**\n * @private\n * @type {number}\n */\n\n _this.tilePixelRatio_ = options.tilePixelRatio !== undefined ? options.tilePixelRatio : 1;\n /**\n * @protected\n * @type {import("../tilegrid/TileGrid.js").default}\n */\n\n _this.tileGrid = options.tileGrid !== undefined ? options.tileGrid : null;\n var tileSize = [256, 256];\n var tileGrid = options.tileGrid;\n\n if (tileGrid) {\n toSize(tileGrid.getTileSize(tileGrid.getMinZoom()), tileSize);\n }\n /**\n * @protected\n * @type {import("../TileCache.js").default}\n */\n\n\n _this.tileCache = new ol_TileCache(options.cacheSize || 0);\n /**\n * @protected\n * @type {import("../size.js").Size}\n */\n\n _this.tmpSize = [0, 0];\n /**\n * @private\n * @type {string}\n */\n\n _this.key_ = options.key || \'\';\n /**\n * @protected\n * @type {import("../Tile.js").Options}\n */\n\n _this.tileOptions = {\n transition: options.transition\n };\n /**\n * zDirection hint, read by the renderer. Indicates which resolution should be used\n * by a renderer if the views resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @type {number}\n */\n\n _this.zDirection = options.zDirection ? options.zDirection : 0;\n return _this;\n }\n /**\n * @return {boolean} Can expire cache.\n */\n\n\n TileSource.prototype.canExpireCache = function () {\n return this.tileCache.canExpireCache();\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n\n\n TileSource.prototype.expireCache = function (projection, usedTiles) {\n var tileCache = this.getTileCacheForProjection(projection);\n\n if (tileCache) {\n tileCache.expireCache(usedTiles);\n }\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @param {number} z Zoom level.\n * @param {import("../TileRange.js").default} tileRange Tile range.\n * @param {function(import("../Tile.js").default):(boolean|void)} callback Called with each\n * loaded tile. If the callback returns `false`, the tile will not be\n * considered loaded.\n * @return {boolean} The tile range is fully covered with loaded tiles.\n */\n\n\n TileSource.prototype.forEachLoadedTile = function (projection, z, tileRange, callback) {\n var tileCache = this.getTileCacheForProjection(projection);\n\n if (!tileCache) {\n return false;\n }\n\n var covered = true;\n var tile, tileCoordKey, loaded;\n\n for (var x = tileRange.minX; x <= tileRange.maxX; ++x) {\n for (var y = tileRange.minY; y <= tileRange.maxY; ++y) {\n tileCoordKey = getKeyZXY(z, x, y);\n loaded = false;\n\n if (tileCache.containsKey(tileCoordKey)) {\n tile =\n /** @type {!import("../Tile.js").default} */\n tileCache.get(tileCoordKey);\n loaded = tile.getState() === TileState.LOADED;\n\n if (loaded) {\n loaded = callback(tile) !== false;\n }\n }\n\n if (!loaded) {\n covered = false;\n }\n }\n }\n\n return covered;\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {number} Gutter.\n */\n\n\n TileSource.prototype.getGutterForProjection = function (projection) {\n return 0;\n };\n /**\n * Return the key to be used for all tiles in the source.\n * @return {string} The key for all tiles.\n * @protected\n */\n\n\n TileSource.prototype.getKey = function () {\n return this.key_;\n };\n /**\n * Set the value to be used as the key for all tiles in the source.\n * @param {string} key The key for tiles.\n * @protected\n */\n\n\n TileSource.prototype.setKey = function (key) {\n if (this.key_ !== key) {\n this.key_ = key;\n this.changed();\n }\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {boolean} Opaque.\n */\n\n\n TileSource.prototype.getOpaque = function (projection) {\n return this.opaque_;\n };\n /**\n * @return {Array<number>} Resolutions.\n */\n\n\n TileSource.prototype.getResolutions = function () {\n return this.tileGrid.getResolutions();\n };\n /**\n * @abstract\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../Tile.js").default} Tile.\n */\n\n\n TileSource.prototype.getTile = function (z, x, y, pixelRatio, projection) {\n return util_abstract();\n };\n /**\n * Return the tile grid of the tile source.\n * @return {import("../tilegrid/TileGrid.js").default} Tile grid.\n * @api\n */\n\n\n TileSource.prototype.getTileGrid = function () {\n return this.tileGrid;\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../tilegrid/TileGrid.js").default} Tile grid.\n */\n\n\n TileSource.prototype.getTileGridForProjection = function (projection) {\n if (!this.tileGrid) {\n return getForProjection(projection);\n } else {\n return this.tileGrid;\n }\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {import("../TileCache.js").default} Tile cache.\n * @protected\n */\n\n\n TileSource.prototype.getTileCacheForProjection = function (projection) {\n asserts_assert(equivalent(this.getProjection(), projection), 68 // A VectorTile source can only be rendered if it has a projection compatible with the view projection.\n );\n return this.tileCache;\n };\n /**\n * Get the tile pixel ratio for this source. Subclasses may override this\n * method, which is meant to return a supported pixel ratio that matches the\n * provided `pixelRatio` as close as possible.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Tile pixel ratio.\n */\n\n\n TileSource.prototype.getTilePixelRatio = function (pixelRatio) {\n return this.tilePixelRatio_;\n };\n /**\n * @param {number} z Z.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {import("../size.js").Size} Tile size.\n */\n\n\n TileSource.prototype.getTilePixelSize = function (z, pixelRatio, projection) {\n var tileGrid = this.getTileGridForProjection(projection);\n var tilePixelRatio = this.getTilePixelRatio(pixelRatio);\n var tileSize = toSize(tileGrid.getTileSize(z), this.tmpSize);\n\n if (tilePixelRatio == 1) {\n return tileSize;\n } else {\n return size_scale(tileSize, tilePixelRatio, this.tmpSize);\n }\n };\n /**\n * Returns a tile coordinate wrapped around the x-axis. When the tile coordinate\n * is outside the resolution and extent range of the tile grid, `null` will be\n * returned.\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("../proj/Projection.js").default=} opt_projection Projection.\n * @return {import("../tilecoord.js").TileCoord} Tile coordinate to be passed to the tileUrlFunction or\n * null if no tile URL should be created for the passed `tileCoord`.\n */\n\n\n TileSource.prototype.getTileCoordForTileUrlFunction = function (tileCoord, opt_projection) {\n var projection = opt_projection !== undefined ? opt_projection : this.getProjection();\n var tileGrid = this.getTileGridForProjection(projection);\n\n if (this.getWrapX() && projection.isGlobal()) {\n tileCoord = tilegrid_wrapX(tileGrid, tileCoord, projection);\n }\n\n return withinExtentAndZ(tileCoord, tileGrid) ? tileCoord : null;\n };\n /**\n * Remove all cached tiles from the source. The next render cycle will fetch new tiles.\n * @api\n */\n\n\n TileSource.prototype.clear = function () {\n this.tileCache.clear();\n };\n\n TileSource.prototype.refresh = function () {\n this.clear();\n\n _super.prototype.refresh.call(this);\n };\n /**\n * Increases the cache size if needed\n * @param {number} tileCount Minimum number of tiles needed.\n * @param {import("../proj/Projection.js").default} projection Projection.\n */\n\n\n TileSource.prototype.updateCacheSize = function (tileCount, projection) {\n var tileCache = this.getTileCacheForProjection(projection);\n\n if (tileCount > tileCache.highWaterMark) {\n tileCache.highWaterMark = tileCount;\n }\n };\n /**\n * Marks a tile coord as being used, without triggering a load.\n * @abstract\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {import("../proj/Projection.js").default} projection Projection.\n */\n\n\n TileSource.prototype.useTile = function (z, x, y, projection) {};\n\n return TileSource;\n}(source_Source);\n/**\n * @classdesc\n * Events emitted by {@link module:ol/source/Tile~TileSource} instances are instances of this\n * type.\n */\n\n\nvar TileSourceEvent =\n/** @class */\nfunction (_super) {\n source_Tile_extends(TileSourceEvent, _super);\n /**\n * @param {string} type Type.\n * @param {import("../Tile.js").default} tile The tile.\n */\n\n\n function TileSourceEvent(type, tile) {\n var _this = _super.call(this, type) || this;\n /**\n * The tile related to the event.\n * @type {import("../Tile.js").default}\n * @api\n */\n\n\n _this.tile = tile;\n return _this;\n }\n\n return TileSourceEvent;\n}(Event);\n\n\n/* harmony default export */ var source_Tile = (TileSource);\n;// CONCATENATED MODULE: ./node_modules/ol/tileurlfunction.js\n/**\n * @module ol/tileurlfunction\n */\n\n\n\n/**\n * @param {string} template Template.\n * @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.\n * @return {import("./Tile.js").UrlFunction} Tile URL function.\n */\n\nfunction createFromTemplate(template, tileGrid) {\n var zRegEx = /\\{z\\}/g;\n var xRegEx = /\\{x\\}/g;\n var yRegEx = /\\{y\\}/g;\n var dashYRegEx = /\\{-y\\}/g;\n return (\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile Coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n function (tileCoord, pixelRatio, projection) {\n if (!tileCoord) {\n return undefined;\n } else {\n return template.replace(zRegEx, tileCoord[0].toString()).replace(xRegEx, tileCoord[1].toString()).replace(yRegEx, tileCoord[2].toString()).replace(dashYRegEx, function () {\n var z = tileCoord[0];\n var range = tileGrid.getFullTileRange(z);\n asserts_assert(range, 55); // The {-y} placeholder requires a tile grid with extent\n\n var y = range.getHeight() - tileCoord[2] - 1;\n return y.toString();\n });\n }\n }\n );\n}\n/**\n * @param {Array<string>} templates Templates.\n * @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.\n * @return {import("./Tile.js").UrlFunction} Tile URL function.\n */\n\nfunction createFromTemplates(templates, tileGrid) {\n var len = templates.length;\n var tileUrlFunctions = new Array(len);\n\n for (var i = 0; i < len; ++i) {\n tileUrlFunctions[i] = createFromTemplate(templates[i], tileGrid);\n }\n\n return createFromTileUrlFunctions(tileUrlFunctions);\n}\n/**\n * @param {Array<import("./Tile.js").UrlFunction>} tileUrlFunctions Tile URL Functions.\n * @return {import("./Tile.js").UrlFunction} Tile URL function.\n */\n\nfunction createFromTileUrlFunctions(tileUrlFunctions) {\n if (tileUrlFunctions.length === 1) {\n return tileUrlFunctions[0];\n }\n\n return (\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile Coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n function (tileCoord, pixelRatio, projection) {\n if (!tileCoord) {\n return undefined;\n } else {\n var h = hash(tileCoord);\n var index = math_modulo(h, tileUrlFunctions.length);\n return tileUrlFunctions[index](tileCoord, pixelRatio, projection);\n }\n }\n );\n}\n/**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n\nfunction nullTileUrlFunction(tileCoord, pixelRatio, projection) {\n return undefined;\n}\n/**\n * @param {string} url URL.\n * @return {Array<string>} Array of urls.\n */\n\nfunction expandUrl(url) {\n var urls = [];\n var match = /\\{([a-z])-([a-z])\\}/.exec(url);\n\n if (match) {\n // char range\n var startCharCode = match[1].charCodeAt(0);\n var stopCharCode = match[2].charCodeAt(0);\n var charCode = void 0;\n\n for (charCode = startCharCode; charCode <= stopCharCode; ++charCode) {\n urls.push(url.replace(match[0], String.fromCharCode(charCode)));\n }\n\n return urls;\n }\n\n match = /\\{(\\d+)-(\\d+)\\}/.exec(url);\n\n if (match) {\n // number range\n var stop_1 = parseInt(match[2], 10);\n\n for (var i = parseInt(match[1], 10); i <= stop_1; i++) {\n urls.push(url.replace(match[0], i.toString()));\n }\n\n return urls;\n }\n\n urls.push(url);\n return urls;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/source/UrlTile.js\nvar UrlTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/source/UrlTile\n */\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions]\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize]\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {import("../proj.js").ProjectionLike} [projection]\n * @property {import("./State.js").default} [state]\n * @property {import("../tilegrid/TileGrid.js").default} [tileGrid]\n * @property {import("../Tile.js").LoadFunction} tileLoadFunction\n * @property {number} [tilePixelRatio]\n * @property {import("../Tile.js").UrlFunction} [tileUrlFunction]\n * @property {string} [url]\n * @property {Array<string>} [urls]\n * @property {boolean} [wrapX=true]\n * @property {number} [transition]\n * @property {string} [key]\n * @property {number} [zDirection=0]\n */\n\n/**\n * @classdesc\n * Base class for sources providing tiles divided into a tile grid over http.\n *\n * @fires import("./Tile.js").TileSourceEvent\n */\n\nvar UrlTile =\n/** @class */\nfunction (_super) {\n UrlTile_extends(UrlTile, _super);\n /**\n * @param {Options} options Image tile options.\n */\n\n\n function UrlTile(options) {\n var _this = _super.call(this, {\n attributions: options.attributions,\n cacheSize: options.cacheSize,\n opaque: options.opaque,\n projection: options.projection,\n state: options.state,\n tileGrid: options.tileGrid,\n tilePixelRatio: options.tilePixelRatio,\n wrapX: options.wrapX,\n transition: options.transition,\n key: options.key,\n attributionsCollapsible: options.attributionsCollapsible,\n zDirection: options.zDirection\n }) || this;\n /**\n * @private\n * @type {boolean}\n */\n\n\n _this.generateTileUrlFunction_ = _this.tileUrlFunction === UrlTile.prototype.tileUrlFunction;\n /**\n * @protected\n * @type {import("../Tile.js").LoadFunction}\n */\n\n _this.tileLoadFunction = options.tileLoadFunction;\n\n if (options.tileUrlFunction) {\n _this.tileUrlFunction = options.tileUrlFunction;\n }\n /**\n * @protected\n * @type {!Array<string>|null}\n */\n\n\n _this.urls = null;\n\n if (options.urls) {\n _this.setUrls(options.urls);\n } else if (options.url) {\n _this.setUrl(options.url);\n }\n /**\n * @private\n * @type {!Object<string, boolean>}\n */\n\n\n _this.tileLoadingKeys_ = {};\n return _this;\n }\n /**\n * Return the tile load function of the source.\n * @return {import("../Tile.js").LoadFunction} TileLoadFunction\n * @api\n */\n\n\n UrlTile.prototype.getTileLoadFunction = function () {\n return this.tileLoadFunction;\n };\n /**\n * Return the tile URL function of the source.\n * @return {import("../Tile.js").UrlFunction} TileUrlFunction\n * @api\n */\n\n\n UrlTile.prototype.getTileUrlFunction = function () {\n return Object.getPrototypeOf(this).tileUrlFunction === this.tileUrlFunction ? this.tileUrlFunction.bind(this) : this.tileUrlFunction;\n };\n /**\n * Return the URLs used for this source.\n * When a tileUrlFunction is used instead of url or urls,\n * null will be returned.\n * @return {!Array<string>|null} URLs.\n * @api\n */\n\n\n UrlTile.prototype.getUrls = function () {\n return this.urls;\n };\n /**\n * Handle tile change events.\n * @param {import("../events/Event.js").default} event Event.\n * @protected\n */\n\n\n UrlTile.prototype.handleTileChange = function (event) {\n var tile =\n /** @type {import("../Tile.js").default} */\n event.target;\n var uid = getUid(tile);\n var tileState = tile.getState();\n var type;\n\n if (tileState == TileState.LOADING) {\n this.tileLoadingKeys_[uid] = true;\n type = TileEventType.TILELOADSTART;\n } else if (uid in this.tileLoadingKeys_) {\n delete this.tileLoadingKeys_[uid];\n type = tileState == TileState.ERROR ? TileEventType.TILELOADERROR : tileState == TileState.LOADED ? TileEventType.TILELOADEND : undefined;\n }\n\n if (type != undefined) {\n this.dispatchEvent(new TileSourceEvent(type, tile));\n }\n };\n /**\n * Set the tile load function of the source.\n * @param {import("../Tile.js").LoadFunction} tileLoadFunction Tile load function.\n * @api\n */\n\n\n UrlTile.prototype.setTileLoadFunction = function (tileLoadFunction) {\n this.tileCache.clear();\n this.tileLoadFunction = tileLoadFunction;\n this.changed();\n };\n /**\n * Set the tile URL function of the source.\n * @param {import("../Tile.js").UrlFunction} tileUrlFunction Tile URL function.\n * @param {string=} key Optional new tile key for the source.\n * @api\n */\n\n\n UrlTile.prototype.setTileUrlFunction = function (tileUrlFunction, key) {\n this.tileUrlFunction = tileUrlFunction;\n this.tileCache.pruneExceptNewestZ();\n\n if (typeof key !== \'undefined\') {\n this.setKey(key);\n } else {\n this.changed();\n }\n };\n /**\n * Set the URL to use for requests.\n * @param {string} url URL.\n * @api\n */\n\n\n UrlTile.prototype.setUrl = function (url) {\n var urls = expandUrl(url);\n this.urls = urls;\n this.setUrls(urls);\n };\n /**\n * Set the URLs to use for requests.\n * @param {Array<string>} urls URLs.\n * @api\n */\n\n\n UrlTile.prototype.setUrls = function (urls) {\n this.urls = urls;\n var key = urls.join(\'\\n\');\n\n if (this.generateTileUrlFunction_) {\n this.setTileUrlFunction(createFromTemplates(urls, this.tileGrid), key);\n } else {\n this.setKey(key);\n }\n };\n /**\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n\n\n UrlTile.prototype.tileUrlFunction = function (tileCoord, pixelRatio, projection) {\n return undefined;\n };\n /**\n * Marks a tile coord as being used, without triggering a load.\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n */\n\n\n UrlTile.prototype.useTile = function (z, x, y) {\n var tileCoordKey = getKeyZXY(z, x, y);\n\n if (this.tileCache.containsKey(tileCoordKey)) {\n this.tileCache.get(tileCoordKey);\n }\n };\n\n return UrlTile;\n}(source_Tile);\n\n/* harmony default export */ var source_UrlTile = (UrlTile);\n;// CONCATENATED MODULE: ./node_modules/ol/VectorRenderTile.js\nvar VectorRenderTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/VectorRenderTile\n */\n\n\n\n\n\n/**\n * @typedef {Object} ReplayState\n * @property {boolean} dirty\n * @property {null|import("./render.js").OrderFunction} renderedRenderOrder\n * @property {number} renderedTileRevision\n * @property {number} renderedResolution\n * @property {number} renderedRevision\n * @property {number} renderedZ\n * @property {number} renderedTileResolution\n * @property {number} renderedTileZ\n */\n\n/**\n * @type {Array<HTMLCanvasElement>}\n */\n\nvar canvasPool = [];\n\nvar VectorRenderTile =\n/** @class */\nfunction (_super) {\n VectorRenderTile_extends(VectorRenderTile, _super);\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("./TileState.js").default} state State.\n * @param {import("./tilecoord.js").TileCoord} urlTileCoord Wrapped tile coordinate for source urls.\n * @param {function(VectorRenderTile):Array<import("./VectorTile").default>} getSourceTiles Function\n * to get source tiles for this tile.\n */\n\n\n function VectorRenderTile(tileCoord, state, urlTileCoord, getSourceTiles) {\n var _this = _super.call(this, tileCoord, state, {\n transition: 0\n }) || this;\n /**\n * @private\n * @type {!Object<string, CanvasRenderingContext2D>}\n */\n\n\n _this.context_ = {};\n /**\n * Executor groups by layer uid. Entries are read/written by the renderer.\n * @type {Object<string, Array<import("./render/canvas/ExecutorGroup.js").default>>}\n */\n\n _this.executorGroups = {};\n /**\n * Executor groups for decluttering, by layer uid. Entries are read/written by the renderer.\n * @type {Object<string, Array<import("./render/canvas/ExecutorGroup.js").default>>}\n */\n\n _this.declutterExecutorGroups = {};\n /**\n * Number of loading source tiles. Read/written by the source.\n * @type {number}\n */\n\n _this.loadingSourceTiles = 0;\n /**\n * Tile keys of error source tiles. Read/written by the source.\n * @type {Object<string, boolean>}\n */\n\n _this.errorSourceTileKeys = {};\n /**\n * @type {Object<number, ImageData>}\n */\n\n _this.hitDetectionImageData = {};\n /**\n * @private\n * @type {!Object<string, ReplayState>}\n */\n\n _this.replayState_ = {};\n /**\n * @type {Array<import("./VectorTile.js").default>}\n */\n\n _this.sourceTiles = null;\n /**\n * @type {number}\n */\n\n _this.wantedResolution;\n /**\n * @type {!function():Array<import("./VectorTile.js").default>}\n */\n\n _this.getSourceTiles = getSourceTiles.bind(undefined, _this);\n /**\n * z of the source tiles of the last getSourceTiles call.\n * @type {number}\n */\n\n _this.sourceZ = -1;\n /**\n * True when all tiles for this tile\'s nominal resolution are available.\n * @type {boolean}\n */\n\n _this.hifi = false;\n /**\n * @type {import("./tilecoord.js").TileCoord}\n */\n\n _this.wrappedTileCoord = urlTileCoord;\n return _this;\n }\n /**\n * @param {import("./layer/Layer.js").default} layer Layer.\n * @return {CanvasRenderingContext2D} The rendering context.\n */\n\n\n VectorRenderTile.prototype.getContext = function (layer) {\n var key = getUid(layer);\n\n if (!(key in this.context_)) {\n this.context_[key] = createCanvasContext2D(1, 1, canvasPool);\n }\n\n return this.context_[key];\n };\n /**\n * @param {import("./layer/Layer.js").default} layer Layer.\n * @return {boolean} Tile has a rendering context for the given layer.\n */\n\n\n VectorRenderTile.prototype.hasContext = function (layer) {\n return getUid(layer) in this.context_;\n };\n /**\n * Get the Canvas for this tile.\n * @param {import("./layer/Layer.js").default} layer Layer.\n * @return {HTMLCanvasElement} Canvas.\n */\n\n\n VectorRenderTile.prototype.getImage = function (layer) {\n return this.hasContext(layer) ? this.getContext(layer).canvas : null;\n };\n /**\n * @param {import("./layer/Layer.js").default} layer Layer.\n * @return {ReplayState} The replay state.\n */\n\n\n VectorRenderTile.prototype.getReplayState = function (layer) {\n var key = getUid(layer);\n\n if (!(key in this.replayState_)) {\n this.replayState_[key] = {\n dirty: false,\n renderedRenderOrder: null,\n renderedResolution: NaN,\n renderedRevision: -1,\n renderedTileResolution: NaN,\n renderedTileRevision: -1,\n renderedZ: -1,\n renderedTileZ: -1\n };\n }\n\n return this.replayState_[key];\n };\n /**\n * Load the tile.\n */\n\n\n VectorRenderTile.prototype.load = function () {\n this.getSourceTiles();\n };\n /**\n * Remove from the cache due to expiry\n */\n\n\n VectorRenderTile.prototype.release = function () {\n for (var key in this.context_) {\n canvasPool.push(this.context_[key].canvas);\n delete this.context_[key];\n }\n\n _super.prototype.release.call(this);\n };\n\n return VectorRenderTile;\n}(ol_Tile);\n\n/* harmony default export */ var ol_VectorRenderTile = (VectorRenderTile);\n;// CONCATENATED MODULE: ./node_modules/ol/source/VectorTile.js\n/**\n * @module ol/source/VectorTile\n */\nvar source_VectorTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions] Attributions.\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least twice the number of tiles in the viewport.\n * @property {import("../extent.js").Extent} [extent]\n * @property {import("../format/Feature.js").default} [format] Feature format for tiles. Used and required by the default.\n * @property {boolean} [overlaps=true] This source may have overlapping geometries. Setting this\n * to `false` (e.g. for sources with polygons that represent administrative\n * boundaries or TopoJSON sources) allows the renderer to optimise fill and\n * stroke operations.\n * @property {import("../proj.js").ProjectionLike} [projection=\'EPSG:3857\'] Projection of the tile grid.\n * @property {import("./State.js").default} [state] Source state.\n * @property {typeof import("../VectorTile.js").default} [tileClass] Class used to instantiate image tiles.\n * Default is {@link module:ol/VectorTile}.\n * @property {number} [maxZoom=22] Optional max zoom level. Not used if `tileGrid` is provided.\n * @property {number} [minZoom] Optional min zoom level. Not used if `tileGrid` is provided.\n * @property {number|import("../size.js").Size} [tileSize=512] Optional tile size. Not used if `tileGrid` is provided.\n * @property {number} [maxResolution] Optional tile grid resolution at level zero. Not used if `tileGrid` is provided.\n * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.\n * @property {import("../Tile.js").LoadFunction} [tileLoadFunction]\n * Optional function to load a tile given a URL. Could look like this for pbf tiles:\n * ```js\n * function(tile, url) {\n * tile.setLoader(function(extent, resolution, projection) {\n * fetch(url).then(function(response) {\n * response.arrayBuffer().then(function(data) {\n * const format = tile.getFormat() // ol/format/MVT configured as source format\n * const features = format.readFeatures(data, {\n * extent: extent,\n * featureProjection: projection\n * });\n * tile.setFeatures(features);\n * });\n * });\n * });\n * }\n * ```\n * If you do not need extent, resolution and projection to get the features for a tile (e.g.\n * for GeoJSON tiles), your `tileLoadFunction` does not need a `setLoader()` call. Only make sure\n * to call `setFeatures()` on the tile:\n * ```js\n * const format = new GeoJSON({featureProjection: map.getView().getProjection()});\n * async function tileLoadFunction(tile, url) {\n * const response = await fetch(url);\n * const data = await response.json();\n * tile.setFeatures(format.readFeatures(data));\n * }\n * ```\n * @property {import("../Tile.js").UrlFunction} [tileUrlFunction] Optional function to get tile URL given a tile coordinate and the projection.\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.\n * A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`, may be\n * used instead of defining each one separately in the `urls` option.\n * @property {number} [transition] A duration for tile opacity\n * transitions in milliseconds. A duration of 0 disables the opacity transition.\n * @property {Array<string>} [urls] An array of URL templates.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * When set to `false`, only one world\n * will be rendered. When set to `true`, tiles will be wrapped horizontally to\n * render multiple worlds.\n * @property {number} [zDirection=1] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n */\n\n/**\n * @classdesc\n * Class for layer sources providing vector data divided into a tile grid, to be\n * used with {@link module:ol/layer/VectorTile~VectorTile}. Although this source receives tiles\n * with vector features from the server, it is not meant for feature editing.\n * Features are optimized for rendering, their geometries are clipped at or near\n * tile boundaries and simplified for a view resolution. See\n * {@link module:ol/source/Vector} for vector sources that are suitable for feature\n * editing.\n *\n * @fires import("./Tile.js").TileSourceEvent\n * @api\n */\n\nvar source_VectorTile_VectorTile =\n/** @class */\nfunction (_super) {\n source_VectorTile_extends(VectorTile, _super);\n /**\n * @param {!Options} options Vector tile options.\n */\n\n\n function VectorTile(options) {\n var _this = this;\n\n var projection = options.projection || \'EPSG:3857\';\n var extent = options.extent || extentFromProjection(projection);\n var tileGrid = options.tileGrid || createXYZ({\n extent: extent,\n maxResolution: options.maxResolution,\n maxZoom: options.maxZoom !== undefined ? options.maxZoom : 22,\n minZoom: options.minZoom,\n tileSize: options.tileSize || 512\n });\n _this = _super.call(this, {\n attributions: options.attributions,\n attributionsCollapsible: options.attributionsCollapsible,\n cacheSize: options.cacheSize,\n opaque: false,\n projection: projection,\n state: options.state,\n tileGrid: tileGrid,\n tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : defaultLoadFunction,\n tileUrlFunction: options.tileUrlFunction,\n url: options.url,\n urls: options.urls,\n wrapX: options.wrapX === undefined ? true : options.wrapX,\n transition: options.transition,\n zDirection: options.zDirection === undefined ? 1 : options.zDirection\n }) || this;\n /**\n * @private\n * @type {import("../format/Feature.js").default}\n */\n\n _this.format_ = options.format ? options.format : null;\n /**\n * @type {Object<string, import("./VectorTile").default>}\n */\n\n _this.loadingTiles_ = {};\n /**\n * @private\n * @type {TileCache}\n */\n\n _this.sourceTileCache = new ol_TileCache(_this.tileCache.highWaterMark);\n /**\n * @private\n * @type {boolean}\n */\n\n _this.overlaps_ = options.overlaps == undefined ? true : options.overlaps;\n /**\n * @protected\n * @type {typeof import("../VectorTile.js").default}\n */\n\n _this.tileClass = options.tileClass ? options.tileClass : ol_VectorTile;\n /**\n * @private\n * @type {Object<string, import("../tilegrid/TileGrid.js").default>}\n */\n\n _this.tileGrids_ = {};\n return _this;\n }\n /**\n * Get features whose bounding box intersects the provided extent. Only features for cached\n * tiles for the last rendered zoom level are available in the source. So this method is only\n * suitable for requesting tiles for extents that are currently rendered.\n *\n * Features are returned in random tile order and as they are included in the tiles. This means\n * they can be clipped, duplicated across tiles, and simplified to the render resolution.\n *\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {Array<import("../Feature.js").FeatureLike>} Features.\n * @api\n */\n\n\n VectorTile.prototype.getFeaturesInExtent = function (extent) {\n var features = [];\n var tileCache = this.tileCache;\n\n if (tileCache.getCount() === 0) {\n return features;\n }\n\n var z = fromKey(tileCache.peekFirstKey())[0];\n var tileGrid = this.tileGrid;\n tileCache.forEach(function (tile) {\n if (tile.tileCoord[0] !== z || tile.getState() !== TileState.LOADED) {\n return;\n }\n\n var sourceTiles = tile.getSourceTiles();\n\n for (var i = 0, ii = sourceTiles.length; i < ii; ++i) {\n var sourceTile = sourceTiles[i];\n var tileCoord = sourceTile.tileCoord;\n\n if (intersects(extent, tileGrid.getTileCoordExtent(tileCoord))) {\n var tileFeatures = sourceTile.getFeatures();\n\n if (tileFeatures) {\n for (var j = 0, jj = tileFeatures.length; j < jj; ++j) {\n var candidate = tileFeatures[j];\n var geometry = candidate.getGeometry();\n\n if (intersects(extent, geometry.getExtent())) {\n features.push(candidate);\n }\n }\n }\n }\n }\n });\n return features;\n };\n /**\n * @return {boolean} The source can have overlapping geometries.\n */\n\n\n VectorTile.prototype.getOverlaps = function () {\n return this.overlaps_;\n };\n /**\n * clear {@link module:ol/TileCache~TileCache} and delete all source tiles\n * @api\n */\n\n\n VectorTile.prototype.clear = function () {\n this.tileCache.clear();\n this.sourceTileCache.clear();\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n\n\n VectorTile.prototype.expireCache = function (projection, usedTiles) {\n _super.prototype.expireCache.call(this, projection, usedTiles);\n\n this.sourceTileCache.expireCache({});\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection").default} projection Projection.\n * @param {VectorRenderTile} tile Vector image tile.\n * @return {Array<import("../VectorTile").default>} Tile keys.\n */\n\n\n VectorTile.prototype.getSourceTiles = function (pixelRatio, projection, tile) {\n var urlTileCoord = tile.wrappedTileCoord;\n var tileGrid = this.getTileGridForProjection(projection);\n var extent = tileGrid.getTileCoordExtent(urlTileCoord);\n var z = urlTileCoord[0];\n var resolution = tileGrid.getResolution(z); // make extent 1 pixel smaller so we don\'t load tiles for < 0.5 pixel render space\n\n buffer(extent, -resolution, extent);\n var sourceTileGrid = this.tileGrid;\n var sourceExtent = sourceTileGrid.getExtent();\n\n if (sourceExtent) {\n getIntersection(extent, sourceExtent, extent);\n }\n\n var sourceZ = sourceTileGrid.getZForResolution(resolution, 1);\n var minZoom = sourceTileGrid.getMinZoom();\n var previousSourceTiles = tile.sourceTiles;\n var sourceTiles, covered, loadedZ;\n\n if (previousSourceTiles && previousSourceTiles.length > 0 && previousSourceTiles[0].tileCoord[0] === sourceZ) {\n sourceTiles = previousSourceTiles;\n covered = true;\n loadedZ = sourceZ;\n } else {\n sourceTiles = [];\n loadedZ = sourceZ + 1;\n\n do {\n --loadedZ;\n covered = true;\n sourceTileGrid.forEachTileCoord(extent, loadedZ, function (sourceTileCoord) {\n var tileUrl = this.tileUrlFunction(sourceTileCoord, pixelRatio, projection);\n var sourceTile;\n\n if (tileUrl !== undefined) {\n if (this.sourceTileCache.containsKey(tileUrl)) {\n sourceTile = this.sourceTileCache.get(tileUrl);\n var state = sourceTile.getState();\n\n if (state === TileState.LOADED || state === TileState.ERROR || state === TileState.EMPTY) {\n sourceTiles.push(sourceTile);\n return;\n }\n } else if (loadedZ === sourceZ) {\n sourceTile = new this.tileClass(sourceTileCoord, TileState.IDLE, tileUrl, this.format_, this.tileLoadFunction);\n sourceTile.extent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);\n sourceTile.projection = projection;\n sourceTile.resolution = sourceTileGrid.getResolution(sourceTileCoord[0]);\n this.sourceTileCache.set(tileUrl, sourceTile);\n sourceTile.addEventListener(EventType.CHANGE, this.handleTileChange.bind(this));\n sourceTile.load();\n }\n }\n\n covered = covered && sourceTile && sourceTile.getState() === TileState.LOADED;\n\n if (!sourceTile) {\n return;\n }\n\n if (sourceTile.getState() !== TileState.EMPTY && tile.getState() === TileState.IDLE) {\n tile.loadingSourceTiles++;\n sourceTile.addEventListener(EventType.CHANGE, function listenChange() {\n var state = sourceTile.getState();\n var sourceTileKey = sourceTile.getKey();\n\n if (state === TileState.LOADED || state === TileState.ERROR) {\n if (state === TileState.LOADED) {\n sourceTile.removeEventListener(EventType.CHANGE, listenChange);\n tile.loadingSourceTiles--;\n delete tile.errorSourceTileKeys[sourceTileKey];\n } else if (state === TileState.ERROR) {\n tile.errorSourceTileKeys[sourceTileKey] = true;\n }\n\n var errorTileCount = Object.keys(tile.errorSourceTileKeys).length;\n\n if (tile.loadingSourceTiles - errorTileCount === 0) {\n tile.hifi = errorTileCount === 0;\n tile.sourceZ = sourceZ;\n tile.setState(TileState.LOADED);\n }\n }\n });\n }\n }.bind(this));\n\n if (!covered) {\n sourceTiles.length = 0;\n }\n } while (!covered && loadedZ > minZoom);\n }\n\n if (tile.getState() === TileState.IDLE) {\n tile.setState(TileState.LOADING);\n }\n\n if (covered) {\n tile.hifi = sourceZ === loadedZ;\n tile.sourceZ = loadedZ;\n\n if (tile.getState() < TileState.LOADED) {\n tile.setState(TileState.LOADED);\n } else if (!previousSourceTiles || !equals(sourceTiles, previousSourceTiles)) {\n tile.sourceTiles = sourceTiles;\n }\n }\n\n return sourceTiles;\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!VectorRenderTile} Tile.\n */\n\n\n VectorTile.prototype.getTile = function (z, x, y, pixelRatio, projection) {\n var coordKey = getKeyZXY(z, x, y);\n var key = this.getKey();\n var tile;\n\n if (this.tileCache.containsKey(coordKey)) {\n tile = this.tileCache.get(coordKey);\n\n if (tile.key === key) {\n return tile;\n }\n }\n\n var tileCoord = [z, x, y];\n var urlTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection);\n var sourceExtent = this.getTileGrid().getExtent();\n var tileGrid = this.getTileGridForProjection(projection);\n\n if (urlTileCoord && sourceExtent) {\n var tileExtent = tileGrid.getTileCoordExtent(urlTileCoord); // make extent 1 pixel smaller so we don\'t load tiles for < 0.5 pixel render space\n\n buffer(tileExtent, -tileGrid.getResolution(z), tileExtent);\n\n if (!intersects(sourceExtent, tileExtent)) {\n urlTileCoord = null;\n }\n }\n\n var empty = true;\n\n if (urlTileCoord !== null) {\n var sourceTileGrid = this.tileGrid;\n var resolution = tileGrid.getResolution(z);\n var sourceZ = sourceTileGrid.getZForResolution(resolution, 1); // make extent 1 pixel smaller so we don\'t load tiles for < 0.5 pixel render space\n\n var extent = tileGrid.getTileCoordExtent(urlTileCoord);\n buffer(extent, -resolution, extent);\n sourceTileGrid.forEachTileCoord(extent, sourceZ, function (sourceTileCoord) {\n empty = empty && !this.tileUrlFunction(sourceTileCoord, pixelRatio, projection);\n }.bind(this));\n }\n\n var newTile = new ol_VectorRenderTile(tileCoord, empty ? TileState.EMPTY : TileState.IDLE, urlTileCoord, this.getSourceTiles.bind(this, pixelRatio, projection));\n newTile.key = key;\n\n if (tile) {\n newTile.interimTile = tile;\n newTile.refreshInterimChain();\n this.tileCache.replace(coordKey, newTile);\n } else {\n this.tileCache.set(coordKey, newTile);\n }\n\n return newTile;\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../tilegrid/TileGrid.js").default} Tile grid.\n */\n\n\n VectorTile.prototype.getTileGridForProjection = function (projection) {\n var code = projection.getCode();\n var tileGrid = this.tileGrids_[code];\n\n if (!tileGrid) {\n // A tile grid that matches the tile size of the source tile grid is more\n // likely to have 1:1 relationships between source tiles and rendered tiles.\n var sourceTileGrid = this.tileGrid;\n tileGrid = createForProjection(projection, undefined, sourceTileGrid ? sourceTileGrid.getTileSize(sourceTileGrid.getMinZoom()) : undefined);\n this.tileGrids_[code] = tileGrid;\n }\n\n return tileGrid;\n };\n /**\n * Get the tile pixel ratio for this source.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Tile pixel ratio.\n */\n\n\n VectorTile.prototype.getTilePixelRatio = function (pixelRatio) {\n return pixelRatio;\n };\n /**\n * @param {number} z Z.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {import("../size.js").Size} Tile size.\n */\n\n\n VectorTile.prototype.getTilePixelSize = function (z, pixelRatio, projection) {\n var tileGrid = this.getTileGridForProjection(projection);\n var tileSize = toSize(tileGrid.getTileSize(z), this.tmpSize);\n return [Math.round(tileSize[0] * pixelRatio), Math.round(tileSize[1] * pixelRatio)];\n };\n /**\n * Increases the cache size if needed\n * @param {number} tileCount Minimum number of tiles needed.\n * @param {import("../proj/Projection.js").default} projection Projection.\n */\n\n\n VectorTile.prototype.updateCacheSize = function (tileCount, projection) {\n _super.prototype.updateCacheSize.call(this, tileCount * 2, projection);\n };\n\n return VectorTile;\n}(source_UrlTile);\n\n/* harmony default export */ var source_VectorTile = (source_VectorTile_VectorTile);\n/**\n * Sets the loader for a tile.\n * @param {import("../VectorTile.js").default} tile Vector tile.\n * @param {string} url URL.\n */\n\nfunction defaultLoadFunction(tile, url) {\n tile.setLoader(\n /**\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import("../proj/Projection.js").default} projection Projection.\n */\n function (extent, resolution, projection) {\n loadFeaturesXhr(url, tile.getFormat(), extent, resolution, projection, tile.onLoad.bind(tile), tile.onError.bind(tile));\n });\n}\n;// CONCATENATED MODULE: ./node_modules/ol/format/Feature.js\n/**\n * @module ol/format/Feature\n */\n\n\n\n\n/**\n * @typedef {Object} ReadOptions\n * @property {import("../proj.js").ProjectionLike} [dataProjection] Projection of the data we are reading.\n * If not provided, the projection will be derived from the data (where possible) or\n * the `dataProjection` of the format is assigned (where set). If the projection\n * can not be derived from the data and if no `dataProjection` is set for a format,\n * the features will not be reprojected.\n * @property {import("../extent.js").Extent} [extent] Tile extent in map units of the tile being read.\n * This is only required when reading data with tile pixels as geometry units. When configured,\n * a `dataProjection` with `TILE_PIXELS` as `units` and the tile\'s pixel extent as `extent` needs to be\n * provided.\n * @property {import("../proj.js").ProjectionLike} [featureProjection] Projection of the feature geometries\n * created by the format reader. If not provided, features will be returned in the\n * `dataProjection`.\n */\n\n/**\n * @typedef {Object} WriteOptions\n * @property {import("../proj.js").ProjectionLike} [dataProjection] Projection of the data we are writing.\n * If not provided, the `dataProjection` of the format is assigned (where set).\n * If no `dataProjection` is set for a format, the features will be returned\n * in the `featureProjection`.\n * @property {import("../proj.js").ProjectionLike} [featureProjection] Projection of the feature geometries\n * that will be serialized by the format writer. If not provided, geometries are assumed\n * to be in the `dataProjection` if that is set; in other words, they are not transformed.\n * @property {boolean} [rightHanded] When writing geometries, follow the right-hand\n * rule for linear ring orientation. This means that polygons will have counter-clockwise\n * exterior rings and clockwise interior rings. By default, coordinates are serialized\n * as they are provided at construction. If `true`, the right-hand rule will\n * be applied. If `false`, the left-hand rule will be applied (clockwise for\n * exterior and counter-clockwise for interior rings). Note that not all\n * formats support this. The GeoJSON format does use this property when writing\n * geometries.\n * @property {number} [decimals] Maximum number of decimal places for coordinates.\n * Coordinates are stored internally as floats, but floating-point arithmetic can create\n * coordinates with a large number of decimal places, not generally wanted on output.\n * Set a number here to round coordinates. Can also be used to ensure that\n * coordinates read in can be written back out with the same number of decimals.\n * Default is no rounding.\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for feature formats.\n * {@link module:ol/format/Feature~FeatureFormat} subclasses provide the ability to decode and encode\n * {@link module:ol/Feature~Feature} objects from a variety of commonly used geospatial\n * file formats. See the documentation for each format for more details.\n *\n * @abstract\n * @api\n */\n\nvar FeatureFormat =\n/** @class */\nfunction () {\n function FeatureFormat() {\n /**\n * @protected\n * @type {import("../proj/Projection.js").default}\n */\n this.dataProjection = null;\n /**\n * @protected\n * @type {import("../proj/Projection.js").default}\n */\n\n this.defaultFeatureProjection = null;\n }\n /**\n * Adds the data projection to the read options.\n * @param {Document|Element|Object|string} source Source.\n * @param {ReadOptions=} opt_options Options.\n * @return {ReadOptions|undefined} Options.\n * @protected\n */\n\n\n FeatureFormat.prototype.getReadOptions = function (source, opt_options) {\n var options;\n\n if (opt_options) {\n var dataProjection = opt_options.dataProjection ? proj_get(opt_options.dataProjection) : this.readProjection(source);\n\n if (opt_options.extent && dataProjection && dataProjection.getUnits() === proj_Units.TILE_PIXELS) {\n dataProjection = proj_get(dataProjection);\n dataProjection.setWorldExtent(opt_options.extent);\n }\n\n options = {\n dataProjection: dataProjection,\n featureProjection: opt_options.featureProjection\n };\n }\n\n return this.adaptOptions(options);\n };\n /**\n * Sets the `dataProjection` on the options, if no `dataProjection`\n * is set.\n * @param {WriteOptions|ReadOptions|undefined} options\n * Options.\n * @protected\n * @return {WriteOptions|ReadOptions|undefined}\n * Updated options.\n */\n\n\n FeatureFormat.prototype.adaptOptions = function (options) {\n return obj_assign({\n dataProjection: this.dataProjection,\n featureProjection: this.defaultFeatureProjection\n }, options);\n };\n /**\n * @abstract\n * @return {import("./FormatType.js").default} Format.\n */\n\n\n FeatureFormat.prototype.getType = function () {\n return util_abstract();\n };\n /**\n * Read a single feature from a source.\n *\n * @abstract\n * @param {Document|Element|Object|string} source Source.\n * @param {ReadOptions=} opt_options Read options.\n * @return {import("../Feature.js").FeatureLike} Feature.\n */\n\n\n FeatureFormat.prototype.readFeature = function (source, opt_options) {\n return util_abstract();\n };\n /**\n * Read all features from a source.\n *\n * @abstract\n * @param {Document|Element|ArrayBuffer|Object|string} source Source.\n * @param {ReadOptions=} opt_options Read options.\n * @return {Array<import("../Feature.js").FeatureLike>} Features.\n */\n\n\n FeatureFormat.prototype.readFeatures = function (source, opt_options) {\n return util_abstract();\n };\n /**\n * Read a single geometry from a source.\n *\n * @abstract\n * @param {Document|Element|Object|string} source Source.\n * @param {ReadOptions=} opt_options Read options.\n * @return {import("../geom/Geometry.js").default} Geometry.\n */\n\n\n FeatureFormat.prototype.readGeometry = function (source, opt_options) {\n return util_abstract();\n };\n /**\n * Read the projection from a source.\n *\n * @abstract\n * @param {Document|Element|Object|string} source Source.\n * @return {import("../proj/Projection.js").default} Projection.\n */\n\n\n FeatureFormat.prototype.readProjection = function (source) {\n return util_abstract();\n };\n /**\n * Encode a feature in this format.\n *\n * @abstract\n * @param {import("../Feature.js").default} feature Feature.\n * @param {WriteOptions=} opt_options Write options.\n * @return {string} Result.\n */\n\n\n FeatureFormat.prototype.writeFeature = function (feature, opt_options) {\n return util_abstract();\n };\n /**\n * Encode an array of features in this format.\n *\n * @abstract\n * @param {Array<import("../Feature.js").default>} features Features.\n * @param {WriteOptions=} opt_options Write options.\n * @return {string} Result.\n */\n\n\n FeatureFormat.prototype.writeFeatures = function (features, opt_options) {\n return util_abstract();\n };\n /**\n * Write a single geometry in this format.\n *\n * @abstract\n * @param {import("../geom/Geometry.js").default} geometry Geometry.\n * @param {WriteOptions=} opt_options Write options.\n * @return {string} Result.\n */\n\n\n FeatureFormat.prototype.writeGeometry = function (geometry, opt_options) {\n return util_abstract();\n };\n\n return FeatureFormat;\n}();\n\n/* harmony default export */ var Feature = (FeatureFormat);\n/**\n * @param {import("../geom/Geometry.js").default} geometry Geometry.\n * @param {boolean} write Set to true for writing, false for reading.\n * @param {(WriteOptions|ReadOptions)=} opt_options Options.\n * @return {import("../geom/Geometry.js").default} Transformed geometry.\n */\n\nfunction transformGeometryWithOptions(geometry, write, opt_options) {\n var featureProjection = opt_options ? proj_get(opt_options.featureProjection) : null;\n var dataProjection = opt_options ? proj_get(opt_options.dataProjection) : null;\n var transformed;\n\n if (featureProjection && dataProjection && !equivalent(featureProjection, dataProjection)) {\n transformed = (write ? geometry.clone() : geometry).transform(write ? featureProjection : dataProjection, write ? dataProjection : featureProjection);\n } else {\n transformed = geometry;\n }\n\n if (write && opt_options &&\n /** @type {WriteOptions} */\n opt_options.decimals !== undefined) {\n var power_1 = Math.pow(10,\n /** @type {WriteOptions} */\n opt_options.decimals); // if decimals option on write, round each coordinate appropriately\n\n /**\n * @param {Array<number>} coordinates Coordinates.\n * @return {Array<number>} Transformed coordinates.\n */\n\n var transform = function transform(coordinates) {\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n coordinates[i] = Math.round(coordinates[i] * power_1) / power_1;\n }\n\n return coordinates;\n };\n\n if (transformed === geometry) {\n transformed = geometry.clone();\n }\n\n transformed.applyTransform(transform);\n }\n\n return transformed;\n}\n/**\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {ReadOptions=} opt_options Read options.\n * @return {import("../extent.js").Extent} Transformed extent.\n */\n\nfunction transformExtentWithOptions(extent, opt_options) {\n var featureProjection = opt_options ? getProjection(opt_options.featureProjection) : null;\n var dataProjection = opt_options ? getProjection(opt_options.dataProjection) : null;\n\n if (featureProjection && dataProjection && !equivalentProjection(featureProjection, dataProjection)) {\n return transformExtent(extent, dataProjection, featureProjection);\n } else {\n return extent;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/interpolate.js\n/**\n * @module ol/geom/flat/interpolate\n */\n\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} fraction Fraction.\n * @param {Array<number>=} opt_dest Destination.\n * @param {number=} opt_dimension Destination dimension (default is `2`)\n * @return {Array<number>} Destination.\n */\n\nfunction interpolatePoint(flatCoordinates, offset, end, stride, fraction, opt_dest, opt_dimension) {\n var o, t;\n var n = (end - offset) / stride;\n\n if (n === 1) {\n o = offset;\n } else if (n === 2) {\n o = offset;\n t = fraction;\n } else if (n !== 0) {\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1];\n var length_1 = 0;\n var cumulativeLengths = [0];\n\n for (var i = offset + stride; i < end; i += stride) {\n var x2 = flatCoordinates[i];\n var y2 = flatCoordinates[i + 1];\n length_1 += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n cumulativeLengths.push(length_1);\n x1 = x2;\n y1 = y2;\n }\n\n var target = fraction * length_1;\n var index = binarySearch(cumulativeLengths, target);\n\n if (index < 0) {\n t = (target - cumulativeLengths[-index - 2]) / (cumulativeLengths[-index - 1] - cumulativeLengths[-index - 2]);\n o = offset + (-index - 2) * stride;\n } else {\n o = offset + index * stride;\n }\n }\n\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var dest = opt_dest ? opt_dest : new Array(dimension);\n\n for (var i = 0; i < dimension; ++i) {\n dest[i] = o === undefined ? NaN : t === undefined ? flatCoordinates[o + i] : lerp(flatCoordinates[o + i], flatCoordinates[o + stride + i], t);\n }\n\n return dest;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} m M.\n * @param {boolean} extrapolate Extrapolate.\n * @return {import("../../coordinate.js").Coordinate} Coordinate.\n */\n\nfunction lineStringCoordinateAtM(flatCoordinates, offset, end, stride, m, extrapolate) {\n if (end == offset) {\n return null;\n }\n\n var coordinate;\n\n if (m < flatCoordinates[offset + stride - 1]) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(offset, offset + stride);\n coordinate[stride - 1] = m;\n return coordinate;\n } else {\n return null;\n }\n } else if (flatCoordinates[end - 1] < m) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(end - stride, end);\n coordinate[stride - 1] = m;\n return coordinate;\n } else {\n return null;\n }\n } // FIXME use O(1) search\n\n\n if (m == flatCoordinates[offset + stride - 1]) {\n return flatCoordinates.slice(offset, offset + stride);\n }\n\n var lo = offset / stride;\n var hi = end / stride;\n\n while (lo < hi) {\n var mid = lo + hi >> 1;\n\n if (m < flatCoordinates[(mid + 1) * stride - 1]) {\n hi = mid;\n } else {\n lo = mid + 1;\n }\n }\n\n var m0 = flatCoordinates[lo * stride - 1];\n\n if (m == m0) {\n return flatCoordinates.slice((lo - 1) * stride, (lo - 1) * stride + stride);\n }\n\n var m1 = flatCoordinates[(lo + 1) * stride - 1];\n var t = (m - m0) / (m1 - m0);\n coordinate = [];\n\n for (var i = 0; i < stride - 1; ++i) {\n coordinate.push(lerp(flatCoordinates[(lo - 1) * stride + i], flatCoordinates[lo * stride + i], t));\n }\n\n coordinate.push(m);\n return coordinate;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} m M.\n * @param {boolean} extrapolate Extrapolate.\n * @param {boolean} interpolate Interpolate.\n * @return {import("../../coordinate.js").Coordinate} Coordinate.\n */\n\nfunction lineStringsCoordinateAtM(flatCoordinates, offset, ends, stride, m, extrapolate, interpolate) {\n if (interpolate) {\n return lineStringCoordinateAtM(flatCoordinates, offset, ends[ends.length - 1], stride, m, extrapolate);\n }\n\n var coordinate;\n\n if (m < flatCoordinates[stride - 1]) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(0, stride);\n coordinate[stride - 1] = m;\n return coordinate;\n } else {\n return null;\n }\n }\n\n if (flatCoordinates[flatCoordinates.length - 1] < m) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(flatCoordinates.length - stride);\n coordinate[stride - 1] = m;\n return coordinate;\n } else {\n return null;\n }\n }\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n\n if (offset == end) {\n continue;\n }\n\n if (m < flatCoordinates[offset + stride - 1]) {\n return null;\n } else if (m <= flatCoordinates[end - 1]) {\n return lineStringCoordinateAtM(flatCoordinates, offset, end, stride, m, false);\n }\n\n offset = end;\n }\n\n return null;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/LineString.js\nvar LineString_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/LineString\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Linestring geometry.\n *\n * @api\n */\n\nvar LineString =\n/** @class */\nfunction (_super) {\n LineString_extends(LineString, _super);\n /**\n * @param {Array<import("../coordinate.js").Coordinate>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n */\n\n\n function LineString(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import("../coordinate.js").Coordinate}\n */\n\n\n _this.flatMidpoint_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.flatMidpointRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDeltaRevision_ = -1;\n\n if (opt_layout !== undefined && !Array.isArray(coordinates[0])) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n } else {\n _this.setCoordinates(\n /** @type {Array<import("../coordinate.js").Coordinate>} */\n coordinates, opt_layout);\n }\n\n return _this;\n }\n /**\n * Append the passed coordinate to the coordinates of the linestring.\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @api\n */\n\n\n LineString.prototype.appendCoordinate = function (coordinate) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = coordinate.slice();\n } else {\n array_extend(this.flatCoordinates, coordinate);\n }\n\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!LineString} Clone.\n * @api\n */\n\n\n LineString.prototype.clone = function () {\n var lineString = new LineString(this.flatCoordinates.slice(), this.layout);\n lineString.applyProperties(this);\n return lineString;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n LineString.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(maxSquaredDelta(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n\n return assignClosestPoint(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, this.maxDelta_, false, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * Iterate over each segment, calling the provided callback.\n * If the callback returns a truthy value the function returns that\n * value immediately. Otherwise the function returns `false`.\n *\n * @param {function(this: S, import("../coordinate.js").Coordinate, import("../coordinate.js").Coordinate): T} callback Function\n * called for each segment. The function will receive two arguments, the start and end coordinates of the segment.\n * @return {T|boolean} Value.\n * @template T,S\n * @api\n */\n\n\n LineString.prototype.forEachSegment = function (callback) {\n return forEach(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, callback);\n };\n /**\n * Returns the coordinate at `m` using linear interpolation, or `null` if no\n * such coordinate exists.\n *\n * `opt_extrapolate` controls extrapolation beyond the range of Ms in the\n * MultiLineString. If `opt_extrapolate` is `true` then Ms less than the first\n * M will return the first coordinate and Ms greater than the last M will\n * return the last coordinate.\n *\n * @param {number} m M.\n * @param {boolean=} opt_extrapolate Extrapolate. Default is `false`.\n * @return {import("../coordinate.js").Coordinate} Coordinate.\n * @api\n */\n\n\n LineString.prototype.getCoordinateAtM = function (m, opt_extrapolate) {\n if (this.layout != geom_GeometryLayout.XYM && this.layout != geom_GeometryLayout.XYZM) {\n return null;\n }\n\n var extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;\n return lineStringCoordinateAtM(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, m, extrapolate);\n };\n /**\n * Return the coordinates of the linestring.\n * @return {Array<import("../coordinate.js").Coordinate>} Coordinates.\n * @api\n */\n\n\n LineString.prototype.getCoordinates = function () {\n return inflateCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * Return the coordinate at the provided fraction along the linestring.\n * The `fraction` is a number between 0 and 1, where 0 is the start of the\n * linestring and 1 is the end.\n * @param {number} fraction Fraction.\n * @param {import("../coordinate.js").Coordinate=} opt_dest Optional coordinate whose values will\n * be modified. If not provided, a new coordinate will be returned.\n * @return {import("../coordinate.js").Coordinate} Coordinate of the interpolated point.\n * @api\n */\n\n\n LineString.prototype.getCoordinateAt = function (fraction, opt_dest) {\n return interpolatePoint(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, fraction, opt_dest, this.stride);\n };\n /**\n * Return the length of the linestring on projected plane.\n * @return {number} Length (on projected plane).\n * @api\n */\n\n\n LineString.prototype.getLength = function () {\n return lineStringLength(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * @return {Array<number>} Flat midpoint.\n */\n\n\n LineString.prototype.getFlatMidpoint = function () {\n if (this.flatMidpointRevision_ != this.getRevision()) {\n this.flatMidpoint_ = this.getCoordinateAt(0.5, this.flatMidpoint_);\n this.flatMidpointRevision_ = this.getRevision();\n }\n\n return this.flatMidpoint_;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {LineString} Simplified LineString.\n * @protected\n */\n\n\n LineString.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n simplifiedFlatCoordinates.length = douglasPeucker(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n return new LineString(simplifiedFlatCoordinates, geom_GeometryLayout.XY);\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n LineString.prototype.getType = function () {\n return geom_GeometryType.LINE_STRING;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n LineString.prototype.intersectsExtent = function (extent) {\n return intersectsLineString(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, extent);\n };\n /**\n * Set the coordinates of the linestring.\n * @param {!Array<import("../coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n LineString.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 1);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n this.flatCoordinates.length = deflateCoordinates(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n\n return LineString;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_LineString = (LineString);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/MultiLineString.js\nvar MultiLineString_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/MultiLineString\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Multi-linestring geometry.\n *\n * @api\n */\n\nvar MultiLineString =\n/** @class */\nfunction (_super) {\n MultiLineString_extends(MultiLineString, _super);\n /**\n * @param {Array<Array<import("../coordinate.js").Coordinate>|LineString>|Array<number>} coordinates\n * Coordinates or LineString geometries. (For internal use, flat coordinates in\n * combination with `opt_layout` and `opt_ends` are also accepted.)\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @param {Array<number>=} opt_ends Flat coordinate ends for internal use.\n */\n\n\n function MultiLineString(coordinates, opt_layout, opt_ends) {\n var _this = _super.call(this) || this;\n /**\n * @type {Array<number>}\n * @private\n */\n\n\n _this.ends_ = [];\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDeltaRevision_ = -1;\n\n if (Array.isArray(coordinates[0])) {\n _this.setCoordinates(\n /** @type {Array<Array<import("../coordinate.js").Coordinate>>} */\n coordinates, opt_layout);\n } else if (opt_layout !== undefined && opt_ends) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n\n _this.ends_ = opt_ends;\n } else {\n var layout = _this.getLayout();\n\n var lineStrings =\n /** @type {Array<LineString>} */\n coordinates;\n var flatCoordinates = [];\n var ends = [];\n\n for (var i = 0, ii = lineStrings.length; i < ii; ++i) {\n var lineString = lineStrings[i];\n\n if (i === 0) {\n layout = lineString.getLayout();\n }\n\n array_extend(flatCoordinates, lineString.getFlatCoordinates());\n ends.push(flatCoordinates.length);\n }\n\n _this.setFlatCoordinates(layout, flatCoordinates);\n\n _this.ends_ = ends;\n }\n\n return _this;\n }\n /**\n * Append the passed linestring to the multilinestring.\n * @param {LineString} lineString LineString.\n * @api\n */\n\n\n MultiLineString.prototype.appendLineString = function (lineString) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = lineString.getFlatCoordinates().slice();\n } else {\n array_extend(this.flatCoordinates, lineString.getFlatCoordinates().slice());\n }\n\n this.ends_.push(this.flatCoordinates.length);\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!MultiLineString} Clone.\n * @api\n */\n\n\n MultiLineString.prototype.clone = function () {\n var multiLineString = new MultiLineString(this.flatCoordinates.slice(), this.layout, this.ends_.slice());\n multiLineString.applyProperties(this);\n return multiLineString;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n MultiLineString.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(arrayMaxSquaredDelta(this.flatCoordinates, 0, this.ends_, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n\n return assignClosestArrayPoint(this.flatCoordinates, 0, this.ends_, this.stride, this.maxDelta_, false, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * Returns the coordinate at `m` using linear interpolation, or `null` if no\n * such coordinate exists.\n *\n * `opt_extrapolate` controls extrapolation beyond the range of Ms in the\n * MultiLineString. If `opt_extrapolate` is `true` then Ms less than the first\n * M will return the first coordinate and Ms greater than the last M will\n * return the last coordinate.\n *\n * `opt_interpolate` controls interpolation between consecutive LineStrings\n * within the MultiLineString. If `opt_interpolate` is `true` the coordinates\n * will be linearly interpolated between the last coordinate of one LineString\n * and the first coordinate of the next LineString. If `opt_interpolate` is\n * `false` then the function will return `null` for Ms falling between\n * LineStrings.\n *\n * @param {number} m M.\n * @param {boolean=} opt_extrapolate Extrapolate. Default is `false`.\n * @param {boolean=} opt_interpolate Interpolate. Default is `false`.\n * @return {import("../coordinate.js").Coordinate} Coordinate.\n * @api\n */\n\n\n MultiLineString.prototype.getCoordinateAtM = function (m, opt_extrapolate, opt_interpolate) {\n if (this.layout != geom_GeometryLayout.XYM && this.layout != geom_GeometryLayout.XYZM || this.flatCoordinates.length === 0) {\n return null;\n }\n\n var extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;\n var interpolate = opt_interpolate !== undefined ? opt_interpolate : false;\n return lineStringsCoordinateAtM(this.flatCoordinates, 0, this.ends_, this.stride, m, extrapolate, interpolate);\n };\n /**\n * Return the coordinates of the multilinestring.\n * @return {Array<Array<import("../coordinate.js").Coordinate>>} Coordinates.\n * @api\n */\n\n\n MultiLineString.prototype.getCoordinates = function () {\n return inflateCoordinatesArray(this.flatCoordinates, 0, this.ends_, this.stride);\n };\n /**\n * @return {Array<number>} Ends.\n */\n\n\n MultiLineString.prototype.getEnds = function () {\n return this.ends_;\n };\n /**\n * Return the linestring at the specified index.\n * @param {number} index Index.\n * @return {LineString} LineString.\n * @api\n */\n\n\n MultiLineString.prototype.getLineString = function (index) {\n if (index < 0 || this.ends_.length <= index) {\n return null;\n }\n\n return new geom_LineString(this.flatCoordinates.slice(index === 0 ? 0 : this.ends_[index - 1], this.ends_[index]), this.layout);\n };\n /**\n * Return the linestrings of this multilinestring.\n * @return {Array<LineString>} LineStrings.\n * @api\n */\n\n\n MultiLineString.prototype.getLineStrings = function () {\n var flatCoordinates = this.flatCoordinates;\n var ends = this.ends_;\n var layout = this.layout;\n /** @type {Array<LineString>} */\n\n var lineStrings = [];\n var offset = 0;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var lineString = new geom_LineString(flatCoordinates.slice(offset, end), layout);\n lineStrings.push(lineString);\n offset = end;\n }\n\n return lineStrings;\n };\n /**\n * @return {Array<number>} Flat midpoints.\n */\n\n\n MultiLineString.prototype.getFlatMidpoints = function () {\n var midpoints = [];\n var flatCoordinates = this.flatCoordinates;\n var offset = 0;\n var ends = this.ends_;\n var stride = this.stride;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var midpoint = interpolatePoint(flatCoordinates, offset, end, stride, 0.5);\n array_extend(midpoints, midpoint);\n offset = end;\n }\n\n return midpoints;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {MultiLineString} Simplified MultiLineString.\n * @protected\n */\n\n\n MultiLineString.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n var simplifiedEnds = [];\n simplifiedFlatCoordinates.length = douglasPeuckerArray(this.flatCoordinates, 0, this.ends_, this.stride, squaredTolerance, simplifiedFlatCoordinates, 0, simplifiedEnds);\n return new MultiLineString(simplifiedFlatCoordinates, geom_GeometryLayout.XY, simplifiedEnds);\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n MultiLineString.prototype.getType = function () {\n return geom_GeometryType.MULTI_LINE_STRING;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n MultiLineString.prototype.intersectsExtent = function (extent) {\n return intersectsLineStringArray(this.flatCoordinates, 0, this.ends_, this.stride, extent);\n };\n /**\n * Set the coordinates of the multilinestring.\n * @param {!Array<Array<import("../coordinate.js").Coordinate>>} coordinates Coordinates.\n * @param {GeometryLayout=} opt_layout Layout.\n * @api\n */\n\n\n MultiLineString.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 2);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n var ends = deflateCoordinatesArray(this.flatCoordinates, 0, coordinates, this.stride, this.ends_);\n this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];\n this.changed();\n };\n\n return MultiLineString;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_MultiLineString = (MultiLineString);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/MultiPoint.js\nvar MultiPoint_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/MultiPoint\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Multi-point geometry.\n *\n * @api\n */\n\nvar MultiPoint =\n/** @class */\nfunction (_super) {\n MultiPoint_extends(MultiPoint, _super);\n /**\n * @param {Array<import("../coordinate.js").Coordinate>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n */\n\n\n function MultiPoint(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n\n if (opt_layout && !Array.isArray(coordinates[0])) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n } else {\n _this.setCoordinates(\n /** @type {Array<import("../coordinate.js").Coordinate>} */\n coordinates, opt_layout);\n }\n\n return _this;\n }\n /**\n * Append the passed point to this multipoint.\n * @param {Point} point Point.\n * @api\n */\n\n\n MultiPoint.prototype.appendPoint = function (point) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = point.getFlatCoordinates().slice();\n } else {\n array_extend(this.flatCoordinates, point.getFlatCoordinates());\n }\n\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!MultiPoint} Clone.\n * @api\n */\n\n\n MultiPoint.prototype.clone = function () {\n var multiPoint = new MultiPoint(this.flatCoordinates.slice(), this.layout);\n multiPoint.applyProperties(this);\n return multiPoint;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n MultiPoint.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n var flatCoordinates = this.flatCoordinates;\n var stride = this.stride;\n\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n var squaredDistance = math_squaredDistance(x, y, flatCoordinates[i], flatCoordinates[i + 1]);\n\n if (squaredDistance < minSquaredDistance) {\n minSquaredDistance = squaredDistance;\n\n for (var j = 0; j < stride; ++j) {\n closestPoint[j] = flatCoordinates[i + j];\n }\n\n closestPoint.length = stride;\n }\n }\n\n return minSquaredDistance;\n };\n /**\n * Return the coordinates of the multipoint.\n * @return {Array<import("../coordinate.js").Coordinate>} Coordinates.\n * @api\n */\n\n\n MultiPoint.prototype.getCoordinates = function () {\n return inflateCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * Return the point at the specified index.\n * @param {number} index Index.\n * @return {Point} Point.\n * @api\n */\n\n\n MultiPoint.prototype.getPoint = function (index) {\n var n = !this.flatCoordinates ? 0 : this.flatCoordinates.length / this.stride;\n\n if (index < 0 || n <= index) {\n return null;\n }\n\n return new geom_Point(this.flatCoordinates.slice(index * this.stride, (index + 1) * this.stride), this.layout);\n };\n /**\n * Return the points of this multipoint.\n * @return {Array<Point>} Points.\n * @api\n */\n\n\n MultiPoint.prototype.getPoints = function () {\n var flatCoordinates = this.flatCoordinates;\n var layout = this.layout;\n var stride = this.stride;\n /** @type {Array<Point>} */\n\n var points = [];\n\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n var point = new geom_Point(flatCoordinates.slice(i, i + stride), layout);\n points.push(point);\n }\n\n return points;\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n MultiPoint.prototype.getType = function () {\n return geom_GeometryType.MULTI_POINT;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n MultiPoint.prototype.intersectsExtent = function (extent) {\n var flatCoordinates = this.flatCoordinates;\n var stride = this.stride;\n\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n var x = flatCoordinates[i];\n var y = flatCoordinates[i + 1];\n\n if (containsXY(extent, x, y)) {\n return true;\n }\n }\n\n return false;\n };\n /**\n * Set the coordinates of the multipoint.\n * @param {!Array<import("../coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n MultiPoint.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 1);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n this.flatCoordinates.length = deflateCoordinates(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n\n return MultiPoint;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_MultiPoint = (MultiPoint);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/center.js\n/**\n * @module ol/geom/flat/center\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @return {Array<number>} Flat centers.\n */\n\nfunction center_linearRingss(flatCoordinates, offset, endss, stride) {\n var flatCenters = [];\n var extent = createEmpty();\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n extent = createOrUpdateFromFlatCoordinates(flatCoordinates, offset, ends[0], stride);\n flatCenters.push((extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2);\n offset = ends[ends.length - 1];\n }\n\n return flatCenters;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/MultiPolygon.js\nvar MultiPolygon_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/MultiPolygon\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Multi-polygon geometry.\n *\n * @api\n */\n\nvar MultiPolygon =\n/** @class */\nfunction (_super) {\n MultiPolygon_extends(MultiPolygon, _super);\n /**\n * @param {Array<Array<Array<import("../coordinate.js").Coordinate>>|Polygon>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` and `opt_endss` are also accepted.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @param {Array<Array<number>>=} opt_endss Array of ends for internal use with flat coordinates.\n */\n\n\n function MultiPolygon(coordinates, opt_layout, opt_endss) {\n var _this = _super.call(this) || this;\n /**\n * @type {Array<Array<number>>}\n * @private\n */\n\n\n _this.endss_ = [];\n /**\n * @private\n * @type {number}\n */\n\n _this.flatInteriorPointsRevision_ = -1;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.flatInteriorPoints_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDeltaRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.orientedRevision_ = -1;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.orientedFlatCoordinates_ = null;\n\n if (!opt_endss && !Array.isArray(coordinates[0])) {\n var layout = _this.getLayout();\n\n var polygons =\n /** @type {Array<Polygon>} */\n coordinates;\n var flatCoordinates = [];\n var endss = [];\n\n for (var i = 0, ii = polygons.length; i < ii; ++i) {\n var polygon = polygons[i];\n\n if (i === 0) {\n layout = polygon.getLayout();\n }\n\n var offset = flatCoordinates.length;\n var ends = polygon.getEnds();\n\n for (var j = 0, jj = ends.length; j < jj; ++j) {\n ends[j] += offset;\n }\n\n array_extend(flatCoordinates, polygon.getFlatCoordinates());\n endss.push(ends);\n }\n\n opt_layout = layout;\n coordinates = flatCoordinates;\n opt_endss = endss;\n }\n\n if (opt_layout !== undefined && opt_endss) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n\n _this.endss_ = opt_endss;\n } else {\n _this.setCoordinates(\n /** @type {Array<Array<Array<import("../coordinate.js").Coordinate>>>} */\n coordinates, opt_layout);\n }\n\n return _this;\n }\n /**\n * Append the passed polygon to this multipolygon.\n * @param {Polygon} polygon Polygon.\n * @api\n */\n\n\n MultiPolygon.prototype.appendPolygon = function (polygon) {\n /** @type {Array<number>} */\n var ends;\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = polygon.getFlatCoordinates().slice();\n ends = polygon.getEnds().slice();\n this.endss_.push();\n } else {\n var offset = this.flatCoordinates.length;\n array_extend(this.flatCoordinates, polygon.getFlatCoordinates());\n ends = polygon.getEnds().slice();\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n ends[i] += offset;\n }\n }\n\n this.endss_.push(ends);\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!MultiPolygon} Clone.\n * @api\n */\n\n\n MultiPolygon.prototype.clone = function () {\n var len = this.endss_.length;\n var newEndss = new Array(len);\n\n for (var i = 0; i < len; ++i) {\n newEndss[i] = this.endss_[i].slice();\n }\n\n var multiPolygon = new MultiPolygon(this.flatCoordinates.slice(), this.layout, newEndss);\n multiPolygon.applyProperties(this);\n return multiPolygon;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n MultiPolygon.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(multiArrayMaxSquaredDelta(this.flatCoordinates, 0, this.endss_, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n\n return assignClosestMultiArrayPoint(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\n\n MultiPolygon.prototype.containsXY = function (x, y) {\n return linearRingssContainsXY(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, x, y);\n };\n /**\n * Return the area of the multipolygon on projected plane.\n * @return {number} Area (on projected plane).\n * @api\n */\n\n\n MultiPolygon.prototype.getArea = function () {\n return linearRingss(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride);\n };\n /**\n * Get the coordinate array for this geometry. This array has the structure\n * of a GeoJSON coordinate array for multi-polygons.\n *\n * @param {boolean=} opt_right Orient coordinates according to the right-hand\n * rule (counter-clockwise for exterior and clockwise for interior rings).\n * If `false`, coordinates will be oriented according to the left-hand rule\n * (clockwise for exterior and counter-clockwise for interior rings).\n * By default, coordinate orientation will depend on how the geometry was\n * constructed.\n * @return {Array<Array<Array<import("../coordinate.js").Coordinate>>>} Coordinates.\n * @api\n */\n\n\n MultiPolygon.prototype.getCoordinates = function (opt_right) {\n var flatCoordinates;\n\n if (opt_right !== undefined) {\n flatCoordinates = this.getOrientedFlatCoordinates().slice();\n orientLinearRingsArray(flatCoordinates, 0, this.endss_, this.stride, opt_right);\n } else {\n flatCoordinates = this.flatCoordinates;\n }\n\n return inflateMultiCoordinatesArray(flatCoordinates, 0, this.endss_, this.stride);\n };\n /**\n * @return {Array<Array<number>>} Endss.\n */\n\n\n MultiPolygon.prototype.getEndss = function () {\n return this.endss_;\n };\n /**\n * @return {Array<number>} Flat interior points.\n */\n\n\n MultiPolygon.prototype.getFlatInteriorPoints = function () {\n if (this.flatInteriorPointsRevision_ != this.getRevision()) {\n var flatCenters = center_linearRingss(this.flatCoordinates, 0, this.endss_, this.stride);\n this.flatInteriorPoints_ = getInteriorPointsOfMultiArray(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, flatCenters);\n this.flatInteriorPointsRevision_ = this.getRevision();\n }\n\n return this.flatInteriorPoints_;\n };\n /**\n * Return the interior points as {@link module:ol/geom/MultiPoint multipoint}.\n * @return {MultiPoint} Interior points as XYM coordinates, where M is\n * the length of the horizontal intersection that the point belongs to.\n * @api\n */\n\n\n MultiPolygon.prototype.getInteriorPoints = function () {\n return new geom_MultiPoint(this.getFlatInteriorPoints().slice(), geom_GeometryLayout.XYM);\n };\n /**\n * @return {Array<number>} Oriented flat coordinates.\n */\n\n\n MultiPolygon.prototype.getOrientedFlatCoordinates = function () {\n if (this.orientedRevision_ != this.getRevision()) {\n var flatCoordinates = this.flatCoordinates;\n\n if (linearRingssAreOriented(flatCoordinates, 0, this.endss_, this.stride)) {\n this.orientedFlatCoordinates_ = flatCoordinates;\n } else {\n this.orientedFlatCoordinates_ = flatCoordinates.slice();\n this.orientedFlatCoordinates_.length = orientLinearRingsArray(this.orientedFlatCoordinates_, 0, this.endss_, this.stride);\n }\n\n this.orientedRevision_ = this.getRevision();\n }\n\n return this.orientedFlatCoordinates_;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {MultiPolygon} Simplified MultiPolygon.\n * @protected\n */\n\n\n MultiPolygon.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n var simplifiedEndss = [];\n simplifiedFlatCoordinates.length = quantizeMultiArray(this.flatCoordinates, 0, this.endss_, this.stride, Math.sqrt(squaredTolerance), simplifiedFlatCoordinates, 0, simplifiedEndss);\n return new MultiPolygon(simplifiedFlatCoordinates, geom_GeometryLayout.XY, simplifiedEndss);\n };\n /**\n * Return the polygon at the specified index.\n * @param {number} index Index.\n * @return {Polygon} Polygon.\n * @api\n */\n\n\n MultiPolygon.prototype.getPolygon = function (index) {\n if (index < 0 || this.endss_.length <= index) {\n return null;\n }\n\n var offset;\n\n if (index === 0) {\n offset = 0;\n } else {\n var prevEnds = this.endss_[index - 1];\n offset = prevEnds[prevEnds.length - 1];\n }\n\n var ends = this.endss_[index].slice();\n var end = ends[ends.length - 1];\n\n if (offset !== 0) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n ends[i] -= offset;\n }\n }\n\n return new geom_Polygon(this.flatCoordinates.slice(offset, end), this.layout, ends);\n };\n /**\n * Return the polygons of this multipolygon.\n * @return {Array<Polygon>} Polygons.\n * @api\n */\n\n\n MultiPolygon.prototype.getPolygons = function () {\n var layout = this.layout;\n var flatCoordinates = this.flatCoordinates;\n var endss = this.endss_;\n var polygons = [];\n var offset = 0;\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i].slice();\n var end = ends[ends.length - 1];\n\n if (offset !== 0) {\n for (var j = 0, jj = ends.length; j < jj; ++j) {\n ends[j] -= offset;\n }\n }\n\n var polygon = new geom_Polygon(flatCoordinates.slice(offset, end), layout, ends);\n polygons.push(polygon);\n offset = end;\n }\n\n return polygons;\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n MultiPolygon.prototype.getType = function () {\n return geom_GeometryType.MULTI_POLYGON;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n MultiPolygon.prototype.intersectsExtent = function (extent) {\n return intersectsLinearRingMultiArray(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, extent);\n };\n /**\n * Set the coordinates of the multipolygon.\n * @param {!Array<Array<Array<import("../coordinate.js").Coordinate>>>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n MultiPolygon.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 3);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n var endss = deflateMultiCoordinatesArray(this.flatCoordinates, 0, coordinates, this.stride, this.endss_);\n\n if (endss.length === 0) {\n this.flatCoordinates.length = 0;\n } else {\n var lastEnds = endss[endss.length - 1];\n this.flatCoordinates.length = lastEnds.length === 0 ? 0 : lastEnds[lastEnds.length - 1];\n }\n\n this.changed();\n };\n\n return MultiPolygon;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_MultiPolygon = (MultiPolygon);\n// EXTERNAL MODULE: ./node_modules/pbf/index.js\nvar node_modules_pbf = __webpack_require__(4362);\nvar pbf_default = /*#__PURE__*/__webpack_require__.n(node_modules_pbf);\n;// CONCATENATED MODULE: ./node_modules/ol/render/Feature.js\n/**\n * @module ol/render/Feature\n */\n\n\n\n\n\n\n\n\n\n/**\n * @type {import("../transform.js").Transform}\n */\n\nvar Feature_tmpTransform = create();\n/**\n * Lightweight, read-only, {@link module:ol/Feature~Feature} and {@link module:ol/geom/Geometry~Geometry} like\n * structure, optimized for vector tile rendering and styling. Geometry access\n * through the API is limited to getting the type and extent of the geometry.\n */\n\nvar RenderFeature =\n/** @class */\nfunction () {\n /**\n * @param {import("../geom/GeometryType.js").default} type Geometry type.\n * @param {Array<number>} flatCoordinates Flat coordinates. These always need\n * to be right-handed for polygons.\n * @param {Array<number>|Array<Array<number>>} ends Ends or Endss.\n * @param {Object<string, *>} properties Properties.\n * @param {number|string|undefined} id Feature id.\n */\n function RenderFeature(type, flatCoordinates, ends, properties, id) {\n /**\n * @private\n * @type {import("../extent.js").Extent|undefined}\n */\n this.extent_;\n /**\n * @private\n * @type {number|string|undefined}\n */\n\n this.id_ = id;\n /**\n * @private\n * @type {import("../geom/GeometryType.js").default}\n */\n\n this.type_ = type;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.flatCoordinates_ = flatCoordinates;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.flatInteriorPoints_ = null;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.flatMidpoints_ = null;\n /**\n * @private\n * @type {Array<number>|Array<Array<number>>}\n */\n\n this.ends_ = ends;\n /**\n * @private\n * @type {Object<string, *>}\n */\n\n this.properties_ = properties;\n }\n /**\n * Get a feature property by its key.\n * @param {string} key Key\n * @return {*} Value for the requested key.\n * @api\n */\n\n\n RenderFeature.prototype.get = function (key) {\n return this.properties_[key];\n };\n /**\n * Get the extent of this feature\'s geometry.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n RenderFeature.prototype.getExtent = function () {\n if (!this.extent_) {\n this.extent_ = this.type_ === geom_GeometryType.POINT ? createOrUpdateFromCoordinate(this.flatCoordinates_) : createOrUpdateFromFlatCoordinates(this.flatCoordinates_, 0, this.flatCoordinates_.length, 2);\n }\n\n return this.extent_;\n };\n /**\n * @return {Array<number>} Flat interior points.\n */\n\n\n RenderFeature.prototype.getFlatInteriorPoint = function () {\n if (!this.flatInteriorPoints_) {\n var flatCenter = getCenter(this.getExtent());\n this.flatInteriorPoints_ = getInteriorPointOfArray(this.flatCoordinates_, 0,\n /** @type {Array<number>} */\n this.ends_, 2, flatCenter, 0);\n }\n\n return this.flatInteriorPoints_;\n };\n /**\n * @return {Array<number>} Flat interior points.\n */\n\n\n RenderFeature.prototype.getFlatInteriorPoints = function () {\n if (!this.flatInteriorPoints_) {\n var flatCenters = center_linearRingss(this.flatCoordinates_, 0,\n /** @type {Array<Array<number>>} */\n this.ends_, 2);\n this.flatInteriorPoints_ = getInteriorPointsOfMultiArray(this.flatCoordinates_, 0,\n /** @type {Array<Array<number>>} */\n this.ends_, 2, flatCenters);\n }\n\n return this.flatInteriorPoints_;\n };\n /**\n * @return {Array<number>} Flat midpoint.\n */\n\n\n RenderFeature.prototype.getFlatMidpoint = function () {\n if (!this.flatMidpoints_) {\n this.flatMidpoints_ = interpolatePoint(this.flatCoordinates_, 0, this.flatCoordinates_.length, 2, 0.5);\n }\n\n return this.flatMidpoints_;\n };\n /**\n * @return {Array<number>} Flat midpoints.\n */\n\n\n RenderFeature.prototype.getFlatMidpoints = function () {\n if (!this.flatMidpoints_) {\n this.flatMidpoints_ = [];\n var flatCoordinates = this.flatCoordinates_;\n var offset = 0;\n var ends =\n /** @type {Array<number>} */\n this.ends_;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var midpoint = interpolatePoint(flatCoordinates, offset, end, 2, 0.5);\n array_extend(this.flatMidpoints_, midpoint);\n offset = end;\n }\n }\n\n return this.flatMidpoints_;\n };\n /**\n * Get the feature identifier. This is a stable identifier for the feature and\n * is set when reading data from a remote source.\n * @return {number|string|undefined} Id.\n * @api\n */\n\n\n RenderFeature.prototype.getId = function () {\n return this.id_;\n };\n /**\n * @return {Array<number>} Flat coordinates.\n */\n\n\n RenderFeature.prototype.getOrientedFlatCoordinates = function () {\n return this.flatCoordinates_;\n };\n /**\n * For API compatibility with {@link module:ol/Feature~Feature}, this method is useful when\n * determining the geometry type in style function (see {@link #getType}).\n * @return {RenderFeature} Feature.\n * @api\n */\n\n\n RenderFeature.prototype.getGeometry = function () {\n return this;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {RenderFeature} Simplified geometry.\n */\n\n\n RenderFeature.prototype.getSimplifiedGeometry = function (squaredTolerance) {\n return this;\n };\n /**\n * Get a transformed and simplified version of the geometry.\n * @abstract\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import("../proj.js").TransformFunction} [opt_transform] Optional transform function.\n * @return {RenderFeature} Simplified geometry.\n */\n\n\n RenderFeature.prototype.simplifyTransformed = function (squaredTolerance, opt_transform) {\n return this;\n };\n /**\n * Get the feature properties.\n * @return {Object<string, *>} Feature properties.\n * @api\n */\n\n\n RenderFeature.prototype.getProperties = function () {\n return this.properties_;\n };\n /**\n * @return {number} Stride.\n */\n\n\n RenderFeature.prototype.getStride = function () {\n return 2;\n };\n /**\n * @return {undefined}\n */\n\n\n RenderFeature.prototype.getStyleFunction = function () {\n return undefined;\n };\n /**\n * Get the type of this feature\'s geometry.\n * @return {import("../geom/GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n RenderFeature.prototype.getType = function () {\n return this.type_;\n };\n /**\n * Transform geometry coordinates from tile pixel space to projected.\n *\n * @param {import("../proj.js").ProjectionLike} projection The data projection\n */\n\n\n RenderFeature.prototype.transform = function (projection) {\n projection = proj_get(projection);\n var pixelExtent = projection.getExtent();\n var projectedExtent = projection.getWorldExtent();\n\n if (pixelExtent && projectedExtent) {\n var scale = getHeight(projectedExtent) / getHeight(pixelExtent);\n compose(Feature_tmpTransform, projectedExtent[0], projectedExtent[3], scale, -scale, 0, 0, 0);\n transform2D(this.flatCoordinates_, 0, this.flatCoordinates_.length, 2, Feature_tmpTransform, this.flatCoordinates_);\n }\n };\n /**\n * @return {Array<number>|Array<Array<number>>} Ends or endss.\n */\n\n\n RenderFeature.prototype.getEnds = function () {\n return this.ends_;\n };\n\n return RenderFeature;\n}();\n\nRenderFeature.prototype.getEndss = RenderFeature.prototype.getEnds;\n/**\n * @return {Array<number>} Flat coordinates.\n */\n\nRenderFeature.prototype.getFlatCoordinates = RenderFeature.prototype.getOrientedFlatCoordinates;\n/* harmony default export */ var render_Feature = (RenderFeature);\n;// CONCATENATED MODULE: ./node_modules/ol/format/MVT.js\n/**\n * @module ol/format/MVT\n */\n//FIXME Implement projection handling\nvar MVT_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("../Feature.js").FeatureClass} [featureClass] Class for features returned by\n * {@link module:ol/format/MVT#readFeatures}. Set to {@link module:ol/Feature~Feature} to get full editing and geometry\n * support at the cost of decreased rendering performance. The default is\n * {@link module:ol/render/Feature~RenderFeature}, which is optimized for rendering and hit detection.\n * @property {string} [geometryName=\'geometry\'] Geometry name to use when creating features.\n * @property {string} [layerName=\'layer\'] Name of the feature attribute that holds the layer name.\n * @property {Array<string>} [layers] Layers to read features from. If not provided, features will be read from all\n * @property {string} [idProperty] Optional property that will be assigned as the feature id and removed from the properties.\n * layers.\n */\n\n/**\n * @classdesc\n * Feature format for reading data in the Mapbox MVT format.\n *\n * @param {Options=} opt_options Options.\n * @api\n */\n\nvar MVT =\n/** @class */\nfunction (_super) {\n MVT_extends(MVT, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function MVT(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @type {Projection}\n */\n\n _this.dataProjection = new proj_Projection({\n code: \'\',\n units: proj_Units.TILE_PIXELS\n });\n /**\n * @private\n * @type {import("../Feature.js").FeatureClass}\n */\n\n _this.featureClass_ = options.featureClass ? options.featureClass : render_Feature;\n /**\n * @private\n * @type {string|undefined}\n */\n\n _this.geometryName_ = options.geometryName;\n /**\n * @private\n * @type {string}\n */\n\n _this.layerName_ = options.layerName ? options.layerName : \'layer\';\n /**\n * @private\n * @type {Array<string>}\n */\n\n _this.layers_ = options.layers ? options.layers : null;\n /**\n * @private\n * @type {string}\n */\n\n _this.idProperty_ = options.idProperty;\n return _this;\n }\n /**\n * Read the raw geometry from the pbf offset stored in a raw feature\'s geometry\n * property.\n * @param {PBF} pbf PBF.\n * @param {Object} feature Raw feature.\n * @param {Array<number>} flatCoordinates Array to store flat coordinates in.\n * @param {Array<number>} ends Array to store ends in.\n * @private\n */\n\n\n MVT.prototype.readRawGeometry_ = function (pbf, feature, flatCoordinates, ends) {\n pbf.pos = feature.geometry;\n var end = pbf.readVarint() + pbf.pos;\n var cmd = 1;\n var length = 0;\n var x = 0;\n var y = 0;\n var coordsLen = 0;\n var currentEnd = 0;\n\n while (pbf.pos < end) {\n if (!length) {\n var cmdLen = pbf.readVarint();\n cmd = cmdLen & 0x7;\n length = cmdLen >> 3;\n }\n\n length--;\n\n if (cmd === 1 || cmd === 2) {\n x += pbf.readSVarint();\n y += pbf.readSVarint();\n\n if (cmd === 1) {\n // moveTo\n if (coordsLen > currentEnd) {\n ends.push(coordsLen);\n currentEnd = coordsLen;\n }\n }\n\n flatCoordinates.push(x, y);\n coordsLen += 2;\n } else if (cmd === 7) {\n if (coordsLen > currentEnd) {\n // close polygon\n flatCoordinates.push(flatCoordinates[currentEnd], flatCoordinates[currentEnd + 1]);\n coordsLen += 2;\n }\n } else {\n asserts_assert(false, 59); // Invalid command found in the PBF\n }\n }\n\n if (coordsLen > currentEnd) {\n ends.push(coordsLen);\n currentEnd = coordsLen;\n }\n };\n /**\n * @private\n * @param {PBF} pbf PBF\n * @param {Object} rawFeature Raw Mapbox feature.\n * @param {import("./Feature.js").ReadOptions} options Read options.\n * @return {import("../Feature.js").FeatureLike} Feature.\n */\n\n\n MVT.prototype.createFeature_ = function (pbf, rawFeature, options) {\n var type = rawFeature.type;\n\n if (type === 0) {\n return null;\n }\n\n var feature;\n var values = rawFeature.properties;\n var id;\n\n if (!this.idProperty_) {\n id = rawFeature.id;\n } else {\n id = values[this.idProperty_];\n delete values[this.idProperty_];\n }\n\n values[this.layerName_] = rawFeature.layer.name;\n var flatCoordinates = [];\n var ends = [];\n this.readRawGeometry_(pbf, rawFeature, flatCoordinates, ends);\n var geometryType = getGeometryType(type, ends.length);\n\n if (this.featureClass_ === render_Feature) {\n feature = new this.featureClass_(geometryType, flatCoordinates, ends, values, id);\n feature.transform(options.dataProjection);\n } else {\n var geom = void 0;\n\n if (geometryType == geom_GeometryType.POLYGON) {\n var endss = [];\n var offset = 0;\n var prevEndIndex = 0;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i]; // classifies an array of rings into polygons with outer rings and holes\n\n if (!linearRingIsClockwise(flatCoordinates, offset, end, 2)) {\n endss.push(ends.slice(prevEndIndex, i + 1));\n } else {\n if (endss.length === 0) {\n continue;\n }\n\n endss[endss.length - 1].push(ends[prevEndIndex]);\n }\n\n prevEndIndex = i + 1;\n offset = end;\n }\n\n if (endss.length > 1) {\n geom = new geom_MultiPolygon(flatCoordinates, geom_GeometryLayout.XY, endss);\n } else {\n geom = new geom_Polygon(flatCoordinates, geom_GeometryLayout.XY, ends);\n }\n } else {\n geom = geometryType === geom_GeometryType.POINT ? new geom_Point(flatCoordinates, geom_GeometryLayout.XY) : geometryType === geom_GeometryType.LINE_STRING ? new geom_LineString(flatCoordinates, geom_GeometryLayout.XY) : geometryType === geom_GeometryType.POLYGON ? new geom_Polygon(flatCoordinates, geom_GeometryLayout.XY, ends) : geometryType === geom_GeometryType.MULTI_POINT ? new geom_MultiPoint(flatCoordinates, geom_GeometryLayout.XY) : geometryType === geom_GeometryType.MULTI_LINE_STRING ? new geom_MultiLineString(flatCoordinates, geom_GeometryLayout.XY, ends) : null;\n }\n\n var ctor =\n /** @type {typeof import("../Feature.js").default} */\n this.featureClass_;\n feature = new ctor();\n\n if (this.geometryName_) {\n feature.setGeometryName(this.geometryName_);\n }\n\n var geometry = transformGeometryWithOptions(geom, false, options);\n feature.setGeometry(geometry);\n feature.setId(id);\n feature.setProperties(values, true);\n }\n\n return feature;\n };\n /**\n * @return {import("./FormatType.js").default} Format.\n */\n\n\n MVT.prototype.getType = function () {\n return FormatType.ARRAY_BUFFER;\n };\n /**\n * Read all features.\n *\n * @param {ArrayBuffer} source Source.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @return {Array<import("../Feature.js").FeatureLike>} Features.\n * @api\n */\n\n\n MVT.prototype.readFeatures = function (source, opt_options) {\n var layers = this.layers_;\n var options =\n /** @type {import("./Feature.js").ReadOptions} */\n this.adaptOptions(opt_options);\n var dataProjection = proj_get(options.dataProjection);\n dataProjection.setWorldExtent(options.extent);\n options.dataProjection = dataProjection;\n var pbf = new (pbf_default())(\n /** @type {ArrayBuffer} */\n source);\n var pbfLayers = pbf.readFields(layersPBFReader, {});\n var features = [];\n\n for (var name_1 in pbfLayers) {\n if (layers && layers.indexOf(name_1) == -1) {\n continue;\n }\n\n var pbfLayer = pbfLayers[name_1];\n var extent = pbfLayer ? [0, 0, pbfLayer.extent, pbfLayer.extent] : null;\n dataProjection.setExtent(extent);\n\n for (var i = 0, ii = pbfLayer.length; i < ii; ++i) {\n var rawFeature = readRawFeature(pbf, pbfLayer, i);\n features.push(this.createFeature_(pbf, rawFeature, options));\n }\n }\n\n return features;\n };\n /**\n * Read the projection from the source.\n *\n * @param {Document|Element|Object|string} source Source.\n * @return {import("../proj/Projection.js").default} Projection.\n * @api\n */\n\n\n MVT.prototype.readProjection = function (source) {\n return this.dataProjection;\n };\n /**\n * Sets the layers that features will be read from.\n * @param {Array<string>} layers Layers.\n * @api\n */\n\n\n MVT.prototype.setLayers = function (layers) {\n this.layers_ = layers;\n };\n\n return MVT;\n}(Feature);\n/**\n * Reader callback for parsing layers.\n * @param {number} tag The tag.\n * @param {Object} layers The layers object.\n * @param {PBF} pbf The PBF.\n */\n\n\nfunction layersPBFReader(tag, layers, pbf) {\n if (tag === 3) {\n var layer = {\n keys: [],\n values: [],\n features: []\n };\n var end = pbf.readVarint() + pbf.pos;\n pbf.readFields(layerPBFReader, layer, end);\n layer.length = layer.features.length;\n\n if (layer.length) {\n layers[layer.name] = layer;\n }\n }\n}\n/**\n * Reader callback for parsing layer.\n * @param {number} tag The tag.\n * @param {Object} layer The layer object.\n * @param {PBF} pbf The PBF.\n */\n\n\nfunction layerPBFReader(tag, layer, pbf) {\n if (tag === 15) {\n layer.version = pbf.readVarint();\n } else if (tag === 1) {\n layer.name = pbf.readString();\n } else if (tag === 5) {\n layer.extent = pbf.readVarint();\n } else if (tag === 2) {\n layer.features.push(pbf.pos);\n } else if (tag === 3) {\n layer.keys.push(pbf.readString());\n } else if (tag === 4) {\n var value = null;\n var end = pbf.readVarint() + pbf.pos;\n\n while (pbf.pos < end) {\n tag = pbf.readVarint() >> 3;\n value = tag === 1 ? pbf.readString() : tag === 2 ? pbf.readFloat() : tag === 3 ? pbf.readDouble() : tag === 4 ? pbf.readVarint64() : tag === 5 ? pbf.readVarint() : tag === 6 ? pbf.readSVarint() : tag === 7 ? pbf.readBoolean() : null;\n }\n\n layer.values.push(value);\n }\n}\n/**\n * Reader callback for parsing feature.\n * @param {number} tag The tag.\n * @param {Object} feature The feature object.\n * @param {PBF} pbf The PBF.\n */\n\n\nfunction featurePBFReader(tag, feature, pbf) {\n if (tag == 1) {\n feature.id = pbf.readVarint();\n } else if (tag == 2) {\n var end = pbf.readVarint() + pbf.pos;\n\n while (pbf.pos < end) {\n var key = feature.layer.keys[pbf.readVarint()];\n var value = feature.layer.values[pbf.readVarint()];\n feature.properties[key] = value;\n }\n } else if (tag == 3) {\n feature.type = pbf.readVarint();\n } else if (tag == 4) {\n feature.geometry = pbf.pos;\n }\n}\n/**\n * Read a raw feature from the pbf offset stored at index `i` in the raw layer.\n * @param {PBF} pbf PBF.\n * @param {Object} layer Raw layer.\n * @param {number} i Index of the feature in the raw layer\'s `features` array.\n * @return {Object} Raw feature.\n */\n\n\nfunction readRawFeature(pbf, layer, i) {\n pbf.pos = layer.features[i];\n var end = pbf.readVarint() + pbf.pos;\n var feature = {\n layer: layer,\n type: 0,\n properties: {}\n };\n pbf.readFields(featurePBFReader, feature, end);\n return feature;\n}\n/**\n * @param {number} type The raw feature\'s geometry type\n * @param {number} numEnds Number of ends of the flat coordinates of the\n * geometry.\n * @return {import("../geom/GeometryType.js").default} The geometry type.\n */\n\n\nfunction getGeometryType(type, numEnds) {\n /** @type {import("../geom/GeometryType.js").default} */\n var geometryType;\n\n if (type === 1) {\n geometryType = numEnds === 1 ? geom_GeometryType.POINT : geom_GeometryType.MULTI_POINT;\n } else if (type === 2) {\n geometryType = numEnds === 1 ? geom_GeometryType.LINE_STRING : geom_GeometryType.MULTI_LINE_STRING;\n } else if (type === 3) {\n geometryType = geom_GeometryType.POLYGON; // MultiPolygon not relevant for rendering - winding order determines\n // outer rings of polygons.\n }\n\n return geometryType;\n}\n\n/* harmony default export */ var format_MVT = (MVT);\n;// CONCATENATED MODULE: ./node_modules/ol/ImageTile.js\nvar ImageTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/ImageTile\n */\n\n\n\n\n\n\n\nvar ImageTile =\n/** @class */\nfunction (_super) {\n ImageTile_extends(ImageTile, _super);\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("./TileState.js").default} state State.\n * @param {string} src Image source URI.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("./Tile.js").LoadFunction} tileLoadFunction Tile load function.\n * @param {import("./Tile.js").Options=} opt_options Tile options.\n */\n\n\n function ImageTile(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {\n var _this = _super.call(this, tileCoord, state, opt_options) || this;\n /**\n * @private\n * @type {?string}\n */\n\n\n _this.crossOrigin_ = crossOrigin;\n /**\n * Image URI\n *\n * @private\n * @type {string}\n */\n\n _this.src_ = src;\n _this.key = src;\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n\n _this.image_ = new Image();\n\n if (crossOrigin !== null) {\n _this.image_.crossOrigin = crossOrigin;\n }\n /**\n * @private\n * @type {?function():void}\n */\n\n\n _this.unlisten_ = null;\n /**\n * @private\n * @type {import("./Tile.js").LoadFunction}\n */\n\n _this.tileLoadFunction_ = tileLoadFunction;\n return _this;\n }\n /**\n * Get the HTML image element for this tile (may be a Canvas, Image, or Video).\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n * @api\n */\n\n\n ImageTile.prototype.getImage = function () {\n return this.image_;\n };\n /**\n * Tracks loading or read errors.\n *\n * @private\n */\n\n\n ImageTile.prototype.handleImageError_ = function () {\n this.state = TileState.ERROR;\n this.unlistenImage_();\n this.image_ = getBlankImage();\n this.changed();\n };\n /**\n * Tracks successful image load.\n *\n * @private\n */\n\n\n ImageTile.prototype.handleImageLoad_ = function () {\n var image =\n /** @type {HTMLImageElement} */\n this.image_;\n\n if (image.naturalWidth && image.naturalHeight) {\n this.state = TileState.LOADED;\n } else {\n this.state = TileState.EMPTY;\n }\n\n this.unlistenImage_();\n this.changed();\n };\n /**\n * Load not yet loaded URI.\n * @api\n */\n\n\n ImageTile.prototype.load = function () {\n if (this.state == TileState.ERROR) {\n this.state = TileState.IDLE;\n this.image_ = new Image();\n\n if (this.crossOrigin_ !== null) {\n this.image_.crossOrigin = this.crossOrigin_;\n }\n }\n\n if (this.state == TileState.IDLE) {\n this.state = TileState.LOADING;\n this.changed();\n this.tileLoadFunction_(this, this.src_);\n this.unlisten_ = listenImage(this.image_, this.handleImageLoad_.bind(this), this.handleImageError_.bind(this));\n }\n };\n /**\n * Discards event handlers which listen for load completion or errors.\n *\n * @private\n */\n\n\n ImageTile.prototype.unlistenImage_ = function () {\n if (this.unlisten_) {\n this.unlisten_();\n this.unlisten_ = null;\n }\n };\n\n return ImageTile;\n}(ol_Tile);\n/**\n * Get a 1-pixel blank image.\n * @return {HTMLCanvasElement} Blank image.\n */\n\n\nfunction getBlankImage() {\n var ctx = createCanvasContext2D(1, 1);\n ctx.fillStyle = \'rgba(0,0,0,0)\';\n ctx.fillRect(0, 0, 1, 1);\n return ctx.canvas;\n}\n\n/* harmony default export */ var ol_ImageTile = (ImageTile);\n;// CONCATENATED MODULE: ./node_modules/ol/reproj/common.js\n/**\n * @module ol/reproj/common\n */\n\n/**\n * Default maximum allowed threshold (in pixels) for reprojection\n * triangulation.\n * @type {number}\n */\nvar ERROR_THRESHOLD = 0.5;\n/**\n * Enable automatic reprojection of raster sources. Default is `true`.\n * TODO: decide if we want to expose this as a build flag or remove it\n * @type {boolean}\n */\n\nvar ENABLE_RASTER_REPROJECTION = true;\n;// CONCATENATED MODULE: ./node_modules/ol/reproj/Triangulation.js\n/**\n * @module ol/reproj/Triangulation\n */\n\n\n\n/**\n * Single triangle; consists of 3 source points and 3 target points.\n * @typedef {Object} Triangle\n * @property {Array<import("../coordinate.js").Coordinate>} source\n * @property {Array<import("../coordinate.js").Coordinate>} target\n */\n\n/**\n * Maximum number of subdivision steps during raster reprojection triangulation.\n * Prevents high memory usage and large number of proj4 calls (for certain\n * transformations and areas). At most `2*(2^this)` triangles are created for\n * each triangulated extent (tile/image).\n * @type {number}\n */\n\nvar MAX_SUBDIVISION = 10;\n/**\n * Maximum allowed size of triangle relative to world width. When transforming\n * corners of world extent between certain projections, the resulting\n * triangulation seems to have zero error and no subdivision is performed. If\n * the triangle width is more than this (relative to world width; 0-1),\n * subdivison is forced (up to `MAX_SUBDIVISION`). Default is `0.25`.\n * @type {number}\n */\n\nvar MAX_TRIANGLE_WIDTH = 0.25;\n/**\n * @classdesc\n * Class containing triangulation of the given target extent.\n * Used for determining source data and the reprojection itself.\n */\n\nvar Triangulation =\n/** @class */\nfunction () {\n /**\n * @param {import("../proj/Projection.js").default} sourceProj Source projection.\n * @param {import("../proj/Projection.js").default} targetProj Target projection.\n * @param {import("../extent.js").Extent} targetExtent Target extent to triangulate.\n * @param {import("../extent.js").Extent} maxSourceExtent Maximal source extent that can be used.\n * @param {number} errorThreshold Acceptable error (in source units).\n * @param {?number} opt_destinationResolution The (optional) resolution of the destination.\n */\n function Triangulation(sourceProj, targetProj, targetExtent, maxSourceExtent, errorThreshold, opt_destinationResolution) {\n /**\n * @type {import("../proj/Projection.js").default}\n * @private\n */\n this.sourceProj_ = sourceProj;\n /**\n * @type {import("../proj/Projection.js").default}\n * @private\n */\n\n this.targetProj_ = targetProj;\n /** @type {!Object<string, import("../coordinate.js").Coordinate>} */\n\n var transformInvCache = {};\n var transformInv = getTransform(this.targetProj_, this.sourceProj_);\n /**\n * @param {import("../coordinate.js").Coordinate} c A coordinate.\n * @return {import("../coordinate.js").Coordinate} Transformed coordinate.\n * @private\n */\n\n this.transformInv_ = function (c) {\n var key = c[0] + \'/\' + c[1];\n\n if (!transformInvCache[key]) {\n transformInvCache[key] = transformInv(c);\n }\n\n return transformInvCache[key];\n };\n /**\n * @type {import("../extent.js").Extent}\n * @private\n */\n\n\n this.maxSourceExtent_ = maxSourceExtent;\n /**\n * @type {number}\n * @private\n */\n\n this.errorThresholdSquared_ = errorThreshold * errorThreshold;\n /**\n * @type {Array<Triangle>}\n * @private\n */\n\n this.triangles_ = [];\n /**\n * Indicates that the triangulation crosses edge of the source projection.\n * @type {boolean}\n * @private\n */\n\n this.wrapsXInSource_ = false;\n /**\n * @type {boolean}\n * @private\n */\n\n this.canWrapXInSource_ = this.sourceProj_.canWrapX() && !!maxSourceExtent && !!this.sourceProj_.getExtent() && extent_getWidth(maxSourceExtent) == extent_getWidth(this.sourceProj_.getExtent());\n /**\n * @type {?number}\n * @private\n */\n\n this.sourceWorldWidth_ = this.sourceProj_.getExtent() ? extent_getWidth(this.sourceProj_.getExtent()) : null;\n /**\n * @type {?number}\n * @private\n */\n\n this.targetWorldWidth_ = this.targetProj_.getExtent() ? extent_getWidth(this.targetProj_.getExtent()) : null;\n var destinationTopLeft = getTopLeft(targetExtent);\n var destinationTopRight = getTopRight(targetExtent);\n var destinationBottomRight = getBottomRight(targetExtent);\n var destinationBottomLeft = getBottomLeft(targetExtent);\n var sourceTopLeft = this.transformInv_(destinationTopLeft);\n var sourceTopRight = this.transformInv_(destinationTopRight);\n var sourceBottomRight = this.transformInv_(destinationBottomRight);\n var sourceBottomLeft = this.transformInv_(destinationBottomLeft);\n /*\n * The maxSubdivision controls how many splittings of the target area can\n * be done. The idea here is to do a linear mapping of the target areas\n * but the actual overal reprojection (can be) extremely non-linear. The\n * default value of MAX_SUBDIVISION was chosen based on mapping a 256x256\n * tile size. However this function is also called to remap canvas rendered\n * layers which can be much larger. This calculation increases the maxSubdivision\n * value by the right factor so that each 256x256 pixel area has\n * MAX_SUBDIVISION divisions.\n */\n\n var maxSubdivision = MAX_SUBDIVISION + (opt_destinationResolution ? Math.max(0, Math.ceil(log2(getArea(targetExtent) / (opt_destinationResolution * opt_destinationResolution * 256 * 256)))) : 0);\n this.addQuad_(destinationTopLeft, destinationTopRight, destinationBottomRight, destinationBottomLeft, sourceTopLeft, sourceTopRight, sourceBottomRight, sourceBottomLeft, maxSubdivision);\n\n if (this.wrapsXInSource_) {\n var leftBound_1 = Infinity;\n this.triangles_.forEach(function (triangle, i, arr) {\n leftBound_1 = Math.min(leftBound_1, triangle.source[0][0], triangle.source[1][0], triangle.source[2][0]);\n }); // Shift triangles to be as close to `leftBound` as possible\n // (if the distance is more than `worldWidth / 2` it can be closer.\n\n this.triangles_.forEach(function (triangle) {\n if (Math.max(triangle.source[0][0], triangle.source[1][0], triangle.source[2][0]) - leftBound_1 > this.sourceWorldWidth_ / 2) {\n var newTriangle = [[triangle.source[0][0], triangle.source[0][1]], [triangle.source[1][0], triangle.source[1][1]], [triangle.source[2][0], triangle.source[2][1]]];\n\n if (newTriangle[0][0] - leftBound_1 > this.sourceWorldWidth_ / 2) {\n newTriangle[0][0] -= this.sourceWorldWidth_;\n }\n\n if (newTriangle[1][0] - leftBound_1 > this.sourceWorldWidth_ / 2) {\n newTriangle[1][0] -= this.sourceWorldWidth_;\n }\n\n if (newTriangle[2][0] - leftBound_1 > this.sourceWorldWidth_ / 2) {\n newTriangle[2][0] -= this.sourceWorldWidth_;\n } // Rarely (if the extent contains both the dateline and prime meridian)\n // the shift can in turn break some triangles.\n // Detect this here and don\'t shift in such cases.\n\n\n var minX = Math.min(newTriangle[0][0], newTriangle[1][0], newTriangle[2][0]);\n var maxX = Math.max(newTriangle[0][0], newTriangle[1][0], newTriangle[2][0]);\n\n if (maxX - minX < this.sourceWorldWidth_ / 2) {\n triangle.source = newTriangle;\n }\n }\n }.bind(this));\n }\n\n transformInvCache = {};\n }\n /**\n * Adds triangle to the triangulation.\n * @param {import("../coordinate.js").Coordinate} a The target a coordinate.\n * @param {import("../coordinate.js").Coordinate} b The target b coordinate.\n * @param {import("../coordinate.js").Coordinate} c The target c coordinate.\n * @param {import("../coordinate.js").Coordinate} aSrc The source a coordinate.\n * @param {import("../coordinate.js").Coordinate} bSrc The source b coordinate.\n * @param {import("../coordinate.js").Coordinate} cSrc The source c coordinate.\n * @private\n */\n\n\n Triangulation.prototype.addTriangle_ = function (a, b, c, aSrc, bSrc, cSrc) {\n this.triangles_.push({\n source: [aSrc, bSrc, cSrc],\n target: [a, b, c]\n });\n };\n /**\n * Adds quad (points in clock-wise order) to the triangulation\n * (and reprojects the vertices) if valid.\n * Performs quad subdivision if needed to increase precision.\n *\n * @param {import("../coordinate.js").Coordinate} a The target a coordinate.\n * @param {import("../coordinate.js").Coordinate} b The target b coordinate.\n * @param {import("../coordinate.js").Coordinate} c The target c coordinate.\n * @param {import("../coordinate.js").Coordinate} d The target d coordinate.\n * @param {import("../coordinate.js").Coordinate} aSrc The source a coordinate.\n * @param {import("../coordinate.js").Coordinate} bSrc The source b coordinate.\n * @param {import("../coordinate.js").Coordinate} cSrc The source c coordinate.\n * @param {import("../coordinate.js").Coordinate} dSrc The source d coordinate.\n * @param {number} maxSubdivision Maximal allowed subdivision of the quad.\n * @private\n */\n\n\n Triangulation.prototype.addQuad_ = function (a, b, c, d, aSrc, bSrc, cSrc, dSrc, maxSubdivision) {\n var sourceQuadExtent = boundingExtent([aSrc, bSrc, cSrc, dSrc]);\n var sourceCoverageX = this.sourceWorldWidth_ ? extent_getWidth(sourceQuadExtent) / this.sourceWorldWidth_ : null;\n var sourceWorldWidth =\n /** @type {number} */\n this.sourceWorldWidth_; // when the quad is wrapped in the source projection\n // it covers most of the projection extent, but not fully\n\n var wrapsX = this.sourceProj_.canWrapX() && sourceCoverageX > 0.5 && sourceCoverageX < 1;\n var needsSubdivision = false;\n\n if (maxSubdivision > 0) {\n if (this.targetProj_.isGlobal() && this.targetWorldWidth_) {\n var targetQuadExtent = boundingExtent([a, b, c, d]);\n var targetCoverageX = extent_getWidth(targetQuadExtent) / this.targetWorldWidth_;\n needsSubdivision = targetCoverageX > MAX_TRIANGLE_WIDTH || needsSubdivision;\n }\n\n if (!wrapsX && this.sourceProj_.isGlobal() && sourceCoverageX) {\n needsSubdivision = sourceCoverageX > MAX_TRIANGLE_WIDTH || needsSubdivision;\n }\n }\n\n if (!needsSubdivision && this.maxSourceExtent_) {\n if (isFinite(sourceQuadExtent[0]) && isFinite(sourceQuadExtent[1]) && isFinite(sourceQuadExtent[2]) && isFinite(sourceQuadExtent[3])) {\n if (!intersects(sourceQuadExtent, this.maxSourceExtent_)) {\n // whole quad outside source projection extent -> ignore\n return;\n }\n }\n }\n\n var isNotFinite = 0;\n\n if (!needsSubdivision) {\n if (!isFinite(aSrc[0]) || !isFinite(aSrc[1]) || !isFinite(bSrc[0]) || !isFinite(bSrc[1]) || !isFinite(cSrc[0]) || !isFinite(cSrc[1]) || !isFinite(dSrc[0]) || !isFinite(dSrc[1])) {\n if (maxSubdivision > 0) {\n needsSubdivision = true;\n } else {\n // It might be the case that only 1 of the points is infinite. In this case\n // we can draw a single triangle with the other three points\n isNotFinite = (!isFinite(aSrc[0]) || !isFinite(aSrc[1]) ? 8 : 0) + (!isFinite(bSrc[0]) || !isFinite(bSrc[1]) ? 4 : 0) + (!isFinite(cSrc[0]) || !isFinite(cSrc[1]) ? 2 : 0) + (!isFinite(dSrc[0]) || !isFinite(dSrc[1]) ? 1 : 0);\n\n if (isNotFinite != 1 && isNotFinite != 2 && isNotFinite != 4 && isNotFinite != 8) {\n return;\n }\n }\n }\n }\n\n if (maxSubdivision > 0) {\n if (!needsSubdivision) {\n var center = [(a[0] + c[0]) / 2, (a[1] + c[1]) / 2];\n var centerSrc = this.transformInv_(center);\n var dx = void 0;\n\n if (wrapsX) {\n var centerSrcEstimX = (math_modulo(aSrc[0], sourceWorldWidth) + math_modulo(cSrc[0], sourceWorldWidth)) / 2;\n dx = centerSrcEstimX - math_modulo(centerSrc[0], sourceWorldWidth);\n } else {\n dx = (aSrc[0] + cSrc[0]) / 2 - centerSrc[0];\n }\n\n var dy = (aSrc[1] + cSrc[1]) / 2 - centerSrc[1];\n var centerSrcErrorSquared = dx * dx + dy * dy;\n needsSubdivision = centerSrcErrorSquared > this.errorThresholdSquared_;\n }\n\n if (needsSubdivision) {\n if (Math.abs(a[0] - c[0]) <= Math.abs(a[1] - c[1])) {\n // split horizontally (top & bottom)\n var bc = [(b[0] + c[0]) / 2, (b[1] + c[1]) / 2];\n var bcSrc = this.transformInv_(bc);\n var da = [(d[0] + a[0]) / 2, (d[1] + a[1]) / 2];\n var daSrc = this.transformInv_(da);\n this.addQuad_(a, b, bc, da, aSrc, bSrc, bcSrc, daSrc, maxSubdivision - 1);\n this.addQuad_(da, bc, c, d, daSrc, bcSrc, cSrc, dSrc, maxSubdivision - 1);\n } else {\n // split vertically (left & right)\n var ab = [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];\n var abSrc = this.transformInv_(ab);\n var cd = [(c[0] + d[0]) / 2, (c[1] + d[1]) / 2];\n var cdSrc = this.transformInv_(cd);\n this.addQuad_(a, ab, cd, d, aSrc, abSrc, cdSrc, dSrc, maxSubdivision - 1);\n this.addQuad_(ab, b, c, cd, abSrc, bSrc, cSrc, cdSrc, maxSubdivision - 1);\n }\n\n return;\n }\n }\n\n if (wrapsX) {\n if (!this.canWrapXInSource_) {\n return;\n }\n\n this.wrapsXInSource_ = true;\n } // Exactly zero or one of *Src is not finite\n // The triangles must have the diagonal line as the first side\n // This is to allow easy code in reproj.s to make it straight for broken\n // browsers that can\'t handle diagonal clipping\n\n\n if ((isNotFinite & 0xb) == 0) {\n this.addTriangle_(a, c, d, aSrc, cSrc, dSrc);\n }\n\n if ((isNotFinite & 0xe) == 0) {\n this.addTriangle_(a, c, b, aSrc, cSrc, bSrc);\n }\n\n if (isNotFinite) {\n // Try the other two triangles\n if ((isNotFinite & 0xd) == 0) {\n this.addTriangle_(b, d, a, bSrc, dSrc, aSrc);\n }\n\n if ((isNotFinite & 0x7) == 0) {\n this.addTriangle_(b, d, c, bSrc, dSrc, cSrc);\n }\n }\n };\n /**\n * Calculates extent of the \'source\' coordinates from all the triangles.\n *\n * @return {import("../extent.js").Extent} Calculated extent.\n */\n\n\n Triangulation.prototype.calculateSourceExtent = function () {\n var extent = createEmpty();\n this.triangles_.forEach(function (triangle, i, arr) {\n var src = triangle.source;\n extendCoordinate(extent, src[0]);\n extendCoordinate(extent, src[1]);\n extendCoordinate(extent, src[2]);\n });\n return extent;\n };\n /**\n * @return {Array<Triangle>} Array of the calculated triangles.\n */\n\n\n Triangulation.prototype.getTriangles = function () {\n return this.triangles_;\n };\n\n return Triangulation;\n}();\n\n/* harmony default export */ var reproj_Triangulation = (Triangulation);\n;// CONCATENATED MODULE: ./node_modules/ol/source/common.js\n/**\n * @module ol/source/common\n */\n\n/**\n * Default WMS version.\n * @type {string}\n */\nvar DEFAULT_WMS_VERSION = \'1.3.0\';\n/**\n * Context options to disable image smoothing.\n * @type {Object}\n */\n\nvar IMAGE_SMOOTHING_DISABLED = {\n imageSmoothingEnabled: false,\n msImageSmoothingEnabled: false\n};\n;// CONCATENATED MODULE: ./node_modules/ol/reproj.js\n/**\n * @module ol/reproj\n */\n\n\n\n\n\n\nvar brokenDiagonalRendering_;\n/**\n * This draws a small triangle into a canvas by setting the triangle as the clip region\n * and then drawing a (too large) rectangle\n *\n * @param {CanvasRenderingContext2D} ctx The context in which to draw the triangle\n * @param {number} u1 The x-coordinate of the second point. The first point is 0,0.\n * @param {number} v1 The y-coordinate of the second point.\n * @param {number} u2 The x-coordinate of the third point.\n * @param {number} v2 The y-coordinate of the third point.\n */\n\nfunction drawTestTriangle(ctx, u1, v1, u2, v2) {\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(u1, v1);\n ctx.lineTo(u2, v2);\n ctx.closePath();\n ctx.save();\n ctx.clip();\n ctx.fillRect(0, 0, Math.max(u1, u2) + 1, Math.max(v1, v2));\n ctx.restore();\n}\n/**\n * Given the data from getImageData, see if the right values appear at the provided offset.\n * Returns true if either the color or transparency is off\n *\n * @param {Uint8ClampedArray} data The data returned from getImageData\n * @param {number} offset The pixel offset from the start of data.\n * @return {boolean} true if the diagonal rendering is broken\n */\n\n\nfunction verifyBrokenDiagonalRendering(data, offset) {\n // the values ought to be close to the rgba(210, 0, 0, 0.75)\n return Math.abs(data[offset * 4] - 210) > 2 || Math.abs(data[offset * 4 + 3] - 0.75 * 255) > 2;\n}\n/**\n * Determines if the current browser configuration can render triangular clip regions correctly.\n * This value is cached so the function is only expensive the first time called.\n * Firefox on Windows (as of now) does not if HWA is enabled. See https://bugzilla.mozilla.org/show_bug.cgi?id=1606976\n * IE also doesn\'t. Chrome works, and everything seems to work on OSX and Android. This function caches the\n * result. I suppose that it is conceivably possible that a browser might flip modes while the app is\n * running, but lets hope not.\n *\n * @return {boolean} true if the Diagonal Rendering is broken.\n */\n\n\nfunction isBrokenDiagonalRendering() {\n if (brokenDiagonalRendering_ === undefined) {\n var ctx = document.createElement(\'canvas\').getContext(\'2d\');\n ctx.globalCompositeOperation = \'lighter\';\n ctx.fillStyle = \'rgba(210, 0, 0, 0.75)\';\n drawTestTriangle(ctx, 4, 5, 4, 0);\n drawTestTriangle(ctx, 4, 5, 0, 5);\n var data = ctx.getImageData(0, 0, 3, 3).data;\n brokenDiagonalRendering_ = verifyBrokenDiagonalRendering(data, 0) || verifyBrokenDiagonalRendering(data, 4) || verifyBrokenDiagonalRendering(data, 8);\n }\n\n return brokenDiagonalRendering_;\n}\n/**\n * Calculates ideal resolution to use from the source in order to achieve\n * pixel mapping as close as possible to 1:1 during reprojection.\n * The resolution is calculated regardless of what resolutions\n * are actually available in the dataset (TileGrid, Image, ...).\n *\n * @param {import("./proj/Projection.js").default} sourceProj Source projection.\n * @param {import("./proj/Projection.js").default} targetProj Target projection.\n * @param {import("./coordinate.js").Coordinate} targetCenter Target center.\n * @param {number} targetResolution Target resolution.\n * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0.\n */\n\n\nfunction calculateSourceResolution(sourceProj, targetProj, targetCenter, targetResolution) {\n var sourceCenter = transform(targetCenter, targetProj, sourceProj); // calculate the ideal resolution of the source data\n\n var sourceResolution = getPointResolution(targetProj, targetResolution, targetCenter);\n var targetMetersPerUnit = targetProj.getMetersPerUnit();\n\n if (targetMetersPerUnit !== undefined) {\n sourceResolution *= targetMetersPerUnit;\n }\n\n var sourceMetersPerUnit = sourceProj.getMetersPerUnit();\n\n if (sourceMetersPerUnit !== undefined) {\n sourceResolution /= sourceMetersPerUnit;\n } // Based on the projection properties, the point resolution at the specified\n // coordinates may be slightly different. We need to reverse-compensate this\n // in order to achieve optimal results.\n\n\n var sourceExtent = sourceProj.getExtent();\n\n if (!sourceExtent || containsCoordinate(sourceExtent, sourceCenter)) {\n var compensationFactor = getPointResolution(sourceProj, sourceResolution, sourceCenter) / sourceResolution;\n\n if (isFinite(compensationFactor) && compensationFactor > 0) {\n sourceResolution /= compensationFactor;\n }\n }\n\n return sourceResolution;\n}\n/**\n * Calculates ideal resolution to use from the source in order to achieve\n * pixel mapping as close as possible to 1:1 during reprojection.\n * The resolution is calculated regardless of what resolutions\n * are actually available in the dataset (TileGrid, Image, ...).\n *\n * @param {import("./proj/Projection.js").default} sourceProj Source projection.\n * @param {import("./proj/Projection.js").default} targetProj Target projection.\n * @param {import("./extent.js").Extent} targetExtent Target extent\n * @param {number} targetResolution Target resolution.\n * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0.\n */\n\nfunction calculateSourceExtentResolution(sourceProj, targetProj, targetExtent, targetResolution) {\n var targetCenter = getCenter(targetExtent);\n var sourceResolution = calculateSourceResolution(sourceProj, targetProj, targetCenter, targetResolution);\n\n if (!isFinite(sourceResolution) || sourceResolution <= 0) {\n forEachCorner(targetExtent, function (corner) {\n sourceResolution = calculateSourceResolution(sourceProj, targetProj, corner, targetResolution);\n return isFinite(sourceResolution) && sourceResolution > 0;\n });\n }\n\n return sourceResolution;\n}\n/**\n * Renders the source data into new canvas based on the triangulation.\n *\n * @param {number} width Width of the canvas.\n * @param {number} height Height of the canvas.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} sourceResolution Source resolution.\n * @param {import("./extent.js").Extent} sourceExtent Extent of the data source.\n * @param {number} targetResolution Target resolution.\n * @param {import("./extent.js").Extent} targetExtent Target extent.\n * @param {import("./reproj/Triangulation.js").default} triangulation\n * Calculated triangulation.\n * @param {Array<{extent: import("./extent.js").Extent,\n * image: (HTMLCanvasElement|HTMLImageElement|HTMLVideoElement)}>} sources\n * Array of sources.\n * @param {number} gutter Gutter of the sources.\n * @param {boolean=} opt_renderEdges Render reprojection edges.\n * @param {object=} opt_contextOptions Properties to set on the canvas context.\n * @return {HTMLCanvasElement} Canvas with reprojected data.\n */\n\nfunction render(width, height, pixelRatio, sourceResolution, sourceExtent, targetResolution, targetExtent, triangulation, sources, gutter, opt_renderEdges, opt_contextOptions) {\n var context = createCanvasContext2D(Math.round(pixelRatio * width), Math.round(pixelRatio * height));\n obj_assign(context, opt_contextOptions);\n\n if (sources.length === 0) {\n return context.canvas;\n }\n\n context.scale(pixelRatio, pixelRatio);\n\n function pixelRound(value) {\n return Math.round(value * pixelRatio) / pixelRatio;\n }\n\n context.globalCompositeOperation = \'lighter\';\n var sourceDataExtent = createEmpty();\n sources.forEach(function (src, i, arr) {\n extent_extend(sourceDataExtent, src.extent);\n });\n var canvasWidthInUnits = extent_getWidth(sourceDataExtent);\n var canvasHeightInUnits = getHeight(sourceDataExtent);\n var stitchContext = createCanvasContext2D(Math.round(pixelRatio * canvasWidthInUnits / sourceResolution), Math.round(pixelRatio * canvasHeightInUnits / sourceResolution));\n obj_assign(stitchContext, opt_contextOptions);\n var stitchScale = pixelRatio / sourceResolution;\n sources.forEach(function (src, i, arr) {\n var xPos = src.extent[0] - sourceDataExtent[0];\n var yPos = -(src.extent[3] - sourceDataExtent[3]);\n var srcWidth = extent_getWidth(src.extent);\n var srcHeight = getHeight(src.extent); // This test should never fail -- but it does. Need to find a fix the upstream condition\n\n if (src.image.width > 0 && src.image.height > 0) {\n stitchContext.drawImage(src.image, gutter, gutter, src.image.width - 2 * gutter, src.image.height - 2 * gutter, xPos * stitchScale, yPos * stitchScale, srcWidth * stitchScale, srcHeight * stitchScale);\n }\n });\n var targetTopLeft = getTopLeft(targetExtent);\n triangulation.getTriangles().forEach(function (triangle, i, arr) {\n /* Calculate affine transform (src -> dst)\n * Resulting matrix can be used to transform coordinate\n * from `sourceProjection` to destination pixels.\n *\n * To optimize number of context calls and increase numerical stability,\n * we also do the following operations:\n * trans(-topLeftExtentCorner), scale(1 / targetResolution), scale(1, -1)\n * here before solving the linear system so [ui, vi] are pixel coordinates.\n *\n * Src points: xi, yi\n * Dst points: ui, vi\n * Affine coefficients: aij\n *\n * | x0 y0 1 0 0 0 | |a00| |u0|\n * | x1 y1 1 0 0 0 | |a01| |u1|\n * | x2 y2 1 0 0 0 | x |a02| = |u2|\n * | 0 0 0 x0 y0 1 | |a10| |v0|\n * | 0 0 0 x1 y1 1 | |a11| |v1|\n * | 0 0 0 x2 y2 1 | |a12| |v2|\n */\n var source = triangle.source;\n var target = triangle.target;\n var x0 = source[0][0],\n y0 = source[0][1];\n var x1 = source[1][0],\n y1 = source[1][1];\n var x2 = source[2][0],\n y2 = source[2][1]; // Make sure that everything is on pixel boundaries\n\n var u0 = pixelRound((target[0][0] - targetTopLeft[0]) / targetResolution);\n var v0 = pixelRound(-(target[0][1] - targetTopLeft[1]) / targetResolution);\n var u1 = pixelRound((target[1][0] - targetTopLeft[0]) / targetResolution);\n var v1 = pixelRound(-(target[1][1] - targetTopLeft[1]) / targetResolution);\n var u2 = pixelRound((target[2][0] - targetTopLeft[0]) / targetResolution);\n var v2 = pixelRound(-(target[2][1] - targetTopLeft[1]) / targetResolution); // Shift all the source points to improve numerical stability\n // of all the subsequent calculations. The [x0, y0] is used here.\n // This is also used to simplify the linear system.\n\n var sourceNumericalShiftX = x0;\n var sourceNumericalShiftY = y0;\n x0 = 0;\n y0 = 0;\n x1 -= sourceNumericalShiftX;\n y1 -= sourceNumericalShiftY;\n x2 -= sourceNumericalShiftX;\n y2 -= sourceNumericalShiftY;\n var augmentedMatrix = [[x1, y1, 0, 0, u1 - u0], [x2, y2, 0, 0, u2 - u0], [0, 0, x1, y1, v1 - v0], [0, 0, x2, y2, v2 - v0]];\n var affineCoefs = solveLinearSystem(augmentedMatrix);\n\n if (!affineCoefs) {\n return;\n }\n\n context.save();\n context.beginPath();\n\n if (isBrokenDiagonalRendering() || opt_contextOptions === IMAGE_SMOOTHING_DISABLED) {\n // Make sure that all lines are horizontal or vertical\n context.moveTo(u1, v1); // This is the diagonal line. Do it in 4 steps\n\n var steps = 4;\n var ud = u0 - u1;\n var vd = v0 - v1;\n\n for (var step = 0; step < steps; step++) {\n // Go horizontally\n context.lineTo(u1 + pixelRound((step + 1) * ud / steps), v1 + pixelRound(step * vd / (steps - 1))); // Go vertically\n\n if (step != steps - 1) {\n context.lineTo(u1 + pixelRound((step + 1) * ud / steps), v1 + pixelRound((step + 1) * vd / (steps - 1)));\n }\n } // We are almost at u0r, v0r\n\n\n context.lineTo(u2, v2);\n } else {\n context.moveTo(u1, v1);\n context.lineTo(u0, v0);\n context.lineTo(u2, v2);\n }\n\n context.clip();\n context.transform(affineCoefs[0], affineCoefs[2], affineCoefs[1], affineCoefs[3], u0, v0);\n context.translate(sourceDataExtent[0] - sourceNumericalShiftX, sourceDataExtent[3] - sourceNumericalShiftY);\n context.scale(sourceResolution / pixelRatio, -sourceResolution / pixelRatio);\n context.drawImage(stitchContext.canvas, 0, 0);\n context.restore();\n });\n\n if (opt_renderEdges) {\n context.save();\n context.globalCompositeOperation = \'source-over\';\n context.strokeStyle = \'black\';\n context.lineWidth = 1;\n triangulation.getTriangles().forEach(function (triangle, i, arr) {\n var target = triangle.target;\n var u0 = (target[0][0] - targetTopLeft[0]) / targetResolution;\n var v0 = -(target[0][1] - targetTopLeft[1]) / targetResolution;\n var u1 = (target[1][0] - targetTopLeft[0]) / targetResolution;\n var v1 = -(target[1][1] - targetTopLeft[1]) / targetResolution;\n var u2 = (target[2][0] - targetTopLeft[0]) / targetResolution;\n var v2 = -(target[2][1] - targetTopLeft[1]) / targetResolution;\n context.beginPath();\n context.moveTo(u1, v1);\n context.lineTo(u0, v0);\n context.lineTo(u2, v2);\n context.closePath();\n context.stroke();\n });\n context.restore();\n }\n\n return context.canvas;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/reproj/Tile.js\nvar reproj_Tile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/reproj/Tile\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {function(number, number, number, number) : import("../Tile.js").default} FunctionType\n */\n\n/**\n * @classdesc\n * Class encapsulating single reprojected tile.\n * See {@link module:ol/source/TileImage~TileImage}.\n *\n */\n\nvar ReprojTile =\n/** @class */\nfunction (_super) {\n reproj_Tile_extends(ReprojTile, _super);\n /**\n * @param {import("../proj/Projection.js").default} sourceProj Source projection.\n * @param {import("../tilegrid/TileGrid.js").default} sourceTileGrid Source tile grid.\n * @param {import("../proj/Projection.js").default} targetProj Target projection.\n * @param {import("../tilegrid/TileGrid.js").default} targetTileGrid Target tile grid.\n * @param {import("../tilecoord.js").TileCoord} tileCoord Coordinate of the tile.\n * @param {import("../tilecoord.js").TileCoord} wrappedTileCoord Coordinate of the tile wrapped in X.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} gutter Gutter of the source tiles.\n * @param {FunctionType} getTileFunction\n * Function returning source tiles (z, x, y, pixelRatio).\n * @param {number=} opt_errorThreshold Acceptable reprojection error (in px).\n * @param {boolean=} opt_renderEdges Render reprojection edges.\n * @param {object=} opt_contextOptions Properties to set on the canvas context.\n */\n\n\n function ReprojTile(sourceProj, sourceTileGrid, targetProj, targetTileGrid, tileCoord, wrappedTileCoord, pixelRatio, gutter, getTileFunction, opt_errorThreshold, opt_renderEdges, opt_contextOptions) {\n var _this = _super.call(this, tileCoord, TileState.IDLE) || this;\n /**\n * @private\n * @type {boolean}\n */\n\n\n _this.renderEdges_ = opt_renderEdges !== undefined ? opt_renderEdges : false;\n /**\n * @private\n * @type {object}\n */\n\n _this.contextOptions_ = opt_contextOptions;\n /**\n * @private\n * @type {number}\n */\n\n _this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {number}\n */\n\n _this.gutter_ = gutter;\n /**\n * @private\n * @type {HTMLCanvasElement}\n */\n\n _this.canvas_ = null;\n /**\n * @private\n * @type {import("../tilegrid/TileGrid.js").default}\n */\n\n _this.sourceTileGrid_ = sourceTileGrid;\n /**\n * @private\n * @type {import("../tilegrid/TileGrid.js").default}\n */\n\n _this.targetTileGrid_ = targetTileGrid;\n /**\n * @private\n * @type {import("../tilecoord.js").TileCoord}\n */\n\n _this.wrappedTileCoord_ = wrappedTileCoord ? wrappedTileCoord : tileCoord;\n /**\n * @private\n * @type {!Array<import("../Tile.js").default>}\n */\n\n _this.sourceTiles_ = [];\n /**\n * @private\n * @type {?Array<import("../events.js").EventsKey>}\n */\n\n _this.sourcesListenerKeys_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.sourceZ_ = 0;\n var targetExtent = targetTileGrid.getTileCoordExtent(_this.wrappedTileCoord_);\n\n var maxTargetExtent = _this.targetTileGrid_.getExtent();\n\n var maxSourceExtent = _this.sourceTileGrid_.getExtent();\n\n var limitedTargetExtent = maxTargetExtent ? getIntersection(targetExtent, maxTargetExtent) : targetExtent;\n\n if (getArea(limitedTargetExtent) === 0) {\n // Tile is completely outside range -> EMPTY\n // TODO: is it actually correct that the source even creates the tile ?\n _this.state = TileState.EMPTY;\n return _this;\n }\n\n var sourceProjExtent = sourceProj.getExtent();\n\n if (sourceProjExtent) {\n if (!maxSourceExtent) {\n maxSourceExtent = sourceProjExtent;\n } else {\n maxSourceExtent = getIntersection(maxSourceExtent, sourceProjExtent);\n }\n }\n\n var targetResolution = targetTileGrid.getResolution(_this.wrappedTileCoord_[0]);\n var sourceResolution = calculateSourceExtentResolution(sourceProj, targetProj, limitedTargetExtent, targetResolution);\n\n if (!isFinite(sourceResolution) || sourceResolution <= 0) {\n // invalid sourceResolution -> EMPTY\n // probably edges of the projections when no extent is defined\n _this.state = TileState.EMPTY;\n return _this;\n }\n\n var errorThresholdInPixels = opt_errorThreshold !== undefined ? opt_errorThreshold : ERROR_THRESHOLD;\n /**\n * @private\n * @type {!import("./Triangulation.js").default}\n */\n\n _this.triangulation_ = new reproj_Triangulation(sourceProj, targetProj, limitedTargetExtent, maxSourceExtent, sourceResolution * errorThresholdInPixels, targetResolution);\n\n if (_this.triangulation_.getTriangles().length === 0) {\n // no valid triangles -> EMPTY\n _this.state = TileState.EMPTY;\n return _this;\n }\n\n _this.sourceZ_ = sourceTileGrid.getZForResolution(sourceResolution);\n\n var sourceExtent = _this.triangulation_.calculateSourceExtent();\n\n if (maxSourceExtent) {\n if (sourceProj.canWrapX()) {\n sourceExtent[1] = math_clamp(sourceExtent[1], maxSourceExtent[1], maxSourceExtent[3]);\n sourceExtent[3] = math_clamp(sourceExtent[3], maxSourceExtent[1], maxSourceExtent[3]);\n } else {\n sourceExtent = getIntersection(sourceExtent, maxSourceExtent);\n }\n }\n\n if (!getArea(sourceExtent)) {\n _this.state = TileState.EMPTY;\n } else {\n var sourceRange = sourceTileGrid.getTileRangeForExtentAndZ(sourceExtent, _this.sourceZ_);\n\n for (var srcX = sourceRange.minX; srcX <= sourceRange.maxX; srcX++) {\n for (var srcY = sourceRange.minY; srcY <= sourceRange.maxY; srcY++) {\n var tile = getTileFunction(_this.sourceZ_, srcX, srcY, pixelRatio);\n\n if (tile) {\n _this.sourceTiles_.push(tile);\n }\n }\n }\n\n if (_this.sourceTiles_.length === 0) {\n _this.state = TileState.EMPTY;\n }\n }\n\n return _this;\n }\n /**\n * Get the HTML Canvas element for this tile.\n * @return {HTMLCanvasElement} Canvas.\n */\n\n\n ReprojTile.prototype.getImage = function () {\n return this.canvas_;\n };\n /**\n * @private\n */\n\n\n ReprojTile.prototype.reproject_ = function () {\n var sources = [];\n this.sourceTiles_.forEach(function (tile, i, arr) {\n if (tile && tile.getState() == TileState.LOADED) {\n sources.push({\n extent: this.sourceTileGrid_.getTileCoordExtent(tile.tileCoord),\n image: tile.getImage()\n });\n }\n }.bind(this));\n this.sourceTiles_.length = 0;\n\n if (sources.length === 0) {\n this.state = TileState.ERROR;\n } else {\n var z = this.wrappedTileCoord_[0];\n var size = this.targetTileGrid_.getTileSize(z);\n var width = typeof size === \'number\' ? size : size[0];\n var height = typeof size === \'number\' ? size : size[1];\n var targetResolution = this.targetTileGrid_.getResolution(z);\n var sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_);\n var targetExtent = this.targetTileGrid_.getTileCoordExtent(this.wrappedTileCoord_);\n this.canvas_ = render(width, height, this.pixelRatio_, sourceResolution, this.sourceTileGrid_.getExtent(), targetResolution, targetExtent, this.triangulation_, sources, this.gutter_, this.renderEdges_, this.contextOptions_);\n this.state = TileState.LOADED;\n }\n\n this.changed();\n };\n /**\n * Load not yet loaded URI.\n */\n\n\n ReprojTile.prototype.load = function () {\n if (this.state == TileState.IDLE) {\n this.state = TileState.LOADING;\n this.changed();\n var leftToLoad_1 = 0;\n this.sourcesListenerKeys_ = [];\n this.sourceTiles_.forEach(function (tile, i, arr) {\n var state = tile.getState();\n\n if (state == TileState.IDLE || state == TileState.LOADING) {\n leftToLoad_1++;\n var sourceListenKey_1 = listen(tile, EventType.CHANGE, function (e) {\n var state = tile.getState();\n\n if (state == TileState.LOADED || state == TileState.ERROR || state == TileState.EMPTY) {\n unlistenByKey(sourceListenKey_1);\n leftToLoad_1--;\n\n if (leftToLoad_1 === 0) {\n this.unlistenSources_();\n this.reproject_();\n }\n }\n }, this);\n this.sourcesListenerKeys_.push(sourceListenKey_1);\n }\n }.bind(this));\n this.sourceTiles_.forEach(function (tile, i, arr) {\n var state = tile.getState();\n\n if (state == TileState.IDLE) {\n tile.load();\n }\n });\n\n if (leftToLoad_1 === 0) {\n setTimeout(this.reproject_.bind(this), 0);\n }\n }\n };\n /**\n * @private\n */\n\n\n ReprojTile.prototype.unlistenSources_ = function () {\n this.sourcesListenerKeys_.forEach(unlistenByKey);\n this.sourcesListenerKeys_ = null;\n };\n\n return ReprojTile;\n}(ol_Tile);\n\n/* harmony default export */ var reproj_Tile = (ReprojTile);\n;// CONCATENATED MODULE: ./node_modules/ol/source/TileImage.js\nvar TileImage_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/source/TileImage\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions] Attributions.\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that\n * you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [imageSmoothing=true] Enable image smoothing.\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {import("./State.js").default} [state] Source state.\n * @property {typeof import("../ImageTile.js").default} [tileClass] Class used to instantiate image tiles.\n * Default is {@link module:ol/ImageTile~ImageTile}.\n * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.\n * @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n * imageTile.getImage().src = src;\n * };\n * ```\n * @property {number} [tilePixelRatio=1] The pixel ratio used by the tile service. For example, if the tile\n * service advertizes 256px by 256px tiles but actually sends 512px\n * by 512px images (for retina/hidpi devices) then `tilePixelRatio`\n * should be set to `2`.\n * @property {import("../Tile.js").UrlFunction} [tileUrlFunction] Optional function to get tile URL given a tile coordinate and the projection.\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.\n * A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`, may be\n * used instead of defining each one separately in the `urls` option.\n * @property {Array<string>} [urls] An array of URL templates.\n * @property {boolean} [wrapX] Whether to wrap the world horizontally. The default, is to\n * request out-of-bounds tiles from the server. When set to `false`, only one\n * world will be rendered. When set to `true`, tiles will be requested for one\n * world only, but they will be wrapped horizontally to render multiple worlds.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n * @property {string} [key] Optional tile key for proper cache fetching\n * @property {number} [zDirection=0] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n */\n\n/**\n * @classdesc\n * Base class for sources providing images divided into a tile grid.\n *\n * @fires import("./Tile.js").TileSourceEvent\n * @api\n */\n\nvar TileImage =\n/** @class */\nfunction (_super) {\n TileImage_extends(TileImage, _super);\n /**\n * @param {!Options} options Image tile options.\n */\n\n\n function TileImage(options) {\n var _this = _super.call(this, {\n attributions: options.attributions,\n cacheSize: options.cacheSize,\n opaque: options.opaque,\n projection: options.projection,\n state: options.state,\n tileGrid: options.tileGrid,\n tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : defaultTileLoadFunction,\n tilePixelRatio: options.tilePixelRatio,\n tileUrlFunction: options.tileUrlFunction,\n url: options.url,\n urls: options.urls,\n wrapX: options.wrapX,\n transition: options.transition,\n key: options.key,\n attributionsCollapsible: options.attributionsCollapsible,\n zDirection: options.zDirection\n }) || this;\n /**\n * @protected\n * @type {?string}\n */\n\n\n _this.crossOrigin = options.crossOrigin !== undefined ? options.crossOrigin : null;\n /**\n * @protected\n * @type {typeof ImageTile}\n */\n\n _this.tileClass = options.tileClass !== undefined ? options.tileClass : ol_ImageTile;\n /**\n * @protected\n * @type {!Object<string, TileCache>}\n */\n\n _this.tileCacheForProjection = {};\n /**\n * @protected\n * @type {!Object<string, import("../tilegrid/TileGrid.js").default>}\n */\n\n _this.tileGridForProjection = {};\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.reprojectionErrorThreshold_ = options.reprojectionErrorThreshold;\n /**\n * @private\n * @type {object|undefined}\n */\n\n _this.contextOptions_ = options.imageSmoothing === false ? IMAGE_SMOOTHING_DISABLED : undefined;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.renderReprojectionEdges_ = false;\n return _this;\n }\n /**\n * @return {boolean} Can expire cache.\n */\n\n\n TileImage.prototype.canExpireCache = function () {\n if (!ENABLE_RASTER_REPROJECTION) {\n return _super.prototype.canExpireCache.call(this);\n }\n\n if (this.tileCache.canExpireCache()) {\n return true;\n } else {\n for (var key in this.tileCacheForProjection) {\n if (this.tileCacheForProjection[key].canExpireCache()) {\n return true;\n }\n }\n }\n\n return false;\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n\n\n TileImage.prototype.expireCache = function (projection, usedTiles) {\n if (!ENABLE_RASTER_REPROJECTION) {\n _super.prototype.expireCache.call(this, projection, usedTiles);\n\n return;\n }\n\n var usedTileCache = this.getTileCacheForProjection(projection);\n this.tileCache.expireCache(this.tileCache == usedTileCache ? usedTiles : {});\n\n for (var id in this.tileCacheForProjection) {\n var tileCache = this.tileCacheForProjection[id];\n tileCache.expireCache(tileCache == usedTileCache ? usedTiles : {});\n }\n };\n /**\n * @return {Object|undefined} Context options.\n */\n\n\n TileImage.prototype.getContextOptions = function () {\n return this.contextOptions_;\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {number} Gutter.\n */\n\n\n TileImage.prototype.getGutterForProjection = function (projection) {\n if (ENABLE_RASTER_REPROJECTION && this.getProjection() && projection && !equivalent(this.getProjection(), projection)) {\n return 0;\n } else {\n return this.getGutter();\n }\n };\n /**\n * @return {number} Gutter.\n */\n\n\n TileImage.prototype.getGutter = function () {\n return 0;\n };\n /**\n * Return the key to be used for all tiles in the source.\n * @return {string} The key for all tiles.\n * @protected\n */\n\n\n TileImage.prototype.getKey = function () {\n return _super.prototype.getKey.call(this) + (this.contextOptions_ ? \'\\n\' + JSON.stringify(this.contextOptions_) : \'\');\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {boolean} Opaque.\n */\n\n\n TileImage.prototype.getOpaque = function (projection) {\n if (ENABLE_RASTER_REPROJECTION && this.getProjection() && projection && !equivalent(this.getProjection(), projection)) {\n return false;\n } else {\n return _super.prototype.getOpaque.call(this, projection);\n }\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../tilegrid/TileGrid.js").default} Tile grid.\n */\n\n\n TileImage.prototype.getTileGridForProjection = function (projection) {\n if (!ENABLE_RASTER_REPROJECTION) {\n return _super.prototype.getTileGridForProjection.call(this, projection);\n }\n\n var thisProj = this.getProjection();\n\n if (this.tileGrid && (!thisProj || equivalent(thisProj, projection))) {\n return this.tileGrid;\n } else {\n var projKey = getUid(projection);\n\n if (!(projKey in this.tileGridForProjection)) {\n this.tileGridForProjection[projKey] = getForProjection(projection);\n }\n\n return this.tileGridForProjection[projKey];\n }\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {import("../TileCache.js").default} Tile cache.\n */\n\n\n TileImage.prototype.getTileCacheForProjection = function (projection) {\n if (!ENABLE_RASTER_REPROJECTION) {\n return _super.prototype.getTileCacheForProjection.call(this, projection);\n }\n\n var thisProj = this.getProjection();\n\n if (!thisProj || equivalent(thisProj, projection)) {\n return this.tileCache;\n } else {\n var projKey = getUid(projection);\n\n if (!(projKey in this.tileCacheForProjection)) {\n this.tileCacheForProjection[projKey] = new ol_TileCache(this.tileCache.highWaterMark);\n }\n\n return this.tileCacheForProjection[projKey];\n }\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @param {string} key The key set on the tile.\n * @return {!import("../Tile.js").default} Tile.\n * @private\n */\n\n\n TileImage.prototype.createTile_ = function (z, x, y, pixelRatio, projection, key) {\n var tileCoord = [z, x, y];\n var urlTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection);\n var tileUrl = urlTileCoord ? this.tileUrlFunction(urlTileCoord, pixelRatio, projection) : undefined;\n var tile = new this.tileClass(tileCoord, tileUrl !== undefined ? TileState.IDLE : TileState.EMPTY, tileUrl !== undefined ? tileUrl : \'\', this.crossOrigin, this.tileLoadFunction, this.tileOptions);\n tile.key = key;\n tile.addEventListener(EventType.CHANGE, this.handleTileChange.bind(this));\n return tile;\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../Tile.js").default} Tile.\n */\n\n\n TileImage.prototype.getTile = function (z, x, y, pixelRatio, projection) {\n var sourceProjection = this.getProjection();\n\n if (!ENABLE_RASTER_REPROJECTION || !sourceProjection || !projection || equivalent(sourceProjection, projection)) {\n return this.getTileInternal(z, x, y, pixelRatio, sourceProjection || projection);\n } else {\n var cache = this.getTileCacheForProjection(projection);\n var tileCoord = [z, x, y];\n var tile = void 0;\n var tileCoordKey = tilecoord_getKey(tileCoord);\n\n if (cache.containsKey(tileCoordKey)) {\n tile = cache.get(tileCoordKey);\n }\n\n var key = this.getKey();\n\n if (tile && tile.key == key) {\n return tile;\n } else {\n var sourceTileGrid = this.getTileGridForProjection(sourceProjection);\n var targetTileGrid = this.getTileGridForProjection(projection);\n var wrappedTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection);\n var newTile = new reproj_Tile(sourceProjection, sourceTileGrid, projection, targetTileGrid, tileCoord, wrappedTileCoord, this.getTilePixelRatio(pixelRatio), this.getGutter(), function (z, x, y, pixelRatio) {\n return this.getTileInternal(z, x, y, pixelRatio, sourceProjection);\n }.bind(this), this.reprojectionErrorThreshold_, this.renderReprojectionEdges_, this.contextOptions_);\n newTile.key = key;\n\n if (tile) {\n newTile.interimTile = tile;\n newTile.refreshInterimChain();\n cache.replace(tileCoordKey, newTile);\n } else {\n cache.set(tileCoordKey, newTile);\n }\n\n return newTile;\n }\n }\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {!import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../Tile.js").default} Tile.\n * @protected\n */\n\n\n TileImage.prototype.getTileInternal = function (z, x, y, pixelRatio, projection) {\n var tile = null;\n var tileCoordKey = getKeyZXY(z, x, y);\n var key = this.getKey();\n\n if (!this.tileCache.containsKey(tileCoordKey)) {\n tile = this.createTile_(z, x, y, pixelRatio, projection, key);\n this.tileCache.set(tileCoordKey, tile);\n } else {\n tile = this.tileCache.get(tileCoordKey);\n\n if (tile.key != key) {\n // The source\'s params changed. If the tile has an interim tile and if we\n // can use it then we use it. Otherwise we create a new tile. In both\n // cases we attempt to assign an interim tile to the new tile.\n var interimTile = tile;\n tile = this.createTile_(z, x, y, pixelRatio, projection, key); //make the new tile the head of the list,\n\n if (interimTile.getState() == TileState.IDLE) {\n //the old tile hasn\'t begun loading yet, and is now outdated, so we can simply discard it\n tile.interimTile = interimTile.interimTile;\n } else {\n tile.interimTile = interimTile;\n }\n\n tile.refreshInterimChain();\n this.tileCache.replace(tileCoordKey, tile);\n }\n }\n\n return tile;\n };\n /**\n * Sets whether to render reprojection edges or not (usually for debugging).\n * @param {boolean} render Render the edges.\n * @api\n */\n\n\n TileImage.prototype.setRenderReprojectionEdges = function (render) {\n if (!ENABLE_RASTER_REPROJECTION || this.renderReprojectionEdges_ == render) {\n return;\n }\n\n this.renderReprojectionEdges_ = render;\n\n for (var id in this.tileCacheForProjection) {\n this.tileCacheForProjection[id].clear();\n }\n\n this.changed();\n };\n /**\n * Sets the tile grid to use when reprojecting the tiles to the given\n * projection instead of the default tile grid for the projection.\n *\n * This can be useful when the default tile grid cannot be created\n * (e.g. projection has no extent defined) or\n * for optimization reasons (custom tile size, resolutions, ...).\n *\n * @param {import("../proj.js").ProjectionLike} projection Projection.\n * @param {import("../tilegrid/TileGrid.js").default} tilegrid Tile grid to use for the projection.\n * @api\n */\n\n\n TileImage.prototype.setTileGridForProjection = function (projection, tilegrid) {\n if (ENABLE_RASTER_REPROJECTION) {\n var proj = proj_get(projection);\n\n if (proj) {\n var projKey = getUid(proj);\n\n if (!(projKey in this.tileGridForProjection)) {\n this.tileGridForProjection[projKey] = tilegrid;\n }\n }\n }\n };\n\n return TileImage;\n}(source_UrlTile);\n/**\n * @param {ImageTile} imageTile Image tile.\n * @param {string} src Source.\n */\n\n\nfunction defaultTileLoadFunction(imageTile, src) {\n /** @type {HTMLImageElement|HTMLVideoElement} */\n imageTile.getImage().src = src;\n}\n\n/* harmony default export */ var source_TileImage = (TileImage);\n;// CONCATENATED MODULE: ./node_modules/ol/source/XYZ.js\n/**\n * @module ol/source/XYZ\n */\nvar XYZ_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions] Attributions.\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that\n * you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [imageSmoothing=true] Enable image smoothing.\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {import("../proj.js").ProjectionLike} [projection=\'EPSG:3857\'] Projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {number} [maxZoom=42] Optional max zoom level. Not used if `tileGrid` is provided.\n * @property {number} [minZoom=0] Optional min zoom level. Not used if `tileGrid` is provided.\n * @property {number} [maxResolution] Optional tile grid resolution at level zero. Not used if `tileGrid` is provided.\n * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.\n * @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n * imageTile.getImage().src = src;\n * };\n * ```\n * @property {number} [tilePixelRatio=1] The pixel ratio used by the tile service.\n * For example, if the tile service advertizes 256px by 256px tiles but actually sends 512px\n * by 512px images (for retina/hidpi devices) then `tilePixelRatio`\n * should be set to `2`.\n * @property {number|import("../size.js").Size} [tileSize=[256, 256]] The tile size used by the tile service.\n * Not used if `tileGrid` is provided.\n * @property {import("../Tile.js").UrlFunction} [tileUrlFunction] Optional function to get\n * tile URL given a tile coordinate and the projection.\n * Required if `url` or `urls` are not provided.\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`,\n * and `{z}` placeholders. A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`,\n * may be used instead of defining each one separately in the `urls` option.\n * @property {Array<string>} [urls] An array of URL templates.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * @property {number} [transition=250] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n * @property {number} [zDirection=0] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n */\n\n/**\n * @classdesc\n * Layer source for tile data with URLs in a set XYZ format that are\n * defined in a URL template. By default, this follows the widely-used\n * Google grid where `x` 0 and `y` 0 are in the top left. Grids like\n * TMS where `x` 0 and `y` 0 are in the bottom left can be used by\n * using the `{-y}` placeholder in the URL template, so long as the\n * source does not have a custom tile grid. In this case\n * a `tileUrlFunction` can be used, such as:\n * ```js\n * tileUrlFunction: function(coordinate) {\n * return \'http://mapserver.com/\' + coordinate[0] + \'/\' +\n * coordinate[1] + \'/\' + (-coordinate[2] - 1) + \'.png\';\n * }\n * ```\n * @api\n */\n\nvar XYZ =\n/** @class */\nfunction (_super) {\n XYZ_extends(XYZ, _super);\n /**\n * @param {Options=} opt_options XYZ options.\n */\n\n\n function XYZ(opt_options) {\n var _this = this;\n\n var options = opt_options || {};\n var projection = options.projection !== undefined ? options.projection : \'EPSG:3857\';\n var tileGrid = options.tileGrid !== undefined ? options.tileGrid : createXYZ({\n extent: extentFromProjection(projection),\n maxResolution: options.maxResolution,\n maxZoom: options.maxZoom,\n minZoom: options.minZoom,\n tileSize: options.tileSize\n });\n _this = _super.call(this, {\n attributions: options.attributions,\n cacheSize: options.cacheSize,\n crossOrigin: options.crossOrigin,\n imageSmoothing: options.imageSmoothing,\n opaque: options.opaque,\n projection: projection,\n reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n tileGrid: tileGrid,\n tileLoadFunction: options.tileLoadFunction,\n tilePixelRatio: options.tilePixelRatio,\n tileUrlFunction: options.tileUrlFunction,\n url: options.url,\n urls: options.urls,\n wrapX: options.wrapX !== undefined ? options.wrapX : true,\n transition: options.transition,\n attributionsCollapsible: options.attributionsCollapsible,\n zDirection: options.zDirection\n }) || this;\n return _this;\n }\n\n return XYZ;\n}(source_TileImage);\n\n/* harmony default export */ var source_XYZ = (XYZ);\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/defineProperty.js\nvar defineProperty = __webpack_require__(6156);\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selector.js\nfunction selector_none() {}\n\n/* harmony default export */ function selector(selector) {\n return selector == null ? selector_none : function () {\n return this.querySelector(selector);\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/select.js\n\n\n/* harmony default export */ function selection_select(select) {\n if (typeof select !== "function") select = selector(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n if ("__data__" in node) subnode.__data__ = node.__data__;\n subgroup[i] = subnode;\n }\n }\n }\n\n return new Selection(subgroups, this._parents);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/array.js\n// Given something array like (or null), returns something that is strictly an\n// array. This is used to ensure that array-like objects passed to d3.selectAll\n// or selection.selectAll are converted into proper arrays when creating a\n// selection; we don’t ever want to create a selection backed by a live\n// HTMLCollection or NodeList. However, note that selection.selectAll will use a\n// static NodeList as a group, since it safely derived from querySelectorAll.\nfunction array(x) {\n return x == null ? [] : Array.isArray(x) ? x : Array.from(x);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selectorAll.js\nfunction empty() {\n return [];\n}\n\n/* harmony default export */ function selectorAll(selector) {\n return selector == null ? empty : function () {\n return this.querySelectorAll(selector);\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/selectAll.js\n\n\n\n\nfunction arrayAll(select) {\n return function () {\n return array(select.apply(this, arguments));\n };\n}\n\n/* harmony default export */ function selectAll(select) {\n if (typeof select === "function") select = arrayAll(select);else select = selectorAll(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n subgroups.push(select.call(node, node.__data__, i, group));\n parents.push(node);\n }\n }\n }\n\n return new Selection(subgroups, parents);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/matcher.js\n/* harmony default export */ function matcher(selector) {\n return function () {\n return this.matches(selector);\n };\n}\nfunction childMatcher(selector) {\n return function (node) {\n return node.matches(selector);\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/selectChild.js\n\nvar selectChild_find = Array.prototype.find;\n\nfunction childFind(match) {\n return function () {\n return selectChild_find.call(this.children, match);\n };\n}\n\nfunction childFirst() {\n return this.firstElementChild;\n}\n\n/* harmony default export */ function selectChild(match) {\n return this.select(match == null ? childFirst : childFind(typeof match === "function" ? match : childMatcher(match)));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/selectChildren.js\n\nvar filter = Array.prototype.filter;\n\nfunction children() {\n return Array.from(this.children);\n}\n\nfunction childrenFilter(match) {\n return function () {\n return filter.call(this.children, match);\n };\n}\n\n/* harmony default export */ function selectChildren(match) {\n return this.selectAll(match == null ? children : childrenFilter(typeof match === "function" ? match : childMatcher(match)));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/filter.js\n\n\n/* harmony default export */ function selection_filter(match) {\n if (typeof match !== "function") match = matcher(match);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n subgroup.push(node);\n }\n }\n }\n\n return new Selection(subgroups, this._parents);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/sparse.js\n/* harmony default export */ function sparse(update) {\n return new Array(update.length);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/enter.js\n\n\n/* harmony default export */ function enter() {\n return new Selection(this._enter || this._groups.map(sparse), this._parents);\n}\nfunction EnterNode(parent, datum) {\n this.ownerDocument = parent.ownerDocument;\n this.namespaceURI = parent.namespaceURI;\n this._next = null;\n this._parent = parent;\n this.__data__ = datum;\n}\nEnterNode.prototype = {\n constructor: EnterNode,\n appendChild: function appendChild(child) {\n return this._parent.insertBefore(child, this._next);\n },\n insertBefore: function insertBefore(child, next) {\n return this._parent.insertBefore(child, next);\n },\n querySelector: function querySelector(selector) {\n return this._parent.querySelector(selector);\n },\n querySelectorAll: function querySelectorAll(selector) {\n return this._parent.querySelectorAll(selector);\n }\n};\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/constant.js\n/* harmony default export */ function src_constant(x) {\n return function () {\n return x;\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/data.js\n\n\n\n\nfunction bindIndex(parent, group, enter, update, exit, data) {\n var i = 0,\n node,\n groupLength = group.length,\n dataLength = data.length; // Put any non-null nodes that fit into update.\n // Put any null nodes into enter.\n // Put any remaining data into enter.\n\n for (; i < dataLength; ++i) {\n if (node = group[i]) {\n node.__data__ = data[i];\n update[i] = node;\n } else {\n enter[i] = new EnterNode(parent, data[i]);\n }\n } // Put any non-null nodes that don’t fit into exit.\n\n\n for (; i < groupLength; ++i) {\n if (node = group[i]) {\n exit[i] = node;\n }\n }\n}\n\nfunction bindKey(parent, group, enter, update, exit, data, key) {\n var i,\n node,\n nodeByKeyValue = new Map(),\n groupLength = group.length,\n dataLength = data.length,\n keyValues = new Array(groupLength),\n keyValue; // Compute the key for each node.\n // If multiple nodes have the same key, the duplicates are added to exit.\n\n for (i = 0; i < groupLength; ++i) {\n if (node = group[i]) {\n keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + "";\n\n if (nodeByKeyValue.has(keyValue)) {\n exit[i] = node;\n } else {\n nodeByKeyValue.set(keyValue, node);\n }\n }\n } // Compute the key for each datum.\n // If there a node associated with this key, join and add it to update.\n // If there is not (or the key is a duplicate), add it to enter.\n\n\n for (i = 0; i < dataLength; ++i) {\n keyValue = key.call(parent, data[i], i, data) + "";\n\n if (node = nodeByKeyValue.get(keyValue)) {\n update[i] = node;\n node.__data__ = data[i];\n nodeByKeyValue.delete(keyValue);\n } else {\n enter[i] = new EnterNode(parent, data[i]);\n }\n } // Add any remaining nodes that were not bound to data to exit.\n\n\n for (i = 0; i < groupLength; ++i) {\n if ((node = group[i]) && nodeByKeyValue.get(keyValues[i]) === node) {\n exit[i] = node;\n }\n }\n}\n\nfunction datum(node) {\n return node.__data__;\n}\n\n/* harmony default export */ function data(value, key) {\n if (!arguments.length) return Array.from(this, datum);\n var bind = key ? bindKey : bindIndex,\n parents = this._parents,\n groups = this._groups;\n if (typeof value !== "function") value = src_constant(value);\n\n for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {\n var parent = parents[j],\n group = groups[j],\n groupLength = group.length,\n data = arraylike(value.call(parent, parent && parent.__data__, j, parents)),\n dataLength = data.length,\n enterGroup = enter[j] = new Array(dataLength),\n updateGroup = update[j] = new Array(dataLength),\n exitGroup = exit[j] = new Array(groupLength);\n bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); // Now connect the enter nodes to their following update node, such that\n // appendChild can insert the materialized enter node before this node,\n // rather than at the end of the parent node.\n\n for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {\n if (previous = enterGroup[i0]) {\n if (i0 >= i1) i1 = i0 + 1;\n\n while (!(next = updateGroup[i1]) && ++i1 < dataLength) {\n ;\n }\n\n previous._next = next || null;\n }\n }\n }\n\n update = new Selection(update, parents);\n update._enter = enter;\n update._exit = exit;\n return update;\n} // Given some data, this returns an array-like view of it: an object that\n// exposes a length property and allows numeric indexing. Note that unlike\n// selectAll, this isn’t worried about “live” collections because the resulting\n// array will only be used briefly while data is being bound. (It is possible to\n// cause the data to change while iterating by using a key function, but please\n// don’t; we’d rather avoid a gratuitous copy.)\n\nfunction arraylike(data) {\n return typeof data === "object" && "length" in data ? data // Array, TypedArray, NodeList, array-like\n : Array.from(data); // Map, Set, iterable, string, or anything else\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/exit.js\n\n\n/* harmony default export */ function exit() {\n return new Selection(this._exit || this._groups.map(sparse), this._parents);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/join.js\n/* harmony default export */ function join(onenter, onupdate, onexit) {\n var enter = this.enter(),\n update = this,\n exit = this.exit();\n\n if (typeof onenter === "function") {\n enter = onenter(enter);\n if (enter) enter = enter.selection();\n } else {\n enter = enter.append(onenter + "");\n }\n\n if (onupdate != null) {\n update = onupdate(update);\n if (update) update = update.selection();\n }\n\n if (onexit == null) exit.remove();else onexit(exit);\n return enter && update ? enter.merge(update).order() : update;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/merge.js\n\n/* harmony default export */ function merge(context) {\n var selection = context.selection ? context.selection() : context;\n\n for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group0[i] || group1[i]) {\n merge[i] = node;\n }\n }\n }\n\n for (; j < m0; ++j) {\n merges[j] = groups0[j];\n }\n\n return new Selection(merges, this._parents);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/order.js\n/* harmony default export */ function order() {\n for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {\n for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {\n if (node = group[i]) {\n if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next);\n next = node;\n }\n }\n }\n\n return this;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/sort.js\n\n/* harmony default export */ function sort(compare) {\n if (!compare) compare = ascending;\n\n function compareNode(a, b) {\n return a && b ? compare(a.__data__, b.__data__) : !a - !b;\n }\n\n for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n sortgroup[i] = node;\n }\n }\n\n sortgroup.sort(compareNode);\n }\n\n return new Selection(sortgroups, this._parents).order();\n}\n\nfunction ascending(a, b) {\n return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/call.js\n/* harmony default export */ function call() {\n var callback = arguments[0];\n arguments[0] = this;\n callback.apply(null, arguments);\n return this;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/nodes.js\n/* harmony default export */ function nodes() {\n return Array.from(this);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/node.js\n/* harmony default export */ function node() {\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {\n var node = group[i];\n if (node) return node;\n }\n }\n\n return null;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/size.js\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n/* harmony default export */ function size() {\n var size = 0;\n\n var _iterator = _createForOfIteratorHelper(this),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var node = _step.value;\n ++size;\n } // eslint-disable-line no-unused-vars\n\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n return size;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/empty.js\n/* harmony default export */ function selection_empty() {\n return !this.node();\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/each.js\n/* harmony default export */ function each(callback) {\n for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {\n if (node = group[i]) callback.call(node, node.__data__, i, group);\n }\n }\n\n return this;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/namespaces.js\nvar xhtml = "http://www.w3.org/1999/xhtml";\n/* harmony default export */ var namespaces = ({\n svg: "http://www.w3.org/2000/svg",\n xhtml: xhtml,\n xlink: "http://www.w3.org/1999/xlink",\n xml: "http://www.w3.org/XML/1998/namespace",\n xmlns: "http://www.w3.org/2000/xmlns/"\n});\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/namespace.js\n\n/* harmony default export */ function namespace(name) {\n var prefix = name += "",\n i = prefix.indexOf(":");\n if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);\n return namespaces.hasOwnProperty(prefix) ? {\n space: namespaces[prefix],\n local: name\n } : name; // eslint-disable-line no-prototype-builtins\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/attr.js\n\n\nfunction attrRemove(name) {\n return function () {\n this.removeAttribute(name);\n };\n}\n\nfunction attrRemoveNS(fullname) {\n return function () {\n this.removeAttributeNS(fullname.space, fullname.local);\n };\n}\n\nfunction attrConstant(name, value) {\n return function () {\n this.setAttribute(name, value);\n };\n}\n\nfunction attrConstantNS(fullname, value) {\n return function () {\n this.setAttributeNS(fullname.space, fullname.local, value);\n };\n}\n\nfunction attrFunction(name, value) {\n return function () {\n var v = value.apply(this, arguments);\n if (v == null) this.removeAttribute(name);else this.setAttribute(name, v);\n };\n}\n\nfunction attrFunctionNS(fullname, value) {\n return function () {\n var v = value.apply(this, arguments);\n if (v == null) this.removeAttributeNS(fullname.space, fullname.local);else this.setAttributeNS(fullname.space, fullname.local, v);\n };\n}\n\n/* harmony default export */ function attr(name, value) {\n var fullname = namespace(name);\n\n if (arguments.length < 2) {\n var node = this.node();\n return fullname.local ? node.getAttributeNS(fullname.space, fullname.local) : node.getAttribute(fullname);\n }\n\n return this.each((value == null ? fullname.local ? attrRemoveNS : attrRemove : typeof value === "function" ? fullname.local ? attrFunctionNS : attrFunction : fullname.local ? attrConstantNS : attrConstant)(fullname, value));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/window.js\n/* harmony default export */ function src_window(node) {\n return node.ownerDocument && node.ownerDocument.defaultView || // node is a Node\n node.document && node // node is a Window\n || node.defaultView; // node is a Document\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/style.js\n\n\nfunction styleRemove(name) {\n return function () {\n this.style.removeProperty(name);\n };\n}\n\nfunction styleConstant(name, value, priority) {\n return function () {\n this.style.setProperty(name, value, priority);\n };\n}\n\nfunction styleFunction(name, value, priority) {\n return function () {\n var v = value.apply(this, arguments);\n if (v == null) this.style.removeProperty(name);else this.style.setProperty(name, v, priority);\n };\n}\n\n/* harmony default export */ function style(name, value, priority) {\n return arguments.length > 1 ? this.each((value == null ? styleRemove : typeof value === "function" ? styleFunction : styleConstant)(name, value, priority == null ? "" : priority)) : styleValue(this.node(), name);\n}\nfunction styleValue(node, name) {\n return node.style.getPropertyValue(name) || src_window(node).getComputedStyle(node, null).getPropertyValue(name);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/property.js\nfunction propertyRemove(name) {\n return function () {\n delete this[name];\n };\n}\n\nfunction propertyConstant(name, value) {\n return function () {\n this[name] = value;\n };\n}\n\nfunction propertyFunction(name, value) {\n return function () {\n var v = value.apply(this, arguments);\n if (v == null) delete this[name];else this[name] = v;\n };\n}\n\n/* harmony default export */ function property(name, value) {\n return arguments.length > 1 ? this.each((value == null ? propertyRemove : typeof value === "function" ? propertyFunction : propertyConstant)(name, value)) : this.node()[name];\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/classed.js\nfunction classArray(string) {\n return string.trim().split(/^|\\s+/);\n}\n\nfunction classList(node) {\n return node.classList || new ClassList(node);\n}\n\nfunction ClassList(node) {\n this._node = node;\n this._names = classArray(node.getAttribute("class") || "");\n}\n\nClassList.prototype = {\n add: function add(name) {\n var i = this._names.indexOf(name);\n\n if (i < 0) {\n this._names.push(name);\n\n this._node.setAttribute("class", this._names.join(" "));\n }\n },\n remove: function remove(name) {\n var i = this._names.indexOf(name);\n\n if (i >= 0) {\n this._names.splice(i, 1);\n\n this._node.setAttribute("class", this._names.join(" "));\n }\n },\n contains: function contains(name) {\n return this._names.indexOf(name) >= 0;\n }\n};\n\nfunction classedAdd(node, names) {\n var list = classList(node),\n i = -1,\n n = names.length;\n\n while (++i < n) {\n list.add(names[i]);\n }\n}\n\nfunction classedRemove(node, names) {\n var list = classList(node),\n i = -1,\n n = names.length;\n\n while (++i < n) {\n list.remove(names[i]);\n }\n}\n\nfunction classedTrue(names) {\n return function () {\n classedAdd(this, names);\n };\n}\n\nfunction classedFalse(names) {\n return function () {\n classedRemove(this, names);\n };\n}\n\nfunction classedFunction(names, value) {\n return function () {\n (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);\n };\n}\n\n/* harmony default export */ function classed(name, value) {\n var names = classArray(name + "");\n\n if (arguments.length < 2) {\n var list = classList(this.node()),\n i = -1,\n n = names.length;\n\n while (++i < n) {\n if (!list.contains(names[i])) return false;\n }\n\n return true;\n }\n\n return this.each((typeof value === "function" ? classedFunction : value ? classedTrue : classedFalse)(names, value));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/text.js\nfunction textRemove() {\n this.textContent = "";\n}\n\nfunction textConstant(value) {\n return function () {\n this.textContent = value;\n };\n}\n\nfunction textFunction(value) {\n return function () {\n var v = value.apply(this, arguments);\n this.textContent = v == null ? "" : v;\n };\n}\n\n/* harmony default export */ function selection_text(value) {\n return arguments.length ? this.each(value == null ? textRemove : (typeof value === "function" ? textFunction : textConstant)(value)) : this.node().textContent;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/html.js\nfunction htmlRemove() {\n this.innerHTML = "";\n}\n\nfunction htmlConstant(value) {\n return function () {\n this.innerHTML = value;\n };\n}\n\nfunction htmlFunction(value) {\n return function () {\n var v = value.apply(this, arguments);\n this.innerHTML = v == null ? "" : v;\n };\n}\n\n/* harmony default export */ function html(value) {\n return arguments.length ? this.each(value == null ? htmlRemove : (typeof value === "function" ? htmlFunction : htmlConstant)(value)) : this.node().innerHTML;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/raise.js\nfunction raise() {\n if (this.nextSibling) this.parentNode.appendChild(this);\n}\n\n/* harmony default export */ function selection_raise() {\n return this.each(raise);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/lower.js\nfunction lower() {\n if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);\n}\n\n/* harmony default export */ function selection_lower() {\n return this.each(lower);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/creator.js\n\n\n\nfunction creatorInherit(name) {\n return function () {\n var document = this.ownerDocument,\n uri = this.namespaceURI;\n return uri === xhtml && document.documentElement.namespaceURI === xhtml ? document.createElement(name) : document.createElementNS(uri, name);\n };\n}\n\nfunction creatorFixed(fullname) {\n return function () {\n return this.ownerDocument.createElementNS(fullname.space, fullname.local);\n };\n}\n\n/* harmony default export */ function creator(name) {\n var fullname = namespace(name);\n return (fullname.local ? creatorFixed : creatorInherit)(fullname);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/append.js\n\n/* harmony default export */ function append(name) {\n var create = typeof name === "function" ? name : creator(name);\n return this.select(function () {\n return this.appendChild(create.apply(this, arguments));\n });\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/insert.js\n\n\n\nfunction constantNull() {\n return null;\n}\n\n/* harmony default export */ function insert(name, before) {\n var create = typeof name === "function" ? name : creator(name),\n select = before == null ? constantNull : typeof before === "function" ? before : selector(before);\n return this.select(function () {\n return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);\n });\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/remove.js\nfunction remove_remove() {\n var parent = this.parentNode;\n if (parent) parent.removeChild(this);\n}\n\n/* harmony default export */ function selection_remove() {\n return this.each(remove_remove);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/clone.js\nfunction selection_cloneShallow() {\n var clone = this.cloneNode(false),\n parent = this.parentNode;\n return parent ? parent.insertBefore(clone, this.nextSibling) : clone;\n}\n\nfunction selection_cloneDeep() {\n var clone = this.cloneNode(true),\n parent = this.parentNode;\n return parent ? parent.insertBefore(clone, this.nextSibling) : clone;\n}\n\n/* harmony default export */ function selection_clone(deep) {\n return this.select(deep ? selection_cloneDeep : selection_cloneShallow);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/datum.js\n/* harmony default export */ function selection_datum(value) {\n return arguments.length ? this.property("__data__", value) : this.node().__data__;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/on.js\nfunction contextListener(listener) {\n return function (event) {\n listener.call(this, event, this.__data__);\n };\n}\n\nfunction parseTypenames(typenames) {\n return typenames.trim().split(/^|\\s+/).map(function (t) {\n var name = "",\n i = t.indexOf(".");\n if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n return {\n type: t,\n name: name\n };\n });\n}\n\nfunction onRemove(typename) {\n return function () {\n var on = this.__on;\n if (!on) return;\n\n for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {\n if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {\n this.removeEventListener(o.type, o.listener, o.options);\n } else {\n on[++i] = o;\n }\n }\n\n if (++i) on.length = i;else delete this.__on;\n };\n}\n\nfunction onAdd(typename, value, options) {\n return function () {\n var on = this.__on,\n o,\n listener = contextListener(value);\n if (on) for (var j = 0, m = on.length; j < m; ++j) {\n if ((o = on[j]).type === typename.type && o.name === typename.name) {\n this.removeEventListener(o.type, o.listener, o.options);\n this.addEventListener(o.type, o.listener = listener, o.options = options);\n o.value = value;\n return;\n }\n }\n this.addEventListener(typename.type, listener, options);\n o = {\n type: typename.type,\n name: typename.name,\n value: value,\n listener: listener,\n options: options\n };\n if (!on) this.__on = [o];else on.push(o);\n };\n}\n\n/* harmony default export */ function on(typename, value, options) {\n var typenames = parseTypenames(typename + ""),\n i,\n n = typenames.length,\n t;\n\n if (arguments.length < 2) {\n var on = this.node().__on;\n\n if (on) for (var j = 0, m = on.length, o; j < m; ++j) {\n for (i = 0, o = on[j]; i < n; ++i) {\n if ((t = typenames[i]).type === o.type && t.name === o.name) {\n return o.value;\n }\n }\n }\n return;\n }\n\n on = value ? onAdd : onRemove;\n\n for (i = 0; i < n; ++i) {\n this.each(on(typenames[i], value, options));\n }\n\n return this;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/dispatch.js\n\n\nfunction dispatchEvent(node, type, params) {\n var window = src_window(node),\n event = window.CustomEvent;\n\n if (typeof event === "function") {\n event = new event(type, params);\n } else {\n event = window.document.createEvent("Event");\n if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;else event.initEvent(type, false, false);\n }\n\n node.dispatchEvent(event);\n}\n\nfunction dispatchConstant(type, params) {\n return function () {\n return dispatchEvent(this, type, params);\n };\n}\n\nfunction dispatchFunction(type, params) {\n return function () {\n return dispatchEvent(this, type, params.apply(this, arguments));\n };\n}\n\n/* harmony default export */ function selection_dispatch(type, params) {\n return this.each((typeof params === "function" ? dispatchFunction : dispatchConstant)(type, params));\n}\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/regenerator/index.js\nvar regenerator = __webpack_require__(7757);\nvar regenerator_default = /*#__PURE__*/__webpack_require__.n(regenerator);\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/iterator.js\n\n\nvar _marked = /*#__PURE__*/regenerator_default().mark(_callee);\n\nfunction _callee() {\n var groups, j, m, group, i, n, node;\n return regenerator_default().wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n groups = this._groups, j = 0, m = groups.length;\n\n case 1:\n if (!(j < m)) {\n _context.next = 13;\n break;\n }\n\n group = groups[j], i = 0, n = group.length;\n\n case 3:\n if (!(i < n)) {\n _context.next = 10;\n break;\n }\n\n if (!(node = group[i])) {\n _context.next = 7;\n break;\n }\n\n _context.next = 7;\n return node;\n\n case 7:\n ++i;\n _context.next = 3;\n break;\n\n case 10:\n ++j;\n _context.next = 1;\n break;\n\n case 13:\n case "end":\n return _context.stop();\n }\n }\n }, _marked, this);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-selection/src/selection/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar root = [null];\nfunction Selection(groups, parents) {\n this._groups = groups;\n this._parents = parents;\n}\n\nfunction selection() {\n return new Selection([[document.documentElement]], root);\n}\n\nfunction selection_selection() {\n return this;\n}\n\nSelection.prototype = selection.prototype = (0,defineProperty/* default */.Z)({\n constructor: Selection,\n select: selection_select,\n selectAll: selectAll,\n selectChild: selectChild,\n selectChildren: selectChildren,\n filter: selection_filter,\n data: data,\n enter: enter,\n exit: exit,\n join: join,\n merge: merge,\n selection: selection_selection,\n order: order,\n sort: sort,\n call: call,\n nodes: nodes,\n node: node,\n size: size,\n empty: selection_empty,\n each: each,\n attr: attr,\n style: style,\n property: property,\n classed: classed,\n text: selection_text,\n html: html,\n raise: selection_raise,\n lower: selection_lower,\n append: append,\n insert: insert,\n remove: selection_remove,\n clone: selection_clone,\n datum: selection_datum,\n on: on,\n dispatch: selection_dispatch\n}, Symbol.iterator, _callee);\n/* harmony default export */ var src_selection = (selection);\n;// CONCATENATED MODULE: ./node_modules/d3-dispatch/src/dispatch.js\nvar noop = {\n value: function value() {}\n};\n\nfunction dispatch_dispatch() {\n for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {\n if (!(t = arguments[i] + "") || t in _ || /[\\s.]/.test(t)) throw new Error("illegal type: " + t);\n _[t] = [];\n }\n\n return new Dispatch(_);\n}\n\nfunction Dispatch(_) {\n this._ = _;\n}\n\nfunction dispatch_parseTypenames(typenames, types) {\n return typenames.trim().split(/^|\\s+/).map(function (t) {\n var name = "",\n i = t.indexOf(".");\n if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);\n return {\n type: t,\n name: name\n };\n });\n}\n\nDispatch.prototype = dispatch_dispatch.prototype = {\n constructor: Dispatch,\n on: function on(typename, callback) {\n var _ = this._,\n T = dispatch_parseTypenames(typename + "", _),\n t,\n i = -1,\n n = T.length; // If no callback was specified, return the callback of the given type and name.\n\n if (arguments.length < 2) {\n while (++i < n) {\n if ((t = (typename = T[i]).type) && (t = dispatch_get(_[t], typename.name))) return t;\n }\n\n return;\n } // If a type was specified, set the callback for the given type and name.\n // Otherwise, if a null callback was specified, remove callbacks of the given name.\n\n\n if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);\n\n while (++i < n) {\n if (t = (typename = T[i]).type) _[t] = dispatch_set(_[t], typename.name, callback);else if (callback == null) for (t in _) {\n _[t] = dispatch_set(_[t], typename.name, null);\n }\n }\n\n return this;\n },\n copy: function copy() {\n var copy = {},\n _ = this._;\n\n for (var t in _) {\n copy[t] = _[t].slice();\n }\n\n return new Dispatch(copy);\n },\n call: function call(type, that) {\n if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) {\n args[i] = arguments[i + 2];\n }\n if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);\n\n for (t = this._[type], i = 0, n = t.length; i < n; ++i) {\n t[i].value.apply(that, args);\n }\n },\n apply: function apply(type, that, args) {\n if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);\n\n for (var t = this._[type], i = 0, n = t.length; i < n; ++i) {\n t[i].value.apply(that, args);\n }\n }\n};\n\nfunction dispatch_get(type, name) {\n for (var i = 0, n = type.length, c; i < n; ++i) {\n if ((c = type[i]).name === name) {\n return c.value;\n }\n }\n}\n\nfunction dispatch_set(type, name, callback) {\n for (var i = 0, n = type.length; i < n; ++i) {\n if (type[i].name === name) {\n type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));\n break;\n }\n }\n\n if (callback != null) type.push({\n name: name,\n value: callback\n });\n return type;\n}\n\n/* harmony default export */ var src_dispatch = (dispatch_dispatch);\n;// CONCATENATED MODULE: ./node_modules/d3-timer/src/timer.js\nvar timer_frame = 0,\n // is an animation frame pending?\ntimeout = 0,\n // is a timeout pending?\ninterval = 0,\n // are any timers active?\npokeDelay = 1000,\n // how frequently we check for clock skew\ntaskHead,\n taskTail,\n clockLast = 0,\n clockNow = 0,\n clockSkew = 0,\n clock = typeof performance === "object" && performance.now ? performance : Date,\n setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function (f) {\n setTimeout(f, 17);\n};\nfunction now() {\n return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);\n}\n\nfunction clearNow() {\n clockNow = 0;\n}\n\nfunction Timer() {\n this._call = this._time = this._next = null;\n}\nTimer.prototype = timer.prototype = {\n constructor: Timer,\n restart: function restart(callback, delay, time) {\n if (typeof callback !== "function") throw new TypeError("callback is not a function");\n time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);\n\n if (!this._next && taskTail !== this) {\n if (taskTail) taskTail._next = this;else taskHead = this;\n taskTail = this;\n }\n\n this._call = callback;\n this._time = time;\n sleep();\n },\n stop: function stop() {\n if (this._call) {\n this._call = null;\n this._time = Infinity;\n sleep();\n }\n }\n};\nfunction timer(callback, delay, time) {\n var t = new Timer();\n t.restart(callback, delay, time);\n return t;\n}\nfunction timerFlush() {\n now(); // Get the current time, if not already set.\n\n ++timer_frame; // Pretend we’ve set an alarm, if we haven’t already.\n\n var t = taskHead,\n e;\n\n while (t) {\n if ((e = clockNow - t._time) >= 0) t._call.call(undefined, e);\n t = t._next;\n }\n\n --timer_frame;\n}\n\nfunction wake() {\n clockNow = (clockLast = clock.now()) + clockSkew;\n timer_frame = timeout = 0;\n\n try {\n timerFlush();\n } finally {\n timer_frame = 0;\n nap();\n clockNow = 0;\n }\n}\n\nfunction poke() {\n var now = clock.now(),\n delay = now - clockLast;\n if (delay > pokeDelay) clockSkew -= delay, clockLast = now;\n}\n\nfunction nap() {\n var t0,\n t1 = taskHead,\n t2,\n time = Infinity;\n\n while (t1) {\n if (t1._call) {\n if (time > t1._time) time = t1._time;\n t0 = t1, t1 = t1._next;\n } else {\n t2 = t1._next, t1._next = null;\n t1 = t0 ? t0._next = t2 : taskHead = t2;\n }\n }\n\n taskTail = t0;\n sleep(time);\n}\n\nfunction sleep(time) {\n if (timer_frame) return; // Soonest alarm already set, or will be.\n\n if (timeout) timeout = clearTimeout(timeout);\n var delay = time - clockNow; // Strictly less than if we recomputed clockNow.\n\n if (delay > 24) {\n if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);\n if (interval) interval = clearInterval(interval);\n } else {\n if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);\n timer_frame = 1, setFrame(wake);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/d3-timer/src/timeout.js\n\n/* harmony default export */ function src_timeout(callback, delay, time) {\n var t = new Timer();\n delay = delay == null ? 0 : +delay;\n t.restart(function (elapsed) {\n t.stop();\n callback(elapsed + delay);\n }, delay, time);\n return t;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/schedule.js\n\n\nvar emptyOn = src_dispatch("start", "end", "cancel", "interrupt");\nvar emptyTween = [];\nvar CREATED = 0;\nvar SCHEDULED = 1;\nvar STARTING = 2;\nvar STARTED = 3;\nvar RUNNING = 4;\nvar ENDING = 5;\nvar ENDED = 6;\n/* harmony default export */ function schedule(node, name, id, index, group, timing) {\n var schedules = node.__transition;\n if (!schedules) node.__transition = {};else if (id in schedules) return;\n schedule_create(node, id, {\n name: name,\n index: index,\n // For context during callback.\n group: group,\n // For context during callback.\n on: emptyOn,\n tween: emptyTween,\n time: timing.time,\n delay: timing.delay,\n duration: timing.duration,\n ease: timing.ease,\n timer: null,\n state: CREATED\n });\n}\nfunction init(node, id) {\n var schedule = schedule_get(node, id);\n if (schedule.state > CREATED) throw new Error("too late; already scheduled");\n return schedule;\n}\nfunction schedule_set(node, id) {\n var schedule = schedule_get(node, id);\n if (schedule.state > STARTED) throw new Error("too late; already running");\n return schedule;\n}\nfunction schedule_get(node, id) {\n var schedule = node.__transition;\n if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found");\n return schedule;\n}\n\nfunction schedule_create(node, id, self) {\n var schedules = node.__transition,\n tween; // Initialize the self timer when the transition is created.\n // Note the actual delay is not known until the first callback!\n\n schedules[id] = self;\n self.timer = timer(schedule, 0, self.time);\n\n function schedule(elapsed) {\n self.state = SCHEDULED;\n self.timer.restart(start, self.delay, self.time); // If the elapsed delay is less than our first sleep, start immediately.\n\n if (self.delay <= elapsed) start(elapsed - self.delay);\n }\n\n function start(elapsed) {\n var i, j, n, o; // If the state is not SCHEDULED, then we previously errored on start.\n\n if (self.state !== SCHEDULED) return stop();\n\n for (i in schedules) {\n o = schedules[i];\n if (o.name !== self.name) continue; // While this element already has a starting transition during this frame,\n // defer starting an interrupting transition until that transition has a\n // chance to tick (and possibly end); see d3/d3-transition#54!\n\n if (o.state === STARTED) return src_timeout(start); // Interrupt the active transition, if any.\n\n if (o.state === RUNNING) {\n o.state = ENDED;\n o.timer.stop();\n o.on.call("interrupt", node, node.__data__, o.index, o.group);\n delete schedules[i];\n } // Cancel any pre-empted transitions.\n else if (+i < id) {\n o.state = ENDED;\n o.timer.stop();\n o.on.call("cancel", node, node.__data__, o.index, o.group);\n delete schedules[i];\n }\n } // Defer the first tick to end of the current frame; see d3/d3#1576.\n // Note the transition may be canceled after start and before the first tick!\n // Note this must be scheduled before the start event; see d3/d3-transition#16!\n // Assuming this is successful, subsequent callbacks go straight to tick.\n\n\n src_timeout(function () {\n if (self.state === STARTED) {\n self.state = RUNNING;\n self.timer.restart(tick, self.delay, self.time);\n tick(elapsed);\n }\n }); // Dispatch the start event.\n // Note this must be done before the tween are initialized.\n\n self.state = STARTING;\n self.on.call("start", node, node.__data__, self.index, self.group);\n if (self.state !== STARTING) return; // interrupted\n\n self.state = STARTED; // Initialize the tween, deleting null tween.\n\n tween = new Array(n = self.tween.length);\n\n for (i = 0, j = -1; i < n; ++i) {\n if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {\n tween[++j] = o;\n }\n }\n\n tween.length = j + 1;\n }\n\n function tick(elapsed) {\n var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),\n i = -1,\n n = tween.length;\n\n while (++i < n) {\n tween[i].call(node, t);\n } // Dispatch the end event.\n\n\n if (self.state === ENDING) {\n self.on.call("end", node, node.__data__, self.index, self.group);\n stop();\n }\n }\n\n function stop() {\n self.state = ENDED;\n self.timer.stop();\n delete schedules[id];\n\n for (var i in schedules) {\n return;\n } // eslint-disable-line no-unused-vars\n\n\n delete node.__transition;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/interrupt.js\n\n/* harmony default export */ function src_interrupt(node, name) {\n var schedules = node.__transition,\n schedule,\n active,\n empty = true,\n i;\n if (!schedules) return;\n name = name == null ? null : name + "";\n\n for (i in schedules) {\n if ((schedule = schedules[i]).name !== name) {\n empty = false;\n continue;\n }\n\n active = schedule.state > STARTING && schedule.state < ENDING;\n schedule.state = ENDED;\n schedule.timer.stop();\n schedule.on.call(active ? "interrupt" : "cancel", node, node.__data__, schedule.index, schedule.group);\n delete schedules[i];\n }\n\n if (empty) delete node.__transition;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/selection/interrupt.js\n\n/* harmony default export */ function selection_interrupt(name) {\n return this.each(function () {\n src_interrupt(this, name);\n });\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/number.js\n/* harmony default export */ function src_number(a, b) {\n return a = +a, b = +b, function (t) {\n return a * (1 - t) + b * t;\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/transform/decompose.js\nvar degrees = 180 / Math.PI;\nvar decompose_identity = {\n translateX: 0,\n translateY: 0,\n rotate: 0,\n skewX: 0,\n scaleX: 1,\n scaleY: 1\n};\n/* harmony default export */ function decompose(a, b, c, d, e, f) {\n var scaleX, scaleY, skewX;\n if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;\n if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;\n if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;\n if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;\n return {\n translateX: e,\n translateY: f,\n rotate: Math.atan2(b, a) * degrees,\n skewX: Math.atan(skewX) * degrees,\n scaleX: scaleX,\n scaleY: scaleY\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/transform/parse.js\n\nvar svgNode;\n/* eslint-disable no-undef */\n\nfunction parseCss(value) {\n var m = new (typeof DOMMatrix === "function" ? DOMMatrix : WebKitCSSMatrix)(value + "");\n return m.isIdentity ? decompose_identity : decompose(m.a, m.b, m.c, m.d, m.e, m.f);\n}\nfunction parseSvg(value) {\n if (value == null) return decompose_identity;\n if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");\n svgNode.setAttribute("transform", value);\n if (!(value = svgNode.transform.baseVal.consolidate())) return decompose_identity;\n value = value.matrix;\n return decompose(value.a, value.b, value.c, value.d, value.e, value.f);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/transform/index.js\n\n\n\nfunction interpolateTransform(parse, pxComma, pxParen, degParen) {\n function pop(s) {\n return s.length ? s.pop() + " " : "";\n }\n\n function translate(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push("translate(", null, pxComma, null, pxParen);\n q.push({\n i: i - 4,\n x: src_number(xa, xb)\n }, {\n i: i - 2,\n x: src_number(ya, yb)\n });\n } else if (xb || yb) {\n s.push("translate(" + xb + pxComma + yb + pxParen);\n }\n }\n\n function rotate(a, b, s, q) {\n if (a !== b) {\n if (a - b > 180) b += 360;else if (b - a > 180) a += 360; // shortest path\n\n q.push({\n i: s.push(pop(s) + "rotate(", null, degParen) - 2,\n x: src_number(a, b)\n });\n } else if (b) {\n s.push(pop(s) + "rotate(" + b + degParen);\n }\n }\n\n function skewX(a, b, s, q) {\n if (a !== b) {\n q.push({\n i: s.push(pop(s) + "skewX(", null, degParen) - 2,\n x: src_number(a, b)\n });\n } else if (b) {\n s.push(pop(s) + "skewX(" + b + degParen);\n }\n }\n\n function scale(xa, ya, xb, yb, s, q) {\n if (xa !== xb || ya !== yb) {\n var i = s.push(pop(s) + "scale(", null, ",", null, ")");\n q.push({\n i: i - 4,\n x: src_number(xa, xb)\n }, {\n i: i - 2,\n x: src_number(ya, yb)\n });\n } else if (xb !== 1 || yb !== 1) {\n s.push(pop(s) + "scale(" + xb + "," + yb + ")");\n }\n }\n\n return function (a, b) {\n var s = [],\n // string constants and placeholders\n q = []; // number interpolators\n\n a = parse(a), b = parse(b);\n translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);\n rotate(a.rotate, b.rotate, s, q);\n skewX(a.skewX, b.skewX, s, q);\n scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);\n a = b = null; // gc\n\n return function (t) {\n var i = -1,\n n = q.length,\n o;\n\n while (++i < n) {\n s[(o = q[i]).i] = o.x(t);\n }\n\n return s.join("");\n };\n };\n}\n\nvar interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");\nvar interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/tween.js\n\n\nfunction tweenRemove(id, name) {\n var tween0, tween1;\n return function () {\n var schedule = schedule_set(this, id),\n tween = schedule.tween; // If this node shared tween with the previous node,\n // just assign the updated shared tween and we’re done!\n // Otherwise, copy-on-write.\n\n if (tween !== tween0) {\n tween1 = tween0 = tween;\n\n for (var i = 0, n = tween1.length; i < n; ++i) {\n if (tween1[i].name === name) {\n tween1 = tween1.slice();\n tween1.splice(i, 1);\n break;\n }\n }\n }\n\n schedule.tween = tween1;\n };\n}\n\nfunction tweenFunction(id, name, value) {\n var tween0, tween1;\n if (typeof value !== "function") throw new Error();\n return function () {\n var schedule = schedule_set(this, id),\n tween = schedule.tween; // If this node shared tween with the previous node,\n // just assign the updated shared tween and we’re done!\n // Otherwise, copy-on-write.\n\n if (tween !== tween0) {\n tween1 = (tween0 = tween).slice();\n\n for (var t = {\n name: name,\n value: value\n }, i = 0, n = tween1.length; i < n; ++i) {\n if (tween1[i].name === name) {\n tween1[i] = t;\n break;\n }\n }\n\n if (i === n) tween1.push(t);\n }\n\n schedule.tween = tween1;\n };\n}\n\n/* harmony default export */ function tween(name, value) {\n var id = this._id;\n name += "";\n\n if (arguments.length < 2) {\n var tween = schedule_get(this.node(), id).tween;\n\n for (var i = 0, n = tween.length, t; i < n; ++i) {\n if ((t = tween[i]).name === name) {\n return t.value;\n }\n }\n\n return null;\n }\n\n return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));\n}\nfunction tweenValue(transition, name, value) {\n var id = transition._id;\n transition.each(function () {\n var schedule = schedule_set(this, id);\n (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);\n });\n return function (node) {\n return schedule_get(node, id).value[name];\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-color/src/define.js\n/* harmony default export */ function src_define(constructor, factory, prototype) {\n constructor.prototype = factory.prototype = prototype;\n prototype.constructor = constructor;\n}\nfunction define_extend(parent, definition) {\n var prototype = Object.create(parent.prototype);\n\n for (var key in definition) {\n prototype[key] = definition[key];\n }\n\n return prototype;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-color/src/color.js\n\nfunction Color() {}\nvar _darker = 0.7;\n\n\nvar _brighter = 1 / _darker;\n\n\nvar reI = "\\\\s*([+-]?\\\\d+)\\\\s*",\n reN = "\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*",\n reP = "\\\\s*([+-]?\\\\d*\\\\.?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*",\n reHex = /^#([0-9a-f]{3,8})$/,\n reRgbInteger = new RegExp("^rgb\\\\(" + [reI, reI, reI] + "\\\\)$"),\n reRgbPercent = new RegExp("^rgb\\\\(" + [reP, reP, reP] + "\\\\)$"),\n reRgbaInteger = new RegExp("^rgba\\\\(" + [reI, reI, reI, reN] + "\\\\)$"),\n reRgbaPercent = new RegExp("^rgba\\\\(" + [reP, reP, reP, reN] + "\\\\)$"),\n reHslPercent = new RegExp("^hsl\\\\(" + [reN, reP, reP] + "\\\\)$"),\n reHslaPercent = new RegExp("^hsla\\\\(" + [reN, reP, reP, reN] + "\\\\)$");\nvar named = {\n aliceblue: 0xf0f8ff,\n antiquewhite: 0xfaebd7,\n aqua: 0x00ffff,\n aquamarine: 0x7fffd4,\n azure: 0xf0ffff,\n beige: 0xf5f5dc,\n bisque: 0xffe4c4,\n black: 0x000000,\n blanchedalmond: 0xffebcd,\n blue: 0x0000ff,\n blueviolet: 0x8a2be2,\n brown: 0xa52a2a,\n burlywood: 0xdeb887,\n cadetblue: 0x5f9ea0,\n chartreuse: 0x7fff00,\n chocolate: 0xd2691e,\n coral: 0xff7f50,\n cornflowerblue: 0x6495ed,\n cornsilk: 0xfff8dc,\n crimson: 0xdc143c,\n cyan: 0x00ffff,\n darkblue: 0x00008b,\n darkcyan: 0x008b8b,\n darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9,\n darkgreen: 0x006400,\n darkgrey: 0xa9a9a9,\n darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b,\n darkolivegreen: 0x556b2f,\n darkorange: 0xff8c00,\n darkorchid: 0x9932cc,\n darkred: 0x8b0000,\n darksalmon: 0xe9967a,\n darkseagreen: 0x8fbc8f,\n darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f,\n darkslategrey: 0x2f4f4f,\n darkturquoise: 0x00ced1,\n darkviolet: 0x9400d3,\n deeppink: 0xff1493,\n deepskyblue: 0x00bfff,\n dimgray: 0x696969,\n dimgrey: 0x696969,\n dodgerblue: 0x1e90ff,\n firebrick: 0xb22222,\n floralwhite: 0xfffaf0,\n forestgreen: 0x228b22,\n fuchsia: 0xff00ff,\n gainsboro: 0xdcdcdc,\n ghostwhite: 0xf8f8ff,\n gold: 0xffd700,\n goldenrod: 0xdaa520,\n gray: 0x808080,\n green: 0x008000,\n greenyellow: 0xadff2f,\n grey: 0x808080,\n honeydew: 0xf0fff0,\n hotpink: 0xff69b4,\n indianred: 0xcd5c5c,\n indigo: 0x4b0082,\n ivory: 0xfffff0,\n khaki: 0xf0e68c,\n lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5,\n lawngreen: 0x7cfc00,\n lemonchiffon: 0xfffacd,\n lightblue: 0xadd8e6,\n lightcoral: 0xf08080,\n lightcyan: 0xe0ffff,\n lightgoldenrodyellow: 0xfafad2,\n lightgray: 0xd3d3d3,\n lightgreen: 0x90ee90,\n lightgrey: 0xd3d3d3,\n lightpink: 0xffb6c1,\n lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa,\n lightskyblue: 0x87cefa,\n lightslategray: 0x778899,\n lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de,\n lightyellow: 0xffffe0,\n lime: 0x00ff00,\n limegreen: 0x32cd32,\n linen: 0xfaf0e6,\n magenta: 0xff00ff,\n maroon: 0x800000,\n mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd,\n mediumorchid: 0xba55d3,\n mediumpurple: 0x9370db,\n mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee,\n mediumspringgreen: 0x00fa9a,\n mediumturquoise: 0x48d1cc,\n mediumvioletred: 0xc71585,\n midnightblue: 0x191970,\n mintcream: 0xf5fffa,\n mistyrose: 0xffe4e1,\n moccasin: 0xffe4b5,\n navajowhite: 0xffdead,\n navy: 0x000080,\n oldlace: 0xfdf5e6,\n olive: 0x808000,\n olivedrab: 0x6b8e23,\n orange: 0xffa500,\n orangered: 0xff4500,\n orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa,\n palegreen: 0x98fb98,\n paleturquoise: 0xafeeee,\n palevioletred: 0xdb7093,\n papayawhip: 0xffefd5,\n peachpuff: 0xffdab9,\n peru: 0xcd853f,\n pink: 0xffc0cb,\n plum: 0xdda0dd,\n powderblue: 0xb0e0e6,\n purple: 0x800080,\n rebeccapurple: 0x663399,\n red: 0xff0000,\n rosybrown: 0xbc8f8f,\n royalblue: 0x4169e1,\n saddlebrown: 0x8b4513,\n salmon: 0xfa8072,\n sandybrown: 0xf4a460,\n seagreen: 0x2e8b57,\n seashell: 0xfff5ee,\n sienna: 0xa0522d,\n silver: 0xc0c0c0,\n skyblue: 0x87ceeb,\n slateblue: 0x6a5acd,\n slategray: 0x708090,\n slategrey: 0x708090,\n snow: 0xfffafa,\n springgreen: 0x00ff7f,\n steelblue: 0x4682b4,\n tan: 0xd2b48c,\n teal: 0x008080,\n thistle: 0xd8bfd8,\n tomato: 0xff6347,\n turquoise: 0x40e0d0,\n violet: 0xee82ee,\n wheat: 0xf5deb3,\n white: 0xffffff,\n whitesmoke: 0xf5f5f5,\n yellow: 0xffff00,\n yellowgreen: 0x9acd32\n};\nsrc_define(Color, color, {\n copy: function copy(channels) {\n return Object.assign(new this.constructor(), this, channels);\n },\n displayable: function displayable() {\n return this.rgb().displayable();\n },\n hex: color_formatHex,\n // Deprecated! Use color.formatHex.\n formatHex: color_formatHex,\n formatHsl: color_formatHsl,\n formatRgb: color_formatRgb,\n toString: color_formatRgb\n});\n\nfunction color_formatHex() {\n return this.rgb().formatHex();\n}\n\nfunction color_formatHsl() {\n return hslConvert(this).formatHsl();\n}\n\nfunction color_formatRgb() {\n return this.rgb().formatRgb();\n}\n\nfunction color(format) {\n var m, l;\n format = (format + "").trim().toLowerCase();\n return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000\n : l === 3 ? new Rgb(m >> 8 & 0xf | m >> 4 & 0xf0, m >> 4 & 0xf | m & 0xf0, (m & 0xf) << 4 | m & 0xf, 1) // #f00\n : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000\n : l === 4 ? rgba(m >> 12 & 0xf | m >> 8 & 0xf0, m >> 8 & 0xf | m >> 4 & 0xf0, m >> 4 & 0xf | m & 0xf0, ((m & 0xf) << 4 | m & 0xf) / 0xff) // #f000\n : null // invalid hex\n ) : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)\n : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)\n : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)\n : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)\n : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)\n : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)\n : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins\n : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null;\n}\n\nfunction rgbn(n) {\n return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);\n}\n\nfunction rgba(r, g, b, a) {\n if (a <= 0) r = g = b = NaN;\n return new Rgb(r, g, b, a);\n}\n\nfunction rgbConvert(o) {\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Rgb();\n o = o.rgb();\n return new Rgb(o.r, o.g, o.b, o.opacity);\n}\nfunction color_rgb(r, g, b, opacity) {\n return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);\n}\nfunction Rgb(r, g, b, opacity) {\n this.r = +r;\n this.g = +g;\n this.b = +b;\n this.opacity = +opacity;\n}\nsrc_define(Rgb, color_rgb, define_extend(Color, {\n brighter: function brighter(k) {\n k = k == null ? _brighter : Math.pow(_brighter, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n darker: function darker(k) {\n k = k == null ? _darker : Math.pow(_darker, k);\n return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n },\n rgb: function rgb() {\n return this;\n },\n displayable: function displayable() {\n return -0.5 <= this.r && this.r < 255.5 && -0.5 <= this.g && this.g < 255.5 && -0.5 <= this.b && this.b < 255.5 && 0 <= this.opacity && this.opacity <= 1;\n },\n hex: rgb_formatHex,\n // Deprecated! Use color.formatHex.\n formatHex: rgb_formatHex,\n formatRgb: rgb_formatRgb,\n toString: rgb_formatRgb\n}));\n\nfunction rgb_formatHex() {\n return "#" + hex(this.r) + hex(this.g) + hex(this.b);\n}\n\nfunction rgb_formatRgb() {\n var a = this.opacity;\n a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));\n return (a === 1 ? "rgb(" : "rgba(") + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + (a === 1 ? ")" : ", " + a + ")");\n}\n\nfunction hex(value) {\n value = Math.max(0, Math.min(255, Math.round(value) || 0));\n return (value < 16 ? "0" : "") + value.toString(16);\n}\n\nfunction hsla(h, s, l, a) {\n if (a <= 0) h = s = l = NaN;else if (l <= 0 || l >= 1) h = s = NaN;else if (s <= 0) h = NaN;\n return new Hsl(h, s, l, a);\n}\n\nfunction hslConvert(o) {\n if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);\n if (!(o instanceof Color)) o = color(o);\n if (!o) return new Hsl();\n if (o instanceof Hsl) return o;\n o = o.rgb();\n var r = o.r / 255,\n g = o.g / 255,\n b = o.b / 255,\n min = Math.min(r, g, b),\n max = Math.max(r, g, b),\n h = NaN,\n s = max - min,\n l = (max + min) / 2;\n\n if (s) {\n if (r === max) h = (g - b) / s + (g < b) * 6;else if (g === max) h = (b - r) / s + 2;else h = (r - g) / s + 4;\n s /= l < 0.5 ? max + min : 2 - max - min;\n h *= 60;\n } else {\n s = l > 0 && l < 1 ? 0 : h;\n }\n\n return new Hsl(h, s, l, o.opacity);\n}\nfunction hsl(h, s, l, opacity) {\n return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hsl(h, s, l, opacity) {\n this.h = +h;\n this.s = +s;\n this.l = +l;\n this.opacity = +opacity;\n}\n\nsrc_define(Hsl, hsl, define_extend(Color, {\n brighter: function brighter(k) {\n k = k == null ? _brighter : Math.pow(_brighter, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n darker: function darker(k) {\n k = k == null ? _darker : Math.pow(_darker, k);\n return new Hsl(this.h, this.s, this.l * k, this.opacity);\n },\n rgb: function rgb() {\n var h = this.h % 360 + (this.h < 0) * 360,\n s = isNaN(h) || isNaN(this.s) ? 0 : this.s,\n l = this.l,\n m2 = l + (l < 0.5 ? l : 1 - l) * s,\n m1 = 2 * l - m2;\n return new Rgb(hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), hsl2rgb(h, m1, m2), hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), this.opacity);\n },\n displayable: function displayable() {\n return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && 0 <= this.l && this.l <= 1 && 0 <= this.opacity && this.opacity <= 1;\n },\n formatHsl: function formatHsl() {\n var a = this.opacity;\n a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));\n return (a === 1 ? "hsl(" : "hsla(") + (this.h || 0) + ", " + (this.s || 0) * 100 + "%, " + (this.l || 0) * 100 + "%" + (a === 1 ? ")" : ", " + a + ")");\n }\n}));\n/* From FvD 13.37, CSS Color Module Level 3 */\n\nfunction hsl2rgb(h, m1, m2) {\n return (h < 60 ? m1 + (m2 - m1) * h / 60 : h < 180 ? m2 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 : m1) * 255;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/basis.js\nfunction basis(t1, v0, v1, v2, v3) {\n var t2 = t1 * t1,\n t3 = t2 * t1;\n return ((1 - 3 * t1 + 3 * t2 - t3) * v0 + (4 - 6 * t2 + 3 * t3) * v1 + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 + t3 * v3) / 6;\n}\n/* harmony default export */ function src_basis(values) {\n var n = values.length - 1;\n return function (t) {\n var i = t <= 0 ? t = 0 : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),\n v1 = values[i],\n v2 = values[i + 1],\n v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,\n v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/basisClosed.js\n\n/* harmony default export */ function basisClosed(values) {\n var n = values.length;\n return function (t) {\n var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),\n v0 = values[(i + n - 1) % n],\n v1 = values[i % n],\n v2 = values[(i + 1) % n],\n v3 = values[(i + 2) % n];\n return basis((t - i / n) * n, v0, v1, v2, v3);\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/constant.js\n/* harmony default export */ var d3_interpolate_src_constant = (function (x) {\n return function () {\n return x;\n };\n});\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/color.js\n\n\nfunction color_linear(a, d) {\n return function (t) {\n return a + t * d;\n };\n}\n\nfunction exponential(a, b, y) {\n return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function (t) {\n return Math.pow(a + t * b, y);\n };\n}\n\nfunction hue(a, b) {\n var d = b - a;\n return d ? color_linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a);\n}\nfunction gamma(y) {\n return (y = +y) === 1 ? nogamma : function (a, b) {\n return b - a ? exponential(a, b, y) : d3_interpolate_src_constant(isNaN(a) ? b : a);\n };\n}\nfunction nogamma(a, b) {\n var d = b - a;\n return d ? color_linear(a, d) : d3_interpolate_src_constant(isNaN(a) ? b : a);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/rgb.js\n\n\n\n\n/* harmony default export */ var rgb = ((function rgbGamma(y) {\n var color = gamma(y);\n\n function rgb(start, end) {\n var r = color((start = color_rgb(start)).r, (end = color_rgb(end)).r),\n g = color(start.g, end.g),\n b = color(start.b, end.b),\n opacity = nogamma(start.opacity, end.opacity);\n return function (t) {\n start.r = r(t);\n start.g = g(t);\n start.b = b(t);\n start.opacity = opacity(t);\n return start + "";\n };\n }\n\n rgb.gamma = rgbGamma;\n return rgb;\n})(1));\n\nfunction rgbSpline(spline) {\n return function (colors) {\n var n = colors.length,\n r = new Array(n),\n g = new Array(n),\n b = new Array(n),\n i,\n color;\n\n for (i = 0; i < n; ++i) {\n color = color_rgb(colors[i]);\n r[i] = color.r || 0;\n g[i] = color.g || 0;\n b[i] = color.b || 0;\n }\n\n r = spline(r);\n g = spline(g);\n b = spline(b);\n color.opacity = 1;\n return function (t) {\n color.r = r(t);\n color.g = g(t);\n color.b = b(t);\n return color + "";\n };\n };\n}\n\nvar rgbBasis = rgbSpline(src_basis);\nvar rgbBasisClosed = rgbSpline(basisClosed);\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/string.js\n\nvar reA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,\n reB = new RegExp(reA.source, "g");\n\nfunction zero(b) {\n return function () {\n return b;\n };\n}\n\nfunction one(b) {\n return function (t) {\n return b(t) + "";\n };\n}\n\n/* harmony default export */ function string(a, b) {\n var bi = reA.lastIndex = reB.lastIndex = 0,\n // scan index for next number in b\n am,\n // current match in a\n bm,\n // current match in b\n bs,\n // string preceding current number in b, if any\n i = -1,\n // index in s\n s = [],\n // string constants and placeholders\n q = []; // number interpolators\n // Coerce inputs to strings.\n\n a = a + "", b = b + ""; // Interpolate pairs of numbers in a & b.\n\n while ((am = reA.exec(a)) && (bm = reB.exec(b))) {\n if ((bs = bm.index) > bi) {\n // a string precedes the next number in b\n bs = b.slice(bi, bs);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n }\n\n if ((am = am[0]) === (bm = bm[0])) {\n // numbers in a & b match\n if (s[i]) s[i] += bm; // coalesce with previous string\n else s[++i] = bm;\n } else {\n // interpolate non-matching numbers\n s[++i] = null;\n q.push({\n i: i,\n x: src_number(am, bm)\n });\n }\n\n bi = reB.lastIndex;\n } // Add remains of b.\n\n\n if (bi < b.length) {\n bs = b.slice(bi);\n if (s[i]) s[i] += bs; // coalesce with previous string\n else s[++i] = bs;\n } // Special optimization for only a single match.\n // Otherwise, interpolate each of the numbers and rejoin the string.\n\n\n return s.length < 2 ? q[0] ? one(q[0].x) : zero(b) : (b = q.length, function (t) {\n for (var i = 0, o; i < b; ++i) {\n s[(o = q[i]).i] = o.x(t);\n }\n\n return s.join("");\n });\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/interpolate.js\n\n\n/* harmony default export */ function transition_interpolate(a, b) {\n var c;\n return (typeof b === "number" ? src_number : b instanceof color ? rgb : (c = color(b)) ? (b = c, rgb) : string)(a, b);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/attr.js\n\n\n\n\n\nfunction attr_attrRemove(name) {\n return function () {\n this.removeAttribute(name);\n };\n}\n\nfunction attr_attrRemoveNS(fullname) {\n return function () {\n this.removeAttributeNS(fullname.space, fullname.local);\n };\n}\n\nfunction attr_attrConstant(name, interpolate, value1) {\n var string00,\n string1 = value1 + "",\n interpolate0;\n return function () {\n var string0 = this.getAttribute(name);\n return string0 === string1 ? null : string0 === string00 ? interpolate0 : interpolate0 = interpolate(string00 = string0, value1);\n };\n}\n\nfunction attr_attrConstantNS(fullname, interpolate, value1) {\n var string00,\n string1 = value1 + "",\n interpolate0;\n return function () {\n var string0 = this.getAttributeNS(fullname.space, fullname.local);\n return string0 === string1 ? null : string0 === string00 ? interpolate0 : interpolate0 = interpolate(string00 = string0, value1);\n };\n}\n\nfunction attr_attrFunction(name, interpolate, value) {\n var string00, string10, interpolate0;\n return function () {\n var string0,\n value1 = value(this),\n string1;\n if (value1 == null) return void this.removeAttribute(name);\n string0 = this.getAttribute(name);\n string1 = value1 + "";\n return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));\n };\n}\n\nfunction attr_attrFunctionNS(fullname, interpolate, value) {\n var string00, string10, interpolate0;\n return function () {\n var string0,\n value1 = value(this),\n string1;\n if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);\n string0 = this.getAttributeNS(fullname.space, fullname.local);\n string1 = value1 + "";\n return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));\n };\n}\n\n/* harmony default export */ function transition_attr(name, value) {\n var fullname = namespace(name),\n i = fullname === "transform" ? interpolateTransformSvg : transition_interpolate;\n return this.attrTween(name, typeof value === "function" ? (fullname.local ? attr_attrFunctionNS : attr_attrFunction)(fullname, i, tweenValue(this, "attr." + name, value)) : value == null ? (fullname.local ? attr_attrRemoveNS : attr_attrRemove)(fullname) : (fullname.local ? attr_attrConstantNS : attr_attrConstant)(fullname, i, value));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/attrTween.js\n\n\nfunction attrInterpolate(name, i) {\n return function (t) {\n this.setAttribute(name, i.call(this, t));\n };\n}\n\nfunction attrInterpolateNS(fullname, i) {\n return function (t) {\n this.setAttributeNS(fullname.space, fullname.local, i.call(this, t));\n };\n}\n\nfunction attrTweenNS(fullname, value) {\n var t0, i0;\n\n function tween() {\n var i = value.apply(this, arguments);\n if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i);\n return t0;\n }\n\n tween._value = value;\n return tween;\n}\n\nfunction attrTween(name, value) {\n var t0, i0;\n\n function tween() {\n var i = value.apply(this, arguments);\n if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i);\n return t0;\n }\n\n tween._value = value;\n return tween;\n}\n\n/* harmony default export */ function transition_attrTween(name, value) {\n var key = "attr." + name;\n if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== "function") throw new Error();\n var fullname = namespace(name);\n return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/delay.js\n\n\nfunction delayFunction(id, value) {\n return function () {\n init(this, id).delay = +value.apply(this, arguments);\n };\n}\n\nfunction delayConstant(id, value) {\n return value = +value, function () {\n init(this, id).delay = value;\n };\n}\n\n/* harmony default export */ function delay(value) {\n var id = this._id;\n return arguments.length ? this.each((typeof value === "function" ? delayFunction : delayConstant)(id, value)) : schedule_get(this.node(), id).delay;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/duration.js\n\n\nfunction durationFunction(id, value) {\n return function () {\n schedule_set(this, id).duration = +value.apply(this, arguments);\n };\n}\n\nfunction durationConstant(id, value) {\n return value = +value, function () {\n schedule_set(this, id).duration = value;\n };\n}\n\n/* harmony default export */ function duration(value) {\n var id = this._id;\n return arguments.length ? this.each((typeof value === "function" ? durationFunction : durationConstant)(id, value)) : schedule_get(this.node(), id).duration;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/ease.js\n\n\nfunction easeConstant(id, value) {\n if (typeof value !== "function") throw new Error();\n return function () {\n schedule_set(this, id).ease = value;\n };\n}\n\n/* harmony default export */ function ease(value) {\n var id = this._id;\n return arguments.length ? this.each(easeConstant(id, value)) : schedule_get(this.node(), id).ease;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/easeVarying.js\n\n\nfunction easeVarying(id, value) {\n return function () {\n var v = value.apply(this, arguments);\n if (typeof v !== "function") throw new Error();\n schedule_set(this, id).ease = v;\n };\n}\n\n/* harmony default export */ function transition_easeVarying(value) {\n if (typeof value !== "function") throw new Error();\n return this.each(easeVarying(this._id, value));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/filter.js\n\n\n/* harmony default export */ function transition_filter(match) {\n if (typeof match !== "function") match = matcher(match);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n subgroup.push(node);\n }\n }\n }\n\n return new Transition(subgroups, this._parents, this._name, this._id);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/merge.js\n\n/* harmony default export */ function transition_merge(transition) {\n if (transition._id !== this._id) throw new Error();\n\n for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n if (node = group0[i] || group1[i]) {\n merge[i] = node;\n }\n }\n }\n\n for (; j < m0; ++j) {\n merges[j] = groups0[j];\n }\n\n return new Transition(merges, this._parents, this._name, this._id);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/on.js\n\n\nfunction start(name) {\n return (name + "").trim().split(/^|\\s+/).every(function (t) {\n var i = t.indexOf(".");\n if (i >= 0) t = t.slice(0, i);\n return !t || t === "start";\n });\n}\n\nfunction onFunction(id, name, listener) {\n var on0,\n on1,\n sit = start(name) ? init : schedule_set;\n return function () {\n var schedule = sit(this, id),\n on = schedule.on; // If this node shared a dispatch with the previous node,\n // just assign the updated shared dispatch and we’re done!\n // Otherwise, copy-on-write.\n\n if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);\n schedule.on = on1;\n };\n}\n\n/* harmony default export */ function transition_on(name, listener) {\n var id = this._id;\n return arguments.length < 2 ? schedule_get(this.node(), id).on.on(name) : this.each(onFunction(id, name, listener));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/remove.js\nfunction removeFunction(id) {\n return function () {\n var parent = this.parentNode;\n\n for (var i in this.__transition) {\n if (+i !== id) return;\n }\n\n if (parent) parent.removeChild(this);\n };\n}\n\n/* harmony default export */ function transition_remove() {\n return this.on("end.remove", removeFunction(this._id));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/select.js\n\n\n\n/* harmony default export */ function transition_select(select) {\n var name = this._name,\n id = this._id;\n if (typeof select !== "function") select = selector(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n if ("__data__" in node) subnode.__data__ = node.__data__;\n subgroup[i] = subnode;\n schedule(subgroup[i], name, id, i, subgroup, schedule_get(node, id));\n }\n }\n }\n\n return new Transition(subgroups, this._parents, name, id);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/selectAll.js\n\n\n\n/* harmony default export */ function transition_selectAll(select) {\n var name = this._name,\n id = this._id;\n if (typeof select !== "function") select = selectorAll(select);\n\n for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n for (var children = select.call(node, node.__data__, i, group), child, inherit = schedule_get(node, id), k = 0, l = children.length; k < l; ++k) {\n if (child = children[k]) {\n schedule(child, name, id, k, children, inherit);\n }\n }\n\n subgroups.push(children);\n parents.push(node);\n }\n }\n }\n\n return new Transition(subgroups, parents, name, id);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/selection.js\n\nvar selection_Selection = src_selection.prototype.constructor;\n/* harmony default export */ function transition_selection() {\n return new selection_Selection(this._groups, this._parents);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/style.js\n\n\n\n\n\n\nfunction styleNull(name, interpolate) {\n var string00, string10, interpolate0;\n return function () {\n var string0 = styleValue(this, name),\n string1 = (this.style.removeProperty(name), styleValue(this, name));\n return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : interpolate0 = interpolate(string00 = string0, string10 = string1);\n };\n}\n\nfunction style_styleRemove(name) {\n return function () {\n this.style.removeProperty(name);\n };\n}\n\nfunction style_styleConstant(name, interpolate, value1) {\n var string00,\n string1 = value1 + "",\n interpolate0;\n return function () {\n var string0 = styleValue(this, name);\n return string0 === string1 ? null : string0 === string00 ? interpolate0 : interpolate0 = interpolate(string00 = string0, value1);\n };\n}\n\nfunction style_styleFunction(name, interpolate, value) {\n var string00, string10, interpolate0;\n return function () {\n var string0 = styleValue(this, name),\n value1 = value(this),\n string1 = value1 + "";\n if (value1 == null) string1 = value1 = (this.style.removeProperty(name), styleValue(this, name));\n return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));\n };\n}\n\nfunction styleMaybeRemove(id, name) {\n var on0,\n on1,\n listener0,\n key = "style." + name,\n event = "end." + key,\n remove;\n return function () {\n var schedule = schedule_set(this, id),\n on = schedule.on,\n listener = schedule.value[key] == null ? remove || (remove = style_styleRemove(name)) : undefined; // If this node shared a dispatch with the previous node,\n // just assign the updated shared dispatch and we’re done!\n // Otherwise, copy-on-write.\n\n if (on !== on0 || listener0 !== listener) (on1 = (on0 = on).copy()).on(event, listener0 = listener);\n schedule.on = on1;\n };\n}\n\n/* harmony default export */ function transition_style(name, value, priority) {\n var i = (name += "") === "transform" ? interpolateTransformCss : transition_interpolate;\n return value == null ? this.styleTween(name, styleNull(name, i)).on("end.style." + name, style_styleRemove(name)) : typeof value === "function" ? this.styleTween(name, style_styleFunction(name, i, tweenValue(this, "style." + name, value))).each(styleMaybeRemove(this._id, name)) : this.styleTween(name, style_styleConstant(name, i, value), priority).on("end.style." + name, null);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/styleTween.js\nfunction styleInterpolate(name, i, priority) {\n return function (t) {\n this.style.setProperty(name, i.call(this, t), priority);\n };\n}\n\nfunction styleTween(name, value, priority) {\n var t, i0;\n\n function tween() {\n var i = value.apply(this, arguments);\n if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority);\n return t;\n }\n\n tween._value = value;\n return tween;\n}\n\n/* harmony default export */ function transition_styleTween(name, value, priority) {\n var key = "style." + (name += "");\n if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== "function") throw new Error();\n return this.tween(key, styleTween(name, value, priority == null ? "" : priority));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/text.js\n\n\nfunction text_textConstant(value) {\n return function () {\n this.textContent = value;\n };\n}\n\nfunction text_textFunction(value) {\n return function () {\n var value1 = value(this);\n this.textContent = value1 == null ? "" : value1;\n };\n}\n\n/* harmony default export */ function transition_text(value) {\n return this.tween("text", typeof value === "function" ? text_textFunction(tweenValue(this, "text", value)) : text_textConstant(value == null ? "" : value + ""));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/textTween.js\nfunction textInterpolate(i) {\n return function (t) {\n this.textContent = i.call(this, t);\n };\n}\n\nfunction textTween(value) {\n var t0, i0;\n\n function tween() {\n var i = value.apply(this, arguments);\n if (i !== i0) t0 = (i0 = i) && textInterpolate(i);\n return t0;\n }\n\n tween._value = value;\n return tween;\n}\n\n/* harmony default export */ function transition_textTween(value) {\n var key = "text";\n if (arguments.length < 1) return (key = this.tween(key)) && key._value;\n if (value == null) return this.tween(key, null);\n if (typeof value !== "function") throw new Error();\n return this.tween(key, textTween(value));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/transition.js\n\n\n/* harmony default export */ function transition() {\n var name = this._name,\n id0 = this._id,\n id1 = newId();\n\n for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n var inherit = schedule_get(node, id0);\n schedule(node, name, id1, i, group, {\n time: inherit.time + inherit.delay + inherit.duration,\n delay: 0,\n duration: inherit.duration,\n ease: inherit.ease\n });\n }\n }\n }\n\n return new Transition(groups, this._parents, name, id1);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/end.js\n\n/* harmony default export */ function end() {\n var on0,\n on1,\n that = this,\n id = that._id,\n size = that.size();\n return new Promise(function (resolve, reject) {\n var cancel = {\n value: reject\n },\n end = {\n value: function value() {\n if (--size === 0) resolve();\n }\n };\n that.each(function () {\n var schedule = schedule_set(this, id),\n on = schedule.on; // If this node shared a dispatch with the previous node,\n // just assign the updated shared dispatch and we’re done!\n // Otherwise, copy-on-write.\n\n if (on !== on0) {\n on1 = (on0 = on).copy();\n\n on1._.cancel.push(cancel);\n\n on1._.interrupt.push(cancel);\n\n on1._.end.push(end);\n }\n\n schedule.on = on1;\n }); // The selection was empty, resolve end immediately\n\n if (size === 0) resolve();\n });\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/transition/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar id = 0;\nfunction Transition(groups, parents, name, id) {\n this._groups = groups;\n this._parents = parents;\n this._name = name;\n this._id = id;\n}\nfunction transition_transition(name) {\n return src_selection().transition(name);\n}\nfunction newId() {\n return ++id;\n}\nvar selection_prototype = src_selection.prototype;\nTransition.prototype = transition_transition.prototype = (0,defineProperty/* default */.Z)({\n constructor: Transition,\n select: transition_select,\n selectAll: transition_selectAll,\n selectChild: selection_prototype.selectChild,\n selectChildren: selection_prototype.selectChildren,\n filter: transition_filter,\n merge: transition_merge,\n selection: transition_selection,\n transition: transition,\n call: selection_prototype.call,\n nodes: selection_prototype.nodes,\n node: selection_prototype.node,\n size: selection_prototype.size,\n empty: selection_prototype.empty,\n each: selection_prototype.each,\n on: transition_on,\n attr: transition_attr,\n attrTween: transition_attrTween,\n style: transition_style,\n styleTween: transition_styleTween,\n text: transition_text,\n textTween: transition_textTween,\n remove: transition_remove,\n tween: tween,\n delay: delay,\n duration: duration,\n ease: ease,\n easeVarying: transition_easeVarying,\n end: end\n}, Symbol.iterator, selection_prototype[Symbol.iterator]);\n;// CONCATENATED MODULE: ./node_modules/d3-ease/src/cubic.js\nfunction cubicIn(t) {\n return t * t * t;\n}\nfunction cubicOut(t) {\n return --t * t * t + 1;\n}\nfunction cubicInOut(t) {\n return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/selection/transition.js\n\n\n\n\nvar defaultTiming = {\n time: null,\n // Set on use.\n delay: 0,\n duration: 250,\n ease: cubicInOut\n};\n\nfunction inherit(node, id) {\n var timing;\n\n while (!(timing = node.__transition) || !(timing = timing[id])) {\n if (!(node = node.parentNode)) {\n throw new Error("transition ".concat(id, " not found"));\n }\n }\n\n return timing;\n}\n\n/* harmony default export */ function selection_transition(name) {\n var id, timing;\n\n if (name instanceof Transition) {\n id = name._id, name = name._name;\n } else {\n id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";\n }\n\n for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n if (node = group[i]) {\n schedule(node, name, id, i, group, timing || inherit(node, id));\n }\n }\n }\n\n return new Transition(groups, this._parents, name, id);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/selection/index.js\n\n\n\nsrc_selection.prototype.interrupt = selection_interrupt;\nsrc_selection.prototype.transition = selection_transition;\n;// CONCATENATED MODULE: ./node_modules/d3-transition/src/index.js\n\n\n\n\n;// CONCATENATED MODULE: ./node_modules/d3-brush/src/brush.js\nfunction brush_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = brush_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction brush_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return brush_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return brush_arrayLikeToArray(o, minLen); }\n\nfunction brush_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n\n\n\n\n\n\n\n\nvar MODE_DRAG = {\n name: "drag"\n},\n MODE_SPACE = {\n name: "space"\n},\n MODE_HANDLE = {\n name: "handle"\n},\n MODE_CENTER = {\n name: "center"\n};\nvar abs = Math.abs,\n max = Math.max,\n min = Math.min;\n\nfunction number1(e) {\n return [+e[0], +e[1]];\n}\n\nfunction number2(e) {\n return [number1(e[0]), number1(e[1])];\n}\n\nvar X = {\n name: "x",\n handles: ["w", "e"].map(type),\n input: function input(x, e) {\n return x == null ? null : [[+x[0], e[0][1]], [+x[1], e[1][1]]];\n },\n output: function output(xy) {\n return xy && [xy[0][0], xy[1][0]];\n }\n};\nvar Y = {\n name: "y",\n handles: ["n", "s"].map(type),\n input: function input(y, e) {\n return y == null ? null : [[e[0][0], +y[0]], [e[1][0], +y[1]]];\n },\n output: function output(xy) {\n return xy && [xy[0][1], xy[1][1]];\n }\n};\nvar XY = {\n name: "xy",\n handles: ["n", "w", "e", "s", "nw", "ne", "sw", "se"].map(type),\n input: function input(xy) {\n return xy == null ? null : number2(xy);\n },\n output: function output(xy) {\n return xy;\n }\n};\nvar cursors = {\n overlay: "crosshair",\n selection: "move",\n n: "ns-resize",\n e: "ew-resize",\n s: "ns-resize",\n w: "ew-resize",\n nw: "nwse-resize",\n ne: "nesw-resize",\n se: "nwse-resize",\n sw: "nesw-resize"\n};\nvar flipX = {\n e: "w",\n w: "e",\n nw: "ne",\n ne: "nw",\n se: "sw",\n sw: "se"\n};\nvar flipY = {\n n: "s",\n s: "n",\n nw: "sw",\n ne: "se",\n se: "ne",\n sw: "nw"\n};\nvar signsX = {\n overlay: +1,\n selection: +1,\n n: null,\n e: +1,\n s: null,\n w: -1,\n nw: -1,\n ne: +1,\n se: +1,\n sw: -1\n};\nvar signsY = {\n overlay: +1,\n selection: +1,\n n: -1,\n e: null,\n s: +1,\n w: null,\n nw: -1,\n ne: -1,\n se: +1,\n sw: +1\n};\n\nfunction type(t) {\n return {\n type: t\n };\n} // Ignore right-click, since that should open the context menu.\n\n\nfunction defaultFilter(event) {\n return !event.ctrlKey && !event.button;\n}\n\nfunction defaultExtent() {\n var svg = this.ownerSVGElement || this;\n\n if (svg.hasAttribute("viewBox")) {\n svg = svg.viewBox.baseVal;\n return [[svg.x, svg.y], [svg.x + svg.width, svg.y + svg.height]];\n }\n\n return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];\n}\n\nfunction defaultTouchable() {\n return navigator.maxTouchPoints || "ontouchstart" in this;\n} // Like d3.local, but with the name “__brush” rather than auto-generated.\n\n\nfunction local(node) {\n while (!node.__brush) {\n if (!(node = node.parentNode)) return;\n }\n\n return node.__brush;\n}\n\nfunction brush_empty(extent) {\n return extent[0][0] === extent[1][0] || extent[0][1] === extent[1][1];\n}\n\nfunction brushSelection(node) {\n var state = node.__brush;\n return state ? state.dim.output(state.selection) : null;\n}\nfunction brushX() {\n return brush_brush(X);\n}\nfunction brushY() {\n return brush_brush(Y);\n}\n/* harmony default export */ function brush() {\n return brush_brush(XY);\n}\n\nfunction brush_brush(dim) {\n var extent = defaultExtent,\n filter = defaultFilter,\n touchable = defaultTouchable,\n keys = true,\n listeners = dispatch("start", "brush", "end"),\n handleSize = 6,\n touchending;\n\n function brush(group) {\n var overlay = group.property("__brush", initialize).selectAll(".overlay").data([type("overlay")]);\n overlay.enter().append("rect").attr("class", "overlay").attr("pointer-events", "all").attr("cursor", cursors.overlay).merge(overlay).each(function () {\n var extent = local(this).extent;\n select(this).attr("x", extent[0][0]).attr("y", extent[0][1]).attr("width", extent[1][0] - extent[0][0]).attr("height", extent[1][1] - extent[0][1]);\n });\n group.selectAll(".selection").data([type("selection")]).enter().append("rect").attr("class", "selection").attr("cursor", cursors.selection).attr("fill", "#777").attr("fill-opacity", 0.3).attr("stroke", "#fff").attr("shape-rendering", "crispEdges");\n var handle = group.selectAll(".handle").data(dim.handles, function (d) {\n return d.type;\n });\n handle.exit().remove();\n handle.enter().append("rect").attr("class", function (d) {\n return "handle handle--" + d.type;\n }).attr("cursor", function (d) {\n return cursors[d.type];\n });\n group.each(redraw).attr("fill", "none").attr("pointer-events", "all").on("mousedown.brush", started).filter(touchable).on("touchstart.brush", started).on("touchmove.brush", touchmoved).on("touchend.brush touchcancel.brush", touchended).style("touch-action", "none").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");\n }\n\n brush.move = function (group, selection, event) {\n if (group.tween) {\n group.on("start.brush", function (event) {\n emitter(this, arguments).beforestart().start(event);\n }).on("interrupt.brush end.brush", function (event) {\n emitter(this, arguments).end(event);\n }).tween("brush", function () {\n var that = this,\n state = that.__brush,\n emit = emitter(that, arguments),\n selection0 = state.selection,\n selection1 = dim.input(typeof selection === "function" ? selection.apply(this, arguments) : selection, state.extent),\n i = interpolate(selection0, selection1);\n\n function tween(t) {\n state.selection = t === 1 && selection1 === null ? null : i(t);\n redraw.call(that);\n emit.brush();\n }\n\n return selection0 !== null && selection1 !== null ? tween : tween(1);\n });\n } else {\n group.each(function () {\n var that = this,\n args = arguments,\n state = that.__brush,\n selection1 = dim.input(typeof selection === "function" ? selection.apply(that, args) : selection, state.extent),\n emit = emitter(that, args).beforestart();\n interrupt(that);\n state.selection = selection1 === null ? null : selection1;\n redraw.call(that);\n emit.start(event).brush(event).end(event);\n });\n }\n };\n\n brush.clear = function (group, event) {\n brush.move(group, null, event);\n };\n\n function redraw() {\n var group = select(this),\n selection = local(this).selection;\n\n if (selection) {\n group.selectAll(".selection").style("display", null).attr("x", selection[0][0]).attr("y", selection[0][1]).attr("width", selection[1][0] - selection[0][0]).attr("height", selection[1][1] - selection[0][1]);\n group.selectAll(".handle").style("display", null).attr("x", function (d) {\n return d.type[d.type.length - 1] === "e" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2;\n }).attr("y", function (d) {\n return d.type[0] === "s" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2;\n }).attr("width", function (d) {\n return d.type === "n" || d.type === "s" ? selection[1][0] - selection[0][0] + handleSize : handleSize;\n }).attr("height", function (d) {\n return d.type === "e" || d.type === "w" ? selection[1][1] - selection[0][1] + handleSize : handleSize;\n });\n } else {\n group.selectAll(".selection,.handle").style("display", "none").attr("x", null).attr("y", null).attr("width", null).attr("height", null);\n }\n }\n\n function emitter(that, args, clean) {\n var emit = that.__brush.emitter;\n return emit && (!clean || !emit.clean) ? emit : new Emitter(that, args, clean);\n }\n\n function Emitter(that, args, clean) {\n this.that = that;\n this.args = args;\n this.state = that.__brush;\n this.active = 0;\n this.clean = clean;\n }\n\n Emitter.prototype = {\n beforestart: function beforestart() {\n if (++this.active === 1) this.state.emitter = this, this.starting = true;\n return this;\n },\n start: function start(event, mode) {\n if (this.starting) this.starting = false, this.emit("start", event, mode);else this.emit("brush", event);\n return this;\n },\n brush: function brush(event, mode) {\n this.emit("brush", event, mode);\n return this;\n },\n end: function end(event, mode) {\n if (--this.active === 0) delete this.state.emitter, this.emit("end", event, mode);\n return this;\n },\n emit: function emit(type, event, mode) {\n var d = select(this.that).datum();\n listeners.call(type, this.that, new BrushEvent(type, {\n sourceEvent: event,\n target: brush,\n selection: dim.output(this.state.selection),\n mode: mode,\n dispatch: listeners\n }), d);\n }\n };\n\n function started(event) {\n if (touchending && !event.touches) return;\n if (!filter.apply(this, arguments)) return;\n var that = this,\n type = event.target.__data__.type,\n mode = (keys && event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : keys && event.altKey ? MODE_CENTER : MODE_HANDLE,\n signX = dim === Y ? null : signsX[type],\n signY = dim === X ? null : signsY[type],\n state = local(that),\n extent = state.extent,\n selection = state.selection,\n W = extent[0][0],\n w0,\n w1,\n N = extent[0][1],\n n0,\n n1,\n E = extent[1][0],\n e0,\n e1,\n S = extent[1][1],\n s0,\n s1,\n dx = 0,\n dy = 0,\n moving,\n shifting = signX && signY && keys && event.shiftKey,\n lockX,\n lockY,\n points = Array.from(event.touches || [event], function (t) {\n var i = t.identifier;\n t = pointer(t, that);\n t.point0 = t.slice();\n t.identifier = i;\n return t;\n });\n interrupt(that);\n var emit = emitter(that, arguments, true).beforestart();\n\n if (type === "overlay") {\n if (selection) moving = true;\n var pts = [points[0], points[1] || points[0]];\n state.selection = selection = [[w0 = dim === Y ? W : min(pts[0][0], pts[1][0]), n0 = dim === X ? N : min(pts[0][1], pts[1][1])], [e0 = dim === Y ? E : max(pts[0][0], pts[1][0]), s0 = dim === X ? S : max(pts[0][1], pts[1][1])]];\n if (points.length > 1) move(event);\n } else {\n w0 = selection[0][0];\n n0 = selection[0][1];\n e0 = selection[1][0];\n s0 = selection[1][1];\n }\n\n w1 = w0;\n n1 = n0;\n e1 = e0;\n s1 = s0;\n var group = select(that).attr("pointer-events", "none");\n var overlay = group.selectAll(".overlay").attr("cursor", cursors[type]);\n\n if (event.touches) {\n emit.moved = moved;\n emit.ended = ended;\n } else {\n var view = select(event.view).on("mousemove.brush", moved, true).on("mouseup.brush", ended, true);\n if (keys) view.on("keydown.brush", keydowned, true).on("keyup.brush", keyupped, true);\n dragDisable(event.view);\n }\n\n redraw.call(that);\n emit.start(event, mode.name);\n\n function moved(event) {\n var _iterator = brush_createForOfIteratorHelper(event.changedTouches || [event]),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var p = _step.value;\n\n var _iterator3 = brush_createForOfIteratorHelper(points),\n _step3;\n\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var d = _step3.value;\n if (d.identifier === p.identifier) d.cur = pointer(p, that);\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n if (shifting && !lockX && !lockY && points.length === 1) {\n var point = points[0];\n if (abs(point.cur[0] - point[0]) > abs(point.cur[1] - point[1])) lockY = true;else lockX = true;\n }\n\n var _iterator2 = brush_createForOfIteratorHelper(points),\n _step2;\n\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var _point = _step2.value;\n if (_point.cur) _point[0] = _point.cur[0], _point[1] = _point.cur[1];\n }\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n\n moving = true;\n noevent(event);\n move(event);\n }\n\n function move(event) {\n var point = points[0],\n point0 = point.point0;\n var t;\n dx = point[0] - point0[0];\n dy = point[1] - point0[1];\n\n switch (mode) {\n case MODE_SPACE:\n case MODE_DRAG:\n {\n if (signX) dx = max(W - w0, min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;\n if (signY) dy = max(N - n0, min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;\n break;\n }\n\n case MODE_HANDLE:\n {\n if (points[1]) {\n if (signX) w1 = max(W, min(E, points[0][0])), e1 = max(W, min(E, points[1][0])), signX = 1;\n if (signY) n1 = max(N, min(S, points[0][1])), s1 = max(N, min(S, points[1][1])), signY = 1;\n } else {\n if (signX < 0) dx = max(W - w0, min(E - w0, dx)), w1 = w0 + dx, e1 = e0;else if (signX > 0) dx = max(W - e0, min(E - e0, dx)), w1 = w0, e1 = e0 + dx;\n if (signY < 0) dy = max(N - n0, min(S - n0, dy)), n1 = n0 + dy, s1 = s0;else if (signY > 0) dy = max(N - s0, min(S - s0, dy)), n1 = n0, s1 = s0 + dy;\n }\n\n break;\n }\n\n case MODE_CENTER:\n {\n if (signX) w1 = max(W, min(E, w0 - dx * signX)), e1 = max(W, min(E, e0 + dx * signX));\n if (signY) n1 = max(N, min(S, n0 - dy * signY)), s1 = max(N, min(S, s0 + dy * signY));\n break;\n }\n }\n\n if (e1 < w1) {\n signX *= -1;\n t = w0, w0 = e0, e0 = t;\n t = w1, w1 = e1, e1 = t;\n if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);\n }\n\n if (s1 < n1) {\n signY *= -1;\n t = n0, n0 = s0, s0 = t;\n t = n1, n1 = s1, s1 = t;\n if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);\n }\n\n if (state.selection) selection = state.selection; // May be set by brush.move!\n\n if (lockX) w1 = selection[0][0], e1 = selection[1][0];\n if (lockY) n1 = selection[0][1], s1 = selection[1][1];\n\n if (selection[0][0] !== w1 || selection[0][1] !== n1 || selection[1][0] !== e1 || selection[1][1] !== s1) {\n state.selection = [[w1, n1], [e1, s1]];\n redraw.call(that);\n emit.brush(event, mode.name);\n }\n }\n\n function ended(event) {\n nopropagation(event);\n\n if (event.touches) {\n if (event.touches.length) return;\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function () {\n touchending = null;\n }, 500); // Ghost clicks are delayed!\n } else {\n dragEnable(event.view, moving);\n view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);\n }\n\n group.attr("pointer-events", "all");\n overlay.attr("cursor", cursors.overlay);\n if (state.selection) selection = state.selection; // May be set by brush.move (on start)!\n\n if (brush_empty(selection)) state.selection = null, redraw.call(that);\n emit.end(event, mode.name);\n }\n\n function keydowned(event) {\n switch (event.keyCode) {\n case 16:\n {\n // SHIFT\n shifting = signX && signY;\n break;\n }\n\n case 18:\n {\n // ALT\n if (mode === MODE_HANDLE) {\n if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n mode = MODE_CENTER;\n move(event);\n }\n\n break;\n }\n\n case 32:\n {\n // SPACE; takes priority over ALT\n if (mode === MODE_HANDLE || mode === MODE_CENTER) {\n if (signX < 0) e0 = e1 - dx;else if (signX > 0) w0 = w1 - dx;\n if (signY < 0) s0 = s1 - dy;else if (signY > 0) n0 = n1 - dy;\n mode = MODE_SPACE;\n overlay.attr("cursor", cursors.selection);\n move(event);\n }\n\n break;\n }\n\n default:\n return;\n }\n\n noevent(event);\n }\n\n function keyupped(event) {\n switch (event.keyCode) {\n case 16:\n {\n // SHIFT\n if (shifting) {\n lockX = lockY = shifting = false;\n move(event);\n }\n\n break;\n }\n\n case 18:\n {\n // ALT\n if (mode === MODE_CENTER) {\n if (signX < 0) e0 = e1;else if (signX > 0) w0 = w1;\n if (signY < 0) s0 = s1;else if (signY > 0) n0 = n1;\n mode = MODE_HANDLE;\n move(event);\n }\n\n break;\n }\n\n case 32:\n {\n // SPACE\n if (mode === MODE_SPACE) {\n if (event.altKey) {\n if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n mode = MODE_CENTER;\n } else {\n if (signX < 0) e0 = e1;else if (signX > 0) w0 = w1;\n if (signY < 0) s0 = s1;else if (signY > 0) n0 = n1;\n mode = MODE_HANDLE;\n }\n\n overlay.attr("cursor", cursors[type]);\n move(event);\n }\n\n break;\n }\n\n default:\n return;\n }\n\n noevent(event);\n }\n }\n\n function touchmoved(event) {\n emitter(this, arguments).moved(event);\n }\n\n function touchended(event) {\n emitter(this, arguments).ended(event);\n }\n\n function initialize() {\n var state = this.__brush || {\n selection: null\n };\n state.extent = number2(extent.apply(this, arguments));\n state.dim = dim;\n return state;\n }\n\n brush.extent = function (_) {\n return arguments.length ? (extent = typeof _ === "function" ? _ : constant(number2(_)), brush) : extent;\n };\n\n brush.filter = function (_) {\n return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), brush) : filter;\n };\n\n brush.touchable = function (_) {\n return arguments.length ? (touchable = typeof _ === "function" ? _ : constant(!!_), brush) : touchable;\n };\n\n brush.handleSize = function (_) {\n return arguments.length ? (handleSize = +_, brush) : handleSize;\n };\n\n brush.keyModifiers = function (_) {\n return arguments.length ? (keys = !!_, brush) : keys;\n };\n\n brush.on = function () {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? brush : value;\n };\n\n return brush;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-brush/src/index.js\n\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js\nfunction _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js\nfunction _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i["return"] != null) _i["return"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js\nvar unsupportedIterableToArray = __webpack_require__(2961);\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableRest.js\nfunction _nonIterableRest() {\n throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/slicedToArray.js\n\n\n\n\nfunction _slicedToArray(arr, i) {\n return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || (0,unsupportedIterableToArray/* default */.Z)(arr, i) || _nonIterableRest();\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/array.js\n\n\n/* harmony default export */ function src_array(a, b) {\n return (isNumberArray(b) ? numberArray : genericArray)(a, b);\n}\nfunction genericArray(a, b) {\n var nb = b ? b.length : 0,\n na = a ? Math.min(nb, a.length) : 0,\n x = new Array(na),\n c = new Array(nb),\n i;\n\n for (i = 0; i < na; ++i) {\n x[i] = value(a[i], b[i]);\n }\n\n for (; i < nb; ++i) {\n c[i] = b[i];\n }\n\n return function (t) {\n for (i = 0; i < na; ++i) {\n c[i] = x[i](t);\n }\n\n return c;\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/date.js\n/* harmony default export */ function date(a, b) {\n var d = new Date();\n return a = +a, b = +b, function (t) {\n return d.setTime(a * (1 - t) + b * t), d;\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/object.js\n\n/* harmony default export */ function object(a, b) {\n var i = {},\n c = {},\n k;\n if (a === null || typeof a !== "object") a = {};\n if (b === null || typeof b !== "object") b = {};\n\n for (k in b) {\n if (k in a) {\n i[k] = value(a[k], b[k]);\n } else {\n c[k] = b[k];\n }\n }\n\n return function (t) {\n for (k in i) {\n c[k] = i[k](t);\n }\n\n return c;\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/numberArray.js\n/* harmony default export */ function src_numberArray(a, b) {\n if (!b) b = [];\n var n = a ? Math.min(b.length, a.length) : 0,\n c = b.slice(),\n i;\n return function (t) {\n for (i = 0; i < n; ++i) {\n c[i] = a[i] * (1 - t) + b[i] * t;\n }\n\n return c;\n };\n}\nfunction numberArray_isNumberArray(x) {\n return ArrayBuffer.isView(x) && !(x instanceof DataView);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/value.js\n\n\n\n\n\n\n\n\n\n/* harmony default export */ function value(a, b) {\n var t = typeof b,\n c;\n return b == null || t === "boolean" ? d3_interpolate_src_constant(b) : (t === "number" ? src_number : t === "string" ? (c = color(b)) ? (b = c, rgb) : string : b instanceof color ? rgb : b instanceof Date ? date : numberArray_isNumberArray(b) ? src_numberArray : Array.isArray(b) ? genericArray : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object : src_number)(a, b);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-interpolate/src/round.js\n/* harmony default export */ function round(a, b) {\n return a = +a, b = +b, function (t) {\n return Math.round(a * (1 - t) + b * t);\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-scale/src/continuous.js\n\n\n\n\nvar unit = (/* unused pure expression or super */ null && ([0, 1]));\nfunction continuous_identity(x) {\n return x;\n}\n\nfunction continuous_normalize(a, b) {\n return (b -= a = +a) ? function (x) {\n return (x - a) / b;\n } : constant(isNaN(b) ? NaN : 0.5);\n}\n\nfunction clamper(a, b) {\n var t;\n if (a > b) t = a, a = b, b = t;\n return function (x) {\n return Math.max(a, Math.min(b, x));\n };\n} // normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].\n// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b].\n\n\nfunction bimap(domain, range, interpolate) {\n var d0 = domain[0],\n d1 = domain[1],\n r0 = range[0],\n r1 = range[1];\n if (d1 < d0) d0 = continuous_normalize(d1, d0), r0 = interpolate(r1, r0);else d0 = continuous_normalize(d0, d1), r0 = interpolate(r0, r1);\n return function (x) {\n return r0(d0(x));\n };\n}\n\nfunction polymap(domain, range, interpolate) {\n var j = Math.min(domain.length, range.length) - 1,\n d = new Array(j),\n r = new Array(j),\n i = -1; // Reverse descending domains.\n\n if (domain[j] < domain[0]) {\n domain = domain.slice().reverse();\n range = range.slice().reverse();\n }\n\n while (++i < j) {\n d[i] = continuous_normalize(domain[i], domain[i + 1]);\n r[i] = interpolate(range[i], range[i + 1]);\n }\n\n return function (x) {\n var i = bisect(domain, x, 1, j) - 1;\n return r[i](d[i](x));\n };\n}\n\nfunction continuous_copy(source, target) {\n return target.domain(source.domain()).range(source.range()).interpolate(source.interpolate()).clamp(source.clamp()).unknown(source.unknown());\n}\nfunction transformer() {\n var domain = unit,\n range = unit,\n interpolate = interpolateValue,\n transform,\n untransform,\n unknown,\n clamp = continuous_identity,\n piecewise,\n output,\n input;\n\n function rescale() {\n var n = Math.min(domain.length, range.length);\n if (clamp !== continuous_identity) clamp = clamper(domain[0], domain[n - 1]);\n piecewise = n > 2 ? polymap : bimap;\n output = input = null;\n return scale;\n }\n\n function scale(x) {\n return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x)));\n }\n\n scale.invert = function (y) {\n return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y)));\n };\n\n scale.domain = function (_) {\n return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice();\n };\n\n scale.range = function (_) {\n return arguments.length ? (range = Array.from(_), rescale()) : range.slice();\n };\n\n scale.rangeRound = function (_) {\n return range = Array.from(_), interpolate = interpolateRound, rescale();\n };\n\n scale.clamp = function (_) {\n return arguments.length ? (clamp = _ ? true : continuous_identity, rescale()) : clamp !== continuous_identity;\n };\n\n scale.interpolate = function (_) {\n return arguments.length ? (interpolate = _, rescale()) : interpolate;\n };\n\n scale.unknown = function (_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n return function (t, u) {\n transform = t, untransform = u;\n return rescale();\n };\n}\nfunction continuous_continuous() {\n return transformer()(continuous_identity, continuous_identity);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-scale/src/init.js\nfunction init_initRange(domain, range) {\n switch (arguments.length) {\n case 0:\n break;\n\n case 1:\n this.range(domain);\n break;\n\n default:\n this.range(range).domain(domain);\n break;\n }\n\n return this;\n}\nfunction init_initInterpolator(domain, interpolator) {\n switch (arguments.length) {\n case 0:\n break;\n\n case 1:\n {\n if (typeof domain === "function") this.interpolator(domain);else this.range(domain);\n break;\n }\n\n default:\n {\n this.domain(domain);\n if (typeof interpolator === "function") this.interpolator(interpolator);else this.range(interpolator);\n break;\n }\n }\n\n return this;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-array/src/ticks.js\nvar e10 = Math.sqrt(50),\n e5 = Math.sqrt(10),\n e2 = Math.sqrt(2);\n/* harmony default export */ function ticks(start, stop, count) {\n var reverse,\n i = -1,\n n,\n ticks,\n step;\n stop = +stop, start = +start, count = +count;\n if (start === stop && count > 0) return [start];\n if (reverse = stop < start) n = start, start = stop, stop = n;\n if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];\n\n if (step > 0) {\n var r0 = Math.round(start / step),\n r1 = Math.round(stop / step);\n if (r0 * step < start) ++r0;\n if (r1 * step > stop) --r1;\n ticks = new Array(n = r1 - r0 + 1);\n\n while (++i < n) {\n ticks[i] = (r0 + i) * step;\n }\n } else {\n step = -step;\n\n var _r = Math.round(start * step),\n _r2 = Math.round(stop * step);\n\n if (_r / step < start) ++_r;\n if (_r2 / step > stop) --_r2;\n ticks = new Array(n = _r2 - _r + 1);\n\n while (++i < n) {\n ticks[i] = (_r + i) / step;\n }\n }\n\n if (reverse) ticks.reverse();\n return ticks;\n}\nfunction tickIncrement(start, stop, count) {\n var step = (stop - start) / Math.max(0, count),\n power = Math.floor(Math.log(step) / Math.LN10),\n error = step / Math.pow(10, power);\n return power >= 0 ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);\n}\nfunction tickStep(start, stop, count) {\n var step0 = Math.abs(stop - start) / Math.max(0, count),\n step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),\n error = step0 / step1;\n if (error >= e10) step1 *= 10;else if (error >= e5) step1 *= 5;else if (error >= e2) step1 *= 2;\n return stop < start ? -step1 : step1;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatSpecifier.js\n// [[fill]align][sign][symbol][0][width][,][.precision][~][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?(~)?([a-z%])?$/i;\nfunction formatSpecifier(specifier) {\n if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);\n var match;\n return new FormatSpecifier({\n fill: match[1],\n align: match[2],\n sign: match[3],\n symbol: match[4],\n zero: match[5],\n width: match[6],\n comma: match[7],\n precision: match[8] && match[8].slice(1),\n trim: match[9],\n type: match[10]\n });\n}\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nfunction FormatSpecifier(specifier) {\n this.fill = specifier.fill === undefined ? " " : specifier.fill + "";\n this.align = specifier.align === undefined ? ">" : specifier.align + "";\n this.sign = specifier.sign === undefined ? "-" : specifier.sign + "";\n this.symbol = specifier.symbol === undefined ? "" : specifier.symbol + "";\n this.zero = !!specifier.zero;\n this.width = specifier.width === undefined ? undefined : +specifier.width;\n this.comma = !!specifier.comma;\n this.precision = specifier.precision === undefined ? undefined : +specifier.precision;\n this.trim = !!specifier.trim;\n this.type = specifier.type === undefined ? "" : specifier.type + "";\n}\n\nFormatSpecifier.prototype.toString = function () {\n return this.fill + this.align + this.sign + this.symbol + (this.zero ? "0" : "") + (this.width === undefined ? "" : Math.max(1, this.width | 0)) + (this.comma ? "," : "") + (this.precision === undefined ? "" : "." + Math.max(0, this.precision | 0)) + (this.trim ? "~" : "") + this.type;\n};\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatDecimal.js\n/* harmony default export */ function formatDecimal(x) {\n return Math.abs(x = Math.round(x)) >= 1e21 ? x.toLocaleString("en").replace(/,/g, "") : x.toString(10);\n} // Computes the decimal coefficient and exponent of the specified number x with\n// significant digits p, where x is positive and p is in [1, 21] or undefined.\n// For example, formatDecimalParts(1.23) returns ["123", 0].\n\nfunction formatDecimalParts(x, p) {\n if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity\n\n var i,\n coefficient = x.slice(0, i); // The string returned by toExponential either has the form \\d\\.\\d+e[-+]\\d+\n // (e.g., 1.2e+3) or the form \\de[-+]\\d+ (e.g., 1e+3).\n\n return [coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, +x.slice(i + 1)];\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/exponent.js\n\n/* harmony default export */ function exponent(x) {\n return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/precisionPrefix.js\n\n/* harmony default export */ function precisionPrefix(step, value) {\n return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatGroup.js\n/* harmony default export */ function formatGroup(grouping, thousands) {\n return function (value, width) {\n var i = value.length,\n t = [],\n j = 0,\n g = grouping[0],\n length = 0;\n\n while (i > 0 && g > 0) {\n if (length + g + 1 > width) g = Math.max(1, width - length);\n t.push(value.substring(i -= g, i + g));\n if ((length += g + 1) > width) break;\n g = grouping[j = (j + 1) % grouping.length];\n }\n\n return t.reverse().join(thousands);\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatNumerals.js\n/* harmony default export */ function formatNumerals(numerals) {\n return function (value) {\n return value.replace(/[0-9]/g, function (i) {\n return numerals[+i];\n });\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatTrim.js\n// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.\n/* harmony default export */ function formatTrim(s) {\n out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {\n switch (s[i]) {\n case ".":\n i0 = i1 = i;\n break;\n\n case "0":\n if (i0 === 0) i0 = i;\n i1 = i;\n break;\n\n default:\n if (!+s[i]) break out;\n if (i0 > 0) i0 = 0;\n break;\n }\n }\n\n return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatPrefixAuto.js\n\nvar prefixExponent;\n/* harmony default export */ function formatPrefixAuto(x, p) {\n var d = formatDecimalParts(x, p);\n if (!d) return x + "";\n var coefficient = d[0],\n exponent = d[1],\n i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n n = coefficient.length;\n return i === n ? coefficient : i > n ? coefficient + new Array(i - n + 1).join("0") : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) : "0." + new Array(1 - i).join("0") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatRounded.js\n\n/* harmony default export */ function formatRounded(x, p) {\n var d = formatDecimalParts(x, p);\n if (!d) return x + "";\n var coefficient = d[0],\n exponent = d[1];\n return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) : coefficient + new Array(exponent - coefficient.length + 2).join("0");\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/formatTypes.js\n\n\n\n/* harmony default export */ var formatTypes = ({\n "%": function _(x, p) {\n return (x * 100).toFixed(p);\n },\n "b": function b(x) {\n return Math.round(x).toString(2);\n },\n "c": function c(x) {\n return x + "";\n },\n "d": formatDecimal,\n "e": function e(x, p) {\n return x.toExponential(p);\n },\n "f": function f(x, p) {\n return x.toFixed(p);\n },\n "g": function g(x, p) {\n return x.toPrecision(p);\n },\n "o": function o(x) {\n return Math.round(x).toString(8);\n },\n "p": function p(x, _p) {\n return formatRounded(x * 100, _p);\n },\n "r": formatRounded,\n "s": formatPrefixAuto,\n "X": function X(x) {\n return Math.round(x).toString(16).toUpperCase();\n },\n "x": function x(_x) {\n return Math.round(_x).toString(16);\n }\n});\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/identity.js\n/* harmony default export */ function src_identity(x) {\n return x;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/locale.js\n\n\n\n\n\n\n\n\nvar map = Array.prototype.map,\n prefixes = ["y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"];\n/* harmony default export */ function locale(locale) {\n var group = locale.grouping === undefined || locale.thousands === undefined ? src_identity : formatGroup(map.call(locale.grouping, Number), locale.thousands + ""),\n currencyPrefix = locale.currency === undefined ? "" : locale.currency[0] + "",\n currencySuffix = locale.currency === undefined ? "" : locale.currency[1] + "",\n decimal = locale.decimal === undefined ? "." : locale.decimal + "",\n numerals = locale.numerals === undefined ? src_identity : formatNumerals(map.call(locale.numerals, String)),\n percent = locale.percent === undefined ? "%" : locale.percent + "",\n minus = locale.minus === undefined ? "−" : locale.minus + "",\n nan = locale.nan === undefined ? "NaN" : locale.nan + "";\n\n function newFormat(specifier) {\n specifier = formatSpecifier(specifier);\n var fill = specifier.fill,\n align = specifier.align,\n sign = specifier.sign,\n symbol = specifier.symbol,\n zero = specifier.zero,\n width = specifier.width,\n comma = specifier.comma,\n precision = specifier.precision,\n trim = specifier.trim,\n type = specifier.type; // The "n" type is an alias for ",g".\n\n if (type === "n") comma = true, type = "g"; // The "" type, and any invalid type, is an alias for ".12~g".\n else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = "g"; // If zero fill is specified, padding goes after sign and before digits.\n\n if (zero || fill === "0" && align === "=") zero = true, fill = "0", align = "="; // Compute the prefix and suffix.\n // For SI-prefix, the suffix is lazily computed.\n\n var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",\n suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : ""; // What format function should we use?\n // Is this an integer type?\n // Can this type generate exponential notation?\n\n var formatType = formatTypes[type],\n maybeSuffix = /[defgprs%]/.test(type); // Set the default precision if not specified,\n // or clamp the specified precision to the supported range.\n // For significant precision, it must be in [1, 21].\n // For fixed precision, it must be in [0, 20].\n\n precision = precision === undefined ? 6 : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) : Math.max(0, Math.min(20, precision));\n\n function format(value) {\n var valuePrefix = prefix,\n valueSuffix = suffix,\n i,\n n,\n c;\n\n if (type === "c") {\n valueSuffix = formatType(value) + valueSuffix;\n value = "";\n } else {\n value = +value; // Determine the sign. -0 is not less than 0, but 1 / -0 is!\n\n var valueNegative = value < 0 || 1 / value < 0; // Perform the initial formatting.\n\n value = isNaN(value) ? nan : formatType(Math.abs(value), precision); // Trim insignificant zeros.\n\n if (trim) value = formatTrim(value); // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign.\n\n if (valueNegative && +value === 0 && sign !== "+") valueNegative = false; // Compute the prefix and suffix.\n\n valuePrefix = (valueNegative ? sign === "(" ? sign : minus : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;\n valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : ""); // Break the formatted value into the integer “value” part that can be\n // grouped, and fractional or exponential “suffix” part that is not.\n\n if (maybeSuffix) {\n i = -1, n = value.length;\n\n while (++i < n) {\n if (c = value.charCodeAt(i), 48 > c || c > 57) {\n valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n value = value.slice(0, i);\n break;\n }\n }\n }\n } // If the fill character is not "0", grouping is applied before padding.\n\n\n if (comma && !zero) value = group(value, Infinity); // Compute the padding.\n\n var length = valuePrefix.length + value.length + valueSuffix.length,\n padding = length < width ? new Array(width - length + 1).join(fill) : ""; // If the fill character is "0", grouping is applied after padding.\n\n if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; // Reconstruct the final output based on the desired alignment.\n\n switch (align) {\n case "<":\n value = valuePrefix + value + valueSuffix + padding;\n break;\n\n case "=":\n value = valuePrefix + padding + value + valueSuffix;\n break;\n\n case "^":\n value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length);\n break;\n\n default:\n value = padding + valuePrefix + value + valueSuffix;\n break;\n }\n\n return numerals(value);\n }\n\n format.toString = function () {\n return specifier + "";\n };\n\n return format;\n }\n\n function formatPrefix(specifier, value) {\n var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),\n e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,\n k = Math.pow(10, -e),\n prefix = prefixes[8 + e / 3];\n return function (value) {\n return f(k * value) + prefix;\n };\n }\n\n return {\n format: newFormat,\n formatPrefix: formatPrefix\n };\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/defaultLocale.js\n\nvar defaultLocale_locale;\nvar defaultLocale_format;\nvar formatPrefix;\ndefaultLocale({\n thousands: ",",\n grouping: [3],\n currency: ["$", ""]\n});\nfunction defaultLocale(definition) {\n defaultLocale_locale = locale(definition);\n defaultLocale_format = defaultLocale_locale.format;\n formatPrefix = defaultLocale_locale.formatPrefix;\n return defaultLocale_locale;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/precisionRound.js\n\n/* harmony default export */ function precisionRound(step, max) {\n step = Math.abs(step), max = Math.abs(max) - step;\n return Math.max(0, exponent(max) - exponent(step)) + 1;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-format/src/precisionFixed.js\n\n/* harmony default export */ function precisionFixed(step) {\n return Math.max(0, -exponent(Math.abs(step)));\n}\n;// CONCATENATED MODULE: ./node_modules/d3-scale/src/tickFormat.js\n\n\nfunction tickFormat(start, stop, count, specifier) {\n var step = tickStep(start, stop, count),\n precision;\n specifier = formatSpecifier(specifier == null ? ",f" : specifier);\n\n switch (specifier.type) {\n case "s":\n {\n var value = Math.max(Math.abs(start), Math.abs(stop));\n if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;\n return formatPrefix(specifier, value);\n }\n\n case "":\n case "e":\n case "g":\n case "p":\n case "r":\n {\n if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");\n break;\n }\n\n case "f":\n case "%":\n {\n if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;\n break;\n }\n }\n\n return defaultLocale_format(specifier);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-scale/src/linear.js\n\n\n\n\nfunction linearish(scale) {\n var domain = scale.domain;\n\n scale.ticks = function (count) {\n var d = domain();\n return ticks(d[0], d[d.length - 1], count == null ? 10 : count);\n };\n\n scale.tickFormat = function (count, specifier) {\n var d = domain();\n return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);\n };\n\n scale.nice = function (count) {\n if (count == null) count = 10;\n var d = domain();\n var i0 = 0;\n var i1 = d.length - 1;\n var start = d[i0];\n var stop = d[i1];\n var prestep;\n var step;\n var maxIter = 10;\n\n if (stop < start) {\n step = start, start = stop, stop = step;\n step = i0, i0 = i1, i1 = step;\n }\n\n while (maxIter-- > 0) {\n step = tickIncrement(start, stop, count);\n\n if (step === prestep) {\n d[i0] = start;\n d[i1] = stop;\n return domain(d);\n } else if (step > 0) {\n start = Math.floor(start / step) * step;\n stop = Math.ceil(stop / step) * step;\n } else if (step < 0) {\n start = Math.ceil(start * step) / step;\n stop = Math.floor(stop * step) / step;\n } else {\n break;\n }\n\n prestep = step;\n }\n\n return scale;\n };\n\n return scale;\n}\nfunction linear_linear() {\n var scale = continuous();\n\n scale.copy = function () {\n return copy(scale, linear_linear());\n };\n\n initRange.apply(scale, arguments);\n return linearish(scale);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-scale/src/sequential.js\n\n\n\n\n\n\n\n\n\nfunction sequential_transformer() {\n var x0 = 0,\n x1 = 1,\n t0,\n t1,\n k10,\n transform,\n interpolator = continuous_identity,\n clamp = false,\n unknown;\n\n function scale(x) {\n return x == null || isNaN(x = +x) ? unknown : interpolator(k10 === 0 ? 0.5 : (x = (transform(x) - t0) * k10, clamp ? Math.max(0, Math.min(1, x)) : x));\n }\n\n scale.domain = function (_) {\n var _ref, _ref2;\n\n return arguments.length ? ((_ref = _, _ref2 = _slicedToArray(_ref, 2), x0 = _ref2[0], x1 = _ref2[1], _ref), t0 = transform(x0 = +x0), t1 = transform(x1 = +x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0), scale) : [x0, x1];\n };\n\n scale.clamp = function (_) {\n return arguments.length ? (clamp = !!_, scale) : clamp;\n };\n\n scale.interpolator = function (_) {\n return arguments.length ? (interpolator = _, scale) : interpolator;\n };\n\n function range(interpolate) {\n return function (_) {\n var _ref3, _ref4;\n\n var r0, r1;\n return arguments.length ? ((_ref3 = _, _ref4 = _slicedToArray(_ref3, 2), r0 = _ref4[0], r1 = _ref4[1], _ref3), interpolator = interpolate(r0, r1), scale) : [interpolator(0), interpolator(1)];\n };\n }\n\n scale.range = range(value);\n scale.rangeRound = range(round);\n\n scale.unknown = function (_) {\n return arguments.length ? (unknown = _, scale) : unknown;\n };\n\n return function (t) {\n transform = t, t0 = t(x0), t1 = t(x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0);\n return scale;\n };\n}\n\nfunction sequential_copy(source, target) {\n return target.domain(source.domain()).interpolator(source.interpolator()).clamp(source.clamp()).unknown(source.unknown());\n}\nfunction sequential() {\n var scale = linearish(sequential_transformer()(continuous_identity));\n\n scale.copy = function () {\n return sequential_copy(scale, sequential());\n };\n\n return init_initInterpolator.apply(scale, arguments);\n}\nfunction sequentialLog() {\n var scale = loggish(sequential_transformer()).domain([1, 10]);\n\n scale.copy = function () {\n return sequential_copy(scale, sequentialLog()).base(scale.base());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\nfunction sequentialSymlog() {\n var scale = symlogish(sequential_transformer());\n\n scale.copy = function () {\n return sequential_copy(scale, sequentialSymlog()).constant(scale.constant());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\nfunction sequentialPow() {\n var scale = powish(sequential_transformer());\n\n scale.copy = function () {\n return sequential_copy(scale, sequentialPow()).exponent(scale.exponent());\n };\n\n return initInterpolator.apply(scale, arguments);\n}\nfunction sequentialSqrt() {\n return sequentialPow.apply(null, arguments).exponent(0.5);\n}\n;// CONCATENATED MODULE: ./node_modules/d3-scale/src/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./node_modules/d3-scale-chromatic/src/colors.js\n/* harmony default export */ function colors(specifier) {\n var n = specifier.length / 6 | 0,\n colors = new Array(n),\n i = 0;\n\n while (i < n) {\n colors[i] = "#" + specifier.slice(i * 6, ++i * 6);\n }\n\n return colors;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-scale-chromatic/src/ramp.js\n\n/* harmony default export */ var ramp = (function (scheme) {\n return rgbBasis(scheme[scheme.length - 1]);\n});\n;// CONCATENATED MODULE: ./node_modules/d3-scale-chromatic/src/sequential-single/Blues.js\n\n\nvar scheme = new Array(3).concat("deebf79ecae13182bd", "eff3ffbdd7e76baed62171b5", "eff3ffbdd7e76baed63182bd08519c", "eff3ffc6dbef9ecae16baed63182bd08519c", "eff3ffc6dbef9ecae16baed64292c62171b5084594", "f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594", "f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b").map(colors);\n/* harmony default export */ var Blues = (ramp(scheme));\n;// CONCATENATED MODULE: ./node_modules/d3-scale-chromatic/src/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// EXTERNAL MODULE: ./node_modules/core-js/modules/es.math.hypot.js\nvar es_math_hypot = __webpack_require__(5438);\n;// CONCATENATED MODULE: ./node_modules/d3-zoom/src/transform.js\nfunction transform_Transform(k, x, y) {\n this.k = k;\n this.x = x;\n this.y = y;\n}\ntransform_Transform.prototype = {\n constructor: transform_Transform,\n scale: function scale(k) {\n return k === 1 ? this : new transform_Transform(this.k * k, this.x, this.y);\n },\n translate: function translate(x, y) {\n return x === 0 & y === 0 ? this : new transform_Transform(this.k, this.x + this.k * x, this.y + this.k * y);\n },\n apply: function apply(point) {\n return [point[0] * this.k + this.x, point[1] * this.k + this.y];\n },\n applyX: function applyX(x) {\n return x * this.k + this.x;\n },\n applyY: function applyY(y) {\n return y * this.k + this.y;\n },\n invert: function invert(location) {\n return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];\n },\n invertX: function invertX(x) {\n return (x - this.x) / this.k;\n },\n invertY: function invertY(y) {\n return (y - this.y) / this.k;\n },\n rescaleX: function rescaleX(x) {\n return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));\n },\n rescaleY: function rescaleY(y) {\n return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));\n },\n toString: function toString() {\n return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";\n }\n};\nvar transform_identity = new transform_Transform(1, 0, 0);\ntransform_transform.prototype = transform_Transform.prototype;\nfunction transform_transform(node) {\n while (!node.__zoom) {\n if (!(node = node.parentNode)) return transform_identity;\n }\n\n return node.__zoom;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-zoom/src/zoom.js\n\n\n\n\n\n\n\n\n\n // Ignore right-click, since that should open the context menu.\n// except for pinch-to-zoom, which is sent as a wheel+ctrlKey event\n\nfunction zoom_defaultFilter(event) {\n return (!event.ctrlKey || event.type === \'wheel\') && !event.button;\n}\n\nfunction zoom_defaultExtent() {\n var e = this;\n\n if (e instanceof SVGElement) {\n e = e.ownerSVGElement || e;\n\n if (e.hasAttribute("viewBox")) {\n e = e.viewBox.baseVal;\n return [[e.x, e.y], [e.x + e.width, e.y + e.height]];\n }\n\n return [[0, 0], [e.width.baseVal.value, e.height.baseVal.value]];\n }\n\n return [[0, 0], [e.clientWidth, e.clientHeight]];\n}\n\nfunction defaultTransform() {\n return this.__zoom || identity;\n}\n\nfunction defaultWheelDelta(event) {\n return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * (event.ctrlKey ? 10 : 1);\n}\n\nfunction zoom_defaultTouchable() {\n return navigator.maxTouchPoints || "ontouchstart" in this;\n}\n\nfunction defaultConstrain(transform, extent, translateExtent) {\n var dx0 = transform.invertX(extent[0][0]) - translateExtent[0][0],\n dx1 = transform.invertX(extent[1][0]) - translateExtent[1][0],\n dy0 = transform.invertY(extent[0][1]) - translateExtent[0][1],\n dy1 = transform.invertY(extent[1][1]) - translateExtent[1][1];\n return transform.translate(dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1));\n}\n\n/* harmony default export */ function zoom() {\n var filter = zoom_defaultFilter,\n extent = zoom_defaultExtent,\n constrain = defaultConstrain,\n wheelDelta = defaultWheelDelta,\n touchable = zoom_defaultTouchable,\n scaleExtent = [0, Infinity],\n translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]],\n duration = 250,\n interpolate = interpolateZoom,\n listeners = dispatch("start", "zoom", "end"),\n touchstarting,\n touchfirst,\n touchending,\n touchDelay = 500,\n wheelDelay = 150,\n clickDistance2 = 0,\n tapDistance = 10;\n\n function zoom(selection) {\n selection.property("__zoom", defaultTransform).on("wheel.zoom", wheeled, {\n passive: false\n }).on("mousedown.zoom", mousedowned).on("dblclick.zoom", dblclicked).filter(touchable).on("touchstart.zoom", touchstarted).on("touchmove.zoom", touchmoved).on("touchend.zoom touchcancel.zoom", touchended).style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");\n }\n\n zoom.transform = function (collection, transform, point, event) {\n var selection = collection.selection ? collection.selection() : collection;\n selection.property("__zoom", defaultTransform);\n\n if (collection !== selection) {\n schedule(collection, transform, point, event);\n } else {\n selection.interrupt().each(function () {\n gesture(this, arguments).event(event).start().zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform).end();\n });\n }\n };\n\n zoom.scaleBy = function (selection, k, p, event) {\n zoom.scaleTo(selection, function () {\n var k0 = this.__zoom.k,\n k1 = typeof k === "function" ? k.apply(this, arguments) : k;\n return k0 * k1;\n }, p, event);\n };\n\n zoom.scaleTo = function (selection, k, p, event) {\n zoom.transform(selection, function () {\n var e = extent.apply(this, arguments),\n t0 = this.__zoom,\n p0 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p,\n p1 = t0.invert(p0),\n k1 = typeof k === "function" ? k.apply(this, arguments) : k;\n return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent);\n }, p, event);\n };\n\n zoom.translateBy = function (selection, x, y, event) {\n zoom.transform(selection, function () {\n return constrain(this.__zoom.translate(typeof x === "function" ? x.apply(this, arguments) : x, typeof y === "function" ? y.apply(this, arguments) : y), extent.apply(this, arguments), translateExtent);\n }, null, event);\n };\n\n zoom.translateTo = function (selection, x, y, p, event) {\n zoom.transform(selection, function () {\n var e = extent.apply(this, arguments),\n t = this.__zoom,\n p0 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p;\n return constrain(identity.translate(p0[0], p0[1]).scale(t.k).translate(typeof x === "function" ? -x.apply(this, arguments) : -x, typeof y === "function" ? -y.apply(this, arguments) : -y), e, translateExtent);\n }, p, event);\n };\n\n function scale(transform, k) {\n k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k));\n return k === transform.k ? transform : new Transform(k, transform.x, transform.y);\n }\n\n function translate(transform, p0, p1) {\n var x = p0[0] - p1[0] * transform.k,\n y = p0[1] - p1[1] * transform.k;\n return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y);\n }\n\n function centroid(extent) {\n return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];\n }\n\n function schedule(transition, transform, point, event) {\n transition.on("start.zoom", function () {\n gesture(this, arguments).event(event).start();\n }).on("interrupt.zoom end.zoom", function () {\n gesture(this, arguments).event(event).end();\n }).tween("zoom", function () {\n var that = this,\n args = arguments,\n g = gesture(that, args).event(event),\n e = extent.apply(that, args),\n p = point == null ? centroid(e) : typeof point === "function" ? point.apply(that, args) : point,\n w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),\n a = that.__zoom,\n b = typeof transform === "function" ? transform.apply(that, args) : transform,\n i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));\n return function (t) {\n if (t === 1) t = b; // Avoid rounding error on end.\n else {\n var l = i(t),\n k = w / l[2];\n t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k);\n }\n g.zoom(null, t);\n };\n });\n }\n\n function gesture(that, args, clean) {\n return !clean && that.__zooming || new Gesture(that, args);\n }\n\n function Gesture(that, args) {\n this.that = that;\n this.args = args;\n this.active = 0;\n this.sourceEvent = null;\n this.extent = extent.apply(that, args);\n this.taps = 0;\n }\n\n Gesture.prototype = {\n event: function event(_event) {\n if (_event) this.sourceEvent = _event;\n return this;\n },\n start: function start() {\n if (++this.active === 1) {\n this.that.__zooming = this;\n this.emit("start");\n }\n\n return this;\n },\n zoom: function zoom(key, transform) {\n if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]);\n if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]);\n if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]);\n this.that.__zoom = transform;\n this.emit("zoom");\n return this;\n },\n end: function end() {\n if (--this.active === 0) {\n delete this.that.__zooming;\n this.emit("end");\n }\n\n return this;\n },\n emit: function emit(type) {\n var d = select(this.that).datum();\n listeners.call(type, this.that, new ZoomEvent(type, {\n sourceEvent: this.sourceEvent,\n target: zoom,\n type: type,\n transform: this.that.__zoom,\n dispatch: listeners\n }), d);\n }\n };\n\n function wheeled(event) {\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n if (!filter.apply(this, arguments)) return;\n var g = gesture(this, args).event(event),\n t = this.__zoom,\n k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),\n p = pointer(event); // If the mouse is in the same location as before, reuse it.\n // If there were recent wheel events, reset the wheel idle timeout.\n\n if (g.wheel) {\n if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {\n g.mouse[1] = t.invert(g.mouse[0] = p);\n }\n\n clearTimeout(g.wheel);\n } // If this wheel event won’t trigger a transform change, ignore it.\n else if (t.k === k) return; // Otherwise, capture the mouse point and location at the start.\n else {\n g.mouse = [p, t.invert(p)];\n interrupt(this);\n g.start();\n }\n\n noevent(event);\n g.wheel = setTimeout(wheelidled, wheelDelay);\n g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));\n\n function wheelidled() {\n g.wheel = null;\n g.end();\n }\n }\n\n function mousedowned(event) {\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n\n if (touchending || !filter.apply(this, arguments)) return;\n var currentTarget = event.currentTarget,\n g = gesture(this, args, true).event(event),\n v = select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true),\n p = pointer(event, currentTarget),\n x0 = event.clientX,\n y0 = event.clientY;\n dragDisable(event.view);\n nopropagation(event);\n g.mouse = [p, this.__zoom.invert(p)];\n interrupt(this);\n g.start();\n\n function mousemoved(event) {\n noevent(event);\n\n if (!g.moved) {\n var dx = event.clientX - x0,\n dy = event.clientY - y0;\n g.moved = dx * dx + dy * dy > clickDistance2;\n }\n\n g.event(event).zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = pointer(event, currentTarget), g.mouse[1]), g.extent, translateExtent));\n }\n\n function mouseupped(event) {\n v.on("mousemove.zoom mouseup.zoom", null);\n dragEnable(event.view, g.moved);\n noevent(event);\n g.event(event).end();\n }\n }\n\n function dblclicked(event) {\n for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n args[_key3 - 1] = arguments[_key3];\n }\n\n if (!filter.apply(this, arguments)) return;\n var t0 = this.__zoom,\n p0 = pointer(event.changedTouches ? event.changedTouches[0] : event, this),\n p1 = t0.invert(p0),\n k1 = t0.k * (event.shiftKey ? 0.5 : 2),\n t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, args), translateExtent);\n noevent(event);\n if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0, event);else select(this).call(zoom.transform, t1, p0, event);\n }\n\n function touchstarted(event) {\n for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {\n args[_key4 - 1] = arguments[_key4];\n }\n\n if (!filter.apply(this, arguments)) return;\n var touches = event.touches,\n n = touches.length,\n g = gesture(this, args, event.changedTouches.length === n).event(event),\n started,\n i,\n t,\n p;\n nopropagation(event);\n\n for (i = 0; i < n; ++i) {\n t = touches[i], p = pointer(t, this);\n p = [p, this.__zoom.invert(p), t.identifier];\n if (!g.touch0) g.touch0 = p, started = true, g.taps = 1 + !!touchstarting;else if (!g.touch1 && g.touch0[2] !== p[2]) g.touch1 = p, g.taps = 0;\n }\n\n if (touchstarting) touchstarting = clearTimeout(touchstarting);\n\n if (started) {\n if (g.taps < 2) touchfirst = p[0], touchstarting = setTimeout(function () {\n touchstarting = null;\n }, touchDelay);\n interrupt(this);\n g.start();\n }\n }\n\n function touchmoved(event) {\n if (!this.__zooming) return;\n\n for (var _len5 = arguments.length, args = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {\n args[_key5 - 1] = arguments[_key5];\n }\n\n var g = gesture(this, args).event(event),\n touches = event.changedTouches,\n n = touches.length,\n i,\n t,\n p,\n l;\n noevent(event);\n\n for (i = 0; i < n; ++i) {\n t = touches[i], p = pointer(t, this);\n if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;\n }\n\n t = g.that.__zoom;\n\n if (g.touch1) {\n var p0 = g.touch0[0],\n l0 = g.touch0[1],\n p1 = g.touch1[0],\n l1 = g.touch1[1],\n dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,\n dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;\n t = scale(t, Math.sqrt(dp / dl));\n p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];\n l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];\n } else if (g.touch0) p = g.touch0[0], l = g.touch0[1];else return;\n\n g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent));\n }\n\n function touchended(event) {\n for (var _len6 = arguments.length, args = new Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) {\n args[_key6 - 1] = arguments[_key6];\n }\n\n if (!this.__zooming) return;\n var g = gesture(this, args).event(event),\n touches = event.changedTouches,\n n = touches.length,\n i,\n t;\n nopropagation(event);\n if (touchending) clearTimeout(touchending);\n touchending = setTimeout(function () {\n touchending = null;\n }, touchDelay);\n\n for (i = 0; i < n; ++i) {\n t = touches[i];\n if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;\n }\n\n if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;\n if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]);else {\n g.end(); // If this was a dbltap, reroute to the (optional) dblclick.zoom handler.\n\n if (g.taps === 2) {\n t = pointer(t, this);\n\n if (Math.hypot(touchfirst[0] - t[0], touchfirst[1] - t[1]) < tapDistance) {\n var p = select(this).on("dblclick.zoom");\n if (p) p.apply(this, arguments);\n }\n }\n }\n }\n\n zoom.wheelDelta = function (_) {\n return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant(+_), zoom) : wheelDelta;\n };\n\n zoom.filter = function (_) {\n return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), zoom) : filter;\n };\n\n zoom.touchable = function (_) {\n return arguments.length ? (touchable = typeof _ === "function" ? _ : constant(!!_), zoom) : touchable;\n };\n\n zoom.extent = function (_) {\n return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;\n };\n\n zoom.scaleExtent = function (_) {\n return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]];\n };\n\n zoom.translateExtent = function (_) {\n return arguments.length ? (translateExtent[0][0] = +_[0][0], translateExtent[1][0] = +_[1][0], translateExtent[0][1] = +_[0][1], translateExtent[1][1] = +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0][1]], [translateExtent[1][0], translateExtent[1][1]]];\n };\n\n zoom.constrain = function (_) {\n return arguments.length ? (constrain = _, zoom) : constrain;\n };\n\n zoom.duration = function (_) {\n return arguments.length ? (duration = +_, zoom) : duration;\n };\n\n zoom.interpolate = function (_) {\n return arguments.length ? (interpolate = _, zoom) : interpolate;\n };\n\n zoom.on = function () {\n var value = listeners.on.apply(listeners, arguments);\n return value === listeners ? zoom : value;\n };\n\n zoom.clickDistance = function (_) {\n return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2);\n };\n\n zoom.tapDistance = function (_) {\n return arguments.length ? (tapDistance = +_, zoom) : tapDistance;\n };\n\n return zoom;\n}\n;// CONCATENATED MODULE: ./node_modules/d3-zoom/src/index.js\n\n\n;// CONCATENATED MODULE: ./node_modules/d3/src/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n;// CONCATENATED MODULE: ./node_modules/ol/OverlayPositioning.js\n/**\n * @module ol/OverlayPositioning\n */\n\n/**\n * Overlay position: `\'bottom-left\'`, `\'bottom-center\'`, `\'bottom-right\'`,\n * `\'center-left\'`, `\'center-center\'`, `\'center-right\'`, `\'top-left\'`,\n * `\'top-center\'`, `\'top-right\'`\n * @enum {string}\n */\n/* harmony default export */ var OverlayPositioning = ({\n BOTTOM_LEFT: \'bottom-left\',\n BOTTOM_CENTER: \'bottom-center\',\n BOTTOM_RIGHT: \'bottom-right\',\n CENTER_LEFT: \'center-left\',\n CENTER_CENTER: \'center-center\',\n CENTER_RIGHT: \'center-right\',\n TOP_LEFT: \'top-left\',\n TOP_CENTER: \'top-center\',\n TOP_RIGHT: \'top-right\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/Overlay.js\nvar Overlay_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Overlay\n */\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number|string} [id] Set the overlay id. The overlay id can be used\n * with the {@link module:ol/Map~Map#getOverlayById} method.\n * @property {HTMLElement} [element] The overlay element.\n * @property {Array<number>} [offset=[0, 0]] Offsets in pixels used when positioning\n * the overlay. The first element in the\n * array is the horizontal offset. A positive value shifts the overlay right.\n * The second element in the array is the vertical offset. A positive value\n * shifts the overlay down.\n * @property {import("./coordinate.js").Coordinate} [position] The overlay position\n * in map projection.\n * @property {import("./OverlayPositioning.js").default} [positioning=\'top-left\'] Defines how\n * the overlay is actually positioned with respect to its `position` property.\n * Possible values are `\'bottom-left\'`, `\'bottom-center\'`, `\'bottom-right\'`,\n * `\'center-left\'`, `\'center-center\'`, `\'center-right\'`, `\'top-left\'`,\n * `\'top-center\'`, and `\'top-right\'`.\n * @property {boolean} [stopEvent=true] Whether event propagation to the map\n * viewport should be stopped. If `true` the overlay is placed in the same\n * container as that of the controls (CSS class name\n * `ol-overlaycontainer-stopevent`); if `false` it is placed in the container\n * with CSS class name specified by the `className` property.\n * @property {boolean} [insertFirst=true] Whether the overlay is inserted first\n * in the overlay container, or appended. If the overlay is placed in the same\n * container as that of the controls (see the `stopEvent` option) you will\n * probably set `insertFirst` to `true` so the overlay is displayed below the\n * controls.\n * @property {PanIntoViewOptions|boolean} [autoPan=false] Pan the map when calling\n * `setPosition`, so that the overlay is entirely visible in the current viewport?\n * If `true` (deprecated), then `autoPanAnimation` and `autoPanMargin` will be\n * used to determine the panning parameters; if an object is supplied then other\n * parameters are ignored.\n * @property {PanOptions} [autoPanAnimation] The animation options used to pan\n * the overlay into view. This animation is only used when `autoPan` is enabled.\n * A `duration` and `easing` may be provided to customize the animation.\n * Deprecated and ignored if `autoPan` is supplied as an object.\n * @property {number} [autoPanMargin=20] The margin (in pixels) between the\n * overlay and the borders of the map when autopanning. Deprecated and ignored\n * if `autoPan` is supplied as an object.\n * @property {PanIntoViewOptions} [autoPanOptions] The options to use for the\n * autoPan. This is only used when `autoPan` is enabled and has preference over\n * the individual `autoPanMargin` and `autoPanOptions`.\n * @property {string} [className=\'ol-overlay-container ol-selectable\'] CSS class\n * name.\n */\n\n/**\n * @typedef {Object} PanOptions\n * @property {number} [duration=1000] The duration of the animation in\n * milliseconds.\n * @property {function(number):number} [easing] The easing function to use. Can\n * be one from {@link module:ol/easing} or a custom function.\n * Default is {@link module:ol/easing~inAndOut}.\n */\n\n/**\n * @typedef {Object} PanIntoViewOptions\n * @property {PanOptions} [animation={}] The animation parameters for the pan\n * @property {number} [margin=20] The margin (in pixels) between the\n * overlay and the borders of the map when panning into view.\n */\n\n/**\n * @enum {string}\n * @protected\n */\n\nvar Overlay_Property = {\n ELEMENT: \'element\',\n MAP: \'map\',\n OFFSET: \'offset\',\n POSITION: \'position\',\n POSITIONING: \'positioning\'\n};\n/**\n * @classdesc\n * An element to be displayed over the map and attached to a single map\n * location. Like {@link module:ol/control/Control~Control}, Overlays are\n * visible widgets. Unlike Controls, they are not in a fixed position on the\n * screen, but are tied to a geographical coordinate, so panning the map will\n * move an Overlay but not a Control.\n *\n * Example:\n *\n * import Overlay from \'ol/Overlay\';\n *\n * var popup = new Overlay({\n * element: document.getElementById(\'popup\')\n * });\n * popup.setPosition(coordinate);\n * map.addOverlay(popup);\n *\n * @api\n */\n\nvar Overlay =\n/** @class */\nfunction (_super) {\n Overlay_extends(Overlay, _super);\n /**\n * @param {Options} options Overlay options.\n */\n\n\n function Overlay(options) {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {Options}\n */\n\n\n _this.options = options;\n /**\n * @protected\n * @type {number|string|undefined}\n */\n\n _this.id = options.id;\n /**\n * @protected\n * @type {boolean}\n */\n\n _this.insertFirst = options.insertFirst !== undefined ? options.insertFirst : true;\n /**\n * @protected\n * @type {boolean}\n */\n\n _this.stopEvent = options.stopEvent !== undefined ? options.stopEvent : true;\n /**\n * @protected\n * @type {HTMLElement}\n */\n\n _this.element = document.createElement(\'div\');\n _this.element.className = options.className !== undefined ? options.className : \'ol-overlay-container \' + CLASS_SELECTABLE;\n _this.element.style.position = \'absolute\';\n _this.element.style.pointerEvents = \'auto\';\n var autoPan = options.autoPan;\n\n if (autoPan && \'object\' !== typeof autoPan) {\n autoPan = {\n animation: options.autoPanAnimation,\n margin: options.autoPanMargin\n };\n }\n /**\n * @protected\n * @type {PanIntoViewOptions|false}\n */\n\n\n _this.autoPan =\n /** @type {PanIntoViewOptions} */\n autoPan || false;\n /**\n * @protected\n * @type {{transform_: string,\n * visible: boolean}}\n */\n\n _this.rendered = {\n transform_: \'\',\n visible: true\n };\n /**\n * @protected\n * @type {?import("./events.js").EventsKey}\n */\n\n _this.mapPostrenderListenerKey = null;\n\n _this.addEventListener(getChangeEventType(Overlay_Property.ELEMENT), _this.handleElementChanged);\n\n _this.addEventListener(getChangeEventType(Overlay_Property.MAP), _this.handleMapChanged);\n\n _this.addEventListener(getChangeEventType(Overlay_Property.OFFSET), _this.handleOffsetChanged);\n\n _this.addEventListener(getChangeEventType(Overlay_Property.POSITION), _this.handlePositionChanged);\n\n _this.addEventListener(getChangeEventType(Overlay_Property.POSITIONING), _this.handlePositioningChanged);\n\n if (options.element !== undefined) {\n _this.setElement(options.element);\n }\n\n _this.setOffset(options.offset !== undefined ? options.offset : [0, 0]);\n\n _this.setPositioning(options.positioning !== undefined ?\n /** @type {import("./OverlayPositioning.js").default} */\n options.positioning : OverlayPositioning.TOP_LEFT);\n\n if (options.position !== undefined) {\n _this.setPosition(options.position);\n }\n\n return _this;\n }\n /**\n * Get the DOM element of this overlay.\n * @return {HTMLElement|undefined} The Element containing the overlay.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.getElement = function () {\n return (\n /** @type {HTMLElement|undefined} */\n this.get(Overlay_Property.ELEMENT)\n );\n };\n /**\n * Get the overlay identifier which is set on constructor.\n * @return {number|string|undefined} Id.\n * @api\n */\n\n\n Overlay.prototype.getId = function () {\n return this.id;\n };\n /**\n * Get the map associated with this overlay.\n * @return {import("./PluggableMap.js").default|undefined} The map that the\n * overlay is part of.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.getMap = function () {\n return (\n /** @type {import("./PluggableMap.js").default|undefined} */\n this.get(Overlay_Property.MAP)\n );\n };\n /**\n * Get the offset of this overlay.\n * @return {Array<number>} The offset.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.getOffset = function () {\n return (\n /** @type {Array<number>} */\n this.get(Overlay_Property.OFFSET)\n );\n };\n /**\n * Get the current position of this overlay.\n * @return {import("./coordinate.js").Coordinate|undefined} The spatial point that the overlay is\n * anchored at.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.getPosition = function () {\n return (\n /** @type {import("./coordinate.js").Coordinate|undefined} */\n this.get(Overlay_Property.POSITION)\n );\n };\n /**\n * Get the current positioning of this overlay.\n * @return {import("./OverlayPositioning.js").default} How the overlay is positioned\n * relative to its point on the map.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.getPositioning = function () {\n return (\n /** @type {import("./OverlayPositioning.js").default} */\n this.get(Overlay_Property.POSITIONING)\n );\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.handleElementChanged = function () {\n removeChildren(this.element);\n var element = this.getElement();\n\n if (element) {\n this.element.appendChild(element);\n }\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.handleMapChanged = function () {\n if (this.mapPostrenderListenerKey) {\n removeNode(this.element);\n unlistenByKey(this.mapPostrenderListenerKey);\n this.mapPostrenderListenerKey = null;\n }\n\n var map = this.getMap();\n\n if (map) {\n this.mapPostrenderListenerKey = listen(map, MapEventType.POSTRENDER, this.render, this);\n this.updatePixelPosition();\n var container = this.stopEvent ? map.getOverlayContainerStopEvent() : map.getOverlayContainer();\n\n if (this.insertFirst) {\n container.insertBefore(this.element, container.childNodes[0] || null);\n } else {\n container.appendChild(this.element);\n }\n\n this.performAutoPan();\n }\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.render = function () {\n this.updatePixelPosition();\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.handleOffsetChanged = function () {\n this.updatePixelPosition();\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.handlePositionChanged = function () {\n this.updatePixelPosition();\n this.performAutoPan();\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.handlePositioningChanged = function () {\n this.updatePixelPosition();\n };\n /**\n * Set the DOM element to be associated with this overlay.\n * @param {HTMLElement|undefined} element The Element containing the overlay.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.setElement = function (element) {\n this.set(Overlay_Property.ELEMENT, element);\n };\n /**\n * Set the map to be associated with this overlay.\n * @param {import("./PluggableMap.js").default|undefined} map The map that the\n * overlay is part of.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.setMap = function (map) {\n this.set(Overlay_Property.MAP, map);\n };\n /**\n * Set the offset for this overlay.\n * @param {Array<number>} offset Offset.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.setOffset = function (offset) {\n this.set(Overlay_Property.OFFSET, offset);\n };\n /**\n * Set the position for this overlay. If the position is `undefined` the\n * overlay is hidden.\n * @param {import("./coordinate.js").Coordinate|undefined} position The spatial point that the overlay\n * is anchored at.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.setPosition = function (position) {\n this.set(Overlay_Property.POSITION, position);\n };\n /**\n * Pan the map so that the overlay is entirely visisble in the current viewport\n * (if necessary) using the configured autoPan parameters\n * @protected\n */\n\n\n Overlay.prototype.performAutoPan = function () {\n if (this.autoPan) {\n this.panIntoView(this.autoPan);\n }\n };\n /**\n * Pan the map so that the overlay is entirely visible in the current viewport\n * (if necessary).\n * @param {PanIntoViewOptions=} opt_panIntoViewOptions Options for the pan action\n * @api\n */\n\n\n Overlay.prototype.panIntoView = function (opt_panIntoViewOptions) {\n var map = this.getMap();\n\n if (!map || !map.getTargetElement() || !this.get(Overlay_Property.POSITION)) {\n return;\n }\n\n var mapRect = this.getRect(map.getTargetElement(), map.getSize());\n var element = this.getElement();\n var overlayRect = this.getRect(element, [dom_outerWidth(element), dom_outerHeight(element)]);\n var panIntoViewOptions = opt_panIntoViewOptions || {};\n var myMargin = panIntoViewOptions.margin === undefined ? 20 : panIntoViewOptions.margin;\n\n if (!containsExtent(mapRect, overlayRect)) {\n // the overlay is not completely inside the viewport, so pan the map\n var offsetLeft = overlayRect[0] - mapRect[0];\n var offsetRight = mapRect[2] - overlayRect[2];\n var offsetTop = overlayRect[1] - mapRect[1];\n var offsetBottom = mapRect[3] - overlayRect[3];\n var delta = [0, 0];\n\n if (offsetLeft < 0) {\n // move map to the left\n delta[0] = offsetLeft - myMargin;\n } else if (offsetRight < 0) {\n // move map to the right\n delta[0] = Math.abs(offsetRight) + myMargin;\n }\n\n if (offsetTop < 0) {\n // move map up\n delta[1] = offsetTop - myMargin;\n } else if (offsetBottom < 0) {\n // move map down\n delta[1] = Math.abs(offsetBottom) + myMargin;\n }\n\n if (delta[0] !== 0 || delta[1] !== 0) {\n var center =\n /** @type {import("./coordinate.js").Coordinate} */\n map.getView().getCenterInternal();\n var centerPx = map.getPixelFromCoordinateInternal(center);\n\n if (!centerPx) {\n return;\n }\n\n var newCenterPx = [centerPx[0] + delta[0], centerPx[1] + delta[1]];\n var panOptions = panIntoViewOptions.animation || {};\n map.getView().animateInternal({\n center: map.getCoordinateFromPixelInternal(newCenterPx),\n duration: panOptions.duration,\n easing: panOptions.easing\n });\n }\n }\n };\n /**\n * Get the extent of an element relative to the document\n * @param {HTMLElement} element The element.\n * @param {import("./size.js").Size} size The size of the element.\n * @return {import("./extent.js").Extent} The extent.\n * @protected\n */\n\n\n Overlay.prototype.getRect = function (element, size) {\n var box = element.getBoundingClientRect();\n var offsetX = box.left + window.pageXOffset;\n var offsetY = box.top + window.pageYOffset;\n return [offsetX, offsetY, offsetX + size[0], offsetY + size[1]];\n };\n /**\n * Set the positioning for this overlay.\n * @param {import("./OverlayPositioning.js").default} positioning how the overlay is\n * positioned relative to its point on the map.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.setPositioning = function (positioning) {\n this.set(Overlay_Property.POSITIONING, positioning);\n };\n /**\n * Modify the visibility of the element.\n * @param {boolean} visible Element visibility.\n * @protected\n */\n\n\n Overlay.prototype.setVisible = function (visible) {\n if (this.rendered.visible !== visible) {\n this.element.style.display = visible ? \'\' : \'none\';\n this.rendered.visible = visible;\n }\n };\n /**\n * Update pixel position.\n * @protected\n */\n\n\n Overlay.prototype.updatePixelPosition = function () {\n var map = this.getMap();\n var position = this.getPosition();\n\n if (!map || !map.isRendered() || !position) {\n this.setVisible(false);\n return;\n }\n\n var pixel = map.getPixelFromCoordinate(position);\n var mapSize = map.getSize();\n this.updateRenderedPosition(pixel, mapSize);\n };\n /**\n * @param {import("./pixel.js").Pixel} pixel The pixel location.\n * @param {import("./size.js").Size|undefined} mapSize The map size.\n * @protected\n */\n\n\n Overlay.prototype.updateRenderedPosition = function (pixel, mapSize) {\n var style = this.element.style;\n var offset = this.getOffset();\n var positioning = this.getPositioning();\n this.setVisible(true);\n var x = Math.round(pixel[0] + offset[0]) + \'px\';\n var y = Math.round(pixel[1] + offset[1]) + \'px\';\n var posX = \'0%\';\n var posY = \'0%\';\n\n if (positioning == OverlayPositioning.BOTTOM_RIGHT || positioning == OverlayPositioning.CENTER_RIGHT || positioning == OverlayPositioning.TOP_RIGHT) {\n posX = \'-100%\';\n } else if (positioning == OverlayPositioning.BOTTOM_CENTER || positioning == OverlayPositioning.CENTER_CENTER || positioning == OverlayPositioning.TOP_CENTER) {\n posX = \'-50%\';\n }\n\n if (positioning == OverlayPositioning.BOTTOM_LEFT || positioning == OverlayPositioning.BOTTOM_CENTER || positioning == OverlayPositioning.BOTTOM_RIGHT) {\n posY = \'-100%\';\n } else if (positioning == OverlayPositioning.CENTER_LEFT || positioning == OverlayPositioning.CENTER_CENTER || positioning == OverlayPositioning.CENTER_RIGHT) {\n posY = \'-50%\';\n }\n\n var transform = "translate(" + posX + ", " + posY + ") translate(" + x + ", " + y + ")";\n\n if (this.rendered.transform_ != transform) {\n this.rendered.transform_ = transform;\n style.transform = transform; // @ts-ignore IE9\n\n style.msTransform = transform;\n }\n };\n /**\n * returns the options this Overlay has been created with\n * @return {Options} overlay options\n */\n\n\n Overlay.prototype.getOptions = function () {\n return this.options;\n };\n\n return Overlay;\n}(ol_Object);\n\n/* harmony default export */ var ol_Overlay = (Overlay);\n;// CONCATENATED MODULE: ./src/components/map.tsx\n// import olms from \'ol-mapbox-style\';\n;// The below adapted from\n// https://taylor.callsen.me/using-openlayers-with-react-functional-components/\nvar MapWrapper=function MapWrapper(_ref){var features=_ref.features;var _useState=(0,react.useState)(),map=_useState[0],setMap=_useState[1];var _useState2=(0,react.useState)(),currentOverlay=_useState2[0],setCurrentOverlay=_useState2[1];var _useState3=(0,react.useState)(),featuresLayer=_useState3[0],setFeaturesLayer=_useState3[1];var _useState4=(0,react.useState)(),selectedFeature=_useState4[0],setSelectedFeature=_useState4[1];var _useState5=(0,react.useState)(),hoveredFeature=_useState5[0],setHoveredFeature=_useState5[1];var _useState6=(0,react.useState)(),selectedCoord=_useState6[0],setSelectedCoord=_useState6[1];var mapElement=(0,react.useRef)();var mapRef=(0,react.useRef)();var popupContainer=react.useRef(null);var popupCloser=react.useRef(null);var popupContent=react.useRef(null);var overlayRef=(0,react.useRef)();mapRef.current=map;overlayRef.current=currentOverlay;(0,react.useEffect)(function(){// create and add initial vector source layer, to be replaced layer\nvar initialFeaturesLayer=new Vector({source:new source_Vector()});var j40source=new source_VectorTile({\'format\':new format_MVT(),\'url\':\'http://localhost:8080/data/block2010/{z}/{x}/{y}.pbf\'// \'url\': \'http://usds-geoplatform-justice40-website.s3-website-us-east-1.amazonaws.com/nm/{z}/{x}/{y}.pbf\',\n});var colors=sequential(Blues).domain([0,1]);// d3.scaleOrdinal(d3.interpolateBlues);\nvar j40Layer=new VectorTile({declutter:false,source:j40source,style:function style(feature){var data=feature.get(\'score_a_percentile\');var colorString;if(data){var rgb=colors(data);var rbgArr=rgb.slice(rgb.indexOf(\'(\')+1,rgb.indexOf(\')\')).split(\', \');colorString="rgba("+rbgArr[0]+", "+rbgArr[1]+", "+rbgArr[2]+", 0.5)";}else{colorString=\'white\';}// const inOrOut = feature.get(\'score_a_top_percentile_25\');\nreturn new style_Style({fill:new style_Fill({color:colorString// inOrOut == \'True\' ? \'blue\' : \'white\',\n})});}});popupCloser.current.onclick=function(){overlay.setPosition(undefined);popupCloser.current.blur();return false;};var overlay=new ol_Overlay({element:popupContainer.current,autoPan:true,autoPanAnimation:{duration:250}});var initialMap=new ol_Map({target:mapElement.current,view:new ol_View({center:fromLonLat([-86.502136,32.4687126]),zoom:4}),layers:[new Tile({source:new source_XYZ({url:\'https://{1-4}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png\'})}),j40Layer],controls:[],overlays:[overlay]});initialMap.on(\'click\',handleMapClick);initialMap.on(\'pointermove\',handlePointerMove);setMap(initialMap);setCurrentOverlay(overlay);setFeaturesLayer(initialFeaturesLayer);// olms(initialMap, mapConfig);\n},[]);// update map if features prop changes\n(0,react.useEffect)(function(){if(features.length){// may be empty on first render\n// set features to map\nfeaturesLayer===null||featuresLayer===void 0?void 0:featuresLayer.setSource(new source_Vector({features:features}));var extent=featuresLayer===null||featuresLayer===void 0?void 0:featuresLayer.getSource().getExtent();if(extent!=null){// fit map to feature extent (with 100px of padding)\nmap===null||map===void 0?void 0:map.getView().fit(extent,{padding:[100,100,100,100]});}}},[features]);var handleMapClick=function handleMapClick(event){// get clicked coordinate using mapRef to access current React state inside OpenLayers callback\n// https://stackoverflow.com/a/60643670\nvar clickedCoord=mapRef.current.getCoordinateFromPixel(event.pixel);// transform coord to EPSG 4326 standard Lat Long\nvar transformedCoord=transform(clickedCoord,\'EPSG:3857\',\'EPSG:4326\');// set React state\nsetSelectedCoord(transformedCoord);mapRef.current.forEachFeatureAtPixel(event.pixel,function(feature){setSelectedFeature(feature);return true;});overlayRef.current.setPosition(clickedCoord);};var handlePointerMove=function handlePointerMove(event){if(hoveredFeature!==undefined){hoveredFeature===null||hoveredFeature===void 0?void 0:hoveredFeature.setStyle(undefined);setHoveredFeature(undefined);}mapRef.current.forEachFeatureAtPixel(event.pixel,function(feature){setHoveredFeature(feature);return true;});};var readablePercent=function readablePercent(percent){return parseFloat(percent*100).toFixed(2)+"%";};return/*#__PURE__*/react.createElement(react.Fragment,null,/*#__PURE__*/react.createElement("div",{ref:mapElement,className:mapContainer}),/*#__PURE__*/react.createElement("div",{className:"clicked-coord-label"},/*#__PURE__*/react.createElement("p",null,hoveredFeature?readablePercent(hoveredFeature.properties_[\'score_a_percentile\']):\'\'),/*#__PURE__*/react.createElement("p",null,selectedCoord?toStringXY(selectedCoord,5):\'\'),/*#__PURE__*/react.createElement("div",{ref:popupContainer,className:map_module_popupContainer},/*#__PURE__*/react.createElement("a",{href:"#",ref:popupCloser,className:map_module_popupCloser}),/*#__PURE__*/react.createElement("div",{ref:popupContent,className:map_module_namespaceObject.popupContent},selectedFeature?/*#__PURE__*/react.createElement("div",null,/*#__PURE__*/react.createElement("h2",null,"JustProgress Score:"),/*#__PURE__*/react.createElement("h3",null,readablePercent(selectedFeature.properties_[\'score_a_percentile\']))):\'\'))));};/* harmony default export */ var components_map = (MapWrapper);\n;// CONCATENATED MODULE: ./src/components/HowYouCanHelp.module.scss\n// extracted by mini-css-extract-plugin\nvar howYouCanHelpContainer = "HowYouCanHelp-module--howYouCanHelpContainer--2kqBa";\n;// CONCATENATED MODULE: ./src/components/HowYouCanHelp.tsx\nvar HowYouCanHelp=function HowYouCanHelp(){return/*#__PURE__*/react.createElement("div",{className:howYouCanHelpContainer},/*#__PURE__*/react.createElement("h2",null,"How You Can Help Improve the Tool"),/*#__PURE__*/react.createElement("ul",null,/*#__PURE__*/react.createElement("li",null,"If you have information that could help, we\\u2019d love to hear from you."),/*#__PURE__*/react.createElement("li",null,"View our full set of data sources and methodology where you can add or download sources and check statuses on our data roadmap."),/*#__PURE__*/react.createElement("li",null,"Check out our timeline and send feedback or attend relevant events."),/*#__PURE__*/react.createElement("li",null,"Contact us and share the stories of your community.")));};/* harmony default export */ var components_HowYouCanHelp = (HowYouCanHelp);\n// EXTERNAL MODULE: ./node_modules/@trussworks/react-uswds/lib/index.js\nvar lib = __webpack_require__(2593);\n;// CONCATENATED MODULE: ./src/pages/cejst.module.scss\n// extracted by mini-css-extract-plugin\nvar disclaimer = "cejst-module--disclaimer--3LC1y";\n;// CONCATENATED MODULE: ./src/pages/cejst.tsx\n// import MapControls from \'../components/mapControls\';\nvar CEJSTPage=function CEJSTPage(_ref){var location=_ref.location;var _useState=(0,react.useState)([]),features=_useState[0];return/*#__PURE__*/react.createElement(layout/* default */.Z,{location:location},/*#__PURE__*/react.createElement("main",{id:"main-content",role:"main"},/*#__PURE__*/react.createElement("p",{className:disclaimer},"The Climate and Economic Justice Screening Tool helps identify and prioritize communities across the United States and US territories that have been historically overburdened and underserved so that they may receive 40% of the benefits from investments in six key areas as outlined in the ",/*#__PURE__*/react.createElement("a",{href:\'https://www.whitehouse.gov/briefing-room/\'+\'presidential-actions/2021/01/27/\'+\'executive-order-on-tackling-the-climate-\'+\'crisis-at-home-and-abroad/\',target:\'_blank\',rel:\'noreferrer\'},"Executive Order on Tackling the Climate Crisis at Home and Abroad"),". Explore the map below or learn more about the methodology and data indicators used to prioritize Justice40 communities."),/*#__PURE__*/react.createElement(lib.Alert,{type:"warning",heading:"Limited Data Sources"},/*#__PURE__*/react.createElement("p",null,"In this tool, we are using data sources that our combined by our cumulative impact methodology. Our sources were selected because sit amet, consectetur adipiscing. See all the sources we are investigating on our data roadmap.")),/*#__PURE__*/react.createElement(components_map,{features:features}),/*#__PURE__*/react.createElement(components_HowYouCanHelp,null)));};/* harmony default export */ var cejst = (CEJSTPage);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9EaXNwb3NhYmxlLmpzP2I0NDIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvYXJyYXkuanM/ZjQyZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9mdW5jdGlvbnMuanM/YTRlZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC91dGlsLmpzP2FkNjUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvQXNzZXJ0aW9uRXJyb3IuanM/YzE5YyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9hc3NlcnRzLmpzPzdlYWUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvdHJhbnNmb3JtLmpzPzllZGQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZXh0ZW50L0Nvcm5lci5qcz8xMzJjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2V4dGVudC9SZWxhdGlvbnNoaXAuanM/NWY0NiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9leHRlbnQuanM/YWI5ZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9tYXRoLmpzPzQwODMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvY29sb3IuanM/ZWEzOSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zdHlsZS9JY29uSW1hZ2VDYWNoZS5qcz8yODdjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2V2ZW50cy9FdmVudC5qcz8yMzA2Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL09iamVjdEV2ZW50VHlwZS5qcz8zM2FkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL29iai5qcz9jM2M5Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2V2ZW50cy9UYXJnZXQuanM/M2Y3YyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9ldmVudHMvRXZlbnRUeXBlLmpzPzc0NmYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZXZlbnRzLmpzP2ZiMmMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvT2JzZXJ2YWJsZS5qcz83MDRkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL09iamVjdC5qcz8zM2FiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL1Byb3BlcnR5LmpzPzA3OTkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvbGF5ZXIvQmFzZS5qcz9lMjBmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9FdmVudFR5cGUuanM/NDYyMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zb3VyY2UvU3RhdGUuanM/NTM5NCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9sYXllci9MYXllci5qcz9hMjUyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2Nvb3JkaW5hdGUuanM/OGVjZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXJlci9NYXAuanM/NDAwYiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvRXZlbnQuanM/N2Y0ZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9jc3MuanM/NDcwMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9oYXMuanM/ZGMwMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9kb20uanM/YzQxYSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzLmpzPzkxZTkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVuZGVyZXIvQ29tcG9zaXRlLmpzPzc2NWMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvQ29sbGVjdGlvbkV2ZW50VHlwZS5qcz81YzJkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL0NvbGxlY3Rpb24uanM/MzA1ZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9sYXllci9Hcm91cC5qcz85ZDBiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL01hcEV2ZW50LmpzPzcxYmYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvTWFwQnJvd3NlckV2ZW50LmpzPzY0NjUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvTWFwQnJvd3NlckV2ZW50VHlwZS5qcz83M2RkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3BvaW50ZXIvRXZlbnRUeXBlLmpzP2NiMDYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvTWFwQnJvd3NlckV2ZW50SGFuZGxlci5qcz9kMGMxIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL01hcEV2ZW50VHlwZS5qcz8xNjUzIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL01hcFByb3BlcnR5LmpzP2ZkOWQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc3RydWN0cy9Qcmlvcml0eVF1ZXVlLmpzP2Y2MTAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvVGlsZVN0YXRlLmpzP2MzMGYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvVGlsZVF1ZXVlLmpzPzk3OTUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9HZW9tZXRyeVR5cGUuanM/MmQyMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9wcm9qL1VuaXRzLmpzPzA1MmYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvVmlld0hpbnQuanM/NWRkZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9WaWV3UHJvcGVydHkuanM/YTI1ZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC90aWxlZ3JpZC9jb21tb24uanM/OTQwZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9wcm9qL1Byb2plY3Rpb24uanM/MjM4MCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9wcm9qL2Vwc2czODU3LmpzPzZlMDAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcHJvai9lcHNnNDMyNi5qcz84ODY3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3Byb2ovcHJvamVjdGlvbnMuanM/ZDUzMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9wcm9qL3RyYW5zZm9ybXMuanM/ZmMxNiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zcGhlcmUuanM/ZmIzMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9wcm9qLmpzP2UxZTQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvY2VudGVyY29uc3RyYWludC5qcz9mMjgyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3Jlc29sdXRpb25jb25zdHJhaW50LmpzPzcyYzYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcm90YXRpb25jb25zdHJhaW50LmpzP2I1MDgiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZWFzaW5nLmpzPzkxYzUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9HZW9tZXRyeUxheW91dC5qcz9lZjU4Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC90cmFuc2Zvcm0uanM/MzQ2MyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL0dlb21ldHJ5LmpzPzc1MjIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9TaW1wbGVHZW9tZXRyeS5qcz9iMDQwIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9jbG9zZXN0LmpzPzA1MjIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L2RlZmxhdGUuanM/OTI3OSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL2ZsYXQvc2ltcGxpZnkuanM/ZTdlYiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL2ZsYXQvaW5mbGF0ZS5qcz8yZDk1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9hcmVhLmpzPzUwZWYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9MaW5lYXJSaW5nLmpzPzc3NGYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9Qb2ludC5qcz9mMGFjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9jb250YWlucy5qcz9lNmUyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9pbnRlcmlvcnBvaW50LmpzPzg3NDUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L3NlZ21lbnRzLmpzP2ZhMGMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L2ludGVyc2VjdHNleHRlbnQuanM/NTU5MSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL2ZsYXQvcmV2ZXJzZS5qcz80MWNmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9vcmllbnQuanM/OWZmMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL1BvbHlnb24uanM/MDc5OCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9WaWV3LmpzP2QxOTciLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc2l6ZS5qcz8xMzE1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL1BsdWdnYWJsZU1hcC5qcz83YTNhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2NvbnRyb2wvQ29udHJvbC5qcz9iNzJhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2NvbnRyb2wvQXR0cmlidXRpb24uanM/ZTk2NCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9jb250cm9sL1JvdGF0ZS5qcz9mNGI1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2NvbnRyb2wvWm9vbS5qcz8xYTFhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2NvbnRyb2wuanM/MjJhMSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9pbnRlcmFjdGlvbi9Qcm9wZXJ0eS5qcz8yZDgxIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2ludGVyYWN0aW9uL0ludGVyYWN0aW9uLmpzPzM5MmQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vRG91YmxlQ2xpY2tab29tLmpzPzQ1YmQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vUG9pbnRlci5qcz80OTBjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2V2ZW50cy9jb25kaXRpb24uanM/YzgyYiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9pbnRlcmFjdGlvbi9EcmFnUGFuLmpzP2RkYWQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vRHJhZ1JvdGF0ZS5qcz8yMjg4Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9Cb3guanM/OTdiZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9pbnRlcmFjdGlvbi9EcmFnQm94LmpzPzlmMjAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vRHJhZ1pvb20uanM/MmJjZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9ldmVudHMvS2V5Q29kZS5qcz85NWNmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2ludGVyYWN0aW9uL0tleWJvYXJkUGFuLmpzPzhhMWIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vS2V5Ym9hcmRab29tLmpzPzEzMjEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvS2luZXRpYy5qcz9mZTBiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2ludGVyYWN0aW9uL01vdXNlV2hlZWxab29tLmpzP2ZhYjEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vUGluY2hSb3RhdGUuanM/YjYwZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9pbnRlcmFjdGlvbi9QaW5jaFpvb20uanM/MjZiMCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9pbnRlcmFjdGlvbi5qcz82MDVmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL01hcC5qcz8xMzdjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL0ltYWdlU3RhdGUuanM/ZmQ2MSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zdHlsZS9JbWFnZS5qcz9lNDAyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2NvbG9ybGlrZS5qcz9iZjJiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL1JlZ3VsYXJTaGFwZS5qcz8zNjliIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0NpcmNsZS5qcz8xY2E3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0ZpbGwuanM/MDRlMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zdHlsZS9TdHJva2UuanM/NDU4OSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zdHlsZS9TdHlsZS5qcz85YTRhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL0Jhc2VWZWN0b3IuanM/MWQ2NyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0luc3RydWN0aW9uLmpzP2I3MzAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVuZGVyL1ZlY3RvckNvbnRleHQuanM/OWVjOCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0J1aWxkZXIuanM/ZjZkMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0ltYWdlQnVpbGRlci5qcz85NmYwIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9jYW52YXMvTGluZVN0cmluZ0J1aWxkZXIuanM/MzVhMCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL1BvbHlnb25CdWlsZGVyLmpzP2E1YWYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc3R5bGUvVGV4dFBsYWNlbWVudC5qcz85YjZkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9zdHJhaWdodGNodW5rLmpzPzUxZDIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVuZGVyL2NhbnZhcy9UZXh0QnVpbGRlci5qcz9kZTBkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzP2JjNjUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVuZGVyZXIvTGF5ZXIuanM/MjgzMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXJlci9jYW52YXMvTGF5ZXIuanM/MmVlNCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0J1aWxkZXJUeXBlLmpzPzkyMjciLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L3RleHRwYXRoLmpzP2Q0MTAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L2xlbmd0aC5qcz9mMDJiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9jYW52YXMvRXhlY3V0b3IuanM/YWFmMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0V4ZWN1dG9yR3JvdXAuanM/ODIyZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0ltbWVkaWF0ZS5qcz9kZmZiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0ljb25BbmNob3JVbml0cy5qcz9kNGQzIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0ljb25PcmlnaW4uanM/YWY5YyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9JbWFnZUJhc2UuanM/NzRiZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9JbWFnZS5qcz8yYTlkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0ljb25JbWFnZS5qcz9kNDAxIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0ljb24uanM/MjUxMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL2hpdGRldGVjdC5qcz8xNzA3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlcmVyL3ZlY3Rvci5qcz83MDY1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlcmVyL2NhbnZhcy9WZWN0b3JMYXllci5qcz81MzVlIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL1ZlY3Rvci5qcz9jODBjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0cnVjdHMvUkJ1c2guanM/MzEyNyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zb3VyY2UvU291cmNlLmpzP2U0YzkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc291cmNlL1ZlY3RvckV2ZW50VHlwZS5qcz83NTlhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xvYWRpbmdzdHJhdGVneS5qcz84OWVjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2Zvcm1hdC9Gb3JtYXRUeXBlLmpzPzExYjgiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZmVhdHVyZWxvYWRlci5qcz9lYzUyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3NvdXJjZS9WZWN0b3IuanM/YTZmZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9jb21wb25lbnRzL21hcC5tb2R1bGUuc2Nzcz9jYThkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL1RpbGVQcm9wZXJ0eS5qcz80NGY0Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL0Jhc2VUaWxlLmpzPzgwN2MiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvVGlsZVJhbmdlLmpzPzZkNmYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVuZGVyZXIvY2FudmFzL1RpbGVMYXllci5qcz9kYjI4Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL1RpbGUuanM/YWUxZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9sYXllci9WZWN0b3JUaWxlUmVuZGVyVHlwZS5qcz81NjUyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlcmVyL2NhbnZhcy9WZWN0b3JUaWxlTGF5ZXIuanM/ODAyNyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9sYXllci9WZWN0b3JUaWxlLmpzP2Q5YWUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvVGlsZS5qcz85MzEwIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL1ZlY3RvclRpbGUuanM/YzcyNCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zdHJ1Y3RzL0xSVUNhY2hlLmpzP2Y0YzUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvdGlsZWNvb3JkLmpzPzU1ZmQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvVGlsZUNhY2hlLmpzP2IxMmIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc291cmNlL1RpbGVFdmVudFR5cGUuanM/ZjhmNCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC90aWxlZ3JpZC9UaWxlR3JpZC5qcz9mN2ZkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3RpbGVncmlkLmpzP2VjNGUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc291cmNlL1RpbGUuanM/MDBlNSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC90aWxldXJsZnVuY3Rpb24uanM/OTVhNyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zb3VyY2UvVXJsVGlsZS5qcz82MDRmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL1ZlY3RvclJlbmRlclRpbGUuanM/ODc5NSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zb3VyY2UvVmVjdG9yVGlsZS5qcz8xYThjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2Zvcm1hdC9GZWF0dXJlLmpzPzA4MDUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L2ludGVycG9sYXRlLmpzPzcyNWEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9MaW5lU3RyaW5nLmpzPzMyMTAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9NdWx0aUxpbmVTdHJpbmcuanM/MGFkYSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL011bHRpUG9pbnQuanM/NjMwNyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL2ZsYXQvY2VudGVyLmpzPzY2NDkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9NdWx0aVBvbHlnb24uanM/NDMxNSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvRmVhdHVyZS5qcz83MjdkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2Zvcm1hdC9NVlQuanM/ZmE5ZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9JbWFnZVRpbGUuanM/Y2ZiZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZXByb2ovY29tbW9uLmpzP2QxNTIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVwcm9qL1RyaWFuZ3VsYXRpb24uanM/ZDkxMSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zb3VyY2UvY29tbW9uLmpzPzEwNTYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVwcm9qLmpzPzEzNTgiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVwcm9qL1RpbGUuanM/MGYwMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zb3VyY2UvVGlsZUltYWdlLmpzPzY2ODQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc291cmNlL1hZWi5qcz85OWExIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0b3IuanM/NmQxYyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9zZWxlY3QuanM/MzdlZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL2FycmF5LmpzP2M5NmIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9zZWxlY3RvckFsbC5qcz8xM2VjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL3NlbGVjdEFsbC5qcz8zY2YzIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvbWF0Y2hlci5qcz9lZjc3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL3NlbGVjdENoaWxkLmpzPzkzZTIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9zZWxlY3Rpb24vc2VsZWN0Q2hpbGRyZW4uanM/Yzk5ZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9maWx0ZXIuanM/YzMxZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9zcGFyc2UuanM/MTYyOCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9lbnRlci5qcz83YTU2Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvY29uc3RhbnQuanM/OTdjZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9kYXRhLmpzP2NkM2YiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9zZWxlY3Rpb24vZXhpdC5qcz9lZjZmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL2pvaW4uanM/NDc1YyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9tZXJnZS5qcz9kNzliIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL29yZGVyLmpzPzA0YWMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9zZWxlY3Rpb24vc29ydC5qcz80Njk0Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL2NhbGwuanM/MDY5OSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9ub2Rlcy5qcz83YjY0Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL25vZGUuanM/OTZmMSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9zaXplLmpzPzIwZmQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9zZWxlY3Rpb24vZW1wdHkuanM/MGZlMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9lYWNoLmpzPzYyNGUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9uYW1lc3BhY2VzLmpzP2IyMWMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9uYW1lc3BhY2UuanM/ODY5YiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9hdHRyLmpzP2UxMWUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy93aW5kb3cuanM/NWZlMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9zdHlsZS5qcz82NWJjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL3Byb3BlcnR5LmpzP2MzNmEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9zZWxlY3Rpb24vY2xhc3NlZC5qcz8zYTcyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL3RleHQuanM/NzA0OCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9odG1sLmpzP2M5YzYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9zZWxlY3Rpb24vcmFpc2UuanM/OTYzOCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9sb3dlci5qcz82MWU2Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvY3JlYXRvci5qcz9lMWU0Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL2FwcGVuZC5qcz84OWE5Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL2luc2VydC5qcz83ODc1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL3JlbW92ZS5qcz83YTg1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL2Nsb25lLmpzP2UwMzYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9zZWxlY3Rpb24vZGF0dW0uanM/MjBkZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9vbi5qcz85Njk5Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNlbGVjdGlvbi9zcmMvc2VsZWN0aW9uL2Rpc3BhdGNoLmpzP2U4MzMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL3NyYy9zZWxlY3Rpb24vaXRlcmF0b3IuanM/ZGZiNSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zZWxlY3Rpb24vc3JjL3NlbGVjdGlvbi9pbmRleC5qcz9jZjQyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWRpc3BhdGNoL3NyYy9kaXNwYXRjaC5qcz8yODc1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRpbWVyL3NyYy90aW1lci5qcz9mMDYyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRpbWVyL3NyYy90aW1lb3V0LmpzPzkxZDMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvdHJhbnNpdGlvbi9zY2hlZHVsZS5qcz82NWFlIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRyYW5zaXRpb24vc3JjL2ludGVycnVwdC5qcz9jYjRmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRyYW5zaXRpb24vc3JjL3NlbGVjdGlvbi9pbnRlcnJ1cHQuanM/ZTFhOSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1pbnRlcnBvbGF0ZS9zcmMvbnVtYmVyLmpzP2M2MzIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtaW50ZXJwb2xhdGUvc3JjL3RyYW5zZm9ybS9kZWNvbXBvc2UuanM/YmVlYyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1pbnRlcnBvbGF0ZS9zcmMvdHJhbnNmb3JtL3BhcnNlLmpzPzMxM2UiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtaW50ZXJwb2xhdGUvc3JjL3RyYW5zZm9ybS9pbmRleC5qcz81Y2IzIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRyYW5zaXRpb24vc3JjL3RyYW5zaXRpb24vdHdlZW4uanM/MzUwMCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1jb2xvci9zcmMvZGVmaW5lLmpzPzllNGEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtY29sb3Ivc3JjL2NvbG9yLmpzPzI2YTEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtaW50ZXJwb2xhdGUvc3JjL2Jhc2lzLmpzP2Y4OGEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtaW50ZXJwb2xhdGUvc3JjL2Jhc2lzQ2xvc2VkLmpzP2ZkNjIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtaW50ZXJwb2xhdGUvc3JjL2NvbnN0YW50LmpzP2E3YmUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtaW50ZXJwb2xhdGUvc3JjL2NvbG9yLmpzPzU4YjUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtaW50ZXJwb2xhdGUvc3JjL3JnYi5qcz9hY2Y5Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWludGVycG9sYXRlL3NyYy9zdHJpbmcuanM/OTFjOCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy10cmFuc2l0aW9uL3NyYy90cmFuc2l0aW9uL2ludGVycG9sYXRlLmpzPzBiOWEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvdHJhbnNpdGlvbi9hdHRyLmpzP2Q5MGUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvdHJhbnNpdGlvbi9hdHRyVHdlZW4uanM/ZjFlZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy10cmFuc2l0aW9uL3NyYy90cmFuc2l0aW9uL2RlbGF5LmpzP2U3YzEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvdHJhbnNpdGlvbi9kdXJhdGlvbi5qcz9jMGYzIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRyYW5zaXRpb24vc3JjL3RyYW5zaXRpb24vZWFzZS5qcz80ZGZhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRyYW5zaXRpb24vc3JjL3RyYW5zaXRpb24vZWFzZVZhcnlpbmcuanM/M2EzOSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy10cmFuc2l0aW9uL3NyYy90cmFuc2l0aW9uL2ZpbHRlci5qcz85YTU4Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRyYW5zaXRpb24vc3JjL3RyYW5zaXRpb24vbWVyZ2UuanM/OGM5MiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy10cmFuc2l0aW9uL3NyYy90cmFuc2l0aW9uL29uLmpzP2ZhYzgiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvdHJhbnNpdGlvbi9yZW1vdmUuanM/Yjg2YiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy10cmFuc2l0aW9uL3NyYy90cmFuc2l0aW9uL3NlbGVjdC5qcz8yNDU5Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRyYW5zaXRpb24vc3JjL3RyYW5zaXRpb24vc2VsZWN0QWxsLmpzP2Q5ZGEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvdHJhbnNpdGlvbi9zZWxlY3Rpb24uanM/NmE4MCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy10cmFuc2l0aW9uL3NyYy90cmFuc2l0aW9uL3N0eWxlLmpzPzNlNDAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvdHJhbnNpdGlvbi9zdHlsZVR3ZWVuLmpzPzM3OWIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvdHJhbnNpdGlvbi90ZXh0LmpzPzkzYWUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvdHJhbnNpdGlvbi90ZXh0VHdlZW4uanM/YTU5NiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy10cmFuc2l0aW9uL3NyYy90cmFuc2l0aW9uL3RyYW5zaXRpb24uanM/NWVjNiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy10cmFuc2l0aW9uL3NyYy90cmFuc2l0aW9uL2VuZC5qcz8zN2I5Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRyYW5zaXRpb24vc3JjL3RyYW5zaXRpb24vaW5kZXguanM/NjIyMCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1lYXNlL3NyYy9jdWJpYy5qcz9lNDJkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXRyYW5zaXRpb24vc3JjL3NlbGVjdGlvbi90cmFuc2l0aW9uLmpzPzI2YjkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvc2VsZWN0aW9uL2luZGV4LmpzPzM5MjEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtdHJhbnNpdGlvbi9zcmMvaW5kZXguanM/N2NlNSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1icnVzaC9zcmMvYnJ1c2guanM/NWVhMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hcnJheVdpdGhIb2xlcy5qcz8wZDIxIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2l0ZXJhYmxlVG9BcnJheUxpbWl0LmpzPzA5ZjAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vbm9uSXRlcmFibGVSZXN0LmpzPzNkOGMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheS5qcz8zODM1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWludGVycG9sYXRlL3NyYy9hcnJheS5qcz9jODc1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWludGVycG9sYXRlL3NyYy9kYXRlLmpzPzEwMzQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtaW50ZXJwb2xhdGUvc3JjL29iamVjdC5qcz8wOWZhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWludGVycG9sYXRlL3NyYy9udW1iZXJBcnJheS5qcz8wNDhiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWludGVycG9sYXRlL3NyYy92YWx1ZS5qcz81MmM3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWludGVycG9sYXRlL3NyYy9yb3VuZC5qcz8wOWZhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNjYWxlL3NyYy9jb250aW51b3VzLmpzPzgyNDIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2NhbGUvc3JjL2luaXQuanM/YzA2NSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1hcnJheS9zcmMvdGlja3MuanM/MDgwZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1mb3JtYXQvc3JjL2Zvcm1hdFNwZWNpZmllci5qcz81Mjg2Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWZvcm1hdC9zcmMvZm9ybWF0RGVjaW1hbC5qcz9hNjAyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWZvcm1hdC9zcmMvZXhwb25lbnQuanM/YThmMCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1mb3JtYXQvc3JjL3ByZWNpc2lvblByZWZpeC5qcz84OTNiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWZvcm1hdC9zcmMvZm9ybWF0R3JvdXAuanM/Nzk1ZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1mb3JtYXQvc3JjL2Zvcm1hdE51bWVyYWxzLmpzPzRhZjAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtZm9ybWF0L3NyYy9mb3JtYXRUcmltLmpzPzViNWYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtZm9ybWF0L3NyYy9mb3JtYXRQcmVmaXhBdXRvLmpzP2MzNTAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtZm9ybWF0L3NyYy9mb3JtYXRSb3VuZGVkLmpzP2YwZTMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtZm9ybWF0L3NyYy9mb3JtYXRUeXBlcy5qcz82MjI3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWZvcm1hdC9zcmMvaWRlbnRpdHkuanM/ZmMzMCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1mb3JtYXQvc3JjL2xvY2FsZS5qcz85ZDE2Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWZvcm1hdC9zcmMvZGVmYXVsdExvY2FsZS5qcz8yZmFhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLWZvcm1hdC9zcmMvcHJlY2lzaW9uUm91bmQuanM/NTQwYyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1mb3JtYXQvc3JjL3ByZWNpc2lvbkZpeGVkLmpzPzdkNmYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2NhbGUvc3JjL3RpY2tGb3JtYXQuanM/NTc3NCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zY2FsZS9zcmMvbGluZWFyLmpzP2UwYTkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtc2NhbGUvc3JjL3NlcXVlbnRpYWwuanM/NDY3ZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zY2FsZS9zcmMvaW5kZXguanM/MDY3ZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zY2FsZS1jaHJvbWF0aWMvc3JjL2NvbG9ycy5qcz85ZTE4Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNjYWxlLWNocm9tYXRpYy9zcmMvcmFtcC5qcz83NGVkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXNjYWxlLWNocm9tYXRpYy9zcmMvc2VxdWVudGlhbC1zaW5nbGUvQmx1ZXMuanM/ZWViYiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9kMy1zY2FsZS1jaHJvbWF0aWMvc3JjL2luZGV4LmpzPzcxZGMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtem9vbS9zcmMvdHJhbnNmb3JtLmpzP2Q0MGUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMtem9vbS9zcmMvem9vbS5qcz82M2ZlIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL2QzLXpvb20vc3JjL2luZGV4LmpzPzgzYWMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvZDMvc3JjL2luZGV4LmpzPzkyZTkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvT3ZlcmxheVBvc2l0aW9uaW5nLmpzPzg4YWMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvT3ZlcmxheS5qcz84YzNmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vc3JjL2NvbXBvbmVudHMvbWFwLnRzeD82NjlkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vc3JjL2NvbXBvbmVudHMvSG93WW91Q2FuSGVscC5tb2R1bGUuc2Nzcz9jY2NiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vc3JjL2NvbXBvbmVudHMvSG93WW91Q2FuSGVscC50c3g/OTBiNCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9wYWdlcy9jZWpzdC5tb2R1bGUuc2Nzcz82MWUzIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vc3JjL3BhZ2VzL2NlanN0LnRzeD9lMWRmIl0sIm5hbWVzIjpbIk1hcFdyYXBwZXIiLCJmZWF0dXJlcyIsInVzZVN0YXRlIiwibWFwIiwic2V0TWFwIiwiY3VycmVudE92ZXJsYXkiLCJzZXRDdXJyZW50T3ZlcmxheSIsImZlYXR1cmVzTGF5ZXIiLCJzZXRGZWF0dXJlc0xheWVyIiwic2VsZWN0ZWRGZWF0dXJlIiwic2V0U2VsZWN0ZWRGZWF0dXJlIiwiaG92ZXJlZEZlYXR1cmUiLCJzZXRIb3ZlcmVkRmVhdHVyZSIsInNlbGVjdGVkQ29vcmQiLCJzZXRTZWxlY3RlZENvb3JkIiwibWFwRWxlbWVudCIsInVzZVJlZiIsIm1hcFJlZiIsInBvcHVwQ29udGFpbmVyIiwiUmVhY3QiLCJwb3B1cENsb3NlciIsInBvcHVwQ29udGVudCIsIm92ZXJsYXlSZWYiLCJjdXJyZW50IiwidXNlRWZmZWN0IiwiaW5pdGlhbEZlYXR1cmVzTGF5ZXIiLCJWZWN0b3JMYXllciIsInNvdXJjZSIsIlZlY3RvclNvdXJjZSIsImo0MHNvdXJjZSIsIlZlY3RvclRpbGVTb3VyY2UiLCJNVlQiLCJjb2xvcnMiLCJkMyIsImRvbWFpbiIsImo0MExheWVyIiwiVmVjdG9yVGlsZUxheWVyIiwiZGVjbHV0dGVyIiwic3R5bGUiLCJmZWF0dXJlIiwiZGF0YSIsImdldCIsImNvbG9yU3RyaW5nIiwicmdiIiwicmJnQXJyIiwic2xpY2UiLCJpbmRleE9mIiwic3BsaXQiLCJTdHlsZSIsImZpbGwiLCJGaWxsIiwiY29sb3IiLCJvbmNsaWNrIiwib3ZlcmxheSIsInNldFBvc2l0aW9uIiwidW5kZWZpbmVkIiwiYmx1ciIsIk92ZXJsYXkiLCJlbGVtZW50IiwiYXV0b1BhbiIsImF1dG9QYW5BbmltYXRpb24iLCJkdXJhdGlvbiIsImluaXRpYWxNYXAiLCJNYXAiLCJ0YXJnZXQiLCJ2aWV3IiwiVmlldyIsImNlbnRlciIsImZyb21Mb25MYXQiLCJ6b29tIiwibGF5ZXJzIiwiVGlsZUxheWVyIiwiWFlaIiwidXJsIiwiY29udHJvbHMiLCJvdmVybGF5cyIsIm9uIiwiaGFuZGxlTWFwQ2xpY2siLCJoYW5kbGVQb2ludGVyTW92ZSIsImxlbmd0aCIsInNldFNvdXJjZSIsImV4dGVudCIsImdldFNvdXJjZSIsImdldEV4dGVudCIsImdldFZpZXciLCJmaXQiLCJwYWRkaW5nIiwiZXZlbnQiLCJjbGlja2VkQ29vcmQiLCJnZXRDb29yZGluYXRlRnJvbVBpeGVsIiwicGl4ZWwiLCJ0cmFuc2Zvcm1lZENvb3JkIiwidHJhbnNmb3JtIiwiZm9yRWFjaEZlYXR1cmVBdFBpeGVsIiwic2V0U3R5bGUiLCJyZWFkYWJsZVBlcmNlbnQiLCJwZXJjZW50IiwicGFyc2VGbG9hdCIsInRvRml4ZWQiLCJzdHlsZXMiLCJwcm9wZXJ0aWVzXyIsInRvU3RyaW5nWFkiLCJIb3dZb3VDYW5IZWxwIiwiQ0VKU1RQYWdlIiwibG9jYXRpb24iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQsa0RBQWUsVUFBVSxFOztBQ3pDekI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxTQUFTO0FBQ3BCLFdBQVcsRUFBRTtBQUNiLFdBQVcsVUFBVTtBQUNyQixZQUFZLE9BQU87QUFDbkI7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsRUFBRTtBQUNiLFdBQVcsRUFBRTtBQUNiLFlBQVksT0FBTztBQUNuQjtBQUNBOztBQUVPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFNBQVM7QUFDcEIsV0FBVyxFQUFFO0FBQ2IsWUFBWSxRQUFRO0FBQ3BCOztBQUVPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsV0FBVyxjQUFjO0FBQ3pCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBLFlBQVksT0FBTztBQUNuQjs7QUFFTztBQUNQOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFD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QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkOztB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7OztBQUdEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7OztBQUdEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsU0FBUyxXQUFLO0FBQ2Q7QUFDQTs7QUFFTztBQUNQO0FBQ0E7QUFDQTtBQUNPO0FBQ1AsU0FBUyxXQUFLO0FBQ2Q7QUFDTztBQUNQLFNBQVMsV0FBSztBQUNkO0FBQ0EsNkJBQWUsU0FBUyxRQUFHO0FBQzNCLFNBQVMsV0FBSztBQUNkOztBQUVBLFNBQVMsV0FBSztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFD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QUFNc0csY0FBYSxDQUFHLFFBQWhCQSxjQUFnQixFQUFNLENBQzFCLG1CQUNFLDJCQUFLLFNBQVMsQ0FBRUgsc0JBQWhCLGVBQ0Usa0VBREYsY0FFRSwyQ0FDRSwwR0FERixjQUVFLGdLQUZGLGNBSUUsb0dBSkYsY0FLRSxvRkFMRixDQUZGLENBREYsQ0FZRCxDQWJELENBZUEsNkRBQWVHLGFBQWYsRTs7OztBQ2xCQTtBQUNPLG1EOztBQ0VQO0FBV0EsR0FBTUMsVUFBUyxDQUFHLFFBQVpBLFVBQVksTUFBK0IsSUFBN0JDLFNBQTZCLE1BQTdCQSxRQUE2QixDQUMvQyxjQUFtQnRHLGtCQUFRLENBQXNCLEVBQXRCLENBQTNCLENBQU9ELFFBQVAsY0FFQSxtQkFDRSxvQkFBQyxxQkFBRCxFQUFRLFFBQVEsQ0FBRXVHLFFBQWxCLGVBQ0UsNEJBQU0sRUFBRSxDQUFDLGNBQVQsQ0FBd0IsSUFBSSxDQUFDLE1BQTdCLGVBQ0UseUJBQUcsU0FBUyxDQUFFTCxVQUFkLG1UQU1rQix5QkFDZCxJQUFJLENBQUUsNENBQ0Usa0NBREYsQ0FFRSwwQ0FGRixDQUdFLDRCQUpNLENBS2QsTUFBTSxDQUFFLFFBTE0sQ0FNZCxHQUFHLENBQUUsWUFOUyxzRUFObEIsNkhBREYsY0FvQkUsb0JBQUMsU0FBRCxFQUNFLElBQUksQ0FBQyxTQURQLENBRUUsT0FBTyxDQUFDLHNCQUZWLGVBR0UsaVFBSEYsQ0FwQkYsY0FnQ0Usb0JBQUMsY0FBRCxFQUFZLFFBQVEsQ0FBRWxHLFFBQXRCLEVBaENGLGNBaUNFLG9CQUFDLHdCQUFELE1BakNGLENBREYsQ0FERixDQXVDRCxDQTFDRCxDQTRDQSwwQ0FBZXNHLFNBQWYiLCJmaWxlIjoiNjI5LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIG9sL0Rpc3Bvc2FibGVcbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIE9iamVjdHMgdGhhdCBuZWVkIHRvIGNsZWFuIHVwIGFmdGVyIHRoZW1zZWx2ZXMuXG4gKi9cbnZhciBEaXNwb3NhYmxlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gRGlzcG9zYWJsZSgpIHtcbiAgICAvKipcbiAgICAgKiBUaGUgb2JqZWN0IGhhcyBhbHJlYWR5IGJlZW4gZGlzcG9zZWQuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQHByb3RlY3RlZFxuICAgICAqL1xuICAgIHRoaXMuZGlzcG9zZWQgPSBmYWxzZTtcbiAgfVxuICAvKipcbiAgICogQ2xlYW4gdXAuXG4gICAqL1xuXG5cbiAgRGlzcG9zYWJsZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuZGlzcG9zZWQpIHtcbiAgICAgIHRoaXMuZGlzcG9zZWQgPSB0cnVlO1xuICAgICAgdGhpcy5kaXNwb3NlSW50ZXJuYWwoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBFeHRlbnNpb24gcG9pbnQgZm9yIGRpc3Bvc2FibGUgb2JqZWN0cy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIERpc3Bvc2FibGUucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4gIHJldHVybiBEaXNwb3NhYmxlO1xufSgpO1xuXG5leHBvcnQgZGVmYXVsdCBEaXNwb3NhYmxlOyIsIi8qKlxuICogQG1vZHVsZSBvbC9hcnJheVxuICovXG5cbi8qKlxuICogUGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoIG9uIHRoZSBwcm92aWRlZCBzb3J0ZWQgbGlzdCBhbmQgcmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGl0ZW0gaWYgZm91bmQuIElmIGl0IGNhbid0IGJlIGZvdW5kIGl0J2xsIHJldHVybiAtMS5cbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9kYXJrc2t5YXBwL2JpbmFyeS1zZWFyY2hcbiAqXG4gKiBAcGFyYW0ge0FycmF5PCo+fSBoYXlzdGFjayBJdGVtcyB0byBzZWFyY2ggdGhyb3VnaC5cbiAqIEBwYXJhbSB7Kn0gbmVlZGxlIFRoZSBpdGVtIHRvIGxvb2sgZm9yLlxuICogQHBhcmFtIHtGdW5jdGlvbj19IG9wdF9jb21wYXJhdG9yIENvbXBhcmF0b3IgZnVuY3Rpb24uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBpbmRleCBvZiB0aGUgaXRlbSBpZiBmb3VuZCwgLTEgaWYgbm90LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYmluYXJ5U2VhcmNoKGhheXN0YWNrLCBuZWVkbGUsIG9wdF9jb21wYXJhdG9yKSB7XG4gIHZhciBtaWQsIGNtcDtcbiAgdmFyIGNvbXBhcmF0b3IgPSBvcHRfY29tcGFyYXRvciB8fCBudW1iZXJTYWZlQ29tcGFyZUZ1bmN0aW9uO1xuICB2YXIgbG93ID0gMDtcbiAgdmFyIGhpZ2ggPSBoYXlzdGFjay5sZW5ndGg7XG4gIHZhciBmb3VuZCA9IGZhbHNlO1xuXG4gIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgLyogTm90ZSB0aGF0IFwiKGxvdyArIGhpZ2gpID4+PiAxXCIgbWF5IG92ZXJmbG93LCBhbmQgcmVzdWx0cyBpbiBhIHR5cGVjYXN0XG4gICAgICogdG8gZG91YmxlICh3aGljaCBnaXZlcyB0aGUgd3JvbmcgcmVzdWx0cykuICovXG4gICAgbWlkID0gbG93ICsgKGhpZ2ggLSBsb3cgPj4gMSk7XG4gICAgY21wID0gK2NvbXBhcmF0b3IoaGF5c3RhY2tbbWlkXSwgbmVlZGxlKTtcblxuICAgIGlmIChjbXAgPCAwLjApIHtcbiAgICAgIC8qIFRvbyBsb3cuICovXG4gICAgICBsb3cgPSBtaWQgKyAxO1xuICAgIH0gZWxzZSB7XG4gICAgICAvKiBLZXkgZm91bmQgb3IgdG9vIGhpZ2ggKi9cbiAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICBmb3VuZCA9ICFjbXA7XG4gICAgfVxuICB9XG4gIC8qIEtleSBub3QgZm91bmQuICovXG5cblxuICByZXR1cm4gZm91bmQgPyBsb3cgOiB+bG93O1xufVxuLyoqXG4gKiBDb21wYXJlIGZ1bmN0aW9uIGZvciBhcnJheSBzb3J0IHRoYXQgaXMgc2FmZSBmb3IgbnVtYmVycy5cbiAqIEBwYXJhbSB7Kn0gYSBUaGUgZmlyc3Qgb2JqZWN0IHRvIGJlIGNvbXBhcmVkLlxuICogQHBhcmFtIHsqfSBiIFRoZSBzZWNvbmQgb2JqZWN0IHRvIGJlIGNvbXBhcmVkLlxuICogQHJldHVybiB7bnVtYmVyfSBBIG5lZ2F0aXZlIG51bWJlciwgemVybywgb3IgYSBwb3NpdGl2ZSBudW1iZXIgYXMgdGhlIGZpcnN0XG4gKiAgICAgYXJndW1lbnQgaXMgbGVzcyB0aGFuLCBlcXVhbCB0bywgb3IgZ3JlYXRlciB0aGFuIHRoZSBzZWNvbmQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG51bWJlclNhZmVDb21wYXJlRnVuY3Rpb24oYSwgYikge1xuICByZXR1cm4gYSA+IGIgPyAxIDogYSA8IGIgPyAtMSA6IDA7XG59XG4vKipcbiAqIFdoZXRoZXIgdGhlIGFycmF5IGNvbnRhaW5zIHRoZSBnaXZlbiBvYmplY3QuXG4gKiBAcGFyYW0ge0FycmF5PCo+fSBhcnIgVGhlIGFycmF5IHRvIHRlc3QgZm9yIHRoZSBwcmVzZW5jZSBvZiB0aGUgZWxlbWVudC5cbiAqIEBwYXJhbSB7Kn0gb2JqIFRoZSBvYmplY3QgZm9yIHdoaWNoIHRvIHRlc3QuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgb2JqZWN0IGlzIGluIHRoZSBhcnJheS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW5jbHVkZXMoYXJyLCBvYmopIHtcbiAgcmV0dXJuIGFyci5pbmRleE9mKG9iaikgPj0gMDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBhcnIgQXJyYXkuXG4gKiBAcGFyYW0ge251bWJlcn0gdGFyZ2V0IFRhcmdldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkaXJlY3Rpb24gMCBtZWFucyByZXR1cm4gdGhlIG5lYXJlc3QsID4gMFxuICogICAgbWVhbnMgcmV0dXJuIHRoZSBsYXJnZXN0IG5lYXJlc3QsIDwgMCBtZWFucyByZXR1cm4gdGhlXG4gKiAgICBzbWFsbGVzdCBuZWFyZXN0LlxuICogQHJldHVybiB7bnVtYmVyfSBJbmRleC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbGluZWFyRmluZE5lYXJlc3QoYXJyLCB0YXJnZXQsIGRpcmVjdGlvbikge1xuICB2YXIgbiA9IGFyci5sZW5ndGg7XG5cbiAgaWYgKGFyclswXSA8PSB0YXJnZXQpIHtcbiAgICByZXR1cm4gMDtcbiAgfSBlbHNlIGlmICh0YXJnZXQgPD0gYXJyW24gLSAxXSkge1xuICAgIHJldHVybiBuIC0gMTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaSA9IHZvaWQgMDtcblxuICAgIGlmIChkaXJlY3Rpb24gPiAwKSB7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGlmIChhcnJbaV0gPCB0YXJnZXQpIHtcbiAgICAgICAgICByZXR1cm4gaSAtIDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA8IDApIHtcbiAgICAgIGZvciAoaSA9IDE7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgaWYgKGFycltpXSA8PSB0YXJnZXQpIHtcbiAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGlmIChhcnJbaV0gPT0gdGFyZ2V0KSB7XG4gICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH0gZWxzZSBpZiAoYXJyW2ldIDwgdGFyZ2V0KSB7XG4gICAgICAgICAgaWYgKGFycltpIC0gMV0gLSB0YXJnZXQgPCB0YXJnZXQgLSBhcnJbaV0pIHtcbiAgICAgICAgICAgIHJldHVybiBpIC0gMTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG4gLSAxO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8Kj59IGFyciBBcnJheS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiZWdpbiBCZWdpbiBpbmRleC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kIGluZGV4LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByZXZlcnNlU3ViQXJyYXkoYXJyLCBiZWdpbiwgZW5kKSB7XG4gIHdoaWxlIChiZWdpbiA8IGVuZCkge1xuICAgIHZhciB0bXAgPSBhcnJbYmVnaW5dO1xuICAgIGFycltiZWdpbl0gPSBhcnJbZW5kXTtcbiAgICBhcnJbZW5kXSA9IHRtcDtcbiAgICArK2JlZ2luO1xuICAgIC0tZW5kO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8VkFMVUU+fSBhcnIgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7IUFycmF5PFZBTFVFPnxWQUxVRX0gZGF0YSBUaGUgZWxlbWVudHMgb3IgYXJyYXlzIG9mIGVsZW1lbnRzIHRvIGFkZCB0byBhcnIuXG4gKiBAdGVtcGxhdGUgVkFMVUVcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kKGFyciwgZGF0YSkge1xuICB2YXIgZXh0ZW5zaW9uID0gQXJyYXkuaXNBcnJheShkYXRhKSA/IGRhdGEgOiBbZGF0YV07XG4gIHZhciBsZW5ndGggPSBleHRlbnNpb24ubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBhcnJbYXJyLmxlbmd0aF0gPSBleHRlbnNpb25baV07XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxWQUxVRT59IGFyciBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtWQUxVRX0gb2JqIFRoZSBlbGVtZW50IHRvIHJlbW92ZS5cbiAqIEB0ZW1wbGF0ZSBWQUxVRVxuICogQHJldHVybiB7Ym9vbGVhbn0gSWYgdGhlIGVsZW1lbnQgd2FzIHJlbW92ZWQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZShhcnIsIG9iaikge1xuICB2YXIgaSA9IGFyci5pbmRleE9mKG9iaik7XG4gIHZhciBmb3VuZCA9IGkgPiAtMTtcblxuICBpZiAoZm91bmQpIHtcbiAgICBhcnIuc3BsaWNlKGksIDEpO1xuICB9XG5cbiAgcmV0dXJuIGZvdW5kO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PFZBTFVFPn0gYXJyIFRoZSBhcnJheSB0byBzZWFyY2ggaW4uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFZBTFVFLCBudW1iZXIsID8pIDogYm9vbGVhbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY29tcGFyZS5cbiAqIEB0ZW1wbGF0ZSBWQUxVRVxuICogQHJldHVybiB7VkFMVUV8bnVsbH0gVGhlIGVsZW1lbnQgZm91bmQgb3IgbnVsbC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZmluZChhcnIsIGZ1bmMpIHtcbiAgdmFyIGxlbmd0aCA9IGFyci5sZW5ndGggPj4+IDA7XG4gIHZhciB2YWx1ZTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFsdWUgPSBhcnJbaV07XG5cbiAgICBpZiAoZnVuYyh2YWx1ZSwgaSwgYXJyKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5fFVpbnQ4Q2xhbXBlZEFycmF5fSBhcnIxIFRoZSBmaXJzdCBhcnJheSB0byBjb21wYXJlLlxuICogQHBhcmFtIHtBcnJheXxVaW50OENsYW1wZWRBcnJheX0gYXJyMiBUaGUgc2Vjb25kIGFycmF5IHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHRoZSB0d28gYXJyYXlzIGFyZSBlcXVhbC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxzKGFycjEsIGFycjIpIHtcbiAgdmFyIGxlbjEgPSBhcnIxLmxlbmd0aDtcblxuICBpZiAobGVuMSAhPT0gYXJyMi5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjE7IGkrKykge1xuICAgIGlmIChhcnIxW2ldICE9PSBhcnIyW2ldKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIFNvcnQgdGhlIHBhc3NlZCBhcnJheSBzdWNoIHRoYXQgdGhlIHJlbGF0aXZlIG9yZGVyIG9mIGVxdWFsIGVsZW1lbnRzIGlzIHByZXZlcnZlZC5cbiAqIFNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Tb3J0aW5nX2FsZ29yaXRobSNTdGFiaWxpdHkgZm9yIGRldGFpbHMuXG4gKiBAcGFyYW0ge0FycmF5PCo+fSBhcnIgVGhlIGFycmF5IHRvIHNvcnQgKG1vZGlmaWVzIG9yaWdpbmFsKS5cbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCosICopOiBudW1iZXJ9IGNvbXBhcmVGbmMgQ29tcGFyaXNvbiBmdW5jdGlvbi5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3RhYmxlU29ydChhcnIsIGNvbXBhcmVGbmMpIHtcbiAgdmFyIGxlbmd0aCA9IGFyci5sZW5ndGg7XG4gIHZhciB0bXAgPSBBcnJheShhcnIubGVuZ3RoKTtcbiAgdmFyIGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdG1wW2ldID0ge1xuICAgICAgaW5kZXg6IGksXG4gICAgICB2YWx1ZTogYXJyW2ldXG4gICAgfTtcbiAgfVxuXG4gIHRtcC5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGNvbXBhcmVGbmMoYS52YWx1ZSwgYi52YWx1ZSkgfHwgYS5pbmRleCAtIGIuaW5kZXg7XG4gIH0pO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICBhcnJbaV0gPSB0bXBbaV0udmFsdWU7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTwqPn0gYXJyIFRoZSBhcnJheSB0byBzZWFyY2ggaW4uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIENvbXBhcmlzb24gZnVuY3Rpb24uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFJldHVybiBpbmRleC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZmluZEluZGV4KGFyciwgZnVuYykge1xuICB2YXIgaW5kZXg7XG4gIHZhciBmb3VuZCA9ICFhcnIuZXZlcnkoZnVuY3Rpb24gKGVsLCBpZHgpIHtcbiAgICBpbmRleCA9IGlkeDtcbiAgICByZXR1cm4gIWZ1bmMoZWwsIGlkeCwgYXJyKTtcbiAgfSk7XG4gIHJldHVybiBmb3VuZCA/IGluZGV4IDogLTE7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8Kj59IGFyciBUaGUgYXJyYXkgdG8gdGVzdC5cbiAqIEBwYXJhbSB7RnVuY3Rpb249fSBvcHRfZnVuYyBDb21wYXJpc29uIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3N0cmljdCBTdHJpY3RseSBzb3J0ZWQgKGRlZmF1bHQgZmFsc2UpLlxuICogQHJldHVybiB7Ym9vbGVhbn0gUmV0dXJuIGluZGV4LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1NvcnRlZChhcnIsIG9wdF9mdW5jLCBvcHRfc3RyaWN0KSB7XG4gIHZhciBjb21wYXJlID0gb3B0X2Z1bmMgfHwgbnVtYmVyU2FmZUNvbXBhcmVGdW5jdGlvbjtcbiAgcmV0dXJuIGFyci5ldmVyeShmdW5jdGlvbiAoY3VycmVudFZhbCwgaW5kZXgpIHtcbiAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciByZXMgPSBjb21wYXJlKGFycltpbmRleCAtIDFdLCBjdXJyZW50VmFsKTtcbiAgICByZXR1cm4gIShyZXMgPiAwIHx8IG9wdF9zdHJpY3QgJiYgcmVzID09PSAwKTtcbiAgfSk7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2Z1bmN0aW9uc1xuICovXG5pbXBvcnQgeyBlcXVhbHMgYXMgYXJyYXlFcXVhbHMgfSBmcm9tICcuL2FycmF5LmpzJztcbi8qKlxuICogQWx3YXlzIHJldHVybnMgdHJ1ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBUUlVFKCkge1xuICByZXR1cm4gdHJ1ZTtcbn1cbi8qKlxuICogQWx3YXlzIHJldHVybnMgZmFsc2UuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gZmFsc2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIEZBTFNFKCkge1xuICByZXR1cm4gZmFsc2U7XG59XG4vKipcbiAqIEEgcmV1c2FibGUgZnVuY3Rpb24sIHVzZWQgZS5nLiBhcyBhIGRlZmF1bHQgZm9yIGNhbGxiYWNrcy5cbiAqXG4gKiBAcmV0dXJuIHt2b2lkfSBOb3RoaW5nLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBWT0lEKCkge31cbi8qKlxuICogV3JhcCBhIGZ1bmN0aW9uIGluIGFub3RoZXIgZnVuY3Rpb24gdGhhdCByZW1lbWJlcnMgdGhlIGxhc3QgcmV0dXJuLiAgSWYgdGhlXG4gKiByZXR1cm5lZCBmdW5jdGlvbiBpcyBjYWxsZWQgdHdpY2UgaW4gYSByb3cgd2l0aCB0aGUgc2FtZSBhcmd1bWVudHMgYW5kIHRoZSBzYW1lXG4gKiB0aGlzIG9iamVjdCwgaXQgd2lsbCByZXR1cm4gdGhlIHZhbHVlIGZyb20gdGhlIGZpcnN0IGNhbGwgaW4gdGhlIHNlY29uZCBjYWxsLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oLi4uYW55KTogUmV0dXJuVHlwZX0gZm4gVGhlIGZ1bmN0aW9uIHRvIG1lbW9pemUuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbiguLi5hbnkpOiBSZXR1cm5UeXBlfSBUaGUgbWVtb2l6ZWQgZnVuY3Rpb24uXG4gKiBAdGVtcGxhdGUgUmV0dXJuVHlwZVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtZW1vaXplT25lKGZuKSB7XG4gIHZhciBjYWxsZWQgPSBmYWxzZTtcbiAgLyoqIEB0eXBlIHtSZXR1cm5UeXBlfSAqL1xuXG4gIHZhciBsYXN0UmVzdWx0O1xuICAvKiogQHR5cGUge0FycmF5PGFueT59ICovXG5cbiAgdmFyIGxhc3RBcmdzO1xuICB2YXIgbGFzdFRoaXM7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG5leHRBcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgIGlmICghY2FsbGVkIHx8IHRoaXMgIT09IGxhc3RUaGlzIHx8ICFhcnJheUVxdWFscyhuZXh0QXJncywgbGFzdEFyZ3MpKSB7XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgbGFzdFRoaXMgPSB0aGlzO1xuICAgICAgbGFzdEFyZ3MgPSBuZXh0QXJncztcbiAgICAgIGxhc3RSZXN1bHQgPSBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIHJldHVybiBsYXN0UmVzdWx0O1xuICB9O1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC91dGlsXG4gKi9cblxuLyoqXG4gKiBAcmV0dXJuIHs/fSBBbnkgcmV0dXJuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWJzdHJhY3QoKSB7XG4gIHJldHVybiAoXG4gICAgLyoqIEB0eXBlIHs/fSAqL1xuICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5pbXBsZW1lbnRlZCBhYnN0cmFjdCBtZXRob2QuJyk7XG4gICAgfSgpXG4gICk7XG59XG4vKipcbiAqIENvdW50ZXIgZm9yIGdldFVpZC5cbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAcHJpdmF0ZVxuICovXG5cbnZhciB1aWRDb3VudGVyXyA9IDA7XG4vKipcbiAqIEdldHMgYSB1bmlxdWUgSUQgZm9yIGFuIG9iamVjdC4gVGhpcyBtdXRhdGVzIHRoZSBvYmplY3Qgc28gdGhhdCBmdXJ0aGVyIGNhbGxzXG4gKiB3aXRoIHRoZSBzYW1lIG9iamVjdCBhcyBhIHBhcmFtZXRlciByZXR1cm5zIHRoZSBzYW1lIHZhbHVlLiBVbmlxdWUgSURzIGFyZSBnZW5lcmF0ZWRcbiAqIGFzIGEgc3RyaWN0bHkgaW5jcmVhc2luZyBzZXF1ZW5jZS4gQWRhcHRlZCBmcm9tIGdvb2cuZ2V0VWlkLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdCB0byBnZXQgdGhlIHVuaXF1ZSBJRCBmb3IuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSB1bmlxdWUgSUQgZm9yIHRoZSBvYmplY3QuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVpZChvYmopIHtcbiAgcmV0dXJuIG9iai5vbF91aWQgfHwgKG9iai5vbF91aWQgPSBTdHJpbmcoKyt1aWRDb3VudGVyXykpO1xufVxuLyoqXG4gKiBPcGVuTGF5ZXJzIHZlcnNpb24uXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5cbmV4cG9ydCB2YXIgVkVSU0lPTiA9ICc2LjUuMCc7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9Bc3NlcnRpb25FcnJvclxuICovXG5cblxuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gJy4vdXRpbC5qcyc7XG4vKipcbiAqIEVycm9yIG9iamVjdCB0aHJvd24gd2hlbiBhbiBhc3NlcnRpb24gZmFpbGVkLiBUaGlzIGlzIGFuIEVDTUEtMjYyIEVycm9yLFxuICogZXh0ZW5kZWQgd2l0aCBhIGBjb2RlYCBwcm9wZXJ0eS5cbiAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9FcnJvci5cbiAqL1xuXG52YXIgQXNzZXJ0aW9uRXJyb3IgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQXNzZXJ0aW9uRXJyb3IsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gY29kZSBFcnJvciBjb2RlLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKGNvZGUpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIHBhdGggPSBWRVJTSU9OID09PSAnbGF0ZXN0JyA/IFZFUlNJT04gOiAndicgKyBWRVJTSU9OLnNwbGl0KCctJylbMF07XG4gICAgdmFyIG1lc3NhZ2UgPSAnQXNzZXJ0aW9uIGZhaWxlZC4gU2VlIGh0dHBzOi8vb3BlbmxheWVycy5vcmcvZW4vJyArIHBhdGggKyAnL2RvYy9lcnJvcnMvIycgKyBjb2RlICsgJyBmb3IgZGV0YWlscy4nO1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgbWVzc2FnZSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBFcnJvciBjb2RlLiBUaGUgbWVhbmluZyBvZiB0aGUgY29kZSBjYW4gYmUgZm91bmQgb25cbiAgICAgKiBodHRwczovL29wZW5sYXllcnMub3JnL2VuL2xhdGVzdC9kb2MvZXJyb3JzLyAocmVwbGFjZSBgbGF0ZXN0YCB3aXRoXG4gICAgICogdGhlIHZlcnNpb24gZm91bmQgaW4gdGhlIE9wZW5MYXllcnMgc2NyaXB0J3MgaGVhZGVyIGNvbW1lbnQgaWYgYSB2ZXJzaW9uXG4gICAgICogb3RoZXIgdGhhbiB0aGUgbGF0ZXN0IGlzIHVzZWQpLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29kZSA9IGNvZGU7XG4gICAgLyoqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cblxuICAgIF90aGlzLm5hbWUgPSAnQXNzZXJ0aW9uRXJyb3InOyAvLyBSZS1hc3NpZ24gbWVzc2FnZSwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9SaWNoLUhhcnJpcy9idWJsZS9pc3N1ZXMvNDBcblxuICAgIF90aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIHJldHVybiBBc3NlcnRpb25FcnJvcjtcbn0oRXJyb3IpO1xuXG5leHBvcnQgZGVmYXVsdCBBc3NlcnRpb25FcnJvcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvYXNzZXJ0c1xuICovXG5pbXBvcnQgQXNzZXJ0aW9uRXJyb3IgZnJvbSAnLi9Bc3NlcnRpb25FcnJvci5qcyc7XG4vKipcbiAqIEBwYXJhbSB7Kn0gYXNzZXJ0aW9uIEFzc2VydGlvbiB3ZSBleHBlY3RlZCB0byBiZSB0cnV0aHkuXG4gKiBAcGFyYW0ge251bWJlcn0gZXJyb3JDb2RlIEVycm9yIGNvZGUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydChhc3NlcnRpb24sIGVycm9yQ29kZSkge1xuICBpZiAoIWFzc2VydGlvbikge1xuICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlcnJvckNvZGUpO1xuICB9XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3RyYW5zZm9ybVxuICovXG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuL2Fzc2VydHMuanMnO1xuLyoqXG4gKiBBbiBhcnJheSByZXByZXNlbnRpbmcgYW4gYWZmaW5lIDJkIHRyYW5zZm9ybWF0aW9uIGZvciB1c2Ugd2l0aFxuICoge0BsaW5rIG1vZHVsZTpvbC90cmFuc2Zvcm19IGZ1bmN0aW9ucy4gVGhlIGFycmF5IGhhcyA2IGVsZW1lbnRzLlxuICogQHR5cGVkZWYgeyFBcnJheTxudW1iZXI+fSBUcmFuc2Zvcm1cbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIENvbGxlY3Rpb24gb2YgYWZmaW5lIDJkIHRyYW5zZm9ybWF0aW9uIGZ1bmN0aW9ucy4gVGhlIGZ1bmN0aW9ucyB3b3JrIG9uIGFuXG4gKiBhcnJheSBvZiA2IGVsZW1lbnRzLiBUaGUgZWxlbWVudCBvcmRlciBpcyBjb21wYXRpYmxlIHdpdGggdGhlIFtTVkdNYXRyaXhcbiAqIGludGVyZmFjZV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1NWR01hdHJpeCkgYW5kIGlzXG4gKiBhIHN1YnNldCAoZWxlbWVudHMgYSB0byBmKSBvZiBhIDPDlzMgbWF0cml4OlxuICogYGBgXG4gKiBbIGEgYyBlIF1cbiAqIFsgYiBkIGYgXVxuICogWyAwIDAgMSBdXG4gKiBgYGBcbiAqL1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7VHJhbnNmb3JtfVxuICovXG5cbnZhciB0bXBfID0gbmV3IEFycmF5KDYpO1xuLyoqXG4gKiBDcmVhdGUgYW4gaWRlbnRpdHkgdHJhbnNmb3JtLlxuICogQHJldHVybiB7IVRyYW5zZm9ybX0gSWRlbnRpdHkgdHJhbnNmb3JtLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHJldHVybiBbMSwgMCwgMCwgMSwgMCwgMF07XG59XG4vKipcbiAqIFJlc2V0cyB0aGUgZ2l2ZW4gdHJhbnNmb3JtIHRvIGFuIGlkZW50aXR5IHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7IVRyYW5zZm9ybX0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAqIEByZXR1cm4geyFUcmFuc2Zvcm19IFRyYW5zZm9ybS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmVzZXQodHJhbnNmb3JtKSB7XG4gIHJldHVybiBzZXQodHJhbnNmb3JtLCAxLCAwLCAwLCAxLCAwLCAwKTtcbn1cbi8qKlxuICogTXVsdGlwbHkgdGhlIHVuZGVybHlpbmcgbWF0cmljZXMgb2YgdHdvIHRyYW5zZm9ybXMgYW5kIHJldHVybiB0aGUgcmVzdWx0IGluXG4gKiB0aGUgZmlyc3QgdHJhbnNmb3JtLlxuICogQHBhcmFtIHshVHJhbnNmb3JtfSB0cmFuc2Zvcm0xIFRyYW5zZm9ybSBwYXJhbWV0ZXJzIG9mIG1hdHJpeCAxLlxuICogQHBhcmFtIHshVHJhbnNmb3JtfSB0cmFuc2Zvcm0yIFRyYW5zZm9ybSBwYXJhbWV0ZXJzIG9mIG1hdHJpeCAyLlxuICogQHJldHVybiB7IVRyYW5zZm9ybX0gdHJhbnNmb3JtMSBtdWx0aXBsaWVkIHdpdGggdHJhbnNmb3JtMi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHkodHJhbnNmb3JtMSwgdHJhbnNmb3JtMikge1xuICB2YXIgYTEgPSB0cmFuc2Zvcm0xWzBdO1xuICB2YXIgYjEgPSB0cmFuc2Zvcm0xWzFdO1xuICB2YXIgYzEgPSB0cmFuc2Zvcm0xWzJdO1xuICB2YXIgZDEgPSB0cmFuc2Zvcm0xWzNdO1xuICB2YXIgZTEgPSB0cmFuc2Zvcm0xWzRdO1xuICB2YXIgZjEgPSB0cmFuc2Zvcm0xWzVdO1xuICB2YXIgYTIgPSB0cmFuc2Zvcm0yWzBdO1xuICB2YXIgYjIgPSB0cmFuc2Zvcm0yWzFdO1xuICB2YXIgYzIgPSB0cmFuc2Zvcm0yWzJdO1xuICB2YXIgZDIgPSB0cmFuc2Zvcm0yWzNdO1xuICB2YXIgZTIgPSB0cmFuc2Zvcm0yWzRdO1xuICB2YXIgZjIgPSB0cmFuc2Zvcm0yWzVdO1xuICB0cmFuc2Zvcm0xWzBdID0gYTEgKiBhMiArIGMxICogYjI7XG4gIHRyYW5zZm9ybTFbMV0gPSBiMSAqIGEyICsgZDEgKiBiMjtcbiAgdHJhbnNmb3JtMVsyXSA9IGExICogYzIgKyBjMSAqIGQyO1xuICB0cmFuc2Zvcm0xWzNdID0gYjEgKiBjMiArIGQxICogZDI7XG4gIHRyYW5zZm9ybTFbNF0gPSBhMSAqIGUyICsgYzEgKiBmMiArIGUxO1xuICB0cmFuc2Zvcm0xWzVdID0gYjEgKiBlMiArIGQxICogZjIgKyBmMTtcbiAgcmV0dXJuIHRyYW5zZm9ybTE7XG59XG4vKipcbiAqIFNldCB0aGUgdHJhbnNmb3JtIGNvbXBvbmVudHMgYS1mIG9uIGEgZ2l2ZW4gdHJhbnNmb3JtLlxuICogQHBhcmFtIHshVHJhbnNmb3JtfSB0cmFuc2Zvcm0gVHJhbnNmb3JtLlxuICogQHBhcmFtIHtudW1iZXJ9IGEgVGhlIGEgY29tcG9uZW50IG9mIHRoZSB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0ge251bWJlcn0gYiBUaGUgYiBjb21wb25lbnQgb2YgdGhlIHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBjIFRoZSBjIGNvbXBvbmVudCBvZiB0aGUgdHJhbnNmb3JtLlxuICogQHBhcmFtIHtudW1iZXJ9IGQgVGhlIGQgY29tcG9uZW50IG9mIHRoZSB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0ge251bWJlcn0gZSBUaGUgZSBjb21wb25lbnQgb2YgdGhlIHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmIFRoZSBmIGNvbXBvbmVudCBvZiB0aGUgdHJhbnNmb3JtLlxuICogQHJldHVybiB7IVRyYW5zZm9ybX0gTWF0cml4IHdpdGggdHJhbnNmb3JtIGFwcGxpZWQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNldCh0cmFuc2Zvcm0sIGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgdHJhbnNmb3JtWzBdID0gYTtcbiAgdHJhbnNmb3JtWzFdID0gYjtcbiAgdHJhbnNmb3JtWzJdID0gYztcbiAgdHJhbnNmb3JtWzNdID0gZDtcbiAgdHJhbnNmb3JtWzRdID0gZTtcbiAgdHJhbnNmb3JtWzVdID0gZjtcbiAgcmV0dXJuIHRyYW5zZm9ybTtcbn1cbi8qKlxuICogU2V0IHRyYW5zZm9ybSBvbiBvbmUgbWF0cml4IGZyb20gYW5vdGhlciBtYXRyaXguXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IHRyYW5zZm9ybTEgTWF0cml4IHRvIHNldCB0cmFuc2Zvcm0gdG8uXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IHRyYW5zZm9ybTIgTWF0cml4IHRvIHNldCB0cmFuc2Zvcm0gZnJvbS5cbiAqIEByZXR1cm4geyFUcmFuc2Zvcm19IHRyYW5zZm9ybTEgd2l0aCB0cmFuc2Zvcm0gZnJvbSB0cmFuc2Zvcm0yIGFwcGxpZWQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEZyb21BcnJheSh0cmFuc2Zvcm0xLCB0cmFuc2Zvcm0yKSB7XG4gIHRyYW5zZm9ybTFbMF0gPSB0cmFuc2Zvcm0yWzBdO1xuICB0cmFuc2Zvcm0xWzFdID0gdHJhbnNmb3JtMlsxXTtcbiAgdHJhbnNmb3JtMVsyXSA9IHRyYW5zZm9ybTJbMl07XG4gIHRyYW5zZm9ybTFbM10gPSB0cmFuc2Zvcm0yWzNdO1xuICB0cmFuc2Zvcm0xWzRdID0gdHJhbnNmb3JtMls0XTtcbiAgdHJhbnNmb3JtMVs1XSA9IHRyYW5zZm9ybTJbNV07XG4gIHJldHVybiB0cmFuc2Zvcm0xO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIHRoZSBnaXZlbiBjb29yZGluYXRlIHdpdGggdGhlIGdpdmVuIHRyYW5zZm9ybSByZXR1cm5pbmcgdGhlXG4gKiByZXN1bHRpbmcsIHRyYW5zZm9ybWVkIGNvb3JkaW5hdGUuIFRoZSBjb29yZGluYXRlIHdpbGwgYmUgbW9kaWZpZWQgaW4tcGxhY2UuXG4gKlxuICogQHBhcmFtIHtUcmFuc2Zvcm19IHRyYW5zZm9ybSBUaGUgdHJhbnNmb3JtYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfGltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IGNvb3JkaW5hdGUgVGhlIGNvb3JkaW5hdGUgdG8gdHJhbnNmb3JtLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH0gcmV0dXJuIGNvb3JkaW5hdGUgc28gdGhhdCBvcGVyYXRpb25zIGNhbiBiZVxuICogICAgIGNoYWluZWQgdG9nZXRoZXIuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5KHRyYW5zZm9ybSwgY29vcmRpbmF0ZSkge1xuICB2YXIgeCA9IGNvb3JkaW5hdGVbMF07XG4gIHZhciB5ID0gY29vcmRpbmF0ZVsxXTtcbiAgY29vcmRpbmF0ZVswXSA9IHRyYW5zZm9ybVswXSAqIHggKyB0cmFuc2Zvcm1bMl0gKiB5ICsgdHJhbnNmb3JtWzRdO1xuICBjb29yZGluYXRlWzFdID0gdHJhbnNmb3JtWzFdICogeCArIHRyYW5zZm9ybVszXSAqIHkgKyB0cmFuc2Zvcm1bNV07XG4gIHJldHVybiBjb29yZGluYXRlO1xufVxuLyoqXG4gKiBBcHBsaWVzIHJvdGF0aW9uIHRvIHRoZSBnaXZlbiB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gKiBAcGFyYW0ge251bWJlcn0gYW5nbGUgQW5nbGUgaW4gcmFkaWFucy5cbiAqIEByZXR1cm4geyFUcmFuc2Zvcm19IFRoZSByb3RhdGVkIHRyYW5zZm9ybS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlKHRyYW5zZm9ybSwgYW5nbGUpIHtcbiAgdmFyIGNvcyA9IE1hdGguY29zKGFuZ2xlKTtcbiAgdmFyIHNpbiA9IE1hdGguc2luKGFuZ2xlKTtcbiAgcmV0dXJuIG11bHRpcGx5KHRyYW5zZm9ybSwgc2V0KHRtcF8sIGNvcywgc2luLCAtc2luLCBjb3MsIDAsIDApKTtcbn1cbi8qKlxuICogQXBwbGllcyBzY2FsZSB0byBhIGdpdmVuIHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7IVRyYW5zZm9ybX0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFNjYWxlIGZhY3RvciB4LlxuICogQHBhcmFtIHtudW1iZXJ9IHkgU2NhbGUgZmFjdG9yIHkuXG4gKiBAcmV0dXJuIHshVHJhbnNmb3JtfSBUaGUgc2NhbGVkIHRyYW5zZm9ybS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2NhbGUodHJhbnNmb3JtLCB4LCB5KSB7XG4gIHJldHVybiBtdWx0aXBseSh0cmFuc2Zvcm0sIHNldCh0bXBfLCB4LCAwLCAwLCB5LCAwLCAwKSk7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBzY2FsZSB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IHRhcmdldCBUcmFuc2Zvcm0gdG8gb3ZlcndyaXRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHggU2NhbGUgZmFjdG9yIHguXG4gKiBAcGFyYW0ge251bWJlcn0geSBTY2FsZSBmYWN0b3IgeS5cbiAqIEByZXR1cm4geyFUcmFuc2Zvcm19IFRoZSBzY2FsZSB0cmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG1ha2VTY2FsZSh0YXJnZXQsIHgsIHkpIHtcbiAgcmV0dXJuIHNldCh0YXJnZXQsIHgsIDAsIDAsIHksIDAsIDApO1xufVxuLyoqXG4gKiBBcHBsaWVzIHRyYW5zbGF0aW9uIHRvIHRoZSBnaXZlbiB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gKiBAcGFyYW0ge251bWJlcn0gZHggVHJhbnNsYXRpb24geC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkeSBUcmFuc2xhdGlvbiB5LlxuICogQHJldHVybiB7IVRyYW5zZm9ybX0gVGhlIHRyYW5zbGF0ZWQgdHJhbnNmb3JtLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2xhdGUodHJhbnNmb3JtLCBkeCwgZHkpIHtcbiAgcmV0dXJuIG11bHRpcGx5KHRyYW5zZm9ybSwgc2V0KHRtcF8sIDEsIDAsIDAsIDEsIGR4LCBkeSkpO1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgY29tcG9zaXRlIHRyYW5zZm9ybSBnaXZlbiBhbiBpbml0aWFsIHRyYW5zbGF0aW9uLCBzY2FsZSwgcm90YXRpb24sIGFuZFxuICogZmluYWwgdHJhbnNsYXRpb24gKGluIHRoYXQgb3JkZXIgb25seSwgbm90IGNvbW11dGF0aXZlKS5cbiAqIEBwYXJhbSB7IVRyYW5zZm9ybX0gdHJhbnNmb3JtIFRoZSB0cmFuc2Zvcm0gKHdpbGwgYmUgbW9kaWZpZWQgaW4gcGxhY2UpLlxuICogQHBhcmFtIHtudW1iZXJ9IGR4MSBJbml0aWFsIHRyYW5zbGF0aW9uIHguXG4gKiBAcGFyYW0ge251bWJlcn0gZHkxIEluaXRpYWwgdHJhbnNsYXRpb24geS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzeCBTY2FsZSBmYWN0b3IgeC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzeSBTY2FsZSBmYWN0b3IgeS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBhbmdsZSBSb3RhdGlvbiAoaW4gY291bnRlci1jbG9ja3dpc2UgcmFkaWFucykuXG4gKiBAcGFyYW0ge251bWJlcn0gZHgyIEZpbmFsIHRyYW5zbGF0aW9uIHguXG4gKiBAcGFyYW0ge251bWJlcn0gZHkyIEZpbmFsIHRyYW5zbGF0aW9uIHkuXG4gKiBAcmV0dXJuIHshVHJhbnNmb3JtfSBUaGUgY29tcG9zaXRlIHRyYW5zZm9ybS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29tcG9zZSh0cmFuc2Zvcm0sIGR4MSwgZHkxLCBzeCwgc3ksIGFuZ2xlLCBkeDIsIGR5Mikge1xuICB2YXIgc2luID0gTWF0aC5zaW4oYW5nbGUpO1xuICB2YXIgY29zID0gTWF0aC5jb3MoYW5nbGUpO1xuICB0cmFuc2Zvcm1bMF0gPSBzeCAqIGNvcztcbiAgdHJhbnNmb3JtWzFdID0gc3kgKiBzaW47XG4gIHRyYW5zZm9ybVsyXSA9IC1zeCAqIHNpbjtcbiAgdHJhbnNmb3JtWzNdID0gc3kgKiBjb3M7XG4gIHRyYW5zZm9ybVs0XSA9IGR4MiAqIHN4ICogY29zIC0gZHkyICogc3ggKiBzaW4gKyBkeDE7XG4gIHRyYW5zZm9ybVs1XSA9IGR4MiAqIHN5ICogc2luICsgZHkyICogc3kgKiBjb3MgKyBkeTE7XG4gIHJldHVybiB0cmFuc2Zvcm07XG59XG4vKipcbiAqIENyZWF0ZXMgYSBjb21wb3NpdGUgdHJhbnNmb3JtIGdpdmVuIGFuIGluaXRpYWwgdHJhbnNsYXRpb24sIHNjYWxlLCByb3RhdGlvbiwgYW5kXG4gKiBmaW5hbCB0cmFuc2xhdGlvbiAoaW4gdGhhdCBvcmRlciBvbmx5LCBub3QgY29tbXV0YXRpdmUpLiBUaGUgcmVzdWx0aW5nIHRyYW5zZm9ybVxuICogc3RyaW5nIGNhbiBiZSBhcHBsaWVkIGFzIGB0cmFuc2Zvcm1gIHBvcnBlcnR5IG9mIGFuIEhUTUxFbGVtZW50J3Mgc3R5bGUuXG4gKiBAcGFyYW0ge251bWJlcn0gZHgxIEluaXRpYWwgdHJhbnNsYXRpb24geC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkeTEgSW5pdGlhbCB0cmFuc2xhdGlvbiB5LlxuICogQHBhcmFtIHtudW1iZXJ9IHN4IFNjYWxlIGZhY3RvciB4LlxuICogQHBhcmFtIHtudW1iZXJ9IHN5IFNjYWxlIGZhY3RvciB5LlxuICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlIFJvdGF0aW9uIChpbiBjb3VudGVyLWNsb2Nrd2lzZSByYWRpYW5zKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkeDIgRmluYWwgdHJhbnNsYXRpb24geC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkeTIgRmluYWwgdHJhbnNsYXRpb24geS5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGNvbXBvc2l0ZSBjc3MgdHJhbnNmb3JtLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb21wb3NlQ3NzVHJhbnNmb3JtKGR4MSwgZHkxLCBzeCwgc3ksIGFuZ2xlLCBkeDIsIGR5Mikge1xuICByZXR1cm4gdG9TdHJpbmcoY29tcG9zZShjcmVhdGUoKSwgZHgxLCBkeTEsIHN4LCBzeSwgYW5nbGUsIGR4MiwgZHkyKSk7XG59XG4vKipcbiAqIEludmVydCB0aGUgZ2l2ZW4gdHJhbnNmb3JtLlxuICogQHBhcmFtIHshVHJhbnNmb3JtfSBzb3VyY2UgVGhlIHNvdXJjZSB0cmFuc2Zvcm0gdG8gaW52ZXJ0LlxuICogQHJldHVybiB7IVRyYW5zZm9ybX0gVGhlIGludmVydGVkIChzb3VyY2UpIHRyYW5zZm9ybS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW52ZXJ0KHNvdXJjZSkge1xuICByZXR1cm4gbWFrZUludmVyc2Uoc291cmNlLCBzb3VyY2UpO1xufVxuLyoqXG4gKiBJbnZlcnQgdGhlIGdpdmVuIHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7IVRyYW5zZm9ybX0gdGFyZ2V0IFRyYW5zZm9ybSB0byBiZSBzZXQgYXMgdGhlIGludmVyc2Ugb2ZcbiAqICAgICB0aGUgc291cmNlIHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7IVRyYW5zZm9ybX0gc291cmNlIFRoZSBzb3VyY2UgdHJhbnNmb3JtIHRvIGludmVydC5cbiAqIEByZXR1cm4geyFUcmFuc2Zvcm19IFRoZSBpbnZlcnRlZCAodGFyZ2V0KSB0cmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG1ha2VJbnZlcnNlKHRhcmdldCwgc291cmNlKSB7XG4gIHZhciBkZXQgPSBkZXRlcm1pbmFudChzb3VyY2UpO1xuICBhc3NlcnQoZGV0ICE9PSAwLCAzMik7IC8vIFRyYW5zZm9ybWF0aW9uIG1hdHJpeCBjYW5ub3QgYmUgaW52ZXJ0ZWRcblxuICB2YXIgYSA9IHNvdXJjZVswXTtcbiAgdmFyIGIgPSBzb3VyY2VbMV07XG4gIHZhciBjID0gc291cmNlWzJdO1xuICB2YXIgZCA9IHNvdXJjZVszXTtcbiAgdmFyIGUgPSBzb3VyY2VbNF07XG4gIHZhciBmID0gc291cmNlWzVdO1xuICB0YXJnZXRbMF0gPSBkIC8gZGV0O1xuICB0YXJnZXRbMV0gPSAtYiAvIGRldDtcbiAgdGFyZ2V0WzJdID0gLWMgLyBkZXQ7XG4gIHRhcmdldFszXSA9IGEgLyBkZXQ7XG4gIHRhcmdldFs0XSA9IChjICogZiAtIGQgKiBlKSAvIGRldDtcbiAgdGFyZ2V0WzVdID0gLShhICogZiAtIGIgKiBlKSAvIGRldDtcbiAgcmV0dXJuIHRhcmdldDtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgZGV0ZXJtaW5hbnQgb2YgdGhlIGdpdmVuIG1hdHJpeC5cbiAqIEBwYXJhbSB7IVRyYW5zZm9ybX0gbWF0IE1hdHJpeC5cbiAqIEByZXR1cm4ge251bWJlcn0gRGV0ZXJtaW5hbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRldGVybWluYW50KG1hdCkge1xuICByZXR1cm4gbWF0WzBdICogbWF0WzNdIC0gbWF0WzFdICogbWF0WzJdO1xufVxuLyoqXG4gKiBBIHN0cmluZyB2ZXJzaW9uIG9mIHRoZSB0cmFuc2Zvcm0uICBUaGlzIGNhbiBiZSB1c2VkXG4gKiBmb3IgQ1NTIHRyYW5zZm9ybXMuXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IG1hdCBNYXRyaXguXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSB0cmFuc2Zvcm0gYXMgYSBzdHJpbmcuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvU3RyaW5nKG1hdCkge1xuICByZXR1cm4gJ21hdHJpeCgnICsgbWF0LmpvaW4oJywgJykgKyAnKSc7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2V4dGVudC9Db3JuZXJcbiAqL1xuXG4vKipcbiAqIEV4dGVudCBjb3JuZXIuXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIEJPVFRPTV9MRUZUOiAnYm90dG9tLWxlZnQnLFxuICBCT1RUT01fUklHSFQ6ICdib3R0b20tcmlnaHQnLFxuICBUT1BfTEVGVDogJ3RvcC1sZWZ0JyxcbiAgVE9QX1JJR0hUOiAndG9wLXJpZ2h0J1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZXh0ZW50L1JlbGF0aW9uc2hpcFxuICovXG5cbi8qKlxuICogUmVsYXRpb25zaGlwIHRvIGFuIGV4dGVudC5cbiAqIEBlbnVtIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgVU5LTk9XTjogMCxcbiAgSU5URVJTRUNUSU5HOiAxLFxuICBBQk9WRTogMixcbiAgUklHSFQ6IDQsXG4gIEJFTE9XOiA4LFxuICBMRUZUOiAxNlxufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZXh0ZW50XG4gKi9cbmltcG9ydCBDb3JuZXIgZnJvbSAnLi9leHRlbnQvQ29ybmVyLmpzJztcbmltcG9ydCBSZWxhdGlvbnNoaXAgZnJvbSAnLi9leHRlbnQvUmVsYXRpb25zaGlwLmpzJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4vYXNzZXJ0cy5qcyc7XG4vKipcbiAqIEFuIGFycmF5IG9mIG51bWJlcnMgcmVwcmVzZW50aW5nIGFuIGV4dGVudDogYFttaW54LCBtaW55LCBtYXh4LCBtYXh5XWAuXG4gKiBAdHlwZWRlZiB7QXJyYXk8bnVtYmVyPn0gRXh0ZW50XG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBCdWlsZCBhbiBleHRlbnQgdGhhdCBpbmNsdWRlcyBhbGwgZ2l2ZW4gY29vcmRpbmF0ZXMuXG4gKlxuICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICogQHJldHVybiB7RXh0ZW50fSBCb3VuZGluZyBleHRlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGJvdW5kaW5nRXh0ZW50KGNvb3JkaW5hdGVzKSB7XG4gIHZhciBleHRlbnQgPSBjcmVhdGVFbXB0eSgpO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGNvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICBleHRlbmRDb29yZGluYXRlKGV4dGVudCwgY29vcmRpbmF0ZXNbaV0pO1xuICB9XG5cbiAgcmV0dXJuIGV4dGVudDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSB4cyBYcy5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geXMgWXMuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRGVzdGluYXRpb24gZXh0ZW50LlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge0V4dGVudH0gRXh0ZW50LlxuICovXG5cbmZ1bmN0aW9uIF9ib3VuZGluZ0V4dGVudFhZcyh4cywgeXMsIG9wdF9leHRlbnQpIHtcbiAgdmFyIG1pblggPSBNYXRoLm1pbi5hcHBseShudWxsLCB4cyk7XG4gIHZhciBtaW5ZID0gTWF0aC5taW4uYXBwbHkobnVsbCwgeXMpO1xuICB2YXIgbWF4WCA9IE1hdGgubWF4LmFwcGx5KG51bGwsIHhzKTtcbiAgdmFyIG1heFkgPSBNYXRoLm1heC5hcHBseShudWxsLCB5cyk7XG4gIHJldHVybiBjcmVhdGVPclVwZGF0ZShtaW5YLCBtaW5ZLCBtYXhYLCBtYXhZLCBvcHRfZXh0ZW50KTtcbn1cbi8qKlxuICogUmV0dXJuIGV4dGVudCBpbmNyZWFzZWQgYnkgdGhlIHByb3ZpZGVkIHZhbHVlLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIGFtb3VudCBieSB3aGljaCB0aGUgZXh0ZW50IHNob3VsZCBiZSBidWZmZXJlZC5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBidWZmZXIoZXh0ZW50LCB2YWx1ZSwgb3B0X2V4dGVudCkge1xuICBpZiAob3B0X2V4dGVudCkge1xuICAgIG9wdF9leHRlbnRbMF0gPSBleHRlbnRbMF0gLSB2YWx1ZTtcbiAgICBvcHRfZXh0ZW50WzFdID0gZXh0ZW50WzFdIC0gdmFsdWU7XG4gICAgb3B0X2V4dGVudFsyXSA9IGV4dGVudFsyXSArIHZhbHVlO1xuICAgIG9wdF9leHRlbnRbM10gPSBleHRlbnRbM10gKyB2YWx1ZTtcbiAgICByZXR1cm4gb3B0X2V4dGVudDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW2V4dGVudFswXSAtIHZhbHVlLCBleHRlbnRbMV0gLSB2YWx1ZSwgZXh0ZW50WzJdICsgdmFsdWUsIGV4dGVudFszXSArIHZhbHVlXTtcbiAgfVxufVxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYW4gZXh0ZW50LlxuICpcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50IHRvIGNsb25lLlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge0V4dGVudH0gVGhlIGNsb25lLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZShleHRlbnQsIG9wdF9leHRlbnQpIHtcbiAgaWYgKG9wdF9leHRlbnQpIHtcbiAgICBvcHRfZXh0ZW50WzBdID0gZXh0ZW50WzBdO1xuICAgIG9wdF9leHRlbnRbMV0gPSBleHRlbnRbMV07XG4gICAgb3B0X2V4dGVudFsyXSA9IGV4dGVudFsyXTtcbiAgICBvcHRfZXh0ZW50WzNdID0gZXh0ZW50WzNdO1xuICAgIHJldHVybiBvcHRfZXh0ZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBleHRlbnQuc2xpY2UoKTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICogQHJldHVybiB7bnVtYmVyfSBDbG9zZXN0IHNxdWFyZWQgZGlzdGFuY2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWShleHRlbnQsIHgsIHkpIHtcbiAgdmFyIGR4LCBkeTtcblxuICBpZiAoeCA8IGV4dGVudFswXSkge1xuICAgIGR4ID0gZXh0ZW50WzBdIC0geDtcbiAgfSBlbHNlIGlmIChleHRlbnRbMl0gPCB4KSB7XG4gICAgZHggPSB4IC0gZXh0ZW50WzJdO1xuICB9IGVsc2Uge1xuICAgIGR4ID0gMDtcbiAgfVxuXG4gIGlmICh5IDwgZXh0ZW50WzFdKSB7XG4gICAgZHkgPSBleHRlbnRbMV0gLSB5O1xuICB9IGVsc2UgaWYgKGV4dGVudFszXSA8IHkpIHtcbiAgICBkeSA9IHkgLSBleHRlbnRbM107XG4gIH0gZWxzZSB7XG4gICAgZHkgPSAwO1xuICB9XG5cbiAgcmV0dXJuIGR4ICogZHggKyBkeSAqIGR5O1xufVxuLyoqXG4gKiBDaGVjayBpZiB0aGUgcGFzc2VkIGNvb3JkaW5hdGUgaXMgY29udGFpbmVkIG9yIG9uIHRoZSBlZGdlIG9mIHRoZSBleHRlbnQuXG4gKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgY29vcmRpbmF0ZSBpcyBjb250YWluZWQgaW4gdGhlIGV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnNDb29yZGluYXRlKGV4dGVudCwgY29vcmRpbmF0ZSkge1xuICByZXR1cm4gY29udGFpbnNYWShleHRlbnQsIGNvb3JkaW5hdGVbMF0sIGNvb3JkaW5hdGVbMV0pO1xufVxuLyoqXG4gKiBDaGVjayBpZiBvbmUgZXh0ZW50IGNvbnRhaW5zIGFub3RoZXIuXG4gKlxuICogQW4gZXh0ZW50IGlzIGRlZW1lZCBjb250YWluZWQgaWYgaXQgbGllcyBjb21wbGV0ZWx5IHdpdGhpbiB0aGUgb3RoZXIgZXh0ZW50LFxuICogaW5jbHVkaW5nIGlmIHRoZXkgc2hhcmUgb25lIG9yIG1vcmUgZWRnZXMuXG4gKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDEgRXh0ZW50IDEuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MiBFeHRlbnQgMi5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBzZWNvbmQgZXh0ZW50IGlzIGNvbnRhaW5lZCBieSBvciBvbiB0aGUgZWRnZSBvZiB0aGVcbiAqICAgICBmaXJzdC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnNFeHRlbnQoZXh0ZW50MSwgZXh0ZW50Mikge1xuICByZXR1cm4gZXh0ZW50MVswXSA8PSBleHRlbnQyWzBdICYmIGV4dGVudDJbMl0gPD0gZXh0ZW50MVsyXSAmJiBleHRlbnQxWzFdIDw9IGV4dGVudDJbMV0gJiYgZXh0ZW50MlszXSA8PSBleHRlbnQxWzNdO1xufVxuLyoqXG4gKiBDaGVjayBpZiB0aGUgcGFzc2VkIGNvb3JkaW5hdGUgaXMgY29udGFpbmVkIG9yIG9uIHRoZSBlZGdlIG9mIHRoZSBleHRlbnQuXG4gKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYIGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge251bWJlcn0geSBZIGNvb3JkaW5hdGUuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgeCwgeSB2YWx1ZXMgYXJlIGNvbnRhaW5lZCBpbiB0aGUgZXh0ZW50LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb250YWluc1hZKGV4dGVudCwgeCwgeSkge1xuICByZXR1cm4gZXh0ZW50WzBdIDw9IHggJiYgeCA8PSBleHRlbnRbMl0gJiYgZXh0ZW50WzFdIDw9IHkgJiYgeSA8PSBleHRlbnRbM107XG59XG4vKipcbiAqIEdldCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYSBjb29yZGluYXRlIGFuZCBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IFRoZSBleHRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIFRoZSBjb29yZGluYXRlLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9leHRlbnQvUmVsYXRpb25zaGlwLmpzXCIpLmRlZmF1bHR9IFRoZSByZWxhdGlvbnNoaXAgKGJpdHdpc2UgY29tcGFyZSB3aXRoXG4gKiAgICAgaW1wb3J0KFwiLi9leHRlbnQvUmVsYXRpb25zaGlwLmpzXCIpLlJlbGF0aW9uc2hpcCkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNvb3JkaW5hdGVSZWxhdGlvbnNoaXAoZXh0ZW50LCBjb29yZGluYXRlKSB7XG4gIHZhciBtaW5YID0gZXh0ZW50WzBdO1xuICB2YXIgbWluWSA9IGV4dGVudFsxXTtcbiAgdmFyIG1heFggPSBleHRlbnRbMl07XG4gIHZhciBtYXhZID0gZXh0ZW50WzNdO1xuICB2YXIgeCA9IGNvb3JkaW5hdGVbMF07XG4gIHZhciB5ID0gY29vcmRpbmF0ZVsxXTtcbiAgdmFyIHJlbGF0aW9uc2hpcCA9IFJlbGF0aW9uc2hpcC5VTktOT1dOO1xuXG4gIGlmICh4IDwgbWluWCkge1xuICAgIHJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcCB8IFJlbGF0aW9uc2hpcC5MRUZUO1xuICB9IGVsc2UgaWYgKHggPiBtYXhYKSB7XG4gICAgcmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwIHwgUmVsYXRpb25zaGlwLlJJR0hUO1xuICB9XG5cbiAgaWYgKHkgPCBtaW5ZKSB7XG4gICAgcmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwIHwgUmVsYXRpb25zaGlwLkJFTE9XO1xuICB9IGVsc2UgaWYgKHkgPiBtYXhZKSB7XG4gICAgcmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwIHwgUmVsYXRpb25zaGlwLkFCT1ZFO1xuICB9XG5cbiAgaWYgKHJlbGF0aW9uc2hpcCA9PT0gUmVsYXRpb25zaGlwLlVOS05PV04pIHtcbiAgICByZWxhdGlvbnNoaXAgPSBSZWxhdGlvbnNoaXAuSU5URVJTRUNUSU5HO1xuICB9XG5cbiAgcmV0dXJuIHJlbGF0aW9uc2hpcDtcbn1cbi8qKlxuICogQ3JlYXRlIGFuIGVtcHR5IGV4dGVudC5cbiAqIEByZXR1cm4ge0V4dGVudH0gRW1wdHkgZXh0ZW50LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbXB0eSgpIHtcbiAgcmV0dXJuIFtJbmZpbml0eSwgSW5maW5pdHksIC1JbmZpbml0eSwgLUluZmluaXR5XTtcbn1cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGV4dGVudCBvciB1cGRhdGUgdGhlIHByb3ZpZGVkIGV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5YIE1pbmltdW0gWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5ZIE1pbmltdW0gWS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhYIE1heGltdW0gWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhZIE1heGltdW0gWS5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBEZXN0aW5hdGlvbiBleHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGUobWluWCwgbWluWSwgbWF4WCwgbWF4WSwgb3B0X2V4dGVudCkge1xuICBpZiAob3B0X2V4dGVudCkge1xuICAgIG9wdF9leHRlbnRbMF0gPSBtaW5YO1xuICAgIG9wdF9leHRlbnRbMV0gPSBtaW5ZO1xuICAgIG9wdF9leHRlbnRbMl0gPSBtYXhYO1xuICAgIG9wdF9leHRlbnRbM10gPSBtYXhZO1xuICAgIHJldHVybiBvcHRfZXh0ZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV07XG4gIH1cbn1cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGVtcHR5IGV4dGVudCBvciBtYWtlIHRoZSBwcm92aWRlZCBvbmUgZW1wdHkuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlRW1wdHkob3B0X2V4dGVudCkge1xuICByZXR1cm4gY3JlYXRlT3JVcGRhdGUoSW5maW5pdHksIEluZmluaXR5LCAtSW5maW5pdHksIC1JbmZpbml0eSwgb3B0X2V4dGVudCk7XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGVGcm9tQ29vcmRpbmF0ZShjb29yZGluYXRlLCBvcHRfZXh0ZW50KSB7XG4gIHZhciB4ID0gY29vcmRpbmF0ZVswXTtcbiAgdmFyIHkgPSBjb29yZGluYXRlWzFdO1xuICByZXR1cm4gY3JlYXRlT3JVcGRhdGUoeCwgeSwgeCwgeSwgb3B0X2V4dGVudCk7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGVGcm9tQ29vcmRpbmF0ZXMoY29vcmRpbmF0ZXMsIG9wdF9leHRlbnQpIHtcbiAgdmFyIGV4dGVudCA9IGNyZWF0ZU9yVXBkYXRlRW1wdHkob3B0X2V4dGVudCk7XG4gIHJldHVybiBleHRlbmRDb29yZGluYXRlcyhleHRlbnQsIGNvb3JkaW5hdGVzKTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGVGcm9tRmxhdENvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgb3B0X2V4dGVudCkge1xuICB2YXIgZXh0ZW50ID0gY3JlYXRlT3JVcGRhdGVFbXB0eShvcHRfZXh0ZW50KTtcbiAgcmV0dXJuIGV4dGVuZEZsYXRDb29yZGluYXRlcyhleHRlbnQsIGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSk7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pn0gcmluZ3MgUmluZ3MuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlRnJvbVJpbmdzKHJpbmdzLCBvcHRfZXh0ZW50KSB7XG4gIHZhciBleHRlbnQgPSBjcmVhdGVPclVwZGF0ZUVtcHR5KG9wdF9leHRlbnQpO1xuICByZXR1cm4gZXh0ZW5kUmluZ3MoZXh0ZW50LCByaW5ncyk7XG59XG4vKipcbiAqIERldGVybWluZSBpZiB0d28gZXh0ZW50cyBhcmUgZXF1aXZhbGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQxIEV4dGVudCAxLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDIgRXh0ZW50IDIuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgdHdvIGV4dGVudHMgYXJlIGVxdWl2YWxlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWFscyhleHRlbnQxLCBleHRlbnQyKSB7XG4gIHJldHVybiBleHRlbnQxWzBdID09IGV4dGVudDJbMF0gJiYgZXh0ZW50MVsyXSA9PSBleHRlbnQyWzJdICYmIGV4dGVudDFbMV0gPT0gZXh0ZW50MlsxXSAmJiBleHRlbnQxWzNdID09IGV4dGVudDJbM107XG59XG4vKipcbiAqIERldGVybWluZSBpZiB0d28gZXh0ZW50cyBhcmUgYXBwcm94aW1hdGVseSBlcXVpdmFsZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDEgRXh0ZW50IDEuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MiBFeHRlbnQgMi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0b2xlcmFuY2UgVG9sZXJhbmNlIGluIGV4dGVudCBjb29yZGluYXRlIHVuaXRzLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHR3byBleHRlbnRzIGRpZmZlciBieSBsZXNzIHRoYW4gdGhlIHRvbGVyYW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwcm94aW1hdGVseUVxdWFscyhleHRlbnQxLCBleHRlbnQyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIE1hdGguYWJzKGV4dGVudDFbMF0gLSBleHRlbnQyWzBdKSA8IHRvbGVyYW5jZSAmJiBNYXRoLmFicyhleHRlbnQxWzJdIC0gZXh0ZW50MlsyXSkgPCB0b2xlcmFuY2UgJiYgTWF0aC5hYnMoZXh0ZW50MVsxXSAtIGV4dGVudDJbMV0pIDwgdG9sZXJhbmNlICYmIE1hdGguYWJzKGV4dGVudDFbM10gLSBleHRlbnQyWzNdKSA8IHRvbGVyYW5jZTtcbn1cbi8qKlxuICogTW9kaWZ5IGFuIGV4dGVudCB0byBpbmNsdWRlIGFub3RoZXIgZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDEgVGhlIGV4dGVudCB0byBiZSBtb2RpZmllZC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQyIFRoZSBleHRlbnQgdGhhdCB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBmaXJzdC5cbiAqIEByZXR1cm4ge0V4dGVudH0gQSByZWZlcmVuY2UgdG8gdGhlIGZpcnN0IChleHRlbmRlZCkgZXh0ZW50LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleHRlbmQoZXh0ZW50MSwgZXh0ZW50Mikge1xuICBpZiAoZXh0ZW50MlswXSA8IGV4dGVudDFbMF0pIHtcbiAgICBleHRlbnQxWzBdID0gZXh0ZW50MlswXTtcbiAgfVxuXG4gIGlmIChleHRlbnQyWzJdID4gZXh0ZW50MVsyXSkge1xuICAgIGV4dGVudDFbMl0gPSBleHRlbnQyWzJdO1xuICB9XG5cbiAgaWYgKGV4dGVudDJbMV0gPCBleHRlbnQxWzFdKSB7XG4gICAgZXh0ZW50MVsxXSA9IGV4dGVudDJbMV07XG4gIH1cblxuICBpZiAoZXh0ZW50MlszXSA+IGV4dGVudDFbM10pIHtcbiAgICBleHRlbnQxWzNdID0gZXh0ZW50MlszXTtcbiAgfVxuXG4gIHJldHVybiBleHRlbnQxO1xufVxuLyoqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kQ29vcmRpbmF0ZShleHRlbnQsIGNvb3JkaW5hdGUpIHtcbiAgaWYgKGNvb3JkaW5hdGVbMF0gPCBleHRlbnRbMF0pIHtcbiAgICBleHRlbnRbMF0gPSBjb29yZGluYXRlWzBdO1xuICB9XG5cbiAgaWYgKGNvb3JkaW5hdGVbMF0gPiBleHRlbnRbMl0pIHtcbiAgICBleHRlbnRbMl0gPSBjb29yZGluYXRlWzBdO1xuICB9XG5cbiAgaWYgKGNvb3JkaW5hdGVbMV0gPCBleHRlbnRbMV0pIHtcbiAgICBleHRlbnRbMV0gPSBjb29yZGluYXRlWzFdO1xuICB9XG5cbiAgaWYgKGNvb3JkaW5hdGVbMV0gPiBleHRlbnRbM10pIHtcbiAgICBleHRlbnRbM10gPSBjb29yZGluYXRlWzFdO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZENvb3JkaW5hdGVzKGV4dGVudCwgY29vcmRpbmF0ZXMpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIGV4dGVuZENvb3JkaW5hdGUoZXh0ZW50LCBjb29yZGluYXRlc1tpXSk7XG4gIH1cblxuICByZXR1cm4gZXh0ZW50O1xufVxuLyoqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kRmxhdENvb3JkaW5hdGVzKGV4dGVudCwgZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKSB7XG4gIGZvciAoOyBvZmZzZXQgPCBlbmQ7IG9mZnNldCArPSBzdHJpZGUpIHtcbiAgICBleHRlbmRYWShleHRlbnQsIGZsYXRDb29yZGluYXRlc1tvZmZzZXRdLCBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV0pO1xuICB9XG5cbiAgcmV0dXJuIGV4dGVudDtcbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj59IHJpbmdzIFJpbmdzLlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZFJpbmdzKGV4dGVudCwgcmluZ3MpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gcmluZ3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIGV4dGVuZENvb3JkaW5hdGVzKGV4dGVudCwgcmluZ3NbaV0pO1xuICB9XG5cbiAgcmV0dXJuIGV4dGVudDtcbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kWFkoZXh0ZW50LCB4LCB5KSB7XG4gIGV4dGVudFswXSA9IE1hdGgubWluKGV4dGVudFswXSwgeCk7XG4gIGV4dGVudFsxXSA9IE1hdGgubWluKGV4dGVudFsxXSwgeSk7XG4gIGV4dGVudFsyXSA9IE1hdGgubWF4KGV4dGVudFsyXSwgeCk7XG4gIGV4dGVudFszXSA9IE1hdGgubWF4KGV4dGVudFszXSwgeSk7XG59XG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gY2FsbHMgYGNhbGxiYWNrYCBmb3IgZWFjaCBjb3JuZXIgb2YgdGhlIGV4dGVudC4gSWYgdGhlXG4gKiBjYWxsYmFjayByZXR1cm5zIGEgdHJ1dGh5IHZhbHVlIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRoYXQgdmFsdWVcbiAqIGltbWVkaWF0ZWx5LiBPdGhlcndpc2UgdGhlIGZ1bmN0aW9uIHJldHVybnMgYGZhbHNlYC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6IFN9IGNhbGxiYWNrIENhbGxiYWNrLlxuICogQHJldHVybiB7U3xib29sZWFufSBWYWx1ZS5cbiAqIEB0ZW1wbGF0ZSBTXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZvckVhY2hDb3JuZXIoZXh0ZW50LCBjYWxsYmFjaykge1xuICB2YXIgdmFsO1xuICB2YWwgPSBjYWxsYmFjayhnZXRCb3R0b21MZWZ0KGV4dGVudCkpO1xuXG4gIGlmICh2YWwpIHtcbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgdmFsID0gY2FsbGJhY2soZ2V0Qm90dG9tUmlnaHQoZXh0ZW50KSk7XG5cbiAgaWYgKHZhbCkge1xuICAgIHJldHVybiB2YWw7XG4gIH1cblxuICB2YWwgPSBjYWxsYmFjayhnZXRUb3BSaWdodChleHRlbnQpKTtcblxuICBpZiAodmFsKSB7XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxuXG4gIHZhbCA9IGNhbGxiYWNrKGdldFRvcExlZnQoZXh0ZW50KSk7XG5cbiAgaWYgKHZhbCkge1xuICAgIHJldHVybiB2YWw7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG4vKipcbiAqIEdldCB0aGUgc2l6ZSBvZiBhbiBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gQXJlYS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXJlYShleHRlbnQpIHtcbiAgdmFyIGFyZWEgPSAwO1xuXG4gIGlmICghaXNFbXB0eShleHRlbnQpKSB7XG4gICAgYXJlYSA9IGdldFdpZHRoKGV4dGVudCkgKiBnZXRIZWlnaHQoZXh0ZW50KTtcbiAgfVxuXG4gIHJldHVybiBhcmVhO1xufVxuLyoqXG4gKiBHZXQgdGhlIGJvdHRvbSBsZWZ0IGNvb3JkaW5hdGUgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQm90dG9tIGxlZnQgY29vcmRpbmF0ZS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Qm90dG9tTGVmdChleHRlbnQpIHtcbiAgcmV0dXJuIFtleHRlbnRbMF0sIGV4dGVudFsxXV07XG59XG4vKipcbiAqIEdldCB0aGUgYm90dG9tIHJpZ2h0IGNvb3JkaW5hdGUgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQm90dG9tIHJpZ2h0IGNvb3JkaW5hdGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJvdHRvbVJpZ2h0KGV4dGVudCkge1xuICByZXR1cm4gW2V4dGVudFsyXSwgZXh0ZW50WzFdXTtcbn1cbi8qKlxuICogR2V0IHRoZSBjZW50ZXIgY29vcmRpbmF0ZSBvZiBhbiBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDZW50ZXIuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENlbnRlcihleHRlbnQpIHtcbiAgcmV0dXJuIFsoZXh0ZW50WzBdICsgZXh0ZW50WzJdKSAvIDIsIChleHRlbnRbMV0gKyBleHRlbnRbM10pIC8gMl07XG59XG4vKipcbiAqIEdldCBhIGNvcm5lciBjb29yZGluYXRlIG9mIGFuIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC9Db3JuZXIuanNcIikuZGVmYXVsdH0gY29ybmVyIENvcm5lci5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb3JuZXIgY29vcmRpbmF0ZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29ybmVyKGV4dGVudCwgY29ybmVyKSB7XG4gIHZhciBjb29yZGluYXRlO1xuXG4gIGlmIChjb3JuZXIgPT09IENvcm5lci5CT1RUT01fTEVGVCkge1xuICAgIGNvb3JkaW5hdGUgPSBnZXRCb3R0b21MZWZ0KGV4dGVudCk7XG4gIH0gZWxzZSBpZiAoY29ybmVyID09PSBDb3JuZXIuQk9UVE9NX1JJR0hUKSB7XG4gICAgY29vcmRpbmF0ZSA9IGdldEJvdHRvbVJpZ2h0KGV4dGVudCk7XG4gIH0gZWxzZSBpZiAoY29ybmVyID09PSBDb3JuZXIuVE9QX0xFRlQpIHtcbiAgICBjb29yZGluYXRlID0gZ2V0VG9wTGVmdChleHRlbnQpO1xuICB9IGVsc2UgaWYgKGNvcm5lciA9PT0gQ29ybmVyLlRPUF9SSUdIVCkge1xuICAgIGNvb3JkaW5hdGUgPSBnZXRUb3BSaWdodChleHRlbnQpO1xuICB9IGVsc2Uge1xuICAgIGFzc2VydChmYWxzZSwgMTMpOyAvLyBJbnZhbGlkIGNvcm5lclxuICB9XG5cbiAgcmV0dXJuIGNvb3JkaW5hdGU7XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQxIEV4dGVudCAxLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDIgRXh0ZW50IDIuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEVubGFyZ2VkIGFyZWEuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEVubGFyZ2VkQXJlYShleHRlbnQxLCBleHRlbnQyKSB7XG4gIHZhciBtaW5YID0gTWF0aC5taW4oZXh0ZW50MVswXSwgZXh0ZW50MlswXSk7XG4gIHZhciBtaW5ZID0gTWF0aC5taW4oZXh0ZW50MVsxXSwgZXh0ZW50MlsxXSk7XG4gIHZhciBtYXhYID0gTWF0aC5tYXgoZXh0ZW50MVsyXSwgZXh0ZW50MlsyXSk7XG4gIHZhciBtYXhZID0gTWF0aC5tYXgoZXh0ZW50MVszXSwgZXh0ZW50MlszXSk7XG4gIHJldHVybiAobWF4WCAtIG1pblgpICogKG1heFkgLSBtaW5ZKTtcbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY2VudGVyIENlbnRlci5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gcm90YXRpb24gUm90YXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIFNpemUuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRGVzdGluYXRpb24gZXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvclZpZXdBbmRTaXplKGNlbnRlciwgcmVzb2x1dGlvbiwgcm90YXRpb24sIHNpemUsIG9wdF9leHRlbnQpIHtcbiAgdmFyIGR4ID0gcmVzb2x1dGlvbiAqIHNpemVbMF0gLyAyO1xuICB2YXIgZHkgPSByZXNvbHV0aW9uICogc2l6ZVsxXSAvIDI7XG4gIHZhciBjb3NSb3RhdGlvbiA9IE1hdGguY29zKHJvdGF0aW9uKTtcbiAgdmFyIHNpblJvdGF0aW9uID0gTWF0aC5zaW4ocm90YXRpb24pO1xuICB2YXIgeENvcyA9IGR4ICogY29zUm90YXRpb247XG4gIHZhciB4U2luID0gZHggKiBzaW5Sb3RhdGlvbjtcbiAgdmFyIHlDb3MgPSBkeSAqIGNvc1JvdGF0aW9uO1xuICB2YXIgeVNpbiA9IGR5ICogc2luUm90YXRpb247XG4gIHZhciB4ID0gY2VudGVyWzBdO1xuICB2YXIgeSA9IGNlbnRlclsxXTtcbiAgdmFyIHgwID0geCAtIHhDb3MgKyB5U2luO1xuICB2YXIgeDEgPSB4IC0geENvcyAtIHlTaW47XG4gIHZhciB4MiA9IHggKyB4Q29zIC0geVNpbjtcbiAgdmFyIHgzID0geCArIHhDb3MgKyB5U2luO1xuICB2YXIgeTAgPSB5IC0geFNpbiAtIHlDb3M7XG4gIHZhciB5MSA9IHkgLSB4U2luICsgeUNvcztcbiAgdmFyIHkyID0geSArIHhTaW4gKyB5Q29zO1xuICB2YXIgeTMgPSB5ICsgeFNpbiAtIHlDb3M7XG4gIHJldHVybiBjcmVhdGVPclVwZGF0ZShNYXRoLm1pbih4MCwgeDEsIHgyLCB4MyksIE1hdGgubWluKHkwLCB5MSwgeTIsIHkzKSwgTWF0aC5tYXgoeDAsIHgxLCB4MiwgeDMpLCBNYXRoLm1heCh5MCwgeTEsIHkyLCB5MyksIG9wdF9leHRlbnQpO1xufVxuLyoqXG4gKiBHZXQgdGhlIGhlaWdodCBvZiBhbiBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gSGVpZ2h0LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRIZWlnaHQoZXh0ZW50KSB7XG4gIHJldHVybiBleHRlbnRbM10gLSBleHRlbnRbMV07XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQxIEV4dGVudCAxLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDIgRXh0ZW50IDIuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEludGVyc2VjdGlvbiBhcmVhLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbnRlcnNlY3Rpb25BcmVhKGV4dGVudDEsIGV4dGVudDIpIHtcbiAgdmFyIGludGVyc2VjdGlvbiA9IGdldEludGVyc2VjdGlvbihleHRlbnQxLCBleHRlbnQyKTtcbiAgcmV0dXJuIGdldEFyZWEoaW50ZXJzZWN0aW9uKTtcbn1cbi8qKlxuICogR2V0IHRoZSBpbnRlcnNlY3Rpb24gb2YgdHdvIGV4dGVudHMuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MSBFeHRlbnQgMS5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQyIEV4dGVudCAyLlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IE9wdGlvbmFsIGV4dGVudCB0byBwb3B1bGF0ZSB3aXRoIGludGVyc2VjdGlvbi5cbiAqIEByZXR1cm4ge0V4dGVudH0gSW50ZXJzZWN0aW5nIGV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW50ZXJzZWN0aW9uKGV4dGVudDEsIGV4dGVudDIsIG9wdF9leHRlbnQpIHtcbiAgdmFyIGludGVyc2VjdGlvbiA9IG9wdF9leHRlbnQgPyBvcHRfZXh0ZW50IDogY3JlYXRlRW1wdHkoKTtcblxuICBpZiAoaW50ZXJzZWN0cyhleHRlbnQxLCBleHRlbnQyKSkge1xuICAgIGlmIChleHRlbnQxWzBdID4gZXh0ZW50MlswXSkge1xuICAgICAgaW50ZXJzZWN0aW9uWzBdID0gZXh0ZW50MVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW50ZXJzZWN0aW9uWzBdID0gZXh0ZW50MlswXTtcbiAgICB9XG5cbiAgICBpZiAoZXh0ZW50MVsxXSA+IGV4dGVudDJbMV0pIHtcbiAgICAgIGludGVyc2VjdGlvblsxXSA9IGV4dGVudDFbMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGludGVyc2VjdGlvblsxXSA9IGV4dGVudDJbMV07XG4gICAgfVxuXG4gICAgaWYgKGV4dGVudDFbMl0gPCBleHRlbnQyWzJdKSB7XG4gICAgICBpbnRlcnNlY3Rpb25bMl0gPSBleHRlbnQxWzJdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbnRlcnNlY3Rpb25bMl0gPSBleHRlbnQyWzJdO1xuICAgIH1cblxuICAgIGlmIChleHRlbnQxWzNdIDwgZXh0ZW50MlszXSkge1xuICAgICAgaW50ZXJzZWN0aW9uWzNdID0gZXh0ZW50MVszXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW50ZXJzZWN0aW9uWzNdID0gZXh0ZW50MlszXTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY3JlYXRlT3JVcGRhdGVFbXB0eShpbnRlcnNlY3Rpb24pO1xuICB9XG5cbiAgcmV0dXJuIGludGVyc2VjdGlvbjtcbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE1hcmdpbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWFyZ2luKGV4dGVudCkge1xuICByZXR1cm4gZ2V0V2lkdGgoZXh0ZW50KSArIGdldEhlaWdodChleHRlbnQpO1xufVxuLyoqXG4gKiBHZXQgdGhlIHNpemUgKHdpZHRoLCBoZWlnaHQpIG9mIGFuIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgVGhlIGV4dGVudC5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBUaGUgZXh0ZW50IHNpemUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNpemUoZXh0ZW50KSB7XG4gIHJldHVybiBbZXh0ZW50WzJdIC0gZXh0ZW50WzBdLCBleHRlbnRbM10gLSBleHRlbnRbMV1dO1xufVxuLyoqXG4gKiBHZXQgdGhlIHRvcCBsZWZ0IGNvb3JkaW5hdGUgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gVG9wIGxlZnQgY29vcmRpbmF0ZS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VG9wTGVmdChleHRlbnQpIHtcbiAgcmV0dXJuIFtleHRlbnRbMF0sIGV4dGVudFszXV07XG59XG4vKipcbiAqIEdldCB0aGUgdG9wIHJpZ2h0IGNvb3JkaW5hdGUgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gVG9wIHJpZ2h0IGNvb3JkaW5hdGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRvcFJpZ2h0KGV4dGVudCkge1xuICByZXR1cm4gW2V4dGVudFsyXSwgZXh0ZW50WzNdXTtcbn1cbi8qKlxuICogR2V0IHRoZSB3aWR0aCBvZiBhbiBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gV2lkdGguXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFdpZHRoKGV4dGVudCkge1xuICByZXR1cm4gZXh0ZW50WzJdIC0gZXh0ZW50WzBdO1xufVxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgb25lIGV4dGVudCBpbnRlcnNlY3RzIGFub3RoZXIuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MSBFeHRlbnQgMS5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQyIEV4dGVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSB0d28gZXh0ZW50cyBpbnRlcnNlY3QuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludGVyc2VjdHMoZXh0ZW50MSwgZXh0ZW50Mikge1xuICByZXR1cm4gZXh0ZW50MVswXSA8PSBleHRlbnQyWzJdICYmIGV4dGVudDFbMl0gPj0gZXh0ZW50MlswXSAmJiBleHRlbnQxWzFdIDw9IGV4dGVudDJbM10gJiYgZXh0ZW50MVszXSA+PSBleHRlbnQyWzFdO1xufVxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYW4gZXh0ZW50IGlzIGVtcHR5LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBJcyBlbXB0eS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNFbXB0eShleHRlbnQpIHtcbiAgcmV0dXJuIGV4dGVudFsyXSA8IGV4dGVudFswXSB8fCBleHRlbnRbM10gPCBleHRlbnRbMV07XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge0V4dGVudH0gRXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByZXR1cm5PclVwZGF0ZShleHRlbnQsIG9wdF9leHRlbnQpIHtcbiAgaWYgKG9wdF9leHRlbnQpIHtcbiAgICBvcHRfZXh0ZW50WzBdID0gZXh0ZW50WzBdO1xuICAgIG9wdF9leHRlbnRbMV0gPSBleHRlbnRbMV07XG4gICAgb3B0X2V4dGVudFsyXSA9IGV4dGVudFsyXTtcbiAgICBvcHRfZXh0ZW50WzNdID0gZXh0ZW50WzNdO1xuICAgIHJldHVybiBvcHRfZXh0ZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBleHRlbnQ7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlRnJvbUNlbnRlcihleHRlbnQsIHZhbHVlKSB7XG4gIHZhciBkZWx0YVggPSAoZXh0ZW50WzJdIC0gZXh0ZW50WzBdKSAvIDIgKiAodmFsdWUgLSAxKTtcbiAgdmFyIGRlbHRhWSA9IChleHRlbnRbM10gLSBleHRlbnRbMV0pIC8gMiAqICh2YWx1ZSAtIDEpO1xuICBleHRlbnRbMF0gLT0gZGVsdGFYO1xuICBleHRlbnRbMl0gKz0gZGVsdGFYO1xuICBleHRlbnRbMV0gLT0gZGVsdGFZO1xuICBleHRlbnRbM10gKz0gZGVsdGFZO1xufVxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgdGhlIHNlZ21lbnQgYmV0d2VlbiB0d28gY29vcmRpbmF0ZXMgaW50ZXJzZWN0cyAoY3Jvc3NlcyxcbiAqIHRvdWNoZXMsIG9yIGlzIGNvbnRhaW5lZCBieSkgdGhlIHByb3ZpZGVkIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgVGhlIGV4dGVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHN0YXJ0IFNlZ21lbnQgc3RhcnQgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGVuZCBTZWdtZW50IGVuZCBjb29yZGluYXRlLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHNlZ21lbnQgaW50ZXJzZWN0cyB0aGUgZXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnNlY3RzU2VnbWVudChleHRlbnQsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGludGVyc2VjdHMgPSBmYWxzZTtcbiAgdmFyIHN0YXJ0UmVsID0gY29vcmRpbmF0ZVJlbGF0aW9uc2hpcChleHRlbnQsIHN0YXJ0KTtcbiAgdmFyIGVuZFJlbCA9IGNvb3JkaW5hdGVSZWxhdGlvbnNoaXAoZXh0ZW50LCBlbmQpO1xuXG4gIGlmIChzdGFydFJlbCA9PT0gUmVsYXRpb25zaGlwLklOVEVSU0VDVElORyB8fCBlbmRSZWwgPT09IFJlbGF0aW9uc2hpcC5JTlRFUlNFQ1RJTkcpIHtcbiAgICBpbnRlcnNlY3RzID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbWluWCA9IGV4dGVudFswXTtcbiAgICB2YXIgbWluWSA9IGV4dGVudFsxXTtcbiAgICB2YXIgbWF4WCA9IGV4dGVudFsyXTtcbiAgICB2YXIgbWF4WSA9IGV4dGVudFszXTtcbiAgICB2YXIgc3RhcnRYID0gc3RhcnRbMF07XG4gICAgdmFyIHN0YXJ0WSA9IHN0YXJ0WzFdO1xuICAgIHZhciBlbmRYID0gZW5kWzBdO1xuICAgIHZhciBlbmRZID0gZW5kWzFdO1xuICAgIHZhciBzbG9wZSA9IChlbmRZIC0gc3RhcnRZKSAvIChlbmRYIC0gc3RhcnRYKTtcbiAgICB2YXIgeCA9IHZvaWQgMCxcbiAgICAgICAgeSA9IHZvaWQgMDtcblxuICAgIGlmICghIShlbmRSZWwgJiBSZWxhdGlvbnNoaXAuQUJPVkUpICYmICEoc3RhcnRSZWwgJiBSZWxhdGlvbnNoaXAuQUJPVkUpKSB7XG4gICAgICAvLyBwb3RlbnRpYWxseSBpbnRlcnNlY3RzIHRvcFxuICAgICAgeCA9IGVuZFggLSAoZW5kWSAtIG1heFkpIC8gc2xvcGU7XG4gICAgICBpbnRlcnNlY3RzID0geCA+PSBtaW5YICYmIHggPD0gbWF4WDtcbiAgICB9XG5cbiAgICBpZiAoIWludGVyc2VjdHMgJiYgISEoZW5kUmVsICYgUmVsYXRpb25zaGlwLlJJR0hUKSAmJiAhKHN0YXJ0UmVsICYgUmVsYXRpb25zaGlwLlJJR0hUKSkge1xuICAgICAgLy8gcG90ZW50aWFsbHkgaW50ZXJzZWN0cyByaWdodFxuICAgICAgeSA9IGVuZFkgLSAoZW5kWCAtIG1heFgpICogc2xvcGU7XG4gICAgICBpbnRlcnNlY3RzID0geSA+PSBtaW5ZICYmIHkgPD0gbWF4WTtcbiAgICB9XG5cbiAgICBpZiAoIWludGVyc2VjdHMgJiYgISEoZW5kUmVsICYgUmVsYXRpb25zaGlwLkJFTE9XKSAmJiAhKHN0YXJ0UmVsICYgUmVsYXRpb25zaGlwLkJFTE9XKSkge1xuICAgICAgLy8gcG90ZW50aWFsbHkgaW50ZXJzZWN0cyBib3R0b21cbiAgICAgIHggPSBlbmRYIC0gKGVuZFkgLSBtaW5ZKSAvIHNsb3BlO1xuICAgICAgaW50ZXJzZWN0cyA9IHggPj0gbWluWCAmJiB4IDw9IG1heFg7XG4gICAgfVxuXG4gICAgaWYgKCFpbnRlcnNlY3RzICYmICEhKGVuZFJlbCAmIFJlbGF0aW9uc2hpcC5MRUZUKSAmJiAhKHN0YXJ0UmVsICYgUmVsYXRpb25zaGlwLkxFRlQpKSB7XG4gICAgICAvLyBwb3RlbnRpYWxseSBpbnRlcnNlY3RzIGxlZnRcbiAgICAgIHkgPSBlbmRZIC0gKGVuZFggLSBtaW5YKSAqIHNsb3BlO1xuICAgICAgaW50ZXJzZWN0cyA9IHkgPj0gbWluWSAmJiB5IDw9IG1heFk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGludGVyc2VjdHM7XG59XG4vKipcbiAqIEFwcGx5IGEgdHJhbnNmb3JtIGZ1bmN0aW9uIHRvIHRoZSBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufSB0cmFuc2Zvcm1GbiBUcmFuc2Zvcm0gZnVuY3Rpb24uXG4gKiBDYWxsZWQgd2l0aCBgW21pblgsIG1pblksIG1heFgsIG1heFldYCBleHRlbnQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRGVzdGluYXRpb24gZXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfc3RvcHMgTnVtYmVyIG9mIHN0b3BzIHBlciBzaWRlIHVzZWQgZm9yIHRoZSB0cmFuc2Zvcm0uXG4gKiBCeSBkZWZhdWx0IG9ubHkgdGhlIGNvcm5lcnMgYXJlIHVzZWQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlUcmFuc2Zvcm0oZXh0ZW50LCB0cmFuc2Zvcm1Gbiwgb3B0X2V4dGVudCwgb3B0X3N0b3BzKSB7XG4gIHZhciBjb29yZGluYXRlcyA9IFtdO1xuXG4gIGlmIChvcHRfc3RvcHMgPiAxKSB7XG4gICAgdmFyIHdpZHRoID0gZXh0ZW50WzJdIC0gZXh0ZW50WzBdO1xuICAgIHZhciBoZWlnaHQgPSBleHRlbnRbM10gLSBleHRlbnRbMV07XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wdF9zdG9wczsgKytpKSB7XG4gICAgICBjb29yZGluYXRlcy5wdXNoKGV4dGVudFswXSArIHdpZHRoICogaSAvIG9wdF9zdG9wcywgZXh0ZW50WzFdLCBleHRlbnRbMl0sIGV4dGVudFsxXSArIGhlaWdodCAqIGkgLyBvcHRfc3RvcHMsIGV4dGVudFsyXSAtIHdpZHRoICogaSAvIG9wdF9zdG9wcywgZXh0ZW50WzNdLCBleHRlbnRbMF0sIGV4dGVudFszXSAtIGhlaWdodCAqIGkgLyBvcHRfc3RvcHMpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBjb29yZGluYXRlcyA9IFtleHRlbnRbMF0sIGV4dGVudFsxXSwgZXh0ZW50WzJdLCBleHRlbnRbMV0sIGV4dGVudFsyXSwgZXh0ZW50WzNdLCBleHRlbnRbMF0sIGV4dGVudFszXV07XG4gIH1cblxuICB0cmFuc2Zvcm1Gbihjb29yZGluYXRlcywgY29vcmRpbmF0ZXMsIDIpO1xuICB2YXIgeHMgPSBbXTtcbiAgdmFyIHlzID0gW107XG5cbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBjb29yZGluYXRlcy5sZW5ndGg7IGkgPCBsOyBpICs9IDIpIHtcbiAgICB4cy5wdXNoKGNvb3JkaW5hdGVzW2ldKTtcbiAgICB5cy5wdXNoKGNvb3JkaW5hdGVzW2kgKyAxXSk7XG4gIH1cblxuICByZXR1cm4gX2JvdW5kaW5nRXh0ZW50WFlzKHhzLCB5cywgb3B0X2V4dGVudCk7XG59XG4vKipcbiAqIE1vZGlmaWVzIHRoZSBwcm92aWRlZCBleHRlbnQgaW4tcGxhY2UgdG8gYmUgd2l0aGluIHRoZSByZWFsIHdvcmxkXG4gKiBleHRlbnQuXG4gKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvblxuICogQHJldHVybiB7RXh0ZW50fSBUaGUgZXh0ZW50IHdpdGhpbiB0aGUgcmVhbCB3b3JsZCBleHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBYKGV4dGVudCwgcHJvamVjdGlvbikge1xuICB2YXIgcHJvamVjdGlvbkV4dGVudCA9IHByb2plY3Rpb24uZ2V0RXh0ZW50KCk7XG4gIHZhciBjZW50ZXIgPSBnZXRDZW50ZXIoZXh0ZW50KTtcblxuICBpZiAocHJvamVjdGlvbi5jYW5XcmFwWCgpICYmIChjZW50ZXJbMF0gPCBwcm9qZWN0aW9uRXh0ZW50WzBdIHx8IGNlbnRlclswXSA+PSBwcm9qZWN0aW9uRXh0ZW50WzJdKSkge1xuICAgIHZhciB3b3JsZFdpZHRoID0gZ2V0V2lkdGgocHJvamVjdGlvbkV4dGVudCk7XG4gICAgdmFyIHdvcmxkc0F3YXkgPSBNYXRoLmZsb29yKChjZW50ZXJbMF0gLSBwcm9qZWN0aW9uRXh0ZW50WzBdKSAvIHdvcmxkV2lkdGgpO1xuICAgIHZhciBvZmZzZXQgPSB3b3JsZHNBd2F5ICogd29ybGRXaWR0aDtcbiAgICBleHRlbnRbMF0gLT0gb2Zmc2V0O1xuICAgIGV4dGVudFsyXSAtPSBvZmZzZXQ7XG4gIH1cblxuICByZXR1cm4gZXh0ZW50O1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9tYXRoXG4gKi9cblxuLyoqXG4gKiBUYWtlcyBhIG51bWJlciBhbmQgY2xhbXBzIGl0IHRvIHdpdGhpbiB0aGUgcHJvdmlkZWQgYm91bmRzLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBpbnB1dCBudW1iZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gbWluIFRoZSBtaW5pbXVtIHZhbHVlIHRvIHJldHVybi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXggVGhlIG1heGltdW0gdmFsdWUgdG8gcmV0dXJuLlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgaW5wdXQgbnVtYmVyIGlmIGl0IGlzIHdpdGhpbiBib3VuZHMsIG9yIHRoZSBuZWFyZXN0XG4gKiAgICAgbnVtYmVyIHdpdGhpbiB0aGUgYm91bmRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xhbXAodmFsdWUsIG1pbiwgbWF4KSB7XG4gIHJldHVybiBNYXRoLm1pbihNYXRoLm1heCh2YWx1ZSwgbWluKSwgbWF4KTtcbn1cbi8qKlxuICogUmV0dXJuIHRoZSBoeXBlcmJvbGljIGNvc2luZSBvZiBhIGdpdmVuIG51bWJlci4gVGhlIG1ldGhvZCB3aWxsIHVzZSB0aGVcbiAqIG5hdGl2ZSBgTWF0aC5jb3NoYCBmdW5jdGlvbiBpZiBpdCBpcyBhdmFpbGFibGUsIG90aGVyd2lzZSB0aGUgaHlwZXJib2xpY1xuICogY29zaW5lIHdpbGwgYmUgY2FsY3VsYXRlZCB2aWEgdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTW96aWxsYVxuICogZGV2ZWxvcGVyIG5ldHdvcmsuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAqIEByZXR1cm4ge251bWJlcn0gSHlwZXJib2xpYyBjb3NpbmUgb2YgeC5cbiAqL1xuXG5leHBvcnQgdmFyIGNvc2ggPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFdyYXBwZWQgaW4gYSBpaWZlLCB0byBzYXZlIHRoZSBvdmVyaGVhZCBvZiBjaGVja2luZyBmb3IgdGhlIG5hdGl2ZVxuICAvLyBpbXBsZW1lbnRhdGlvbiBvbiBldmVyeSBpbnZvY2F0aW9uLlxuICB2YXIgY29zaDtcblxuICBpZiAoJ2Nvc2gnIGluIE1hdGgpIHtcbiAgICAvLyBUaGUgZW52aXJvbm1lbnQgc3VwcG9ydHMgdGhlIG5hdGl2ZSBNYXRoLmNvc2ggZnVuY3Rpb24sIHVzZSBpdOKAplxuICAgIGNvc2ggPSBNYXRoLmNvc2g7XG4gIH0gZWxzZSB7XG4gICAgLy8g4oCmIGVsc2UsIHVzZSB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uIG9mIE1ETjpcbiAgICBjb3NoID0gZnVuY3Rpb24gY29zaCh4KSB7XG4gICAgICB2YXIgeSA9XG4gICAgICAvKiogQHR5cGUge01hdGh9ICovXG4gICAgICBNYXRoLmV4cCh4KTtcbiAgICAgIHJldHVybiAoeSArIDEgLyB5KSAvIDI7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBjb3NoO1xufSgpO1xuLyoqXG4gKiBSZXR1cm4gdGhlIGJhc2UgMiBsb2dhcml0aG0gb2YgYSBnaXZlbiBudW1iZXIuIFRoZSBtZXRob2Qgd2lsbCB1c2UgdGhlXG4gKiBuYXRpdmUgYE1hdGgubG9nMmAgZnVuY3Rpb24gaWYgaXQgaXMgYXZhaWxhYmxlLCBvdGhlcndpc2UgdGhlIGJhc2UgMlxuICogbG9nYXJpdGhtIHdpbGwgYmUgY2FsY3VsYXRlZCB2aWEgdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGVcbiAqIE1vemlsbGEgZGV2ZWxvcGVyIG5ldHdvcmsuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAqIEByZXR1cm4ge251bWJlcn0gQmFzZSAyIGxvZ2FyaXRobSBvZiB4LlxuICovXG5cbmV4cG9ydCB2YXIgbG9nMiA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gV3JhcHBlZCBpbiBhIGlpZmUsIHRvIHNhdmUgdGhlIG92ZXJoZWFkIG9mIGNoZWNraW5nIGZvciB0aGUgbmF0aXZlXG4gIC8vIGltcGxlbWVudGF0aW9uIG9uIGV2ZXJ5IGludm9jYXRpb24uXG4gIHZhciBsb2cyO1xuXG4gIGlmICgnbG9nMicgaW4gTWF0aCkge1xuICAgIC8vIFRoZSBlbnZpcm9ubWVudCBzdXBwb3J0cyB0aGUgbmF0aXZlIE1hdGgubG9nMiBmdW5jdGlvbiwgdXNlIGl04oCmXG4gICAgbG9nMiA9IE1hdGgubG9nMjtcbiAgfSBlbHNlIHtcbiAgICAvLyDigKYgZWxzZSwgdXNlIHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gb2YgTUROOlxuICAgIGxvZzIgPSBmdW5jdGlvbiBsb2cyKHgpIHtcbiAgICAgIHJldHVybiBNYXRoLmxvZyh4KSAqIE1hdGguTE9HMkU7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBsb2cyO1xufSgpO1xuLyoqXG4gKiBSZXR1cm5zIHRoZSBzcXVhcmUgb2YgdGhlIGNsb3Nlc3QgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnQgKHgsIHkpIGFuZCB0aGVcbiAqIGxpbmUgc2VnbWVudCAoeDEsIHkxKSB0byAoeDIsIHkyKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICogQHBhcmFtIHtudW1iZXJ9IHgxIFgxLlxuICogQHBhcmFtIHtudW1iZXJ9IHkxIFkxLlxuICogQHBhcmFtIHtudW1iZXJ9IHgyIFgyLlxuICogQHBhcmFtIHtudW1iZXJ9IHkyIFkyLlxuICogQHJldHVybiB7bnVtYmVyfSBTcXVhcmVkIGRpc3RhbmNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzcXVhcmVkU2VnbWVudERpc3RhbmNlKHgsIHksIHgxLCB5MSwgeDIsIHkyKSB7XG4gIHZhciBkeCA9IHgyIC0geDE7XG4gIHZhciBkeSA9IHkyIC0geTE7XG5cbiAgaWYgKGR4ICE9PSAwIHx8IGR5ICE9PSAwKSB7XG4gICAgdmFyIHQgPSAoKHggLSB4MSkgKiBkeCArICh5IC0geTEpICogZHkpIC8gKGR4ICogZHggKyBkeSAqIGR5KTtcblxuICAgIGlmICh0ID4gMSkge1xuICAgICAgeDEgPSB4MjtcbiAgICAgIHkxID0geTI7XG4gICAgfSBlbHNlIGlmICh0ID4gMCkge1xuICAgICAgeDEgKz0gZHggKiB0O1xuICAgICAgeTEgKz0gZHkgKiB0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzcXVhcmVkRGlzdGFuY2UoeCwgeSwgeDEsIHkxKTtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgc3F1YXJlIG9mIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludHMgKHgxLCB5MSkgYW5kICh4MiwgeTIpLlxuICogQHBhcmFtIHtudW1iZXJ9IHgxIFgxLlxuICogQHBhcmFtIHtudW1iZXJ9IHkxIFkxLlxuICogQHBhcmFtIHtudW1iZXJ9IHgyIFgyLlxuICogQHBhcmFtIHtudW1iZXJ9IHkyIFkyLlxuICogQHJldHVybiB7bnVtYmVyfSBTcXVhcmVkIGRpc3RhbmNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzcXVhcmVkRGlzdGFuY2UoeDEsIHkxLCB4MiwgeTIpIHtcbiAgdmFyIGR4ID0geDIgLSB4MTtcbiAgdmFyIGR5ID0geTIgLSB5MTtcbiAgcmV0dXJuIGR4ICogZHggKyBkeSAqIGR5O1xufVxuLyoqXG4gKiBTb2x2ZXMgc3lzdGVtIG9mIGxpbmVhciBlcXVhdGlvbnMgdXNpbmcgR2F1c3NpYW4gZWxpbWluYXRpb24gbWV0aG9kLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IG1hdCBBdWdtZW50ZWQgbWF0cml4IChuIHggbiArIDEgY29sdW1uKVxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gcm93LW1ham9yIG9yZGVyLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gVGhlIHJlc3VsdGluZyB2ZWN0b3IuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNvbHZlTGluZWFyU3lzdGVtKG1hdCkge1xuICB2YXIgbiA9IG1hdC5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAvLyBGaW5kIG1heCBpbiB0aGUgaS10aCBjb2x1bW4gKGlnbm9yaW5nIGkgLSAxIGZpcnN0IHJvd3MpXG4gICAgdmFyIG1heFJvdyA9IGk7XG4gICAgdmFyIG1heEVsID0gTWF0aC5hYnMobWF0W2ldW2ldKTtcblxuICAgIGZvciAodmFyIHIgPSBpICsgMTsgciA8IG47IHIrKykge1xuICAgICAgdmFyIGFic1ZhbHVlID0gTWF0aC5hYnMobWF0W3JdW2ldKTtcblxuICAgICAgaWYgKGFic1ZhbHVlID4gbWF4RWwpIHtcbiAgICAgICAgbWF4RWwgPSBhYnNWYWx1ZTtcbiAgICAgICAgbWF4Um93ID0gcjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWF4RWwgPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsOyAvLyBtYXRyaXggaXMgc2luZ3VsYXJcbiAgICB9IC8vIFN3YXAgbWF4IHJvdyB3aXRoIGktdGggKGN1cnJlbnQpIHJvd1xuXG5cbiAgICB2YXIgdG1wID0gbWF0W21heFJvd107XG4gICAgbWF0W21heFJvd10gPSBtYXRbaV07XG4gICAgbWF0W2ldID0gdG1wOyAvLyBTdWJ0cmFjdCB0aGUgaS10aCByb3cgdG8gbWFrZSBhbGwgdGhlIHJlbWFpbmluZyByb3dzIDAgaW4gdGhlIGktdGggY29sdW1uXG5cbiAgICBmb3IgKHZhciBqID0gaSArIDE7IGogPCBuOyBqKyspIHtcbiAgICAgIHZhciBjb2VmID0gLW1hdFtqXVtpXSAvIG1hdFtpXVtpXTtcblxuICAgICAgZm9yICh2YXIgayA9IGk7IGsgPCBuICsgMTsgaysrKSB7XG4gICAgICAgIGlmIChpID09IGspIHtcbiAgICAgICAgICBtYXRbal1ba10gPSAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1hdFtqXVtrXSArPSBjb2VmICogbWF0W2ldW2tdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IC8vIFNvbHZlIEF4PWIgZm9yIHVwcGVyIHRyaWFuZ3VsYXIgbWF0cml4IEEgKG1hdClcblxuXG4gIHZhciB4ID0gbmV3IEFycmF5KG4pO1xuXG4gIGZvciAodmFyIGwgPSBuIC0gMTsgbCA+PSAwOyBsLS0pIHtcbiAgICB4W2xdID0gbWF0W2xdW25dIC8gbWF0W2xdW2xdO1xuXG4gICAgZm9yICh2YXIgbSA9IGwgLSAxOyBtID49IDA7IG0tLSkge1xuICAgICAgbWF0W21dW25dIC09IG1hdFttXVtsXSAqIHhbbF07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHg7XG59XG4vKipcbiAqIENvbnZlcnRzIHJhZGlhbnMgdG8gdG8gZGVncmVlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYW5nbGVJblJhZGlhbnMgQW5nbGUgaW4gcmFkaWFucy5cbiAqIEByZXR1cm4ge251bWJlcn0gQW5nbGUgaW4gZGVncmVlcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdG9EZWdyZWVzKGFuZ2xlSW5SYWRpYW5zKSB7XG4gIHJldHVybiBhbmdsZUluUmFkaWFucyAqIDE4MCAvIE1hdGguUEk7XG59XG4vKipcbiAqIENvbnZlcnRzIGRlZ3JlZXMgdG8gcmFkaWFucy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYW5nbGVJbkRlZ3JlZXMgQW5nbGUgaW4gZGVncmVlcy5cbiAqIEByZXR1cm4ge251bWJlcn0gQW5nbGUgaW4gcmFkaWFucy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdG9SYWRpYW5zKGFuZ2xlSW5EZWdyZWVzKSB7XG4gIHJldHVybiBhbmdsZUluRGVncmVlcyAqIE1hdGguUEkgLyAxODA7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIG1vZHVsbyBvZiBhIC8gYiwgZGVwZW5kaW5nIG9uIHRoZSBzaWduIG9mIGIuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGEgRGl2aWRlbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gYiBEaXZpc29yLlxuICogQHJldHVybiB7bnVtYmVyfSBNb2R1bG8uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG1vZHVsbyhhLCBiKSB7XG4gIHZhciByID0gYSAlIGI7XG4gIHJldHVybiByICogYiA8IDAgPyByICsgYiA6IHI7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGxpbmVhcmx5IGludGVycG9sYXRlZCB2YWx1ZSBvZiB4IGJldHdlZW4gYSBhbmQgYi5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYSBOdW1iZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSBiIE51bWJlclxuICogQHBhcmFtIHtudW1iZXJ9IHggVmFsdWUgdG8gYmUgaW50ZXJwb2xhdGVkLlxuICogQHJldHVybiB7bnVtYmVyfSBJbnRlcnBvbGF0ZWQgdmFsdWUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxlcnAoYSwgYiwgeCkge1xuICByZXR1cm4gYSArIHggKiAoYiAtIGEpO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9jb2xvclxuICovXG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuL2Fzc2VydHMuanMnO1xuaW1wb3J0IHsgY2xhbXAgfSBmcm9tICcuL21hdGguanMnO1xuLyoqXG4gKiBBIGNvbG9yIHJlcHJlc2VudGVkIGFzIGEgc2hvcnQgYXJyYXkgW3JlZCwgZ3JlZW4sIGJsdWUsIGFscGhhXS5cbiAqIHJlZCwgZ3JlZW4sIGFuZCBibHVlIHNob3VsZCBiZSBpbnRlZ2VycyBpbiB0aGUgcmFuZ2UgMC4uMjU1IGluY2x1c2l2ZS5cbiAqIGFscGhhIHNob3VsZCBiZSBhIGZsb2F0IGluIHRoZSByYW5nZSAwLi4xIGluY2x1c2l2ZS4gSWYgbm8gYWxwaGEgdmFsdWUgaXNcbiAqIGdpdmVuIHRoZW4gYDFgIHdpbGwgYmUgdXNlZC5cbiAqIEB0eXBlZGVmIHtBcnJheTxudW1iZXI+fSBDb2xvclxuICogQGFwaVxuICovXG5cbi8qKlxuICogVGhpcyBSZWdFeHAgbWF0Y2hlcyAjIGZvbGxvd2VkIGJ5IDMsIDQsIDYsIG9yIDggaGV4IGRpZ2l0cy5cbiAqIEBjb25zdFxuICogQHR5cGUge1JlZ0V4cH1cbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIEhFWF9DT0xPUl9SRV8gPSAvXiMoW2EtZjAtOV17M318W2EtZjAtOV17NH0oPzpbYS1mMC05XXsyfSl7MCwyfSkkL2k7XG4vKipcbiAqIFJlZ3VsYXIgZXhwcmVzc2lvbiBmb3IgbWF0Y2hpbmcgcG90ZW50aWFsIG5hbWVkIGNvbG9yIHN0eWxlIHN0cmluZ3MuXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAcHJpdmF0ZVxuICovXG5cbnZhciBOQU1FRF9DT0xPUl9SRV8gPSAvXihbYS16XSopJHxeaHNsYT9cXCguKlxcKSQvaTtcbi8qKlxuICogUmV0dXJuIHRoZSBjb2xvciBhcyBhbiByZ2JhIHN0cmluZy5cbiAqIEBwYXJhbSB7Q29sb3J8c3RyaW5nfSBjb2xvciBDb2xvci5cbiAqIEByZXR1cm4ge3N0cmluZ30gUmdiYSBzdHJpbmcuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFzU3RyaW5nKGNvbG9yKSB7XG4gIGlmICh0eXBlb2YgY29sb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGNvbG9yO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0b1N0cmluZyhjb2xvcik7XG4gIH1cbn1cbi8qKlxuICogUmV0dXJuIG5hbWVkIGNvbG9yIGFzIGFuIHJnYmEgc3RyaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbG9yIE5hbWVkIGNvbG9yLlxuICogQHJldHVybiB7c3RyaW5nfSBSZ2Igc3RyaW5nLlxuICovXG5cbmZ1bmN0aW9uIGZyb21OYW1lZChjb2xvcikge1xuICB2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgZWwuc3R5bGUuY29sb3IgPSBjb2xvcjtcblxuICBpZiAoZWwuc3R5bGUuY29sb3IgIT09ICcnKSB7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChlbCk7XG4gICAgdmFyIHJnYiA9IGdldENvbXB1dGVkU3R5bGUoZWwpLmNvbG9yO1xuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoZWwpO1xuICAgIHJldHVybiByZ2I7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzIFN0cmluZy5cbiAqIEByZXR1cm4ge0NvbG9yfSBDb2xvci5cbiAqL1xuXG5cbmV4cG9ydCB2YXIgZnJvbVN0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gV2UgbWFpbnRhaW4gYSBzbWFsbCBjYWNoZSBvZiBwYXJzZWQgc3RyaW5ncy4gIFRvIHByb3ZpZGUgY2hlYXAgTFJVLWxpa2VcbiAgLy8gc2VtYW50aWNzLCB3aGVuZXZlciB0aGUgY2FjaGUgZ3Jvd3MgdG9vIGxhcmdlIHdlIHNpbXBseSBkZWxldGUgYW5cbiAgLy8gYXJiaXRyYXJ5IDI1JSBvZiB0aGUgZW50cmllcy5cblxuICAvKipcbiAgICogQGNvbnN0XG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICB2YXIgTUFYX0NBQ0hFX1NJWkUgPSAxMDI0O1xuICAvKipcbiAgICogQHR5cGUge09iamVjdDxzdHJpbmcsIENvbG9yPn1cbiAgICovXG5cbiAgdmFyIGNhY2hlID0ge307XG4gIC8qKlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cblxuICB2YXIgY2FjaGVTaXplID0gMDtcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcyBTdHJpbmcuXG4gICAgICogQHJldHVybiB7Q29sb3J9IENvbG9yLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChzKSB7XG4gICAgICB2YXIgY29sb3I7XG5cbiAgICAgIGlmIChjYWNoZS5oYXNPd25Qcm9wZXJ0eShzKSkge1xuICAgICAgICBjb2xvciA9IGNhY2hlW3NdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGNhY2hlU2l6ZSA+PSBNQVhfQ0FDSEVfU0laRSkge1xuICAgICAgICAgIHZhciBpID0gMDtcblxuICAgICAgICAgIGZvciAodmFyIGtleSBpbiBjYWNoZSkge1xuICAgICAgICAgICAgaWYgKChpKysgJiAzKSA9PT0gMCkge1xuICAgICAgICAgICAgICBkZWxldGUgY2FjaGVba2V5XTtcbiAgICAgICAgICAgICAgLS1jYWNoZVNpemU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29sb3IgPSBmcm9tU3RyaW5nSW50ZXJuYWxfKHMpO1xuICAgICAgICBjYWNoZVtzXSA9IGNvbG9yO1xuICAgICAgICArK2NhY2hlU2l6ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNvbG9yO1xuICAgIH1cbiAgKTtcbn0oKTtcbi8qKlxuICogUmV0dXJuIHRoZSBjb2xvciBhcyBhbiBhcnJheS4gVGhpcyBmdW5jdGlvbiBtYWludGFpbnMgYSBjYWNoZSBvZiBjYWxjdWxhdGVkXG4gKiBhcnJheXMgd2hpY2ggbWVhbnMgdGhlIHJlc3VsdCBzaG91bGQgbm90IGJlIG1vZGlmaWVkLlxuICogQHBhcmFtIHtDb2xvcnxzdHJpbmd9IGNvbG9yIENvbG9yLlxuICogQHJldHVybiB7Q29sb3J9IENvbG9yLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhc0FycmF5KGNvbG9yKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGNvbG9yKSkge1xuICAgIHJldHVybiBjb2xvcjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyhjb2xvcik7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHMgU3RyaW5nLlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge0NvbG9yfSBDb2xvci5cbiAqL1xuXG5mdW5jdGlvbiBmcm9tU3RyaW5nSW50ZXJuYWxfKHMpIHtcbiAgdmFyIHIsIGcsIGIsIGEsIGNvbG9yO1xuXG4gIGlmIChOQU1FRF9DT0xPUl9SRV8uZXhlYyhzKSkge1xuICAgIHMgPSBmcm9tTmFtZWQocyk7XG4gIH1cblxuICBpZiAoSEVYX0NPTE9SX1JFXy5leGVjKHMpKSB7XG4gICAgLy8gaGV4XG4gICAgdmFyIG4gPSBzLmxlbmd0aCAtIDE7IC8vIG51bWJlciBvZiBoZXggZGlnaXRzXG5cbiAgICB2YXIgZCA9IC8vIG51bWJlciBvZiBkaWdpdHMgcGVyIGNoYW5uZWxcbiAgICB2b2lkIDA7IC8vIG51bWJlciBvZiBkaWdpdHMgcGVyIGNoYW5uZWxcblxuICAgIGlmIChuIDw9IDQpIHtcbiAgICAgIGQgPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBkID0gMjtcbiAgICB9XG5cbiAgICB2YXIgaGFzQWxwaGEgPSBuID09PSA0IHx8IG4gPT09IDg7XG4gICAgciA9IHBhcnNlSW50KHMuc3Vic3RyKDEgKyAwICogZCwgZCksIDE2KTtcbiAgICBnID0gcGFyc2VJbnQocy5zdWJzdHIoMSArIDEgKiBkLCBkKSwgMTYpO1xuICAgIGIgPSBwYXJzZUludChzLnN1YnN0cigxICsgMiAqIGQsIGQpLCAxNik7XG5cbiAgICBpZiAoaGFzQWxwaGEpIHtcbiAgICAgIGEgPSBwYXJzZUludChzLnN1YnN0cigxICsgMyAqIGQsIGQpLCAxNik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGEgPSAyNTU7XG4gICAgfVxuXG4gICAgaWYgKGQgPT0gMSkge1xuICAgICAgciA9IChyIDw8IDQpICsgcjtcbiAgICAgIGcgPSAoZyA8PCA0KSArIGc7XG4gICAgICBiID0gKGIgPDwgNCkgKyBiO1xuXG4gICAgICBpZiAoaGFzQWxwaGEpIHtcbiAgICAgICAgYSA9IChhIDw8IDQpICsgYTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb2xvciA9IFtyLCBnLCBiLCBhIC8gMjU1XTtcbiAgfSBlbHNlIGlmIChzLmluZGV4T2YoJ3JnYmEoJykgPT0gMCkge1xuICAgIC8vIHJnYmEoKVxuICAgIGNvbG9yID0gcy5zbGljZSg1LCAtMSkuc3BsaXQoJywnKS5tYXAoTnVtYmVyKTtcbiAgICBub3JtYWxpemUoY29sb3IpO1xuICB9IGVsc2UgaWYgKHMuaW5kZXhPZigncmdiKCcpID09IDApIHtcbiAgICAvLyByZ2IoKVxuICAgIGNvbG9yID0gcy5zbGljZSg0LCAtMSkuc3BsaXQoJywnKS5tYXAoTnVtYmVyKTtcbiAgICBjb2xvci5wdXNoKDEpO1xuICAgIG5vcm1hbGl6ZShjb2xvcik7XG4gIH0gZWxzZSB7XG4gICAgYXNzZXJ0KGZhbHNlLCAxNCk7IC8vIEludmFsaWQgY29sb3JcbiAgfVxuXG4gIHJldHVybiBjb2xvcjtcbn1cbi8qKlxuICogVE9ETyB0aGlzIGZ1bmN0aW9uIGlzIG9ubHkgdXNlZCBpbiB0aGUgdGVzdCwgd2UgcHJvYmFibHkgc2hvdWxkbid0IGV4cG9ydCBpdFxuICogQHBhcmFtIHtDb2xvcn0gY29sb3IgQ29sb3IuXG4gKiBAcmV0dXJuIHtDb2xvcn0gQ2xhbXBlZCBjb2xvci5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUoY29sb3IpIHtcbiAgY29sb3JbMF0gPSBjbGFtcChjb2xvclswXSArIDAuNSB8IDAsIDAsIDI1NSk7XG4gIGNvbG9yWzFdID0gY2xhbXAoY29sb3JbMV0gKyAwLjUgfCAwLCAwLCAyNTUpO1xuICBjb2xvclsyXSA9IGNsYW1wKGNvbG9yWzJdICsgMC41IHwgMCwgMCwgMjU1KTtcbiAgY29sb3JbM10gPSBjbGFtcChjb2xvclszXSwgMCwgMSk7XG4gIHJldHVybiBjb2xvcjtcbn1cbi8qKlxuICogQHBhcmFtIHtDb2xvcn0gY29sb3IgQ29sb3IuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFN0cmluZy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdG9TdHJpbmcoY29sb3IpIHtcbiAgdmFyIHIgPSBjb2xvclswXTtcblxuICBpZiAociAhPSAociB8IDApKSB7XG4gICAgciA9IHIgKyAwLjUgfCAwO1xuICB9XG5cbiAgdmFyIGcgPSBjb2xvclsxXTtcblxuICBpZiAoZyAhPSAoZyB8IDApKSB7XG4gICAgZyA9IGcgKyAwLjUgfCAwO1xuICB9XG5cbiAgdmFyIGIgPSBjb2xvclsyXTtcblxuICBpZiAoYiAhPSAoYiB8IDApKSB7XG4gICAgYiA9IGIgKyAwLjUgfCAwO1xuICB9XG5cbiAgdmFyIGEgPSBjb2xvclszXSA9PT0gdW5kZWZpbmVkID8gMSA6IGNvbG9yWzNdO1xuICByZXR1cm4gJ3JnYmEoJyArIHIgKyAnLCcgKyBnICsgJywnICsgYiArICcsJyArIGEgKyAnKSc7XG59XG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzIFN0cmluZy5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHN0cmluZyBpcyBhY3R1YWxseSBhIHZhbGlkIGNvbG9yXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nQ29sb3Iocykge1xuICBpZiAoTkFNRURfQ09MT1JfUkVfLnRlc3QocykpIHtcbiAgICBzID0gZnJvbU5hbWVkKHMpO1xuICB9XG5cbiAgcmV0dXJuIEhFWF9DT0xPUl9SRV8udGVzdChzKSB8fCBzLmluZGV4T2YoJ3JnYmEoJykgPT09IDAgfHwgcy5pbmRleE9mKCdyZ2IoJykgPT09IDA7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL0ljb25JbWFnZUNhY2hlXG4gKi9cbmltcG9ydCB7IGFzU3RyaW5nIH0gZnJvbSAnLi4vY29sb3IuanMnO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBTaW5nbGV0b24gY2xhc3MuIEF2YWlsYWJsZSB0aHJvdWdoIHtAbGluayBtb2R1bGU6b2wvc3R5bGUvSWNvbkltYWdlQ2FjaGV+c2hhcmVkfS5cbiAqL1xuXG52YXIgSWNvbkltYWdlQ2FjaGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBJY29uSW1hZ2VDYWNoZSgpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4vSWNvbkltYWdlLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgdGhpcy5jYWNoZV8gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLmNhY2hlU2l6ZV8gPSAwO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIHRoaXMubWF4Q2FjaGVTaXplXyA9IDMyO1xuICB9XG4gIC8qKlxuICAgKiBGSVhNRSBlbXB0eSBkZXNjcmlwdGlvbiBmb3IganNkb2NcbiAgICovXG5cblxuICBJY29uSW1hZ2VDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5jYWNoZV8gPSB7fTtcbiAgICB0aGlzLmNhY2hlU2l6ZV8gPSAwO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ2FuIGV4cGlyZSBjYWNoZS5cbiAgICovXG5cblxuICBJY29uSW1hZ2VDYWNoZS5wcm90b3R5cGUuY2FuRXhwaXJlQ2FjaGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGVTaXplXyA+IHRoaXMubWF4Q2FjaGVTaXplXztcbiAgfTtcbiAgLyoqXG4gICAqIEZJWE1FIGVtcHR5IGRlc2NyaXB0aW9uIGZvciBqc2RvY1xuICAgKi9cblxuXG4gIEljb25JbWFnZUNhY2hlLnByb3RvdHlwZS5leHBpcmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuY2FuRXhwaXJlQ2FjaGUoKSkge1xuICAgICAgdmFyIGkgPSAwO1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gdGhpcy5jYWNoZV8pIHtcbiAgICAgICAgdmFyIGljb25JbWFnZSA9IHRoaXMuY2FjaGVfW2tleV07XG5cbiAgICAgICAgaWYgKChpKysgJiAzKSA9PT0gMCAmJiAhaWNvbkltYWdlLmhhc0xpc3RlbmVyKCkpIHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5jYWNoZV9ba2V5XTtcbiAgICAgICAgICAtLXRoaXMuY2FjaGVTaXplXztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgU3JjLlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IGNyb3NzT3JpZ2luIENyb3NzIG9yaWdpbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb2xvci5qc1wiKS5Db2xvcn0gY29sb3IgQ29sb3IuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vSWNvbkltYWdlLmpzXCIpLmRlZmF1bHR9IEljb24gaW1hZ2UuXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlQ2FjaGUucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChzcmMsIGNyb3NzT3JpZ2luLCBjb2xvcikge1xuICAgIHZhciBrZXkgPSBnZXRLZXkoc3JjLCBjcm9zc09yaWdpbiwgY29sb3IpO1xuICAgIHJldHVybiBrZXkgaW4gdGhpcy5jYWNoZV8gPyB0aGlzLmNhY2hlX1trZXldIDogbnVsbDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgU3JjLlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IGNyb3NzT3JpZ2luIENyb3NzIG9yaWdpbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb2xvci5qc1wiKS5Db2xvcn0gY29sb3IgQ29sb3IuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9JY29uSW1hZ2UuanNcIikuZGVmYXVsdH0gaWNvbkltYWdlIEljb24gaW1hZ2UuXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlQ2FjaGUucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChzcmMsIGNyb3NzT3JpZ2luLCBjb2xvciwgaWNvbkltYWdlKSB7XG4gICAgdmFyIGtleSA9IGdldEtleShzcmMsIGNyb3NzT3JpZ2luLCBjb2xvcik7XG4gICAgdGhpcy5jYWNoZV9ba2V5XSA9IGljb25JbWFnZTtcbiAgICArK3RoaXMuY2FjaGVTaXplXztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY2FjaGUgc2l6ZSBvZiB0aGUgaWNvbiBjYWNoZS4gRGVmYXVsdCBpcyBgMzJgLiBDaGFuZ2UgdGhpcyB2YWx1ZSB3aGVuXG4gICAqIHlvdXIgbWFwIHVzZXMgbW9yZSB0aGFuIDMyIGRpZmZlcmVudCBpY29uIGltYWdlcyBhbmQgeW91IGFyZSBub3QgY2FjaGluZyBpY29uXG4gICAqIHN0eWxlcyBvbiB0aGUgYXBwbGljYXRpb24gbGV2ZWwuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhDYWNoZVNpemUgQ2FjaGUgbWF4IHNpemUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJY29uSW1hZ2VDYWNoZS5wcm90b3R5cGUuc2V0U2l6ZSA9IGZ1bmN0aW9uIChtYXhDYWNoZVNpemUpIHtcbiAgICB0aGlzLm1heENhY2hlU2l6ZV8gPSBtYXhDYWNoZVNpemU7XG4gICAgdGhpcy5leHBpcmUoKTtcbiAgfTtcblxuICByZXR1cm4gSWNvbkltYWdlQ2FjaGU7XG59KCk7XG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgU3JjLlxuICogQHBhcmFtIHs/c3RyaW5nfSBjcm9zc09yaWdpbiBDcm9zcyBvcmlnaW4uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbG9yLmpzXCIpLkNvbG9yfSBjb2xvciBDb2xvci5cbiAqIEByZXR1cm4ge3N0cmluZ30gQ2FjaGUga2V5LlxuICovXG5cblxuZnVuY3Rpb24gZ2V0S2V5KHNyYywgY3Jvc3NPcmlnaW4sIGNvbG9yKSB7XG4gIHZhciBjb2xvclN0cmluZyA9IGNvbG9yID8gYXNTdHJpbmcoY29sb3IpIDogJ251bGwnO1xuICByZXR1cm4gY3Jvc3NPcmlnaW4gKyAnOicgKyBzcmMgKyAnOicgKyBjb2xvclN0cmluZztcbn1cblxuZXhwb3J0IGRlZmF1bHQgSWNvbkltYWdlQ2FjaGU7XG4vKipcbiAqIFRoZSB7QGxpbmsgbW9kdWxlOm9sL3N0eWxlL0ljb25JbWFnZUNhY2hlfkljb25JbWFnZUNhY2hlfSBmb3JcbiAqIHtAbGluayBtb2R1bGU6b2wvc3R5bGUvSWNvbn5JY29ufSBpbWFnZXMuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBzaGFyZWQgPSBuZXcgSWNvbkltYWdlQ2FjaGUoKTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZXZlbnRzL0V2ZW50XG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBTdHJpcHBlZCBkb3duIGltcGxlbWVudGF0aW9uIG9mIHRoZSBXM0MgRE9NIExldmVsIDIgRXZlbnQgaW50ZXJmYWNlLlxuICogU2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1FdmVudHMvZXZlbnRzLmh0bWwjRXZlbnRzLWludGVyZmFjZS5cbiAqXG4gKiBUaGlzIGltcGxlbWVudGF0aW9uIG9ubHkgcHJvdmlkZXMgYHR5cGVgIGFuZCBgdGFyZ2V0YCBwcm9wZXJ0aWVzLCBhbmRcbiAqIGBzdG9wUHJvcGFnYXRpb25gIGFuZCBgcHJldmVudERlZmF1bHRgIG1ldGhvZHMuIEl0IGlzIG1lYW50IGFzIGJhc2UgY2xhc3NcbiAqIGZvciBoaWdoZXIgbGV2ZWwgZXZlbnRzIGRlZmluZWQgaW4gdGhlIGxpYnJhcnksIGFuZCB3b3JrcyB3aXRoXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50cy9UYXJnZXR+VGFyZ2V0fS5cbiAqL1xudmFyIEJhc2VFdmVudCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUeXBlLlxuICAgKi9cbiAgZnVuY3Rpb24gQmFzZUV2ZW50KHR5cGUpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZDtcbiAgICAvKipcbiAgICAgKiBUaGUgZXZlbnQgdHlwZS5cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgLyoqXG4gICAgICogVGhlIGV2ZW50IHRhcmdldC5cbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICAgIHRoaXMudGFyZ2V0ID0gbnVsbDtcbiAgfVxuICAvKipcbiAgICogU3RvcCBldmVudCBwcm9wYWdhdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VFdmVudC5wcm90b3R5cGUucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5wcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xuICB9O1xuICAvKipcbiAgICogU3RvcCBldmVudCBwcm9wYWdhdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VFdmVudC5wcm90b3R5cGUuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTtcbiAgfTtcblxuICByZXR1cm4gQmFzZUV2ZW50O1xufSgpO1xuLyoqXG4gKiBAcGFyYW0ge0V2ZW50fGltcG9ydChcIi4vRXZlbnQuanNcIikuZGVmYXVsdH0gZXZ0IEV2ZW50XG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKGV2dCkge1xuICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG59XG4vKipcbiAqIEBwYXJhbSB7RXZlbnR8aW1wb3J0KFwiLi9FdmVudC5qc1wiKS5kZWZhdWx0fSBldnQgRXZlbnRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcHJldmVudERlZmF1bHQoZXZ0KSB7XG4gIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xufVxuZXhwb3J0IGRlZmF1bHQgQmFzZUV2ZW50OyIsIi8qKlxuICogQG1vZHVsZSBvbC9PYmplY3RFdmVudFR5cGVcbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFRyaWdnZXJlZCB3aGVuIGEgcHJvcGVydHkgaXMgY2hhbmdlZC5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9PYmplY3QuT2JqZWN0RXZlbnQjcHJvcGVydHljaGFuZ2VcbiAgICogQGFwaVxuICAgKi9cbiAgUFJPUEVSVFlDSEFOR0U6ICdwcm9wZXJ0eWNoYW5nZSdcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL29ialxuICovXG5cbi8qKlxuICogUG9seWZpbGwgZm9yIE9iamVjdC5hc3NpZ24oKS4gIEFzc2lnbnMgZW51bWVyYWJsZSBhbmQgb3duIHByb3BlcnRpZXMgZnJvbVxuICogb25lIG9yIG1vcmUgc291cmNlIG9iamVjdHMgdG8gYSB0YXJnZXQgb2JqZWN0LlxuICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL09iamVjdC9hc3NpZ24uXG4gKlxuICogQHBhcmFtIHshT2JqZWN0fSB0YXJnZXQgVGhlIHRhcmdldCBvYmplY3QuXG4gKiBAcGFyYW0gey4uLk9iamVjdH0gdmFyX3NvdXJjZXMgVGhlIHNvdXJjZSBvYmplY3QocykuXG4gKiBAcmV0dXJuIHshT2JqZWN0fSBUaGUgbW9kaWZpZWQgdGFyZ2V0IG9iamVjdC5cbiAqL1xuZXhwb3J0IHZhciBhc3NpZ24gPSB0eXBlb2YgT2JqZWN0LmFzc2lnbiA9PT0gJ2Z1bmN0aW9uJyA/IE9iamVjdC5hc3NpZ24gOiBmdW5jdGlvbiAodGFyZ2V0LCB2YXJfc291cmNlcykge1xuICBpZiAodGFyZ2V0ID09PSB1bmRlZmluZWQgfHwgdGFyZ2V0ID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgdW5kZWZpbmVkIG9yIG51bGwgdG8gb2JqZWN0Jyk7XG4gIH1cblxuICB2YXIgb3V0cHV0ID0gT2JqZWN0KHRhcmdldCk7XG5cbiAgZm9yICh2YXIgaSA9IDEsIGlpID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuXG4gICAgaWYgKHNvdXJjZSAhPT0gdW5kZWZpbmVkICYmIHNvdXJjZSAhPT0gbnVsbCkge1xuICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xuICAgICAgICBpZiAoc291cmNlLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICBvdXRwdXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn07XG4vKipcbiAqIFJlbW92ZXMgYWxsIHByb3BlcnRpZXMgZnJvbSBhbiBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xlYXIuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyKG9iamVjdCkge1xuICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICBkZWxldGUgb2JqZWN0W3Byb3BlcnR5XTtcbiAgfVxufVxuLyoqXG4gKiBQb2x5ZmlsbCBmb3IgT2JqZWN0LnZhbHVlcygpLiAgR2V0IGFuIGFycmF5IG9mIHByb3BlcnR5IHZhbHVlcyBmcm9tIGFuIG9iamVjdC5cbiAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvdmFsdWVzXG4gKlxuICogQHBhcmFtIHshT2JqZWN0PEssVj59IG9iamVjdCBUaGUgb2JqZWN0IGZyb20gd2hpY2ggdG8gZ2V0IHRoZSB2YWx1ZXMuXG4gKiBAcmV0dXJuIHshQXJyYXk8Vj59IFRoZSBwcm9wZXJ0eSB2YWx1ZXMuXG4gKiBAdGVtcGxhdGUgSyxWXG4gKi9cblxuZXhwb3J0IHZhciBnZXRWYWx1ZXMgPSB0eXBlb2YgT2JqZWN0LnZhbHVlcyA9PT0gJ2Z1bmN0aW9uJyA/IE9iamVjdC52YWx1ZXMgOiBmdW5jdGlvbiAob2JqZWN0KSB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcblxuICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICB2YWx1ZXMucHVzaChvYmplY3RbcHJvcGVydHldKTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZXM7XG59O1xuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYW4gb2JqZWN0IGhhcyBhbnkgcHJvcGVydGllcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjaGVjay5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBvYmplY3QgaXMgZW1wdHkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHkob2JqZWN0KSB7XG4gIHZhciBwcm9wZXJ0eTtcblxuICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiAhcHJvcGVydHk7XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9ldmVudHMvVGFyZ2V0XG4gKi9cblxuXG5pbXBvcnQgRGlzcG9zYWJsZSBmcm9tICcuLi9EaXNwb3NhYmxlLmpzJztcbmltcG9ydCBFdmVudCBmcm9tICcuL0V2ZW50LmpzJztcbmltcG9ydCB7IFZPSUQgfSBmcm9tICcuLi9mdW5jdGlvbnMuanMnO1xuaW1wb3J0IHsgY2xlYXIgfSBmcm9tICcuLi9vYmouanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7RXZlbnRUYXJnZXR8VGFyZ2V0fSBFdmVudFRhcmdldExpa2VcbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEEgc2ltcGxpZmllZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgVzNDIERPTSBMZXZlbCAyIEV2ZW50VGFyZ2V0IGludGVyZmFjZS5cbiAqIFNlZSBodHRwczovL3d3dy53My5vcmcvVFIvMjAwMC9SRUMtRE9NLUxldmVsLTItRXZlbnRzLTIwMDAxMTEzL2V2ZW50cy5odG1sI0V2ZW50cy1FdmVudFRhcmdldC5cbiAqXG4gKiBUaGVyZSBhcmUgdHdvIGltcG9ydGFudCBzaW1wbGlmaWNhdGlvbnMgY29tcGFyZWQgdG8gdGhlIHNwZWNpZmljYXRpb246XG4gKlxuICogMS4gVGhlIGhhbmRsaW5nIG9mIGB1c2VDYXB0dXJlYCBpbiBgYWRkRXZlbnRMaXN0ZW5lcmAgYW5kXG4gKiAgICBgcmVtb3ZlRXZlbnRMaXN0ZW5lcmAuIFRoZXJlIGlzIG5vIHJlYWwgY2FwdHVyZSBtb2RlbC5cbiAqIDIuIFRoZSBoYW5kbGluZyBvZiBgc3RvcFByb3BhZ2F0aW9uYCBhbmQgYHByZXZlbnREZWZhdWx0YCBvbiBgZGlzcGF0Y2hFdmVudGAuXG4gKiAgICBUaGVyZSBpcyBubyBldmVudCB0YXJnZXQgaGllcmFyY2h5LiBXaGVuIGEgbGlzdGVuZXIgY2FsbHNcbiAqICAgIGBzdG9wUHJvcGFnYXRpb25gIG9yIGBwcmV2ZW50RGVmYXVsdGAgb24gYW4gZXZlbnQgb2JqZWN0LCBpdCBtZWFucyB0aGF0IG5vXG4gKiAgICBtb3JlIGxpc3RlbmVycyBhZnRlciB0aGlzIG9uZSB3aWxsIGJlIGNhbGxlZC4gU2FtZSBhcyB3aGVuIHRoZSBsaXN0ZW5lclxuICogICAgcmV0dXJucyBmYWxzZS5cbiAqL1xuXG52YXIgVGFyZ2V0ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFRhcmdldCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Kj19IG9wdF90YXJnZXQgRGVmYXVsdCBldmVudCB0YXJnZXQgZm9yIGRpc3BhdGNoZWQgZXZlbnRzLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFRhcmdldChvcHRfdGFyZ2V0KSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHsqfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5ldmVudFRhcmdldF8gPSBvcHRfdGFyZ2V0O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsIG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5wZW5kaW5nUmVtb3ZhbHNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBudW1iZXI+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZGlzcGF0Y2hpbmdfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBBcnJheTxpbXBvcnQoXCIuLi9ldmVudHMuanNcIikuTGlzdGVuZXI+Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxpc3RlbmVyc18gPSBudWxsO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVHlwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9ldmVudHMuanNcIikuTGlzdGVuZXJ9IGxpc3RlbmVyIExpc3RlbmVyLlxuICAgKi9cblxuXG4gIFRhcmdldC5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uICh0eXBlLCBsaXN0ZW5lcikge1xuICAgIGlmICghdHlwZSB8fCAhbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5saXN0ZW5lcnNfIHx8ICh0aGlzLmxpc3RlbmVyc18gPSB7fSk7XG4gICAgdmFyIGxpc3RlbmVyc0ZvclR5cGUgPSBsaXN0ZW5lcnNbdHlwZV0gfHwgKGxpc3RlbmVyc1t0eXBlXSA9IFtdKTtcblxuICAgIGlmIChsaXN0ZW5lcnNGb3JUeXBlLmluZGV4T2YobGlzdGVuZXIpID09PSAtMSkge1xuICAgICAgbGlzdGVuZXJzRm9yVHlwZS5wdXNoKGxpc3RlbmVyKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBEaXNwYXRjaGVzIGFuIGV2ZW50IGFuZCBjYWxscyBhbGwgbGlzdGVuZXJzIGxpc3RlbmluZyBmb3IgZXZlbnRzXG4gICAqIG9mIHRoaXMgdHlwZS4gVGhlIGV2ZW50IHBhcmFtZXRlciBjYW4gZWl0aGVyIGJlIGEgc3RyaW5nIG9yIGFuXG4gICAqIE9iamVjdCB3aXRoIGEgYHR5cGVgIHByb3BlcnR5LlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vRXZlbnQuanNcIikuZGVmYXVsdHxzdHJpbmd9IGV2ZW50IEV2ZW50IG9iamVjdC5cbiAgICogQHJldHVybiB7Ym9vbGVhbnx1bmRlZmluZWR9IGBmYWxzZWAgaWYgYW55b25lIGNhbGxlZCBwcmV2ZW50RGVmYXVsdCBvbiB0aGVcbiAgICogICAgIGV2ZW50IG9iamVjdCBvciBpZiBhbnkgb2YgdGhlIGxpc3RlbmVycyByZXR1cm5lZCBmYWxzZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRhcmdldC5wcm90b3R5cGUuZGlzcGF0Y2hFdmVudCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9FdmVudC5qc1wiKS5kZWZhdWx0fEV2ZW50fSAqL1xuICAgIHZhciBldnQgPSB0eXBlb2YgZXZlbnQgPT09ICdzdHJpbmcnID8gbmV3IEV2ZW50KGV2ZW50KSA6IGV2ZW50O1xuICAgIHZhciB0eXBlID0gZXZ0LnR5cGU7XG5cbiAgICBpZiAoIWV2dC50YXJnZXQpIHtcbiAgICAgIGV2dC50YXJnZXQgPSB0aGlzLmV2ZW50VGFyZ2V0XyB8fCB0aGlzO1xuICAgIH1cblxuICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVyc18gJiYgdGhpcy5saXN0ZW5lcnNfW3R5cGVdO1xuICAgIHZhciBwcm9wYWdhdGU7XG5cbiAgICBpZiAobGlzdGVuZXJzKSB7XG4gICAgICB2YXIgZGlzcGF0Y2hpbmcgPSB0aGlzLmRpc3BhdGNoaW5nXyB8fCAodGhpcy5kaXNwYXRjaGluZ18gPSB7fSk7XG4gICAgICB2YXIgcGVuZGluZ1JlbW92YWxzID0gdGhpcy5wZW5kaW5nUmVtb3ZhbHNfIHx8ICh0aGlzLnBlbmRpbmdSZW1vdmFsc18gPSB7fSk7XG5cbiAgICAgIGlmICghKHR5cGUgaW4gZGlzcGF0Y2hpbmcpKSB7XG4gICAgICAgIGRpc3BhdGNoaW5nW3R5cGVdID0gMDtcbiAgICAgICAgcGVuZGluZ1JlbW92YWxzW3R5cGVdID0gMDtcbiAgICAgIH1cblxuICAgICAgKytkaXNwYXRjaGluZ1t0eXBlXTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgaWYgKCdoYW5kbGVFdmVudCcgaW4gbGlzdGVuZXJzW2ldKSB7XG4gICAgICAgICAgcHJvcGFnYXRlID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2V2ZW50cy5qc1wiKS5MaXN0ZW5lck9iamVjdH0gKi9cbiAgICAgICAgICBsaXN0ZW5lcnNbaV0uaGFuZGxlRXZlbnQoZXZ0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcm9wYWdhdGUgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkxpc3RlbmVyRnVuY3Rpb259ICovXG4gICAgICAgICAgbGlzdGVuZXJzW2ldLmNhbGwodGhpcywgZXZ0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9wYWdhdGUgPT09IGZhbHNlIHx8IGV2dC5wcm9wYWdhdGlvblN0b3BwZWQpIHtcbiAgICAgICAgICBwcm9wYWdhdGUgPSBmYWxzZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAtLWRpc3BhdGNoaW5nW3R5cGVdO1xuXG4gICAgICBpZiAoZGlzcGF0Y2hpbmdbdHlwZV0gPT09IDApIHtcbiAgICAgICAgdmFyIHByID0gcGVuZGluZ1JlbW92YWxzW3R5cGVdO1xuICAgICAgICBkZWxldGUgcGVuZGluZ1JlbW92YWxzW3R5cGVdO1xuXG4gICAgICAgIHdoaWxlIChwci0tKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIFZPSUQpO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVsZXRlIGRpc3BhdGNoaW5nW3R5cGVdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHJvcGFnYXRlO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIENsZWFuIHVwLlxuICAgKi9cblxuXG4gIFRhcmdldC5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMubGlzdGVuZXJzXyAmJiBjbGVhcih0aGlzLmxpc3RlbmVyc18pO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBsaXN0ZW5lcnMgZm9yIGEgc3BlY2lmaWVkIGV2ZW50IHR5cGUuIExpc3RlbmVycyBhcmUgcmV0dXJuZWQgaW4gdGhlXG4gICAqIG9yZGVyIHRoYXQgdGhleSB3aWxsIGJlIGNhbGxlZCBpbi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVHlwZS5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkxpc3RlbmVyPnx1bmRlZmluZWR9IExpc3RlbmVycy5cbiAgICovXG5cblxuICBUYXJnZXQucHJvdG90eXBlLmdldExpc3RlbmVycyA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXJzXyAmJiB0aGlzLmxpc3RlbmVyc19bdHlwZV0gfHwgdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmc9fSBvcHRfdHlwZSBUeXBlLiBJZiBub3QgcHJvdmlkZWQsXG4gICAqICAgICBgdHJ1ZWAgd2lsbCBiZSByZXR1cm5lZCBpZiB0aGlzIGV2ZW50IHRhcmdldCBoYXMgYW55IGxpc3RlbmVycy5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSGFzIGxpc3RlbmVycy5cbiAgICovXG5cblxuICBUYXJnZXQucHJvdG90eXBlLmhhc0xpc3RlbmVyID0gZnVuY3Rpb24gKG9wdF90eXBlKSB7XG4gICAgaWYgKCF0aGlzLmxpc3RlbmVyc18pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3B0X3R5cGUgPyBvcHRfdHlwZSBpbiB0aGlzLmxpc3RlbmVyc18gOiBPYmplY3Qua2V5cyh0aGlzLmxpc3RlbmVyc18pLmxlbmd0aCA+IDA7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUeXBlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V2ZW50cy5qc1wiKS5MaXN0ZW5lcn0gbGlzdGVuZXIgTGlzdGVuZXIuXG4gICAqL1xuXG5cbiAgVGFyZ2V0LnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgdmFyIGxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzXyAmJiB0aGlzLmxpc3RlbmVyc19bdHlwZV07XG5cbiAgICBpZiAobGlzdGVuZXJzKSB7XG4gICAgICB2YXIgaW5kZXggPSBsaXN0ZW5lcnMuaW5kZXhPZihsaXN0ZW5lcik7XG5cbiAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgaWYgKHRoaXMucGVuZGluZ1JlbW92YWxzXyAmJiB0eXBlIGluIHRoaXMucGVuZGluZ1JlbW92YWxzXykge1xuICAgICAgICAgIC8vIG1ha2UgbGlzdGVuZXIgYSBuby1vcCwgYW5kIHJlbW92ZSBsYXRlciBpbiAjZGlzcGF0Y2hFdmVudCgpXG4gICAgICAgICAgbGlzdGVuZXJzW2luZGV4XSA9IFZPSUQ7XG4gICAgICAgICAgKyt0aGlzLnBlbmRpbmdSZW1vdmFsc19bdHlwZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XG5cbiAgICAgICAgICBpZiAobGlzdGVuZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMubGlzdGVuZXJzX1t0eXBlXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIFRhcmdldDtcbn0oRGlzcG9zYWJsZSk7XG5cbmV4cG9ydCBkZWZhdWx0IFRhcmdldDsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZXZlbnRzL0V2ZW50VHlwZVxuICovXG5cbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqIEBjb25zdFxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBHZW5lcmljIGNoYW5nZSBldmVudC4gVHJpZ2dlcmVkIHdoZW4gdGhlIHJldmlzaW9uIGNvdW50ZXIgaXMgaW5jcmVhc2VkLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL2V2ZW50cy9FdmVudH5CYXNlRXZlbnQjY2hhbmdlXG4gICAqIEBhcGlcbiAgICovXG4gIENIQU5HRTogJ2NoYW5nZScsXG5cbiAgLyoqXG4gICAqIEdlbmVyaWMgZXJyb3IgZXZlbnQuIFRyaWdnZXJlZCB3aGVuIGFuIGVycm9yIG9jY3Vycy5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9ldmVudHMvRXZlbnR+QmFzZUV2ZW50I2Vycm9yXG4gICAqIEBhcGlcbiAgICovXG4gIEVSUk9SOiAnZXJyb3InLFxuICBCTFVSOiAnYmx1cicsXG4gIENMRUFSOiAnY2xlYXInLFxuICBDT05URVhUTUVOVTogJ2NvbnRleHRtZW51JyxcbiAgQ0xJQ0s6ICdjbGljaycsXG4gIERCTENMSUNLOiAnZGJsY2xpY2snLFxuICBEUkFHRU5URVI6ICdkcmFnZW50ZXInLFxuICBEUkFHT1ZFUjogJ2RyYWdvdmVyJyxcbiAgRFJPUDogJ2Ryb3AnLFxuICBGT0NVUzogJ2ZvY3VzJyxcbiAgS0VZRE9XTjogJ2tleWRvd24nLFxuICBLRVlQUkVTUzogJ2tleXByZXNzJyxcbiAgTE9BRDogJ2xvYWQnLFxuICBSRVNJWkU6ICdyZXNpemUnLFxuICBUT1VDSE1PVkU6ICd0b3VjaG1vdmUnLFxuICBXSEVFTDogJ3doZWVsJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZXZlbnRzXG4gKi9cbmltcG9ydCB7IGNsZWFyIH0gZnJvbSAnLi9vYmouanMnO1xuLyoqXG4gKiBLZXkgdG8gdXNlIHdpdGgge0BsaW5rIG1vZHVsZTpvbC9PYnNlcnZhYmxlfk9ic2VydmFibGUjdW5CeUtleX0uXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBFdmVudHNLZXlcbiAqIEBwcm9wZXJ0eSB7TGlzdGVuZXJGdW5jdGlvbn0gbGlzdGVuZXJcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9ldmVudHMvVGFyZ2V0LmpzXCIpLkV2ZW50VGFyZ2V0TGlrZX0gdGFyZ2V0XG4gKiBAcHJvcGVydHkge3N0cmluZ30gdHlwZVxuICogQGFwaVxuICovXG5cbi8qKlxuICogTGlzdGVuZXIgZnVuY3Rpb24uIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggYW4gZXZlbnQgb2JqZWN0IGFzIGFyZ3VtZW50LlxuICogV2hlbiB0aGUgZnVuY3Rpb24gcmV0dXJucyBgZmFsc2VgLCBldmVudCBwcm9wYWdhdGlvbiB3aWxsIHN0b3AuXG4gKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKChFdmVudHxpbXBvcnQoXCIuL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0KSk6ICh2b2lkfGJvb2xlYW4pfSBMaXN0ZW5lckZ1bmN0aW9uXG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBMaXN0ZW5lck9iamVjdFxuICogQHByb3BlcnR5IHtMaXN0ZW5lckZ1bmN0aW9ufSBoYW5kbGVFdmVudFxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge0xpc3RlbmVyRnVuY3Rpb258TGlzdGVuZXJPYmplY3R9IExpc3RlbmVyXG4gKi9cblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gZXZlbnQgbGlzdGVuZXIgb24gYW4gZXZlbnQgdGFyZ2V0LiBJbnNwaXJlZCBieVxuICogaHR0cHM6Ly9nb29nbGUuZ2l0aHViLmlvL2Nsb3N1cmUtbGlicmFyeS9hcGkvc291cmNlL2Nsb3N1cmUvZ29vZy9ldmVudHMvZXZlbnRzLmpzLnNyYy5odG1sXG4gKlxuICogVGhpcyBmdW5jdGlvbiBlZmZpY2llbnRseSBiaW5kcyBhIGBsaXN0ZW5lcmAgdG8gYSBgdGhpc2Agb2JqZWN0LCBhbmQgcmV0dXJuc1xuICogYSBrZXkgZm9yIHVzZSB3aXRoIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzfnVubGlzdGVuQnlLZXl9LlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9ldmVudHMvVGFyZ2V0LmpzXCIpLkV2ZW50VGFyZ2V0TGlrZX0gdGFyZ2V0IEV2ZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIEV2ZW50IHR5cGUuXG4gKiBAcGFyYW0ge0xpc3RlbmVyRnVuY3Rpb259IGxpc3RlbmVyIExpc3RlbmVyLlxuICogQHBhcmFtIHtPYmplY3Q9fSBvcHRfdGhpcyBPYmplY3QgcmVmZXJlbmNlZCBieSB0aGUgYHRoaXNgIGtleXdvcmQgaW4gdGhlXG4gKiAgICAgbGlzdGVuZXIuIERlZmF1bHQgaXMgdGhlIGB0YXJnZXRgLlxuICogQHBhcmFtIHtib29sZWFuPX0gb3B0X29uY2UgSWYgdHJ1ZSwgYWRkIHRoZSBsaXN0ZW5lciBhcyBvbmUtb2ZmIGxpc3RlbmVyLlxuICogQHJldHVybiB7RXZlbnRzS2V5fSBVbmlxdWUga2V5IGZvciB0aGUgbGlzdGVuZXIuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpc3Rlbih0YXJnZXQsIHR5cGUsIF9saXN0ZW5lciwgb3B0X3RoaXMsIG9wdF9vbmNlKSB7XG4gIGlmIChvcHRfdGhpcyAmJiBvcHRfdGhpcyAhPT0gdGFyZ2V0KSB7XG4gICAgX2xpc3RlbmVyID0gX2xpc3RlbmVyLmJpbmQob3B0X3RoaXMpO1xuICB9XG5cbiAgaWYgKG9wdF9vbmNlKSB7XG4gICAgdmFyIG9yaWdpbmFsTGlzdGVuZXJfMSA9IF9saXN0ZW5lcjtcblxuICAgIF9saXN0ZW5lciA9IGZ1bmN0aW9uIGxpc3RlbmVyKCkge1xuICAgICAgdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgX2xpc3RlbmVyKTtcbiAgICAgIG9yaWdpbmFsTGlzdGVuZXJfMS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cblxuICB2YXIgZXZlbnRzS2V5ID0ge1xuICAgIHRhcmdldDogdGFyZ2V0LFxuICAgIHR5cGU6IHR5cGUsXG4gICAgbGlzdGVuZXI6IF9saXN0ZW5lclxuICB9O1xuICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBfbGlzdGVuZXIpO1xuICByZXR1cm4gZXZlbnRzS2V5O1xufVxuLyoqXG4gKiBSZWdpc3RlcnMgYSBvbmUtb2ZmIGV2ZW50IGxpc3RlbmVyIG9uIGFuIGV2ZW50IHRhcmdldC4gSW5zcGlyZWQgYnlcbiAqIGh0dHBzOi8vZ29vZ2xlLmdpdGh1Yi5pby9jbG9zdXJlLWxpYnJhcnkvYXBpL3NvdXJjZS9jbG9zdXJlL2dvb2cvZXZlbnRzL2V2ZW50cy5qcy5zcmMuaHRtbFxuICpcbiAqIFRoaXMgZnVuY3Rpb24gZWZmaWNpZW50bHkgYmluZHMgYSBgbGlzdGVuZXJgIGFzIHNlbGYtdW5yZWdpc3RlcmluZyBsaXN0ZW5lclxuICogdG8gYSBgdGhpc2Agb2JqZWN0LCBhbmQgcmV0dXJucyBhIGtleSBmb3IgdXNlIHdpdGhcbiAqIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzfnVubGlzdGVuQnlLZXl9IGluIGNhc2UgdGhlIGxpc3RlbmVyIG5lZWRzIHRvIGJlXG4gKiB1bnJlZ2lzdGVyZWQgYmVmb3JlIGl0IGlzIGNhbGxlZC5cbiAqXG4gKiBXaGVuIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzfmxpc3Rlbn0gaXMgY2FsbGVkIHdpdGggdGhlIHNhbWUgYXJndW1lbnRzIGFmdGVyIHRoaXNcbiAqIGZ1bmN0aW9uLCB0aGUgc2VsZi11bnJlZ2lzdGVyaW5nIGxpc3RlbmVyIHdpbGwgYmUgdHVybmVkIGludG8gYSBwZXJtYW5lbnRcbiAqIGxpc3RlbmVyLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9ldmVudHMvVGFyZ2V0LmpzXCIpLkV2ZW50VGFyZ2V0TGlrZX0gdGFyZ2V0IEV2ZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIEV2ZW50IHR5cGUuXG4gKiBAcGFyYW0ge0xpc3RlbmVyRnVuY3Rpb259IGxpc3RlbmVyIExpc3RlbmVyLlxuICogQHBhcmFtIHtPYmplY3Q9fSBvcHRfdGhpcyBPYmplY3QgcmVmZXJlbmNlZCBieSB0aGUgYHRoaXNgIGtleXdvcmQgaW4gdGhlXG4gKiAgICAgbGlzdGVuZXIuIERlZmF1bHQgaXMgdGhlIGB0YXJnZXRgLlxuICogQHJldHVybiB7RXZlbnRzS2V5fSBLZXkgZm9yIHVubGlzdGVuQnlLZXkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpc3Rlbk9uY2UodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgb3B0X3RoaXMpIHtcbiAgcmV0dXJuIGxpc3Rlbih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBvcHRfdGhpcywgdHJ1ZSk7XG59XG4vKipcbiAqIFVucmVnaXN0ZXJzIGV2ZW50IGxpc3RlbmVycyBvbiBhbiBldmVudCB0YXJnZXQuIEluc3BpcmVkIGJ5XG4gKiBodHRwczovL2dvb2dsZS5naXRodWIuaW8vY2xvc3VyZS1saWJyYXJ5L2FwaS9zb3VyY2UvY2xvc3VyZS9nb29nL2V2ZW50cy9ldmVudHMuanMuc3JjLmh0bWxcbiAqXG4gKiBUaGUgYXJndW1lbnQgcGFzc2VkIHRvIHRoaXMgZnVuY3Rpb24gaXMgdGhlIGtleSByZXR1cm5lZCBmcm9tXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50c35saXN0ZW59IG9yIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzfmxpc3Rlbk9uY2V9LlxuICpcbiAqIEBwYXJhbSB7RXZlbnRzS2V5fSBrZXkgVGhlIGtleS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdW5saXN0ZW5CeUtleShrZXkpIHtcbiAgaWYgKGtleSAmJiBrZXkudGFyZ2V0KSB7XG4gICAga2V5LnRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKGtleS50eXBlLCBrZXkubGlzdGVuZXIpO1xuICAgIGNsZWFyKGtleSk7XG4gIH1cbn0iLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL09ic2VydmFibGVcbiAqL1xuXG5cbmltcG9ydCBFdmVudFRhcmdldCBmcm9tICcuL2V2ZW50cy9UYXJnZXQuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IHsgbGlzdGVuLCBsaXN0ZW5PbmNlLCB1bmxpc3RlbkJ5S2V5IH0gZnJvbSAnLi9ldmVudHMuanMnO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBYnN0cmFjdCBiYXNlIGNsYXNzOyBub3JtYWxseSBvbmx5IHVzZWQgZm9yIGNyZWF0aW5nIHN1YmNsYXNzZXMgYW5kIG5vdFxuICogaW5zdGFudGlhdGVkIGluIGFwcHMuXG4gKiBBbiBldmVudCB0YXJnZXQgcHJvdmlkaW5nIGNvbnZlbmllbnQgbWV0aG9kcyBmb3IgbGlzdGVuZXIgcmVnaXN0cmF0aW9uXG4gKiBhbmQgdW5yZWdpc3RyYXRpb24uIEEgZ2VuZXJpYyBgY2hhbmdlYCBldmVudCBpcyBhbHdheXMgYXZhaWxhYmxlIHRocm91Z2hcbiAqIHtAbGluayBtb2R1bGU6b2wvT2JzZXJ2YWJsZX5PYnNlcnZhYmxlI2NoYW5nZWR9LlxuICpcbiAqIEBmaXJlcyBpbXBvcnQoXCIuL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0XG4gKiBAYXBpXG4gKi9cblxudmFyIE9ic2VydmFibGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoT2JzZXJ2YWJsZSwgX3N1cGVyKTtcblxuICBmdW5jdGlvbiBPYnNlcnZhYmxlKCkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5yZXZpc2lvbl8gPSAwO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogSW5jcmVhc2VzIHRoZSByZXZpc2lvbiBjb3VudGVyIGFuZCBkaXNwYXRjaGVzIGEgJ2NoYW5nZScgZXZlbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBPYnNlcnZhYmxlLnByb3RvdHlwZS5jaGFuZ2VkID0gZnVuY3Rpb24gKCkge1xuICAgICsrdGhpcy5yZXZpc2lvbl87XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KEV2ZW50VHlwZS5DSEFOR0UpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB2ZXJzaW9uIG51bWJlciBmb3IgdGhpcyBvYmplY3QuICBFYWNoIHRpbWUgdGhlIG9iamVjdCBpcyBtb2RpZmllZCxcbiAgICogaXRzIHZlcnNpb24gbnVtYmVyIHdpbGwgYmUgaW5jcmVtZW50ZWQuXG4gICAqIEByZXR1cm4ge251bWJlcn0gUmV2aXNpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBPYnNlcnZhYmxlLnByb3RvdHlwZS5nZXRSZXZpc2lvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yZXZpc2lvbl87XG4gIH07XG4gIC8qKlxuICAgKiBMaXN0ZW4gZm9yIGEgY2VydGFpbiB0eXBlIG9mIGV2ZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ3xBcnJheTxzdHJpbmc+fSB0eXBlIFRoZSBldmVudCB0eXBlIG9yIGFycmF5IG9mIGV2ZW50IHR5cGVzLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKD8pOiA/fSBsaXN0ZW5lciBUaGUgbGlzdGVuZXIgZnVuY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleXxBcnJheTxpbXBvcnQoXCIuL2V2ZW50cy5qc1wiKS5FdmVudHNLZXk+fSBVbmlxdWUga2V5IGZvciB0aGUgbGlzdGVuZXIuIElmXG4gICAqICAgICBjYWxsZWQgd2l0aCBhbiBhcnJheSBvZiBldmVudCB0eXBlcyBhcyB0aGUgZmlyc3QgYXJndW1lbnQsIHRoZSByZXR1cm5cbiAgICogICAgIHdpbGwgYmUgYW4gYXJyYXkgb2Yga2V5cy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE9ic2VydmFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodHlwZSkpIHtcbiAgICAgIHZhciBsZW4gPSB0eXBlLmxlbmd0aDtcbiAgICAgIHZhciBrZXlzID0gbmV3IEFycmF5KGxlbik7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAga2V5c1tpXSA9IGxpc3Rlbih0aGlzLCB0eXBlW2ldLCBsaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBrZXlzO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbGlzdGVuKHRoaXMsXG4gICAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICAgIHR5cGUsIGxpc3RlbmVyKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBMaXN0ZW4gb25jZSBmb3IgYSBjZXJ0YWluIHR5cGUgb2YgZXZlbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfEFycmF5PHN0cmluZz59IHR5cGUgVGhlIGV2ZW50IHR5cGUgb3IgYXJyYXkgb2YgZXZlbnQgdHlwZXMuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oPyk6ID99IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBmdW5jdGlvbi5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5fEFycmF5PGltcG9ydChcIi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleT59IFVuaXF1ZSBrZXkgZm9yIHRoZSBsaXN0ZW5lci4gSWZcbiAgICogICAgIGNhbGxlZCB3aXRoIGFuIGFycmF5IG9mIGV2ZW50IHR5cGVzIGFzIHRoZSBmaXJzdCBhcmd1bWVudCwgdGhlIHJldHVyblxuICAgKiAgICAgd2lsbCBiZSBhbiBhcnJheSBvZiBrZXlzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT2JzZXJ2YWJsZS5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uICh0eXBlLCBsaXN0ZW5lcikge1xuICAgIHZhciBrZXk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0eXBlKSkge1xuICAgICAgdmFyIGxlbiA9IHR5cGUubGVuZ3RoO1xuICAgICAga2V5ID0gbmV3IEFycmF5KGxlbik7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAga2V5W2ldID0gbGlzdGVuT25jZSh0aGlzLCB0eXBlW2ldLCBsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGtleSA9IGxpc3Rlbk9uY2UodGhpcyxcbiAgICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgICAgdHlwZSwgbGlzdGVuZXIpO1xuICAgIH1cbiAgICAvKiogQHR5cGUge09iamVjdH0gKi9cblxuXG4gICAgbGlzdGVuZXIub2xfa2V5ID0ga2V5O1xuICAgIHJldHVybiBrZXk7XG4gIH07XG4gIC8qKlxuICAgKiBVbmxpc3RlbiBmb3IgYSBjZXJ0YWluIHR5cGUgb2YgZXZlbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfEFycmF5PHN0cmluZz59IHR5cGUgVGhlIGV2ZW50IHR5cGUgb3IgYXJyYXkgb2YgZXZlbnQgdHlwZXMuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oPyk6ID99IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciBmdW5jdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE9ic2VydmFibGUucHJvdG90eXBlLnVuID0gZnVuY3Rpb24gKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgdmFyIGtleSA9XG4gICAgLyoqIEB0eXBlIHtPYmplY3R9ICovXG4gICAgbGlzdGVuZXIub2xfa2V5O1xuXG4gICAgaWYgKGtleSkge1xuICAgICAgdW5CeUtleShrZXkpO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh0eXBlKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdHlwZS5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlW2ldLCBsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBPYnNlcnZhYmxlO1xufShFdmVudFRhcmdldCk7XG4vKipcbiAqIFJlbW92ZXMgYW4gZXZlbnQgbGlzdGVuZXIgdXNpbmcgdGhlIGtleSByZXR1cm5lZCBieSBgb24oKWAgb3IgYG9uY2UoKWAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleXxBcnJheTxpbXBvcnQoXCIuL2V2ZW50cy5qc1wiKS5FdmVudHNLZXk+fSBrZXkgVGhlIGtleSByZXR1cm5lZCBieSBgb24oKWBcbiAqICAgICBvciBgb25jZSgpYCAob3IgYW4gYXJyYXkgb2Yga2V5cykuXG4gKiBAYXBpXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gdW5CeUtleShrZXkpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoa2V5KSkge1xuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGtleS5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB1bmxpc3RlbkJ5S2V5KGtleVtpXSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHVubGlzdGVuQnlLZXkoXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2V2ZW50cy5qc1wiKS5FdmVudHNLZXl9ICovXG4gICAga2V5KTtcbiAgfVxufVxuZXhwb3J0IGRlZmF1bHQgT2JzZXJ2YWJsZTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL09iamVjdFxuICovXG5cblxuaW1wb3J0IEV2ZW50IGZyb20gJy4vZXZlbnRzL0V2ZW50LmpzJztcbmltcG9ydCBPYmplY3RFdmVudFR5cGUgZnJvbSAnLi9PYmplY3RFdmVudFR5cGUuanMnO1xuaW1wb3J0IE9ic2VydmFibGUgZnJvbSAnLi9PYnNlcnZhYmxlLmpzJztcbmltcG9ydCB7IGFzc2lnbiwgaXNFbXB0eSB9IGZyb20gJy4vb2JqLmpzJztcbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJy4vdXRpbC5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEV2ZW50cyBlbWl0dGVkIGJ5IHtAbGluayBtb2R1bGU6b2wvT2JqZWN0fkJhc2VPYmplY3R9IGluc3RhbmNlcyBhcmUgaW5zdGFuY2VzIG9mIHRoaXMgdHlwZS5cbiAqL1xuXG52YXIgT2JqZWN0RXZlbnQgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoT2JqZWN0RXZlbnQsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUgZXZlbnQgdHlwZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgcHJvcGVydHkgbmFtZS5cbiAgICogQHBhcmFtIHsqfSBvbGRWYWx1ZSBUaGUgb2xkIHZhbHVlIGZvciBga2V5YC5cbiAgICovXG5cblxuICBmdW5jdGlvbiBPYmplY3RFdmVudCh0eXBlLCBrZXksIG9sZFZhbHVlKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdHlwZSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgd2hvc2UgdmFsdWUgaXMgY2hhbmdpbmcuXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAYXBpXG4gICAgICovXG5cblxuICAgIF90aGlzLmtleSA9IGtleTtcbiAgICAvKipcbiAgICAgKiBUaGUgb2xkIHZhbHVlLiBUbyBnZXQgdGhlIG5ldyB2YWx1ZSB1c2UgYGUudGFyZ2V0LmdldChlLmtleSlgIHdoZXJlXG4gICAgICogYGVgIGlzIHRoZSBldmVudCBvYmplY3QuXG4gICAgICogQHR5cGUgeyp9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG4gICAgX3RoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0RXZlbnQ7XG59KEV2ZW50KTtcblxuZXhwb3J0IHsgT2JqZWN0RXZlbnQgfTtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWJzdHJhY3QgYmFzZSBjbGFzczsgbm9ybWFsbHkgb25seSB1c2VkIGZvciBjcmVhdGluZyBzdWJjbGFzc2VzIGFuZCBub3RcbiAqIGluc3RhbnRpYXRlZCBpbiBhcHBzLlxuICogTW9zdCBub24tdHJpdmlhbCBjbGFzc2VzIGluaGVyaXQgZnJvbSB0aGlzLlxuICpcbiAqIFRoaXMgZXh0ZW5kcyB7QGxpbmsgbW9kdWxlOm9sL09ic2VydmFibGV9IHdpdGggb2JzZXJ2YWJsZVxuICogcHJvcGVydGllcywgd2hlcmUgZWFjaCBwcm9wZXJ0eSBpcyBvYnNlcnZhYmxlIGFzIHdlbGwgYXMgdGhlIG9iamVjdCBhcyBhXG4gKiB3aG9sZS5cbiAqXG4gKiBDbGFzc2VzIHRoYXQgaW5oZXJpdCBmcm9tIHRoaXMgaGF2ZSBwcmUtZGVmaW5lZCBwcm9wZXJ0aWVzLCB0byB3aGljaCB5b3UgY2FuXG4gKiBhZGQgeW91ciBvd25zLiBUaGUgcHJlLWRlZmluZWQgcHJvcGVydGllcyBhcmUgbGlzdGVkIGluIHRoaXMgZG9jdW1lbnRhdGlvbiBhc1xuICogJ09ic2VydmFibGUgUHJvcGVydGllcycsIGFuZCBoYXZlIHRoZWlyIG93biBhY2Nlc3NvcnM7IGZvciBleGFtcGxlLFxuICoge0BsaW5rIG1vZHVsZTpvbC9NYXB+TWFwfSBoYXMgYSBgdGFyZ2V0YCBwcm9wZXJ0eSwgYWNjZXNzZWQgd2l0aFxuICogYGdldFRhcmdldCgpYCBhbmQgY2hhbmdlZCB3aXRoIGBzZXRUYXJnZXQoKWAuIE5vdCBhbGwgcHJvcGVydGllcyBhcmUgaG93ZXZlclxuICogc2V0dGFibGUuIFRoZXJlIGFyZSBhbHNvIGdlbmVyYWwtcHVycG9zZSBhY2Nlc3NvcnMgYGdldCgpYCBhbmQgYHNldCgpYC4gRm9yXG4gKiBleGFtcGxlLCBgZ2V0KCd0YXJnZXQnKWAgaXMgZXF1aXZhbGVudCB0byBgZ2V0VGFyZ2V0KClgLlxuICpcbiAqIFRoZSBgc2V0YCBhY2Nlc3NvcnMgdHJpZ2dlciBhIGNoYW5nZSBldmVudCwgYW5kIHlvdSBjYW4gbW9uaXRvciB0aGlzIGJ5XG4gKiByZWdpc3RlcmluZyBhIGxpc3RlbmVyLiBGb3IgZXhhbXBsZSwge0BsaW5rIG1vZHVsZTpvbC9WaWV3flZpZXd9IGhhcyBhXG4gKiBgY2VudGVyYCBwcm9wZXJ0eSwgc28gYHZpZXcub24oJ2NoYW5nZTpjZW50ZXInLCBmdW5jdGlvbihldnQpIHsuLi59KTtgIHdvdWxkXG4gKiBjYWxsIHRoZSBmdW5jdGlvbiB3aGVuZXZlciB0aGUgdmFsdWUgb2YgdGhlIGNlbnRlciBwcm9wZXJ0eSBjaGFuZ2VzLiBXaXRoaW5cbiAqIHRoZSBmdW5jdGlvbiwgYGV2dC50YXJnZXRgIHdvdWxkIGJlIHRoZSB2aWV3LCBzbyBgZXZ0LnRhcmdldC5nZXRDZW50ZXIoKWBcbiAqIHdvdWxkIHJldHVybiB0aGUgbmV3IGNlbnRlci5cbiAqXG4gKiBZb3UgY2FuIGFkZCB5b3VyIG93biBvYnNlcnZhYmxlIHByb3BlcnRpZXMgd2l0aFxuICogYG9iamVjdC5zZXQoJ3Byb3AnLCAndmFsdWUnKWAsIGFuZCByZXRyaWV2ZSB0aGF0IHdpdGggYG9iamVjdC5nZXQoJ3Byb3AnKWAuXG4gKiBZb3UgY2FuIGxpc3RlbiBmb3IgY2hhbmdlcyBvbiB0aGF0IHByb3BlcnR5IHZhbHVlIHdpdGhcbiAqIGBvYmplY3Qub24oJ2NoYW5nZTpwcm9wJywgbGlzdGVuZXIpYC4gWW91IGNhbiBnZXQgYSBsaXN0IG9mIGFsbFxuICogcHJvcGVydGllcyB3aXRoIHtAbGluayBtb2R1bGU6b2wvT2JqZWN0fkJhc2VPYmplY3QjZ2V0UHJvcGVydGllc30uXG4gKlxuICogTm90ZSB0aGF0IHRoZSBvYnNlcnZhYmxlIHByb3BlcnRpZXMgYXJlIHNlcGFyYXRlIGZyb20gc3RhbmRhcmQgSlMgcHJvcGVydGllcy5cbiAqIFlvdSBjYW4sIGZvciBleGFtcGxlLCBnaXZlIHlvdXIgbWFwIG9iamVjdCBhIHRpdGxlIHdpdGhcbiAqIGBtYXAudGl0bGU9J05ldyB0aXRsZSdgIGFuZCB3aXRoIGBtYXAuc2V0KCd0aXRsZScsICdBbm90aGVyIHRpdGxlJylgLiBUaGVcbiAqIGZpcnN0IHdpbGwgYmUgYSBgaGFzT3duUHJvcGVydHlgOyB0aGUgc2Vjb25kIHdpbGwgYXBwZWFyIGluXG4gKiBgZ2V0UHJvcGVydGllcygpYC4gT25seSB0aGUgc2Vjb25kIGlzIG9ic2VydmFibGUuXG4gKlxuICogUHJvcGVydGllcyBjYW4gYmUgZGVsZXRlZCBieSB1c2luZyB0aGUgdW5zZXQgbWV0aG9kLiBFLmcuXG4gKiBvYmplY3QudW5zZXQoJ2ZvbycpLlxuICpcbiAqIEBmaXJlcyBPYmplY3RFdmVudFxuICogQGFwaVxuICovXG5cbnZhciBCYXNlT2JqZWN0ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEJhc2VPYmplY3QsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdDxzdHJpbmcsICo+PX0gb3B0X3ZhbHVlcyBBbiBvYmplY3Qgd2l0aCBrZXktdmFsdWUgcGFpcnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQmFzZU9iamVjdChvcHRfdmFsdWVzKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpczsgLy8gQ2FsbCB7QGxpbmsgbW9kdWxlOm9sL3V0aWx+Z2V0VWlkfSB0byBlbnN1cmUgdGhhdCB0aGUgb3JkZXIgb2Ygb2JqZWN0cycgaWRzIGlzXG4gICAgLy8gdGhlIHNhbWUgYXMgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgd2VyZSBjcmVhdGVkLiAgVGhpcyBhbHNvIGhlbHBzIHRvXG4gICAgLy8gZW5zdXJlIHRoYXQgb2JqZWN0IHByb3BlcnRpZXMgYXJlIGFsd2F5cyBhZGRlZCBpbiB0aGUgc2FtZSBvcmRlciwgd2hpY2hcbiAgICAvLyBoZWxwcyBtYW55IEphdmFTY3JpcHQgZW5naW5lcyBnZW5lcmF0ZSBmYXN0ZXIgY29kZS5cblxuXG4gICAgZ2V0VWlkKF90aGlzKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCAqPn1cbiAgICAgKi9cblxuICAgIF90aGlzLnZhbHVlc18gPSBudWxsO1xuXG4gICAgaWYgKG9wdF92YWx1ZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgX3RoaXMuc2V0UHJvcGVydGllcyhvcHRfdmFsdWVzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldHMgYSB2YWx1ZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkgbmFtZS5cbiAgICogQHJldHVybiB7Kn0gVmFsdWUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlT2JqZWN0LnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgdmFyIHZhbHVlO1xuXG4gICAgaWYgKHRoaXMudmFsdWVzXyAmJiB0aGlzLnZhbHVlc18uaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgdmFsdWUgPSB0aGlzLnZhbHVlc19ba2V5XTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgYSBsaXN0IG9mIG9iamVjdCBwcm9wZXJ0eSBuYW1lcy5cbiAgICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn0gTGlzdCBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VPYmplY3QucHJvdG90eXBlLmdldEtleXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWVzXyAmJiBPYmplY3Qua2V5cyh0aGlzLnZhbHVlc18pIHx8IFtdO1xuICB9O1xuICAvKipcbiAgICogR2V0IGFuIG9iamVjdCBvZiBhbGwgcHJvcGVydHkgbmFtZXMgYW5kIHZhbHVlcy5cbiAgICogQHJldHVybiB7T2JqZWN0PHN0cmluZywgKj59IE9iamVjdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VPYmplY3QucHJvdG90eXBlLmdldFByb3BlcnRpZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWVzXyAmJiBhc3NpZ24oe30sIHRoaXMudmFsdWVzXykgfHwge307XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaGUgb2JqZWN0IGhhcyBwcm9wZXJ0aWVzLlxuICAgKi9cblxuXG4gIEJhc2VPYmplY3QucHJvdG90eXBlLmhhc1Byb3BlcnRpZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICEhdGhpcy52YWx1ZXNfO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkgbmFtZS5cbiAgICogQHBhcmFtIHsqfSBvbGRWYWx1ZSBPbGQgdmFsdWUuXG4gICAqL1xuXG5cbiAgQmFzZU9iamVjdC5wcm90b3R5cGUubm90aWZ5ID0gZnVuY3Rpb24gKGtleSwgb2xkVmFsdWUpIHtcbiAgICB2YXIgZXZlbnRUeXBlO1xuICAgIGV2ZW50VHlwZSA9IGdldENoYW5nZUV2ZW50VHlwZShrZXkpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgT2JqZWN0RXZlbnQoZXZlbnRUeXBlLCBrZXksIG9sZFZhbHVlKSk7XG4gICAgZXZlbnRUeXBlID0gT2JqZWN0RXZlbnRUeXBlLlBST1BFUlRZQ0hBTkdFO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgT2JqZWN0RXZlbnQoZXZlbnRUeXBlLCBrZXksIG9sZFZhbHVlKSk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXRzIGEgdmFsdWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5IG5hbWUuXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVmFsdWUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9zaWxlbnQgVXBkYXRlIHdpdGhvdXQgdHJpZ2dlcmluZyBhbiBldmVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VPYmplY3QucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlLCBvcHRfc2lsZW50KSB7XG4gICAgdmFyIHZhbHVlcyA9IHRoaXMudmFsdWVzXyB8fCAodGhpcy52YWx1ZXNfID0ge30pO1xuXG4gICAgaWYgKG9wdF9zaWxlbnQpIHtcbiAgICAgIHZhbHVlc1trZXldID0gdmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBvbGRWYWx1ZSA9IHZhbHVlc1trZXldO1xuICAgICAgdmFsdWVzW2tleV0gPSB2YWx1ZTtcblxuICAgICAgaWYgKG9sZFZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgICB0aGlzLm5vdGlmeShrZXksIG9sZFZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTZXRzIGEgY29sbGVjdGlvbiBvZiBrZXktdmFsdWUgcGFpcnMuICBOb3RlIHRoYXQgdGhpcyBjaGFuZ2VzIGFueSBleGlzdGluZ1xuICAgKiBwcm9wZXJ0aWVzIGFuZCBhZGRzIG5ldyBvbmVzIChpdCBkb2VzIG5vdCByZW1vdmUgYW55IGV4aXN0aW5nIHByb3BlcnRpZXMpLlxuICAgKiBAcGFyYW0ge09iamVjdDxzdHJpbmcsICo+fSB2YWx1ZXMgVmFsdWVzLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc2lsZW50IFVwZGF0ZSB3aXRob3V0IHRyaWdnZXJpbmcgYW4gZXZlbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlT2JqZWN0LnByb3RvdHlwZS5zZXRQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKHZhbHVlcywgb3B0X3NpbGVudCkge1xuICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZXMpIHtcbiAgICAgIHRoaXMuc2V0KGtleSwgdmFsdWVzW2tleV0sIG9wdF9zaWxlbnQpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEFwcGx5IGFueSBwcm9wZXJ0aWVzIGZyb20gYW5vdGhlciBvYmplY3Qgd2l0aG91dCB0cmlnZ2VyaW5nIGV2ZW50cy5cbiAgICogQHBhcmFtIHtCYXNlT2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBCYXNlT2JqZWN0LnByb3RvdHlwZS5hcHBseVByb3BlcnRpZXMgPSBmdW5jdGlvbiAoc291cmNlKSB7XG4gICAgaWYgKCFzb3VyY2UudmFsdWVzXykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGFzc2lnbih0aGlzLnZhbHVlc18gfHwgKHRoaXMudmFsdWVzXyA9IHt9KSwgc291cmNlLnZhbHVlc18pO1xuICB9O1xuICAvKipcbiAgICogVW5zZXRzIGEgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5IG5hbWUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9zaWxlbnQgVW5zZXQgd2l0aG91dCB0cmlnZ2VyaW5nIGFuIGV2ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZU9iamVjdC5wcm90b3R5cGUudW5zZXQgPSBmdW5jdGlvbiAoa2V5LCBvcHRfc2lsZW50KSB7XG4gICAgaWYgKHRoaXMudmFsdWVzXyAmJiBrZXkgaW4gdGhpcy52YWx1ZXNfKSB7XG4gICAgICB2YXIgb2xkVmFsdWUgPSB0aGlzLnZhbHVlc19ba2V5XTtcbiAgICAgIGRlbGV0ZSB0aGlzLnZhbHVlc19ba2V5XTtcblxuICAgICAgaWYgKGlzRW1wdHkodGhpcy52YWx1ZXNfKSkge1xuICAgICAgICB0aGlzLnZhbHVlc18gPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAoIW9wdF9zaWxlbnQpIHtcbiAgICAgICAgdGhpcy5ub3RpZnkoa2V5LCBvbGRWYWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBCYXNlT2JqZWN0O1xufShPYnNlcnZhYmxlKTtcbi8qKlxuICogQHR5cGUge09iamVjdDxzdHJpbmcsIHN0cmluZz59XG4gKi9cblxuXG52YXIgY2hhbmdlRXZlbnRUeXBlQ2FjaGUgPSB7fTtcbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkgbmFtZS5cbiAqIEByZXR1cm4ge3N0cmluZ30gQ2hhbmdlIG5hbWUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENoYW5nZUV2ZW50VHlwZShrZXkpIHtcbiAgcmV0dXJuIGNoYW5nZUV2ZW50VHlwZUNhY2hlLmhhc093blByb3BlcnR5KGtleSkgPyBjaGFuZ2VFdmVudFR5cGVDYWNoZVtrZXldIDogY2hhbmdlRXZlbnRUeXBlQ2FjaGVba2V5XSA9ICdjaGFuZ2U6JyArIGtleTtcbn1cbmV4cG9ydCBkZWZhdWx0IEJhc2VPYmplY3Q7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2xheWVyL1Byb3BlcnR5XG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIE9QQUNJVFk6ICdvcGFjaXR5JyxcbiAgVklTSUJMRTogJ3Zpc2libGUnLFxuICBFWFRFTlQ6ICdleHRlbnQnLFxuICBaX0lOREVYOiAnekluZGV4JyxcbiAgTUFYX1JFU09MVVRJT046ICdtYXhSZXNvbHV0aW9uJyxcbiAgTUlOX1JFU09MVVRJT046ICdtaW5SZXNvbHV0aW9uJyxcbiAgTUFYX1pPT006ICdtYXhab29tJyxcbiAgTUlOX1pPT006ICdtaW5ab29tJyxcbiAgU09VUkNFOiAnc291cmNlJ1xufTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2xheWVyL0Jhc2VcbiAqL1xuXG5cbmltcG9ydCBCYXNlT2JqZWN0IGZyb20gJy4uL09iamVjdC5qcyc7XG5pbXBvcnQgTGF5ZXJQcm9wZXJ0eSBmcm9tICcuL1Byb3BlcnR5LmpzJztcbmltcG9ydCB7IGFic3RyYWN0IH0gZnJvbSAnLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGFzc2lnbiB9IGZyb20gJy4uL29iai5qcyc7XG5pbXBvcnQgeyBjbGFtcCB9IGZyb20gJy4uL21hdGguanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NsYXNzTmFtZT0nb2wtbGF5ZXInXSBBIENTUyBjbGFzcyBuYW1lIHRvIHNldCB0byB0aGUgbGF5ZXIgZWxlbWVudC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbb3BhY2l0eT0xXSBPcGFjaXR5ICgwLCAxKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3Zpc2libGU9dHJ1ZV0gVmlzaWJpbGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF0gVGhlIGJvdW5kaW5nIGV4dGVudCBmb3IgbGF5ZXIgcmVuZGVyaW5nLiAgVGhlIGxheWVyIHdpbGwgbm90IGJlXG4gKiByZW5kZXJlZCBvdXRzaWRlIG9mIHRoaXMgZXh0ZW50LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6SW5kZXhdIFRoZSB6LWluZGV4IGZvciBsYXllciByZW5kZXJpbmcuICBBdCByZW5kZXJpbmcgdGltZSwgdGhlIGxheWVyc1xuICogd2lsbCBiZSBvcmRlcmVkLCBmaXJzdCBieSBaLWluZGV4IGFuZCB0aGVuIGJ5IHBvc2l0aW9uLiBXaGVuIGB1bmRlZmluZWRgLCBhIGB6SW5kZXhgIG9mIDAgaXMgYXNzdW1lZFxuICogZm9yIGxheWVycyB0aGF0IGFyZSBhZGRlZCB0byB0aGUgbWFwJ3MgYGxheWVyc2AgY29sbGVjdGlvbiwgb3IgYEluZmluaXR5YCB3aGVuIHRoZSBsYXllcidzIGBzZXRNYXAoKWBcbiAqIG1ldGhvZCB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluUmVzb2x1dGlvbl0gVGhlIG1pbmltdW0gcmVzb2x1dGlvbiAoaW5jbHVzaXZlKSBhdCB3aGljaCB0aGlzIGxheWVyIHdpbGwgYmVcbiAqIHZpc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFJlc29sdXRpb25dIFRoZSBtYXhpbXVtIHJlc29sdXRpb24gKGV4Y2x1c2l2ZSkgYmVsb3cgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5ab29tXSBUaGUgbWluaW11bSB2aWV3IHpvb20gbGV2ZWwgKGV4Y2x1c2l2ZSkgYWJvdmUgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhab29tXSBUaGUgbWF4aW11bSB2aWV3IHpvb20gbGV2ZWwgKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWJzdHJhY3QgYmFzZSBjbGFzczsgbm9ybWFsbHkgb25seSB1c2VkIGZvciBjcmVhdGluZyBzdWJjbGFzc2VzIGFuZCBub3RcbiAqIGluc3RhbnRpYXRlZCBpbiBhcHBzLlxuICogTm90ZSB0aGF0IHdpdGgge0BsaW5rIG1vZHVsZTpvbC9sYXllci9CYXNlfSBhbmQgYWxsIGl0cyBzdWJjbGFzc2VzLCBhbnkgcHJvcGVydHkgc2V0IGluXG4gKiB0aGUgb3B0aW9ucyBpcyBzZXQgYXMgYSB7QGxpbmsgbW9kdWxlOm9sL09iamVjdH0gcHJvcGVydHkgb24gdGhlIGxheWVyIG9iamVjdCwgc29cbiAqIGlzIG9ic2VydmFibGUsIGFuZCBoYXMgZ2V0L3NldCBhY2Nlc3NvcnMuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBCYXNlTGF5ZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQmFzZUxheWVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIExheWVyIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQmFzZUxheWVyKG9wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCAqPn1cbiAgICAgKi9cblxuXG4gICAgdmFyIHByb3BlcnRpZXMgPSBhc3NpZ24oe30sIG9wdGlvbnMpO1xuICAgIHByb3BlcnRpZXNbTGF5ZXJQcm9wZXJ0eS5PUEFDSVRZXSA9IG9wdGlvbnMub3BhY2l0eSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5vcGFjaXR5IDogMTtcbiAgICBhc3NlcnQodHlwZW9mIHByb3BlcnRpZXNbTGF5ZXJQcm9wZXJ0eS5PUEFDSVRZXSA9PT0gJ251bWJlcicsIDY0KTsgLy8gTGF5ZXIgb3BhY2l0eSBtdXN0IGJlIGEgbnVtYmVyXG5cbiAgICBwcm9wZXJ0aWVzW0xheWVyUHJvcGVydHkuVklTSUJMRV0gPSBvcHRpb25zLnZpc2libGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudmlzaWJsZSA6IHRydWU7XG4gICAgcHJvcGVydGllc1tMYXllclByb3BlcnR5LlpfSU5ERVhdID0gb3B0aW9ucy56SW5kZXg7XG4gICAgcHJvcGVydGllc1tMYXllclByb3BlcnR5Lk1BWF9SRVNPTFVUSU9OXSA9IG9wdGlvbnMubWF4UmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5tYXhSZXNvbHV0aW9uIDogSW5maW5pdHk7XG4gICAgcHJvcGVydGllc1tMYXllclByb3BlcnR5Lk1JTl9SRVNPTFVUSU9OXSA9IG9wdGlvbnMubWluUmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5taW5SZXNvbHV0aW9uIDogMDtcbiAgICBwcm9wZXJ0aWVzW0xheWVyUHJvcGVydHkuTUlOX1pPT01dID0gb3B0aW9ucy5taW5ab29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1pblpvb20gOiAtSW5maW5pdHk7XG4gICAgcHJvcGVydGllc1tMYXllclByb3BlcnR5Lk1BWF9aT09NXSA9IG9wdGlvbnMubWF4Wm9vbSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5tYXhab29tIDogSW5maW5pdHk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMuY2xhc3NOYW1lXyA9IHByb3BlcnRpZXMuY2xhc3NOYW1lICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsYXNzTmFtZSA6ICdvbC1sYXllcic7XG4gICAgZGVsZXRlIHByb3BlcnRpZXMuY2xhc3NOYW1lO1xuXG4gICAgX3RoaXMuc2V0UHJvcGVydGllcyhwcm9wZXJ0aWVzKTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9MYXllci5qc1wiKS5TdGF0ZX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5zdGF0ZV8gPSBudWxsO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHJldHVybiB7c3RyaW5nfSBDU1MgY2xhc3MgbmFtZS5cbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmdldENsYXNzTmFtZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jbGFzc05hbWVfO1xuICB9O1xuICAvKipcbiAgICogVGhpcyBtZXRob2QgaXMgbm90IG1lYW50IHRvIGJlIGNhbGxlZCBieSBsYXllcnMgb3IgbGF5ZXIgcmVuZGVyZXJzIGJlY2F1c2UgdGhlIHN0YXRlXG4gICAqIGlzIGluY29ycmVjdCBpZiB0aGUgbGF5ZXIgaXMgaW5jbHVkZWQgaW4gYSBsYXllciBncm91cC5cbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X21hbmFnZWQgTGF5ZXIgaXMgbWFuYWdlZC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9MYXllci5qc1wiKS5TdGF0ZX0gTGF5ZXIgc3RhdGUuXG4gICAqL1xuXG5cbiAgQmFzZUxheWVyLnByb3RvdHlwZS5nZXRMYXllclN0YXRlID0gZnVuY3Rpb24gKG9wdF9tYW5hZ2VkKSB7XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL0xheWVyLmpzXCIpLlN0YXRlfSAqL1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuc3RhdGVfIHx8XG4gICAgLyoqIEB0eXBlIHs/fSAqL1xuICAgIHtcbiAgICAgIGxheWVyOiB0aGlzLFxuICAgICAgbWFuYWdlZDogb3B0X21hbmFnZWQgPT09IHVuZGVmaW5lZCA/IHRydWUgOiBvcHRfbWFuYWdlZFxuICAgIH07XG4gICAgdmFyIHpJbmRleCA9IHRoaXMuZ2V0WkluZGV4KCk7XG4gICAgc3RhdGUub3BhY2l0eSA9IGNsYW1wKE1hdGgucm91bmQodGhpcy5nZXRPcGFjaXR5KCkgKiAxMDApIC8gMTAwLCAwLCAxKTtcbiAgICBzdGF0ZS5zb3VyY2VTdGF0ZSA9IHRoaXMuZ2V0U291cmNlU3RhdGUoKTtcbiAgICBzdGF0ZS52aXNpYmxlID0gdGhpcy5nZXRWaXNpYmxlKCk7XG4gICAgc3RhdGUuZXh0ZW50ID0gdGhpcy5nZXRFeHRlbnQoKTtcbiAgICBzdGF0ZS56SW5kZXggPSB6SW5kZXggIT09IHVuZGVmaW5lZCA/IHpJbmRleCA6IHN0YXRlLm1hbmFnZWQgPT09IGZhbHNlID8gSW5maW5pdHkgOiAwO1xuICAgIHN0YXRlLm1heFJlc29sdXRpb24gPSB0aGlzLmdldE1heFJlc29sdXRpb24oKTtcbiAgICBzdGF0ZS5taW5SZXNvbHV0aW9uID0gTWF0aC5tYXgodGhpcy5nZXRNaW5SZXNvbHV0aW9uKCksIDApO1xuICAgIHN0YXRlLm1pblpvb20gPSB0aGlzLmdldE1pblpvb20oKTtcbiAgICBzdGF0ZS5tYXhab29tID0gdGhpcy5nZXRNYXhab29tKCk7XG4gICAgdGhpcy5zdGF0ZV8gPSBzdGF0ZTtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL0xheWVyLmpzXCIpLmRlZmF1bHQ+PX0gb3B0X2FycmF5IEFycmF5IG9mIGxheWVycyAodG8gYmVcbiAgICogICAgIG1vZGlmaWVkIGluIHBsYWNlKS5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi9MYXllci5qc1wiKS5kZWZhdWx0Pn0gQXJyYXkgb2YgbGF5ZXJzLlxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZ2V0TGF5ZXJzQXJyYXkgPSBmdW5jdGlvbiAob3B0X2FycmF5KSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL0xheWVyLmpzXCIpLlN0YXRlPj19IG9wdF9zdGF0ZXMgT3B0aW9uYWwgbGlzdCBvZiBsYXllclxuICAgKiAgICAgc3RhdGVzICh0byBiZSBtb2RpZmllZCBpbiBwbGFjZSkuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4vTGF5ZXIuanNcIikuU3RhdGU+fSBMaXN0IG9mIGxheWVyIHN0YXRlcy5cbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmdldExheWVyU3RhdGVzQXJyYXkgPSBmdW5jdGlvbiAob3B0X3N0YXRlcykge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSB7QGxpbmsgbW9kdWxlOm9sL2V4dGVudH5FeHRlbnQgZXh0ZW50fSBvZiB0aGUgbGF5ZXIgb3IgYHVuZGVmaW5lZGAgaWYgaXRcbiAgICogd2lsbCBiZSB2aXNpYmxlIHJlZ2FyZGxlc3Mgb2YgZXh0ZW50LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fHVuZGVmaW5lZH0gVGhlIGxheWVyIGV4dGVudC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZ2V0RXh0ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR8dW5kZWZpbmVkfSAqL1xuICAgICAgdGhpcy5nZXQoTGF5ZXJQcm9wZXJ0eS5FWFRFTlQpXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbWF4aW11bSByZXNvbHV0aW9uIG9mIHRoZSBsYXllci5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgbWF4aW11bSByZXNvbHV0aW9uIG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZ2V0TWF4UmVzb2x1dGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICB0aGlzLmdldChMYXllclByb3BlcnR5Lk1BWF9SRVNPTFVUSU9OKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIG1pbmltdW0gcmVzb2x1dGlvbiBvZiB0aGUgbGF5ZXIuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIG1pbmltdW0gcmVzb2x1dGlvbiBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmdldE1pblJlc29sdXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgdGhpcy5nZXQoTGF5ZXJQcm9wZXJ0eS5NSU5fUkVTT0xVVElPTilcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBtaW5pbXVtIHpvb20gbGV2ZWwgb2YgdGhlIGxheWVyLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBtaW5pbXVtIHpvb20gbGV2ZWwgb2YgdGhlIGxheWVyLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZUxheWVyLnByb3RvdHlwZS5nZXRNaW5ab29tID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgIHRoaXMuZ2V0KExheWVyUHJvcGVydHkuTUlOX1pPT00pXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbWF4aW11bSB6b29tIGxldmVsIG9mIHRoZSBsYXllci5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgbWF4aW11bSB6b29tIGxldmVsIG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZ2V0TWF4Wm9vbSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICB0aGlzLmdldChMYXllclByb3BlcnR5Lk1BWF9aT09NKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIG9wYWNpdHkgb2YgdGhlIGxheWVyIChiZXR3ZWVuIDAgYW5kIDEpLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBvcGFjaXR5IG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZ2V0T3BhY2l0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICB0aGlzLmdldChMYXllclByb3BlcnR5Lk9QQUNJVFkpXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zb3VyY2UvU3RhdGUuanNcIikuZGVmYXVsdH0gU291cmNlIHN0YXRlLlxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZ2V0U291cmNlU3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHZpc2liaWxpdHkgb2YgdGhlIGxheWVyIChgdHJ1ZWAgb3IgYGZhbHNlYCkuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSB2aXNpYmlsaXR5IG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZ2V0VmlzaWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtib29sZWFufSAqL1xuICAgICAgdGhpcy5nZXQoTGF5ZXJQcm9wZXJ0eS5WSVNJQkxFKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIFotaW5kZXggb2YgdGhlIGxheWVyLCB3aGljaCBpcyB1c2VkIHRvIG9yZGVyIGxheWVycyBiZWZvcmVcbiAgICogcmVuZGVyaW5nLiBUaGUgZGVmYXVsdCBaLWluZGV4IGlzIDAuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIFotaW5kZXggb2YgdGhlIGxheWVyLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZUxheWVyLnByb3RvdHlwZS5nZXRaSW5kZXggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgdGhpcy5nZXQoTGF5ZXJQcm9wZXJ0eS5aX0lOREVYKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGV4dGVudCBhdCB3aGljaCB0aGUgbGF5ZXIgaXMgdmlzaWJsZS4gIElmIGB1bmRlZmluZWRgLCB0aGUgbGF5ZXJcbiAgICogd2lsbCBiZSB2aXNpYmxlIGF0IGFsbCBleHRlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR8dW5kZWZpbmVkfSBleHRlbnQgVGhlIGV4dGVudCBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLnNldEV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICB0aGlzLnNldChMYXllclByb3BlcnR5LkVYVEVOVCwgZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgbWF4aW11bSByZXNvbHV0aW9uIGF0IHdoaWNoIHRoZSBsYXllciBpcyB2aXNpYmxlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWF4UmVzb2x1dGlvbiBUaGUgbWF4aW11bSByZXNvbHV0aW9uIG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuc2V0TWF4UmVzb2x1dGlvbiA9IGZ1bmN0aW9uIChtYXhSZXNvbHV0aW9uKSB7XG4gICAgdGhpcy5zZXQoTGF5ZXJQcm9wZXJ0eS5NQVhfUkVTT0xVVElPTiwgbWF4UmVzb2x1dGlvbik7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIG1pbmltdW0gcmVzb2x1dGlvbiBhdCB3aGljaCB0aGUgbGF5ZXIgaXMgdmlzaWJsZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblJlc29sdXRpb24gVGhlIG1pbmltdW0gcmVzb2x1dGlvbiBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLnNldE1pblJlc29sdXRpb24gPSBmdW5jdGlvbiAobWluUmVzb2x1dGlvbikge1xuICAgIHRoaXMuc2V0KExheWVyUHJvcGVydHkuTUlOX1JFU09MVVRJT04sIG1pblJlc29sdXRpb24pO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBtYXhpbXVtIHpvb20gKGV4Y2x1c2l2ZSkgYXQgd2hpY2ggdGhlIGxheWVyIGlzIHZpc2libGUuXG4gICAqIE5vdGUgdGhhdCB0aGUgem9vbSBsZXZlbHMgZm9yIGxheWVyIHZpc2liaWxpdHkgYXJlIGJhc2VkIG9uIHRoZVxuICAgKiB2aWV3IHpvb20gbGV2ZWwsIHdoaWNoIG1heSBiZSBkaWZmZXJlbnQgZnJvbSBhIHRpbGUgc291cmNlIHpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhab29tIFRoZSBtYXhpbXVtIHpvb20gb2YgdGhlIGxheWVyLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZUxheWVyLnByb3RvdHlwZS5zZXRNYXhab29tID0gZnVuY3Rpb24gKG1heFpvb20pIHtcbiAgICB0aGlzLnNldChMYXllclByb3BlcnR5Lk1BWF9aT09NLCBtYXhab29tKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgbWluaW11bSB6b29tIChpbmNsdXNpdmUpIGF0IHdoaWNoIHRoZSBsYXllciBpcyB2aXNpYmxlLlxuICAgKiBOb3RlIHRoYXQgdGhlIHpvb20gbGV2ZWxzIGZvciBsYXllciB2aXNpYmlsaXR5IGFyZSBiYXNlZCBvbiB0aGVcbiAgICogdmlldyB6b29tIGxldmVsLCB3aGljaCBtYXkgYmUgZGlmZmVyZW50IGZyb20gYSB0aWxlIHNvdXJjZSB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWluWm9vbSBUaGUgbWluaW11bSB6b29tIG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuc2V0TWluWm9vbSA9IGZ1bmN0aW9uIChtaW5ab29tKSB7XG4gICAgdGhpcy5zZXQoTGF5ZXJQcm9wZXJ0eS5NSU5fWk9PTSwgbWluWm9vbSk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIG9wYWNpdHkgb2YgdGhlIGxheWVyLCBhbGxvd2VkIHZhbHVlcyByYW5nZSBmcm9tIDAgdG8gMS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9wYWNpdHkgVGhlIG9wYWNpdHkgb2YgdGhlIGxheWVyLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZUxheWVyLnByb3RvdHlwZS5zZXRPcGFjaXR5ID0gZnVuY3Rpb24gKG9wYWNpdHkpIHtcbiAgICBhc3NlcnQodHlwZW9mIG9wYWNpdHkgPT09ICdudW1iZXInLCA2NCk7IC8vIExheWVyIG9wYWNpdHkgbXVzdCBiZSBhIG51bWJlclxuXG4gICAgdGhpcy5zZXQoTGF5ZXJQcm9wZXJ0eS5PUEFDSVRZLCBvcGFjaXR5KTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgbGF5ZXIgKGB0cnVlYCBvciBgZmFsc2VgKS5cbiAgICogQHBhcmFtIHtib29sZWFufSB2aXNpYmxlIFRoZSB2aXNpYmlsaXR5IG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuc2V0VmlzaWJsZSA9IGZ1bmN0aW9uICh2aXNpYmxlKSB7XG4gICAgdGhpcy5zZXQoTGF5ZXJQcm9wZXJ0eS5WSVNJQkxFLCB2aXNpYmxlKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCBaLWluZGV4IG9mIHRoZSBsYXllciwgd2hpY2ggaXMgdXNlZCB0byBvcmRlciBsYXllcnMgYmVmb3JlIHJlbmRlcmluZy5cbiAgICogVGhlIGRlZmF1bHQgWi1pbmRleCBpcyAwLlxuICAgKiBAcGFyYW0ge251bWJlcn0gemluZGV4IFRoZSB6LWluZGV4IG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuc2V0WkluZGV4ID0gZnVuY3Rpb24gKHppbmRleCkge1xuICAgIHRoaXMuc2V0KExheWVyUHJvcGVydHkuWl9JTkRFWCwgemluZGV4KTtcbiAgfTtcbiAgLyoqXG4gICAqIENsZWFuIHVwLlxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnN0YXRlXykge1xuICAgICAgdGhpcy5zdGF0ZV8ubGF5ZXIgPSBudWxsO1xuICAgICAgdGhpcy5zdGF0ZV8gPSBudWxsO1xuICAgIH1cblxuICAgIF9zdXBlci5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsLmNhbGwodGhpcyk7XG4gIH07XG5cbiAgcmV0dXJuIEJhc2VMYXllcjtcbn0oQmFzZU9iamVjdCk7XG5cbmV4cG9ydCBkZWZhdWx0IEJhc2VMYXllcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL0V2ZW50VHlwZVxuICovXG5cbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogVHJpZ2dlcmVkIGJlZm9yZSBhIGxheWVyIGlzIHJlbmRlcmVkLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3JlbmRlci9FdmVudH5SZW5kZXJFdmVudCNwcmVyZW5kZXJcbiAgICogQGFwaVxuICAgKi9cbiAgUFJFUkVOREVSOiAncHJlcmVuZGVyJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIGFmdGVyIGEgbGF5ZXIgaXMgcmVuZGVyZWQuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvcmVuZGVyL0V2ZW50flJlbmRlckV2ZW50I3Bvc3RyZW5kZXJcbiAgICogQGFwaVxuICAgKi9cbiAgUE9TVFJFTkRFUjogJ3Bvc3RyZW5kZXInLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgYmVmb3JlIGxheWVycyBhcmUgcmVuZGVyZWQuXG4gICAqIFRoZSBldmVudCBvYmplY3Qgd2lsbCBub3QgaGF2ZSBhIGBjb250ZXh0YCBzZXQuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvcmVuZGVyL0V2ZW50flJlbmRlckV2ZW50I3ByZWNvbXBvc2VcbiAgICogQGFwaVxuICAgKi9cbiAgUFJFQ09NUE9TRTogJ3ByZWNvbXBvc2UnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgYWZ0ZXIgYWxsIGxheWVycyBhcmUgcmVuZGVyZWQuXG4gICAqIFRoZSBldmVudCBvYmplY3Qgd2lsbCBub3QgaGF2ZSBhIGBjb250ZXh0YCBzZXQuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvcmVuZGVyL0V2ZW50flJlbmRlckV2ZW50I3Bvc3Rjb21wb3NlXG4gICAqIEBhcGlcbiAgICovXG4gIFBPU1RDT01QT1NFOiAncG9zdGNvbXBvc2UnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiByZW5kZXJpbmcgaXMgY29tcGxldGUsIGkuZS4gYWxsIHNvdXJjZXMgYW5kIHRpbGVzIGhhdmVcbiAgICogZmluaXNoZWQgbG9hZGluZyBmb3IgdGhlIGN1cnJlbnQgdmlld3BvcnQsIGFuZCBhbGwgdGlsZXMgYXJlIGZhZGVkIGluLlxuICAgKiBUaGUgZXZlbnQgb2JqZWN0IHdpbGwgbm90IGhhdmUgYSBgY29udGV4dGAgc2V0LlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3JlbmRlci9FdmVudH5SZW5kZXJFdmVudCNyZW5kZXJjb21wbGV0ZVxuICAgKiBAYXBpXG4gICAqL1xuICBSRU5ERVJDT01QTEVURTogJ3JlbmRlcmNvbXBsZXRlJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvc291cmNlL1N0YXRlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICogU3RhdGUgb2YgdGhlIHNvdXJjZSwgb25lIG9mICd1bmRlZmluZWQnLCAnbG9hZGluZycsICdyZWFkeScgb3IgJ2Vycm9yJy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBVTkRFRklORUQ6ICd1bmRlZmluZWQnLFxuICBMT0FESU5HOiAnbG9hZGluZycsXG4gIFJFQURZOiAncmVhZHknLFxuICBFUlJPUjogJ2Vycm9yJ1xufTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2xheWVyL0xheWVyXG4gKi9cblxuXG5pbXBvcnQgQmFzZUxheWVyIGZyb20gJy4vQmFzZS5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IExheWVyUHJvcGVydHkgZnJvbSAnLi9Qcm9wZXJ0eS5qcyc7XG5pbXBvcnQgUmVuZGVyRXZlbnRUeXBlIGZyb20gJy4uL3JlbmRlci9FdmVudFR5cGUuanMnO1xuaW1wb3J0IFNvdXJjZVN0YXRlIGZyb20gJy4uL3NvdXJjZS9TdGF0ZS5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGFzc2lnbiB9IGZyb20gJy4uL29iai5qcyc7XG5pbXBvcnQgeyBnZXRDaGFuZ2VFdmVudFR5cGUgfSBmcm9tICcuLi9PYmplY3QuanMnO1xuaW1wb3J0IHsgbGlzdGVuLCB1bmxpc3RlbkJ5S2V5IH0gZnJvbSAnLi4vZXZlbnRzLmpzJztcbi8qKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKGltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlKTpIVE1MRWxlbWVudH0gUmVuZGVyRnVuY3Rpb25cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbY2xhc3NOYW1lPSdvbC1sYXllciddIEEgQ1NTIGNsYXNzIG5hbWUgdG8gc2V0IHRvIHRoZSBsYXllciBlbGVtZW50LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtvcGFjaXR5PTFdIE9wYWNpdHkgKDAsIDEpLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbdmlzaWJsZT10cnVlXSBWaXNpYmlsaXR5LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBbZXh0ZW50XSBUaGUgYm91bmRpbmcgZXh0ZW50IGZvciBsYXllciByZW5kZXJpbmcuICBUaGUgbGF5ZXIgd2lsbCBub3QgYmVcbiAqIHJlbmRlcmVkIG91dHNpZGUgb2YgdGhpcyBleHRlbnQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3pJbmRleF0gVGhlIHotaW5kZXggZm9yIGxheWVyIHJlbmRlcmluZy4gIEF0IHJlbmRlcmluZyB0aW1lLCB0aGUgbGF5ZXJzXG4gKiB3aWxsIGJlIG9yZGVyZWQsIGZpcnN0IGJ5IFotaW5kZXggYW5kIHRoZW4gYnkgcG9zaXRpb24uIFdoZW4gYHVuZGVmaW5lZGAsIGEgYHpJbmRleGAgb2YgMCBpcyBhc3N1bWVkXG4gKiBmb3IgbGF5ZXJzIHRoYXQgYXJlIGFkZGVkIHRvIHRoZSBtYXAncyBgbGF5ZXJzYCBjb2xsZWN0aW9uLCBvciBgSW5maW5pdHlgIHdoZW4gdGhlIGxheWVyJ3MgYHNldE1hcCgpYFxuICogbWV0aG9kIHdhcyB1c2VkLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5SZXNvbHV0aW9uXSBUaGUgbWluaW11bSByZXNvbHV0aW9uIChpbmNsdXNpdmUpIGF0IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbCBiZVxuICogdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4UmVzb2x1dGlvbl0gVGhlIG1heGltdW0gcmVzb2x1dGlvbiAoZXhjbHVzaXZlKSBiZWxvdyB3aGljaCB0aGlzIGxheWVyIHdpbGxcbiAqIGJlIHZpc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblpvb21dIFRoZSBtaW5pbXVtIHZpZXcgem9vbSBsZXZlbCAoZXhjbHVzaXZlKSBhYm92ZSB3aGljaCB0aGlzIGxheWVyIHdpbGwgYmVcbiAqIHZpc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFpvb21dIFRoZSBtYXhpbXVtIHZpZXcgem9vbSBsZXZlbCAoaW5jbHVzaXZlKSBhdCB3aGljaCB0aGlzIGxheWVyIHdpbGxcbiAqIGJlIHZpc2libGUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3NvdXJjZS9Tb3VyY2UuanNcIikuZGVmYXVsdH0gW3NvdXJjZV0gU291cmNlIGZvciB0aGlzIGxheWVyLiAgSWYgbm90IHByb3ZpZGVkIHRvIHRoZSBjb25zdHJ1Y3RvcixcbiAqIHRoZSBzb3VyY2UgY2FuIGJlIHNldCBieSBjYWxsaW5nIHtAbGluayBtb2R1bGU6b2wvbGF5ZXIvTGF5ZXIjc2V0U291cmNlIGxheWVyLnNldFNvdXJjZShzb3VyY2UpfSBhZnRlclxuICogY29uc3RydWN0aW9uLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gW21hcF0gTWFwLlxuICogQHByb3BlcnR5IHtSZW5kZXJGdW5jdGlvbn0gW3JlbmRlcl0gUmVuZGVyIGZ1bmN0aW9uLiBUYWtlcyB0aGUgZnJhbWUgc3RhdGUgYXMgaW5wdXQgYW5kIGlzIGV4cGVjdGVkIHRvIHJldHVybiBhblxuICogSFRNTCBlbGVtZW50LiBXaWxsIG92ZXJ3cml0ZSB0aGUgZGVmYXVsdCByZW5kZXJpbmcgZm9yIHRoZSBsYXllci5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFN0YXRlXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vTGF5ZXIuanNcIikuZGVmYXVsdH0gbGF5ZXJcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBvcGFjaXR5IE9wYWNpdHksIHRoZSB2YWx1ZSBpcyByb3VuZGVkIHRvIHR3byBkaWdpdHMgdG8gYXBwZWFyIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zb3VyY2UvU3RhdGUuanNcIikuZGVmYXVsdH0gc291cmNlU3RhdGVcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gdmlzaWJsZVxuICogQHByb3BlcnR5IHtib29sZWFufSBtYW5hZ2VkXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IFtleHRlbnRdXG4gKiBAcHJvcGVydHkge251bWJlcn0gekluZGV4XG4gKiBAcHJvcGVydHkge251bWJlcn0gbWF4UmVzb2x1dGlvblxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1pblJlc29sdXRpb25cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtaW5ab29tXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWF4Wm9vbVxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQmFzZSBjbGFzcyBmcm9tIHdoaWNoIGFsbCBsYXllciB0eXBlcyBhcmUgZGVyaXZlZC4gVGhpcyBzaG91bGQgb25seSBiZSBpbnN0YW50aWF0ZWRcbiAqIGluIHRoZSBjYXNlIHdoZXJlIGEgY3VzdG9tIGxheWVyIGlzIGJlIGFkZGVkIHRvIHRoZSBtYXAgd2l0aCBhIGN1c3RvbSBgcmVuZGVyYCBmdW5jdGlvbi5cbiAqIFN1Y2ggYSBmdW5jdGlvbiBjYW4gYmUgc3BlY2lmaWVkIGluIHRoZSBgb3B0aW9uc2Agb2JqZWN0LCBhbmQgaXMgZXhwZWN0ZWQgdG8gcmV0dXJuIGFuIEhUTUwgZWxlbWVudC5cbiAqXG4gKiBBIHZpc3VhbCByZXByZXNlbnRhdGlvbiBvZiByYXN0ZXIgb3IgdmVjdG9yIG1hcCBkYXRhLlxuICogTGF5ZXJzIGdyb3VwIHRvZ2V0aGVyIHRob3NlIHByb3BlcnRpZXMgdGhhdCBwZXJ0YWluIHRvIGhvdyB0aGUgZGF0YSBpcyB0byBiZVxuICogZGlzcGxheWVkLCBpcnJlc3BlY3RpdmUgb2YgdGhlIHNvdXJjZSBvZiB0aGF0IGRhdGEuXG4gKlxuICogTGF5ZXJzIGFyZSB1c3VhbGx5IGFkZGVkIHRvIGEgbWFwIHdpdGgge0BsaW5rIG1vZHVsZTpvbC9NYXAjYWRkTGF5ZXJ9LiBDb21wb25lbnRzXG4gKiBsaWtlIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vU2VsZWN0flNlbGVjdH0gdXNlIHVubWFuYWdlZCBsYXllcnNcbiAqIGludGVybmFsbHkuIFRoZXNlIHVubWFuYWdlZCBsYXllcnMgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWFwIHVzaW5nXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0xheWVyfkxheWVyI3NldE1hcH0gaW5zdGVhZC5cbiAqXG4gKiBBIGdlbmVyaWMgYGNoYW5nZWAgZXZlbnQgaXMgZmlyZWQgd2hlbiB0aGUgc3RhdGUgb2YgdGhlIHNvdXJjZSBjaGFuZ2VzLlxuICpcbiAqIFBsZWFzZSBub3RlIHRoYXQgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgc2V2ZXJhbCBsYXllcnMgbWlnaHQgZ2V0IHJlbmRlcmVkIHRvXG4gKiB0aGUgc2FtZSBIVE1MIGVsZW1lbnQsIHdoaWNoIHdpbGwgY2F1c2Uge0BsaW5rIG1vZHVsZTpvbC9NYXB+TWFwI2ZvckVhY2hMYXllckF0UGl4ZWx9IHRvXG4gKiBnaXZlIGZhbHNlIHBvc2l0aXZlcy4gVG8gYXZvaWQgdGhpcywgYXBwbHkgZGlmZmVyZW50IGBjbGFzc05hbWVgIHByb3BlcnRpZXMgdG8gdGhlXG4gKiBsYXllcnMgYXQgY3JlYXRpb24gdGltZS5cbiAqXG4gKiBAZmlyZXMgaW1wb3J0KFwiLi4vcmVuZGVyL0V2ZW50LmpzXCIpLlJlbmRlckV2ZW50I3ByZXJlbmRlclxuICogQGZpcmVzIGltcG9ydChcIi4uL3JlbmRlci9FdmVudC5qc1wiKS5SZW5kZXJFdmVudCNwb3N0cmVuZGVyXG4gKlxuICogQHRlbXBsYXRlIHtpbXBvcnQoXCIuLi9zb3VyY2UvU291cmNlLmpzXCIpLmRlZmF1bHR9IFNvdXJjZVR5cGVcbiAqIEBhcGlcbiAqL1xuXG52YXIgTGF5ZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoTGF5ZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgTGF5ZXIgb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBMYXllcihvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBiYXNlT3B0aW9ucyA9IGFzc2lnbih7fSwgb3B0aW9ucyk7XG4gICAgZGVsZXRlIGJhc2VPcHRpb25zLnNvdXJjZTtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGJhc2VPcHRpb25zKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi9ldmVudHMuanNcIikuRXZlbnRzS2V5fVxuICAgICAqL1xuXG4gICAgX3RoaXMubWFwUHJlY29tcG9zZUtleV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi9ldmVudHMuanNcIikuRXZlbnRzS2V5fVxuICAgICAqL1xuXG4gICAgX3RoaXMubWFwUmVuZGVyS2V5XyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4uL2V2ZW50cy5qc1wiKS5FdmVudHNLZXl9XG4gICAgICovXG5cbiAgICBfdGhpcy5zb3VyY2VDaGFuZ2VLZXlfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9yZW5kZXJlci9MYXllci5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZXJfID0gbnVsbDsgLy8gT3ZlcndyaXRlIGRlZmF1bHQgcmVuZGVyIG1ldGhvZCB3aXRoIGEgY3VzdG9tIG9uZVxuXG4gICAgaWYgKG9wdGlvbnMucmVuZGVyKSB7XG4gICAgICBfdGhpcy5yZW5kZXIgPSBvcHRpb25zLnJlbmRlcjtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5tYXApIHtcbiAgICAgIF90aGlzLnNldE1hcChvcHRpb25zLm1hcCk7XG4gICAgfVxuXG4gICAgX3RoaXMuYWRkRXZlbnRMaXN0ZW5lcihnZXRDaGFuZ2VFdmVudFR5cGUoTGF5ZXJQcm9wZXJ0eS5TT1VSQ0UpLCBfdGhpcy5oYW5kbGVTb3VyY2VQcm9wZXJ0eUNoYW5nZV8pO1xuXG4gICAgdmFyIHNvdXJjZSA9IG9wdGlvbnMuc291cmNlID9cbiAgICAvKiogQHR5cGUge1NvdXJjZVR5cGV9ICovXG4gICAgb3B0aW9ucy5zb3VyY2UgOiBudWxsO1xuXG4gICAgX3RoaXMuc2V0U291cmNlKHNvdXJjZSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9MYXllci5qc1wiKS5kZWZhdWx0Pj19IG9wdF9hcnJheSBBcnJheSBvZiBsYXllcnMgKHRvIGJlIG1vZGlmaWVkIGluIHBsYWNlKS5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi9MYXllci5qc1wiKS5kZWZhdWx0Pn0gQXJyYXkgb2YgbGF5ZXJzLlxuICAgKi9cblxuXG4gIExheWVyLnByb3RvdHlwZS5nZXRMYXllcnNBcnJheSA9IGZ1bmN0aW9uIChvcHRfYXJyYXkpIHtcbiAgICB2YXIgYXJyYXkgPSBvcHRfYXJyYXkgPyBvcHRfYXJyYXkgOiBbXTtcbiAgICBhcnJheS5wdXNoKHRoaXMpO1xuICAgIHJldHVybiBhcnJheTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9MYXllci5qc1wiKS5TdGF0ZT49fSBvcHRfc3RhdGVzIE9wdGlvbmFsIGxpc3Qgb2YgbGF5ZXIgc3RhdGVzICh0byBiZSBtb2RpZmllZCBpbiBwbGFjZSkuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4vTGF5ZXIuanNcIikuU3RhdGU+fSBMaXN0IG9mIGxheWVyIHN0YXRlcy5cbiAgICovXG5cblxuICBMYXllci5wcm90b3R5cGUuZ2V0TGF5ZXJTdGF0ZXNBcnJheSA9IGZ1bmN0aW9uIChvcHRfc3RhdGVzKSB7XG4gICAgdmFyIHN0YXRlcyA9IG9wdF9zdGF0ZXMgPyBvcHRfc3RhdGVzIDogW107XG4gICAgc3RhdGVzLnB1c2godGhpcy5nZXRMYXllclN0YXRlKCkpO1xuICAgIHJldHVybiBzdGF0ZXM7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGxheWVyIHNvdXJjZS5cbiAgICogQHJldHVybiB7U291cmNlVHlwZX0gVGhlIGxheWVyIHNvdXJjZSAob3IgYG51bGxgIGlmIG5vdCB5ZXQgc2V0KS5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExheWVyLnByb3RvdHlwZS5nZXRTb3VyY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7U291cmNlVHlwZX0gKi9cbiAgICAgIHRoaXMuZ2V0KExheWVyUHJvcGVydHkuU09VUkNFKSB8fCBudWxsXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NvdXJjZS9TdGF0ZS5qc1wiKS5kZWZhdWx0fSBTb3VyY2Ugc3RhdGUuXG4gICAqL1xuXG5cbiAgTGF5ZXIucHJvdG90eXBlLmdldFNvdXJjZVN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzb3VyY2UgPSB0aGlzLmdldFNvdXJjZSgpO1xuICAgIHJldHVybiAhc291cmNlID8gU291cmNlU3RhdGUuVU5ERUZJTkVEIDogc291cmNlLmdldFN0YXRlKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIExheWVyLnByb3RvdHlwZS5oYW5kbGVTb3VyY2VDaGFuZ2VfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBMYXllci5wcm90b3R5cGUuaGFuZGxlU291cmNlUHJvcGVydHlDaGFuZ2VfID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnNvdXJjZUNoYW5nZUtleV8pIHtcbiAgICAgIHVubGlzdGVuQnlLZXkodGhpcy5zb3VyY2VDaGFuZ2VLZXlfKTtcbiAgICAgIHRoaXMuc291cmNlQ2hhbmdlS2V5XyA9IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIHNvdXJjZSA9IHRoaXMuZ2V0U291cmNlKCk7XG5cbiAgICBpZiAoc291cmNlKSB7XG4gICAgICB0aGlzLnNvdXJjZUNoYW5nZUtleV8gPSBsaXN0ZW4oc291cmNlLCBFdmVudFR5cGUuQ0hBTkdFLCB0aGlzLmhhbmRsZVNvdXJjZUNoYW5nZV8sIHRoaXMpO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9waXhlbFwiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZVwiKS5kZWZhdWx0Pj59IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoXG4gICAqIGFuIGFycmF5IG9mIGZlYXR1cmVzLlxuICAgKi9cblxuXG4gIExheWVyLnByb3RvdHlwZS5nZXRGZWF0dXJlcyA9IGZ1bmN0aW9uIChwaXhlbCkge1xuICAgIHJldHVybiB0aGlzLnJlbmRlcmVyXy5nZXRGZWF0dXJlcyhwaXhlbCk7XG4gIH07XG4gIC8qKlxuICAgKiBJbiBjaGFyZ2UgdG8gbWFuYWdlIHRoZSByZW5kZXJpbmcgb2YgdGhlIGxheWVyLiBPbmUgbGF5ZXIgdHlwZSBpc1xuICAgKiBib3VuZGVkIHdpdGggb25lIGxheWVyIHJlbmRlcmVyLlxuICAgKiBAcGFyYW0gez9pbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gdGFyZ2V0IFRhcmdldCB3aGljaCB0aGUgcmVuZGVyZXIgbWF5IChidXQgbmVlZCBub3QpIHVzZVxuICAgKiBmb3IgcmVuZGVyaW5nIGl0cyBjb250ZW50LlxuICAgKiBAcmV0dXJuIHtIVE1MRWxlbWVudH0gVGhlIHJlbmRlcmVkIGVsZW1lbnQuXG4gICAqL1xuXG5cbiAgTGF5ZXIucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlLCB0YXJnZXQpIHtcbiAgICB2YXIgbGF5ZXJSZW5kZXJlciA9IHRoaXMuZ2V0UmVuZGVyZXIoKTtcblxuICAgIGlmIChsYXllclJlbmRlcmVyLnByZXBhcmVGcmFtZShmcmFtZVN0YXRlKSkge1xuICAgICAgcmV0dXJuIGxheWVyUmVuZGVyZXIucmVuZGVyRnJhbWUoZnJhbWVTdGF0ZSwgdGFyZ2V0KTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTZXRzIHRoZSBsYXllciB0byBiZSByZW5kZXJlZCBvbiB0b3Agb2Ygb3RoZXIgbGF5ZXJzIG9uIGEgbWFwLiBUaGUgbWFwIHdpbGxcbiAgICogbm90IG1hbmFnZSB0aGlzIGxheWVyIGluIGl0cyBsYXllcnMgY29sbGVjdGlvbiwgYW5kIHRoZSBjYWxsYmFjayBpblxuICAgKiB7QGxpbmsgbW9kdWxlOm9sL01hcCNmb3JFYWNoTGF5ZXJBdFBpeGVsfSB3aWxsIHJlY2VpdmUgYG51bGxgIGFzIGxheWVyLiBUaGlzXG4gICAqIGlzIHVzZWZ1bCBmb3IgdGVtcG9yYXJ5IGxheWVycy4gVG8gcmVtb3ZlIGFuIHVubWFuYWdlZCBsYXllciBmcm9tIHRoZSBtYXAsXG4gICAqIHVzZSBgI3NldE1hcChudWxsKWAuXG4gICAqXG4gICAqIFRvIGFkZCB0aGUgbGF5ZXIgdG8gYSBtYXAgYW5kIGhhdmUgaXQgbWFuYWdlZCBieSB0aGUgbWFwLCB1c2VcbiAgICoge0BsaW5rIG1vZHVsZTpvbC9NYXAjYWRkTGF5ZXJ9IGluc3RlYWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IG1hcCBNYXAuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMYXllci5wcm90b3R5cGUuc2V0TWFwID0gZnVuY3Rpb24gKG1hcCkge1xuICAgIGlmICh0aGlzLm1hcFByZWNvbXBvc2VLZXlfKSB7XG4gICAgICB1bmxpc3RlbkJ5S2V5KHRoaXMubWFwUHJlY29tcG9zZUtleV8pO1xuICAgICAgdGhpcy5tYXBQcmVjb21wb3NlS2V5XyA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCFtYXApIHtcbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1hcFJlbmRlcktleV8pIHtcbiAgICAgIHVubGlzdGVuQnlLZXkodGhpcy5tYXBSZW5kZXJLZXlfKTtcbiAgICAgIHRoaXMubWFwUmVuZGVyS2V5XyA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKG1hcCkge1xuICAgICAgdGhpcy5tYXBQcmVjb21wb3NlS2V5XyA9IGxpc3RlbihtYXAsIFJlbmRlckV2ZW50VHlwZS5QUkVDT01QT1NFLCBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHZhciByZW5kZXJFdmVudCA9XG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vcmVuZGVyL0V2ZW50LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGV2dDtcbiAgICAgICAgdmFyIGxheWVyU3RhdGVzQXJyYXkgPSByZW5kZXJFdmVudC5mcmFtZVN0YXRlLmxheWVyU3RhdGVzQXJyYXk7XG4gICAgICAgIHZhciBsYXllclN0YXRlID0gdGhpcy5nZXRMYXllclN0YXRlKGZhbHNlKTsgLy8gQSBsYXllciBjYW4gb25seSBiZSBhZGRlZCB0byB0aGUgbWFwIG9uY2UuIFVzZSBlaXRoZXIgYGxheWVyLnNldE1hcCgpYCBvciBgbWFwLmFkZExheWVyKClgLCBub3QgYm90aC5cblxuICAgICAgICBhc3NlcnQoIWxheWVyU3RhdGVzQXJyYXkuc29tZShmdW5jdGlvbiAoYXJyYXlMYXllclN0YXRlKSB7XG4gICAgICAgICAgcmV0dXJuIGFycmF5TGF5ZXJTdGF0ZS5sYXllciA9PT0gbGF5ZXJTdGF0ZS5sYXllcjtcbiAgICAgICAgfSksIDY3KTtcbiAgICAgICAgbGF5ZXJTdGF0ZXNBcnJheS5wdXNoKGxheWVyU3RhdGUpO1xuICAgICAgfSwgdGhpcyk7XG4gICAgICB0aGlzLm1hcFJlbmRlcktleV8gPSBsaXN0ZW4odGhpcywgRXZlbnRUeXBlLkNIQU5HRSwgbWFwLnJlbmRlciwgbWFwKTtcbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgbGF5ZXIgc291cmNlLlxuICAgKiBAcGFyYW0ge1NvdXJjZVR5cGV9IHNvdXJjZSBUaGUgbGF5ZXIgc291cmNlLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTGF5ZXIucHJvdG90eXBlLnNldFNvdXJjZSA9IGZ1bmN0aW9uIChzb3VyY2UpIHtcbiAgICB0aGlzLnNldChMYXllclByb3BlcnR5LlNPVVJDRSwgc291cmNlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgcmVuZGVyZXIgZm9yIHRoaXMgbGF5ZXIuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3JlbmRlcmVyL0xheWVyLmpzXCIpLmRlZmF1bHR9IFRoZSBsYXllciByZW5kZXJlci5cbiAgICovXG5cblxuICBMYXllci5wcm90b3R5cGUuZ2V0UmVuZGVyZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLnJlbmRlcmVyXykge1xuICAgICAgdGhpcy5yZW5kZXJlcl8gPSB0aGlzLmNyZWF0ZVJlbmRlcmVyKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXJfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIGxheWVyIGhhcyBhIHJlbmRlcmVyLlxuICAgKi9cblxuXG4gIExheWVyLnByb3RvdHlwZS5oYXNSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gISF0aGlzLnJlbmRlcmVyXztcbiAgfTtcbiAgLyoqXG4gICAqIENyZWF0ZSBhIHJlbmRlcmVyIGZvciB0aGlzIGxheWVyLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9yZW5kZXJlci9MYXllci5qc1wiKS5kZWZhdWx0fSBBIGxheWVyIHJlbmRlcmVyLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgTGF5ZXIucHJvdG90eXBlLmNyZWF0ZVJlbmRlcmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBudWxsO1xuICB9O1xuICAvKipcbiAgICogQ2xlYW4gdXAuXG4gICAqL1xuXG5cbiAgTGF5ZXIucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNldFNvdXJjZShudWxsKTtcblxuICAgIF9zdXBlci5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsLmNhbGwodGhpcyk7XG4gIH07XG5cbiAgcmV0dXJuIExheWVyO1xufShCYXNlTGF5ZXIpO1xuLyoqXG4gKiBSZXR1cm4gYHRydWVgIGlmIHRoZSBsYXllciBpcyB2aXNpYmxlIGFuZCBpZiB0aGUgcHJvdmlkZWQgdmlldyBzdGF0ZVxuICogaGFzIHJlc29sdXRpb24gYW5kIHpvb20gbGV2ZWxzIHRoYXQgYXJlIGluIHJhbmdlIG9mIHRoZSBsYXllcidzIG1pbi9tYXguXG4gKiBAcGFyYW0ge1N0YXRlfSBsYXllclN0YXRlIExheWVyIHN0YXRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9WaWV3LmpzXCIpLlN0YXRlfSB2aWV3U3RhdGUgVmlldyBzdGF0ZS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBsYXllciBpcyB2aXNpYmxlIGF0IHRoZSBnaXZlbiB2aWV3IHN0YXRlLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGluVmlldyhsYXllclN0YXRlLCB2aWV3U3RhdGUpIHtcbiAgaWYgKCFsYXllclN0YXRlLnZpc2libGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgcmVzb2x1dGlvbiA9IHZpZXdTdGF0ZS5yZXNvbHV0aW9uO1xuXG4gIGlmIChyZXNvbHV0aW9uIDwgbGF5ZXJTdGF0ZS5taW5SZXNvbHV0aW9uIHx8IHJlc29sdXRpb24gPj0gbGF5ZXJTdGF0ZS5tYXhSZXNvbHV0aW9uKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIHpvb20gPSB2aWV3U3RhdGUuem9vbTtcbiAgcmV0dXJuIHpvb20gPiBsYXllclN0YXRlLm1pblpvb20gJiYgem9vbSA8PSBsYXllclN0YXRlLm1heFpvb207XG59XG5leHBvcnQgZGVmYXVsdCBMYXllcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvY29vcmRpbmF0ZVxuICovXG5pbXBvcnQgeyBnZXRXaWR0aCB9IGZyb20gJy4vZXh0ZW50LmpzJztcbmltcG9ydCB7IG1vZHVsbyB9IGZyb20gJy4vbWF0aC5qcyc7XG5pbXBvcnQgeyBwYWROdW1iZXIgfSBmcm9tICcuL3N0cmluZy5qcyc7XG4vKipcbiAqIEFuIGFycmF5IG9mIG51bWJlcnMgcmVwcmVzZW50aW5nIGFuIHh5IGNvb3JkaW5hdGUuIEV4YW1wbGU6IGBbMTYsIDQ4XWAuXG4gKiBAdHlwZWRlZiB7QXJyYXk8bnVtYmVyPn0gQ29vcmRpbmF0ZVxuICogQGFwaVxuICovXG5cbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHRha2VzIGEge0BsaW5rIG1vZHVsZTpvbC9jb29yZGluYXRlfkNvb3JkaW5hdGV9IGFuZFxuICogdHJhbnNmb3JtcyBpdCBpbnRvIGEgYHtzdHJpbmd9YC5cbiAqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oKENvb3JkaW5hdGV8dW5kZWZpbmVkKSk6IHN0cmluZ30gQ29vcmRpbmF0ZUZvcm1hdFxuICogQGFwaVxuICovXG5cbi8qKlxuICogQWRkIGBkZWx0YWAgdG8gYGNvb3JkaW5hdGVgLiBgY29vcmRpbmF0ZWAgaXMgbW9kaWZpZWQgaW4gcGxhY2UgYW5kIHJldHVybmVkXG4gKiBieSB0aGUgZnVuY3Rpb24uXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgaW1wb3J0IHthZGR9IGZyb20gJ29sL2Nvb3JkaW5hdGUnO1xuICpcbiAqICAgICB2YXIgY29vcmQgPSBbNy44NSwgNDcuOTgzMzMzXTtcbiAqICAgICBhZGQoY29vcmQsIFstMiwgNF0pO1xuICogICAgIC8vIGNvb3JkIGlzIG5vdyBbNS44NSwgNTEuOTgzMzMzXVxuICpcbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBkZWx0YSBEZWx0YS5cbiAqIEByZXR1cm4ge0Nvb3JkaW5hdGV9IFRoZSBpbnB1dCBjb29yZGluYXRlIGFkanVzdGVkIGJ5XG4gKiB0aGUgZ2l2ZW4gZGVsdGEuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZChjb29yZGluYXRlLCBkZWx0YSkge1xuICBjb29yZGluYXRlWzBdICs9ICtkZWx0YVswXTtcbiAgY29vcmRpbmF0ZVsxXSArPSArZGVsdGFbMV07XG4gIHJldHVybiBjb29yZGluYXRlO1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBwb2ludCBjbG9zZXN0IHRvIHRoZSBwYXNzZWQgY29vcmRpbmF0ZSBvbiB0aGUgcGFzc2VkIGNpcmNsZS5cbiAqXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkaW5hdGUgVGhlIGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZ2VvbS9DaXJjbGUuanNcIikuZGVmYXVsdH0gY2lyY2xlIFRoZSBjaXJjbGUuXG4gKiBAcmV0dXJuIHtDb29yZGluYXRlfSBDbG9zZXN0IHBvaW50IG9uIHRoZSBjaXJjdW1mZXJlbmNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9zZXN0T25DaXJjbGUoY29vcmRpbmF0ZSwgY2lyY2xlKSB7XG4gIHZhciByID0gY2lyY2xlLmdldFJhZGl1cygpO1xuICB2YXIgY2VudGVyID0gY2lyY2xlLmdldENlbnRlcigpO1xuICB2YXIgeDAgPSBjZW50ZXJbMF07XG4gIHZhciB5MCA9IGNlbnRlclsxXTtcbiAgdmFyIHgxID0gY29vcmRpbmF0ZVswXTtcbiAgdmFyIHkxID0gY29vcmRpbmF0ZVsxXTtcbiAgdmFyIGR4ID0geDEgLSB4MDtcbiAgdmFyIGR5ID0geTEgLSB5MDtcblxuICBpZiAoZHggPT09IDAgJiYgZHkgPT09IDApIHtcbiAgICBkeCA9IDE7XG4gIH1cblxuICB2YXIgZCA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG4gIHZhciB4ID0geDAgKyByICogZHggLyBkO1xuICB2YXIgeSA9IHkwICsgciAqIGR5IC8gZDtcbiAgcmV0dXJuIFt4LCB5XTtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgcG9pbnQgY2xvc2VzdCB0byB0aGUgcGFzc2VkIGNvb3JkaW5hdGUgb24gdGhlIHBhc3NlZCBzZWdtZW50LlxuICogVGhpcyBpcyB0aGUgZm9vdCBvZiB0aGUgcGVycGVuZGljdWxhciBvZiB0aGUgY29vcmRpbmF0ZSB0byB0aGUgc2VnbWVudCB3aGVuXG4gKiB0aGUgZm9vdCBpcyBvbiB0aGUgc2VnbWVudCwgb3IgdGhlIGNsb3Nlc3Qgc2VnbWVudCBjb29yZGluYXRlIHdoZW4gdGhlIGZvb3RcbiAqIGlzIG91dHNpZGUgdGhlIHNlZ21lbnQuXG4gKlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZGluYXRlIFRoZSBjb29yZGluYXRlLlxuICogQHBhcmFtIHtBcnJheTxDb29yZGluYXRlPn0gc2VnbWVudCBUaGUgdHdvIGNvb3JkaW5hdGVzXG4gKiBvZiB0aGUgc2VnbWVudC5cbiAqIEByZXR1cm4ge0Nvb3JkaW5hdGV9IFRoZSBmb290IG9mIHRoZSBwZXJwZW5kaWN1bGFyIG9mXG4gKiB0aGUgY29vcmRpbmF0ZSB0byB0aGUgc2VnbWVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvc2VzdE9uU2VnbWVudChjb29yZGluYXRlLCBzZWdtZW50KSB7XG4gIHZhciB4MCA9IGNvb3JkaW5hdGVbMF07XG4gIHZhciB5MCA9IGNvb3JkaW5hdGVbMV07XG4gIHZhciBzdGFydCA9IHNlZ21lbnRbMF07XG4gIHZhciBlbmQgPSBzZWdtZW50WzFdO1xuICB2YXIgeDEgPSBzdGFydFswXTtcbiAgdmFyIHkxID0gc3RhcnRbMV07XG4gIHZhciB4MiA9IGVuZFswXTtcbiAgdmFyIHkyID0gZW5kWzFdO1xuICB2YXIgZHggPSB4MiAtIHgxO1xuICB2YXIgZHkgPSB5MiAtIHkxO1xuICB2YXIgYWxvbmcgPSBkeCA9PT0gMCAmJiBkeSA9PT0gMCA/IDAgOiAoZHggKiAoeDAgLSB4MSkgKyBkeSAqICh5MCAtIHkxKSkgLyAoZHggKiBkeCArIGR5ICogZHkgfHwgMCk7XG4gIHZhciB4LCB5O1xuXG4gIGlmIChhbG9uZyA8PSAwKSB7XG4gICAgeCA9IHgxO1xuICAgIHkgPSB5MTtcbiAgfSBlbHNlIGlmIChhbG9uZyA+PSAxKSB7XG4gICAgeCA9IHgyO1xuICAgIHkgPSB5MjtcbiAgfSBlbHNlIHtcbiAgICB4ID0geDEgKyBhbG9uZyAqIGR4O1xuICAgIHkgPSB5MSArIGFsb25nICogZHk7XG4gIH1cblxuICByZXR1cm4gW3gsIHldO1xufVxuLyoqXG4gKiBSZXR1cm5zIGEge0BsaW5rIG1vZHVsZTpvbC9jb29yZGluYXRlfkNvb3JkaW5hdGVGb3JtYXR9IGZ1bmN0aW9uIHRoYXQgY2FuIGJlXG4gKiB1c2VkIHRvIGZvcm1hdFxuICogYSB7Q29vcmRpbmF0ZX0gdG8gYSBzdHJpbmcuXG4gKlxuICogRXhhbXBsZSB3aXRob3V0IHNwZWNpZnlpbmcgdGhlIGZyYWN0aW9uYWwgZGlnaXRzOlxuICpcbiAqICAgICBpbXBvcnQge2NyZWF0ZVN0cmluZ1hZfSBmcm9tICdvbC9jb29yZGluYXRlJztcbiAqXG4gKiAgICAgdmFyIGNvb3JkID0gWzcuODUsIDQ3Ljk4MzMzM107XG4gKiAgICAgdmFyIHN0cmluZ2lmeUZ1bmMgPSBjcmVhdGVTdHJpbmdYWSgpO1xuICogICAgIHZhciBvdXQgPSBzdHJpbmdpZnlGdW5jKGNvb3JkKTtcbiAqICAgICAvLyBvdXQgaXMgbm93ICc4LCA0OCdcbiAqXG4gKiBFeGFtcGxlIHdpdGggZXhwbGljaXRseSBzcGVjaWZ5aW5nIDIgZnJhY3Rpb25hbCBkaWdpdHM6XG4gKlxuICogICAgIGltcG9ydCB7Y3JlYXRlU3RyaW5nWFl9IGZyb20gJ29sL2Nvb3JkaW5hdGUnO1xuICpcbiAqICAgICB2YXIgY29vcmQgPSBbNy44NSwgNDcuOTgzMzMzXTtcbiAqICAgICB2YXIgc3RyaW5naWZ5RnVuYyA9IGNyZWF0ZVN0cmluZ1hZKDIpO1xuICogICAgIHZhciBvdXQgPSBzdHJpbmdpZnlGdW5jKGNvb3JkKTtcbiAqICAgICAvLyBvdXQgaXMgbm93ICc3Ljg1LCA0Ny45OCdcbiAqXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9mcmFjdGlvbkRpZ2l0cyBUaGUgbnVtYmVyIG9mIGRpZ2l0cyB0byBpbmNsdWRlXG4gKiAgICBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4gRGVmYXVsdCBpcyBgMGAuXG4gKiBAcmV0dXJuIHtDb29yZGluYXRlRm9ybWF0fSBDb29yZGluYXRlIGZvcm1hdC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU3RyaW5nWFkob3B0X2ZyYWN0aW9uRGlnaXRzKSB7XG4gIHJldHVybiAoXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gICAgICogQHJldHVybiB7c3RyaW5nfSBTdHJpbmcgWFkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gKGNvb3JkaW5hdGUpIHtcbiAgICAgIHJldHVybiB0b1N0cmluZ1hZKGNvb3JkaW5hdGUsIG9wdF9mcmFjdGlvbkRpZ2l0cyk7XG4gICAgfVxuICApO1xufVxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gaGVtaXNwaGVyZXMgSGVtaXNwaGVyZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gZGVncmVlcyBEZWdyZWVzLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZnJhY3Rpb25EaWdpdHMgVGhlIG51bWJlciBvZiBkaWdpdHMgdG8gaW5jbHVkZVxuICogICAgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuIERlZmF1bHQgaXMgYDBgLlxuICogQHJldHVybiB7c3RyaW5nfSBTdHJpbmcuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZ3JlZXNUb1N0cmluZ0hETVMoaGVtaXNwaGVyZXMsIGRlZ3JlZXMsIG9wdF9mcmFjdGlvbkRpZ2l0cykge1xuICB2YXIgbm9ybWFsaXplZERlZ3JlZXMgPSBtb2R1bG8oZGVncmVlcyArIDE4MCwgMzYwKSAtIDE4MDtcbiAgdmFyIHggPSBNYXRoLmFicygzNjAwICogbm9ybWFsaXplZERlZ3JlZXMpO1xuICB2YXIgZGZsUHJlY2lzaW9uID0gb3B0X2ZyYWN0aW9uRGlnaXRzIHx8IDA7XG4gIHZhciBwcmVjaXNpb24gPSBNYXRoLnBvdygxMCwgZGZsUHJlY2lzaW9uKTtcbiAgdmFyIGRlZyA9IE1hdGguZmxvb3IoeCAvIDM2MDApO1xuICB2YXIgbWluID0gTWF0aC5mbG9vcigoeCAtIGRlZyAqIDM2MDApIC8gNjApO1xuICB2YXIgc2VjID0geCAtIGRlZyAqIDM2MDAgLSBtaW4gKiA2MDtcbiAgc2VjID0gTWF0aC5jZWlsKHNlYyAqIHByZWNpc2lvbikgLyBwcmVjaXNpb247XG5cbiAgaWYgKHNlYyA+PSA2MCkge1xuICAgIHNlYyA9IDA7XG4gICAgbWluICs9IDE7XG4gIH1cblxuICBpZiAobWluID49IDYwKSB7XG4gICAgbWluID0gMDtcbiAgICBkZWcgKz0gMTtcbiAgfVxuXG4gIHJldHVybiBkZWcgKyBcIlxceEIwIFwiICsgcGFkTnVtYmVyKG1pbiwgMikgKyBcIlxcdTIwMzIgXCIgKyBwYWROdW1iZXIoc2VjLCAyLCBkZmxQcmVjaXNpb24pICsgXCJcXHUyMDMzXCIgKyAobm9ybWFsaXplZERlZ3JlZXMgPT0gMCA/ICcnIDogJyAnICsgaGVtaXNwaGVyZXMuY2hhckF0KG5vcm1hbGl6ZWREZWdyZWVzIDwgMCA/IDEgOiAwKSk7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIGdpdmVuIHtAbGluayBtb2R1bGU6b2wvY29vcmRpbmF0ZX5Db29yZGluYXRlfSB0byBhIHN0cmluZ1xuICogdXNpbmcgdGhlIGdpdmVuIHN0cmluZyB0ZW1wbGF0ZS4gVGhlIHN0cmluZ3MgYHt4fWAgYW5kIGB7eX1gIGluIHRoZSB0ZW1wbGF0ZVxuICogd2lsbCBiZSByZXBsYWNlZCB3aXRoIHRoZSBmaXJzdCBhbmQgc2Vjb25kIGNvb3JkaW5hdGUgdmFsdWVzIHJlc3BlY3RpdmVseS5cbiAqXG4gKiBFeGFtcGxlIHdpdGhvdXQgc3BlY2lmeWluZyB0aGUgZnJhY3Rpb25hbCBkaWdpdHM6XG4gKlxuICogICAgIGltcG9ydCB7Zm9ybWF0fSBmcm9tICdvbC9jb29yZGluYXRlJztcbiAqXG4gKiAgICAgdmFyIGNvb3JkID0gWzcuODUsIDQ3Ljk4MzMzM107XG4gKiAgICAgdmFyIHRlbXBsYXRlID0gJ0Nvb3JkaW5hdGUgaXMgKHt4fXx7eX0pLic7XG4gKiAgICAgdmFyIG91dCA9IGZvcm1hdChjb29yZCwgdGVtcGxhdGUpO1xuICogICAgIC8vIG91dCBpcyBub3cgJ0Nvb3JkaW5hdGUgaXMgKDh8NDgpLidcbiAqXG4gKiBFeGFtcGxlIGV4cGxpY2l0bHkgc3BlY2lmeWluZyB0aGUgZnJhY3Rpb25hbCBkaWdpdHM6XG4gKlxuICogICAgIGltcG9ydCB7Zm9ybWF0fSBmcm9tICdvbC9jb29yZGluYXRlJztcbiAqXG4gKiAgICAgdmFyIGNvb3JkID0gWzcuODUsIDQ3Ljk4MzMzM107XG4gKiAgICAgdmFyIHRlbXBsYXRlID0gJ0Nvb3JkaW5hdGUgaXMgKHt4fXx7eX0pLic7XG4gKiAgICAgdmFyIG91dCA9IGZvcm1hdChjb29yZCwgdGVtcGxhdGUsIDIpO1xuICogICAgIC8vIG91dCBpcyBub3cgJ0Nvb3JkaW5hdGUgaXMgKDcuODV8NDcuOTgpLidcbiAqXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZW1wbGF0ZSBBIHRlbXBsYXRlIHN0cmluZyB3aXRoIGB7eH1gIGFuZCBge3l9YCBwbGFjZWhvbGRlcnNcbiAqICAgICB0aGF0IHdpbGwgYmUgcmVwbGFjZWQgYnkgZmlyc3QgYW5kIHNlY29uZCBjb29yZGluYXRlIHZhbHVlcy5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2ZyYWN0aW9uRGlnaXRzIFRoZSBudW1iZXIgb2YgZGlnaXRzIHRvIGluY2x1ZGVcbiAqICAgIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50LiBEZWZhdWx0IGlzIGAwYC5cbiAqIEByZXR1cm4ge3N0cmluZ30gRm9ybWF0dGVkIGNvb3JkaW5hdGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdChjb29yZGluYXRlLCB0ZW1wbGF0ZSwgb3B0X2ZyYWN0aW9uRGlnaXRzKSB7XG4gIGlmIChjb29yZGluYXRlKSB7XG4gICAgcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoJ3t4fScsIGNvb3JkaW5hdGVbMF0udG9GaXhlZChvcHRfZnJhY3Rpb25EaWdpdHMpKS5yZXBsYWNlKCd7eX0nLCBjb29yZGluYXRlWzFdLnRvRml4ZWQob3B0X2ZyYWN0aW9uRGlnaXRzKSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmRpbmF0ZTEgRmlyc3QgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmRpbmF0ZTIgU2Vjb25kIGNvb3JkaW5hdGUuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgdHdvIGNvb3JkaW5hdGVzIGFyZSBlcXVhbC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxzKGNvb3JkaW5hdGUxLCBjb29yZGluYXRlMikge1xuICB2YXIgZXF1YWxzID0gdHJ1ZTtcblxuICBmb3IgKHZhciBpID0gY29vcmRpbmF0ZTEubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICBpZiAoY29vcmRpbmF0ZTFbaV0gIT0gY29vcmRpbmF0ZTJbaV0pIHtcbiAgICAgIGVxdWFscyA9IGZhbHNlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVxdWFscztcbn1cbi8qKlxuICogUm90YXRlIGBjb29yZGluYXRlYCBieSBgYW5nbGVgLiBgY29vcmRpbmF0ZWAgaXMgbW9kaWZpZWQgaW4gcGxhY2UgYW5kXG4gKiByZXR1cm5lZCBieSB0aGUgZnVuY3Rpb24uXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgaW1wb3J0IHtyb3RhdGV9IGZyb20gJ29sL2Nvb3JkaW5hdGUnO1xuICpcbiAqICAgICB2YXIgY29vcmQgPSBbNy44NSwgNDcuOTgzMzMzXTtcbiAqICAgICB2YXIgcm90YXRlUmFkaWFucyA9IE1hdGguUEkgLyAyOyAvLyA5MCBkZWdyZWVzXG4gKiAgICAgcm90YXRlKGNvb3JkLCByb3RhdGVSYWRpYW5zKTtcbiAqICAgICAvLyBjb29yZCBpcyBub3cgWy00Ny45ODMzMzMsIDcuODVdXG4gKlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge251bWJlcn0gYW5nbGUgQW5nbGUgaW4gcmFkaWFuLlxuICogQHJldHVybiB7Q29vcmRpbmF0ZX0gQ29vcmRpbmF0ZS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlKGNvb3JkaW5hdGUsIGFuZ2xlKSB7XG4gIHZhciBjb3NBbmdsZSA9IE1hdGguY29zKGFuZ2xlKTtcbiAgdmFyIHNpbkFuZ2xlID0gTWF0aC5zaW4oYW5nbGUpO1xuICB2YXIgeCA9IGNvb3JkaW5hdGVbMF0gKiBjb3NBbmdsZSAtIGNvb3JkaW5hdGVbMV0gKiBzaW5BbmdsZTtcbiAgdmFyIHkgPSBjb29yZGluYXRlWzFdICogY29zQW5nbGUgKyBjb29yZGluYXRlWzBdICogc2luQW5nbGU7XG4gIGNvb3JkaW5hdGVbMF0gPSB4O1xuICBjb29yZGluYXRlWzFdID0geTtcbiAgcmV0dXJuIGNvb3JkaW5hdGU7XG59XG4vKipcbiAqIFNjYWxlIGBjb29yZGluYXRlYCBieSBgc2NhbGVgLiBgY29vcmRpbmF0ZWAgaXMgbW9kaWZpZWQgaW4gcGxhY2UgYW5kIHJldHVybmVkXG4gKiBieSB0aGUgZnVuY3Rpb24uXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgaW1wb3J0IHtzY2FsZSBhcyBzY2FsZUNvb3JkaW5hdGV9IGZyb20gJ29sL2Nvb3JkaW5hdGUnO1xuICpcbiAqICAgICB2YXIgY29vcmQgPSBbNy44NSwgNDcuOTgzMzMzXTtcbiAqICAgICB2YXIgc2NhbGUgPSAxLjI7XG4gKiAgICAgc2NhbGVDb29yZGluYXRlKGNvb3JkLCBzY2FsZSk7XG4gKiAgICAgLy8gY29vcmQgaXMgbm93IFs5LjQyLCA1Ny41Nzk5OTk2XVxuICpcbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHNjYWxlIFNjYWxlIGZhY3Rvci5cbiAqIEByZXR1cm4ge0Nvb3JkaW5hdGV9IENvb3JkaW5hdGUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlKGNvb3JkaW5hdGUsIHNjYWxlKSB7XG4gIGNvb3JkaW5hdGVbMF0gKj0gc2NhbGU7XG4gIGNvb3JkaW5hdGVbMV0gKj0gc2NhbGU7XG4gIHJldHVybiBjb29yZGluYXRlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkMSBGaXJzdCBjb29yZGluYXRlLlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZDIgU2Vjb25kIGNvb3JkaW5hdGUuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFNxdWFyZWQgZGlzdGFuY2UgYmV0d2VlbiBjb29yZDEgYW5kIGNvb3JkMi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3F1YXJlZERpc3RhbmNlKGNvb3JkMSwgY29vcmQyKSB7XG4gIHZhciBkeCA9IGNvb3JkMVswXSAtIGNvb3JkMlswXTtcbiAgdmFyIGR5ID0gY29vcmQxWzFdIC0gY29vcmQyWzFdO1xuICByZXR1cm4gZHggKiBkeCArIGR5ICogZHk7XG59XG4vKipcbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmQxIEZpcnN0IGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkMiBTZWNvbmQgY29vcmRpbmF0ZS5cbiAqIEByZXR1cm4ge251bWJlcn0gRGlzdGFuY2UgYmV0d2VlbiBjb29yZDEgYW5kIGNvb3JkMi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2UoY29vcmQxLCBjb29yZDIpIHtcbiAgcmV0dXJuIE1hdGguc3FydChzcXVhcmVkRGlzdGFuY2UoY29vcmQxLCBjb29yZDIpKTtcbn1cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSBzcXVhcmVkIGRpc3RhbmNlIGZyb20gYSBjb29yZGluYXRlIHRvIGEgbGluZSBzZWdtZW50LlxuICpcbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlIG9mIHRoZSBwb2ludC5cbiAqIEBwYXJhbSB7QXJyYXk8Q29vcmRpbmF0ZT59IHNlZ21lbnQgTGluZSBzZWdtZW50ICgyXG4gKiBjb29yZGluYXRlcykuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFNxdWFyZWQgZGlzdGFuY2UgZnJvbSB0aGUgcG9pbnQgdG8gdGhlIGxpbmUgc2VnbWVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3F1YXJlZERpc3RhbmNlVG9TZWdtZW50KGNvb3JkaW5hdGUsIHNlZ21lbnQpIHtcbiAgcmV0dXJuIHNxdWFyZWREaXN0YW5jZShjb29yZGluYXRlLCBjbG9zZXN0T25TZWdtZW50KGNvb3JkaW5hdGUsIHNlZ21lbnQpKTtcbn1cbi8qKlxuICogRm9ybWF0IGEgZ2VvZ3JhcGhpYyBjb29yZGluYXRlIHdpdGggdGhlIGhlbWlzcGhlcmUsIGRlZ3JlZXMsIG1pbnV0ZXMsIGFuZFxuICogc2Vjb25kcy5cbiAqXG4gKiBFeGFtcGxlIHdpdGhvdXQgc3BlY2lmeWluZyBmcmFjdGlvbmFsIGRpZ2l0czpcbiAqXG4gKiAgICAgaW1wb3J0IHt0b1N0cmluZ0hETVN9IGZyb20gJ29sL2Nvb3JkaW5hdGUnO1xuICpcbiAqICAgICB2YXIgY29vcmQgPSBbNy44NSwgNDcuOTgzMzMzXTtcbiAqICAgICB2YXIgb3V0ID0gdG9TdHJpbmdIRE1TKGNvb3JkKTtcbiAqICAgICAvLyBvdXQgaXMgbm93ICc0N8KwIDU44oCyIDYw4oCzIE4gN8KwIDUw4oCyIDYw4oCzIEUnXG4gKlxuICogRXhhbXBsZSBleHBsaWNpdGx5IHNwZWNpZnlpbmcgMSBmcmFjdGlvbmFsIGRpZ2l0OlxuICpcbiAqICAgICBpbXBvcnQge3RvU3RyaW5nSERNU30gZnJvbSAnb2wvY29vcmRpbmF0ZSc7XG4gKlxuICogICAgIHZhciBjb29yZCA9IFs3Ljg1LCA0Ny45ODMzMzNdO1xuICogICAgIHZhciBvdXQgPSB0b1N0cmluZ0hETVMoY29vcmQsIDEpO1xuICogICAgIC8vIG91dCBpcyBub3cgJzQ3wrAgNTjigLIgNjAuMOKAsyBOIDfCsCA1MOKAsiA2MC4w4oCzIEUnXG4gKlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9mcmFjdGlvbkRpZ2l0cyBUaGUgbnVtYmVyIG9mIGRpZ2l0cyB0byBpbmNsdWRlXG4gKiAgICBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4gRGVmYXVsdCBpcyBgMGAuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IEhlbWlzcGhlcmUsIGRlZ3JlZXMsIG1pbnV0ZXMgYW5kIHNlY29uZHMuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvU3RyaW5nSERNUyhjb29yZGluYXRlLCBvcHRfZnJhY3Rpb25EaWdpdHMpIHtcbiAgaWYgKGNvb3JkaW5hdGUpIHtcbiAgICByZXR1cm4gZGVncmVlc1RvU3RyaW5nSERNUygnTlMnLCBjb29yZGluYXRlWzFdLCBvcHRfZnJhY3Rpb25EaWdpdHMpICsgJyAnICsgZGVncmVlc1RvU3RyaW5nSERNUygnRVcnLCBjb29yZGluYXRlWzBdLCBvcHRfZnJhY3Rpb25EaWdpdHMpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAnJztcbiAgfVxufVxuLyoqXG4gKiBGb3JtYXQgYSBjb29yZGluYXRlIGFzIGEgY29tbWEgZGVsaW1pdGVkIHN0cmluZy5cbiAqXG4gKiBFeGFtcGxlIHdpdGhvdXQgc3BlY2lmeWluZyBmcmFjdGlvbmFsIGRpZ2l0czpcbiAqXG4gKiAgICAgaW1wb3J0IHt0b1N0cmluZ1hZfSBmcm9tICdvbC9jb29yZGluYXRlJztcbiAqXG4gKiAgICAgdmFyIGNvb3JkID0gWzcuODUsIDQ3Ljk4MzMzM107XG4gKiAgICAgdmFyIG91dCA9IHRvU3RyaW5nWFkoY29vcmQpO1xuICogICAgIC8vIG91dCBpcyBub3cgJzgsIDQ4J1xuICpcbiAqIEV4YW1wbGUgZXhwbGljaXRseSBzcGVjaWZ5aW5nIDEgZnJhY3Rpb25hbCBkaWdpdDpcbiAqXG4gKiAgICAgaW1wb3J0IHt0b1N0cmluZ1hZfSBmcm9tICdvbC9jb29yZGluYXRlJztcbiAqXG4gKiAgICAgdmFyIGNvb3JkID0gWzcuODUsIDQ3Ljk4MzMzM107XG4gKiAgICAgdmFyIG91dCA9IHRvU3RyaW5nWFkoY29vcmQsIDEpO1xuICogICAgIC8vIG91dCBpcyBub3cgJzcuOCwgNDguMCdcbiAqXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2ZyYWN0aW9uRGlnaXRzIFRoZSBudW1iZXIgb2YgZGlnaXRzIHRvIGluY2x1ZGVcbiAqICAgIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50LiBEZWZhdWx0IGlzIGAwYC5cbiAqIEByZXR1cm4ge3N0cmluZ30gWFkuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvU3RyaW5nWFkoY29vcmRpbmF0ZSwgb3B0X2ZyYWN0aW9uRGlnaXRzKSB7XG4gIHJldHVybiBmb3JtYXQoY29vcmRpbmF0ZSwgJ3t4fSwge3l9Jywgb3B0X2ZyYWN0aW9uRGlnaXRzKTtcbn1cbi8qKlxuICogTW9kaWZpZXMgdGhlIHByb3ZpZGVkIGNvb3JkaW5hdGUgaW4tcGxhY2UgdG8gYmUgd2l0aGluIHRoZSByZWFsIHdvcmxkXG4gKiBleHRlbnQuIFRoZSBsb3dlciBwcm9qZWN0aW9uIGV4dGVudCBib3VuZGFyeSBpcyBpbmNsdXNpdmUsIHRoZSB1cHBlciBvbmVcbiAqIGV4Y2x1c2l2ZS5cbiAqXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICogQHJldHVybiB7Q29vcmRpbmF0ZX0gVGhlIGNvb3JkaW5hdGUgd2l0aGluIHRoZSByZWFsIHdvcmxkIGV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gd3JhcFgoY29vcmRpbmF0ZSwgcHJvamVjdGlvbikge1xuICBpZiAocHJvamVjdGlvbi5jYW5XcmFwWCgpKSB7XG4gICAgdmFyIHdvcmxkV2lkdGggPSBnZXRXaWR0aChwcm9qZWN0aW9uLmdldEV4dGVudCgpKTtcbiAgICB2YXIgd29ybGRzQXdheSA9IGdldFdvcmxkc0F3YXkoY29vcmRpbmF0ZSwgcHJvamVjdGlvbiwgd29ybGRXaWR0aCk7XG5cbiAgICBpZiAod29ybGRzQXdheSkge1xuICAgICAgY29vcmRpbmF0ZVswXSAtPSB3b3JsZHNBd2F5ICogd29ybGRXaWR0aDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29vcmRpbmF0ZTtcbn1cbi8qKlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3NvdXJjZUV4dGVudFdpZHRoIFdpZHRoIG9mIHRoZSBzb3VyY2UgZXh0ZW50LlxuICogQHJldHVybiB7bnVtYmVyfSBPZmZzZXQgaW4gd29ybGQgd2lkdGhzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXb3JsZHNBd2F5KGNvb3JkaW5hdGUsIHByb2plY3Rpb24sIG9wdF9zb3VyY2VFeHRlbnRXaWR0aCkge1xuICB2YXIgcHJvamVjdGlvbkV4dGVudCA9IHByb2plY3Rpb24uZ2V0RXh0ZW50KCk7XG4gIHZhciB3b3JsZHNBd2F5ID0gMDtcblxuICBpZiAocHJvamVjdGlvbi5jYW5XcmFwWCgpICYmIChjb29yZGluYXRlWzBdIDwgcHJvamVjdGlvbkV4dGVudFswXSB8fCBjb29yZGluYXRlWzBdID4gcHJvamVjdGlvbkV4dGVudFsyXSkpIHtcbiAgICB2YXIgc291cmNlRXh0ZW50V2lkdGggPSBvcHRfc291cmNlRXh0ZW50V2lkdGggfHwgZ2V0V2lkdGgocHJvamVjdGlvbkV4dGVudCk7XG4gICAgd29ybGRzQXdheSA9IE1hdGguZmxvb3IoKGNvb3JkaW5hdGVbMF0gLSBwcm9qZWN0aW9uRXh0ZW50WzBdKSAvIHNvdXJjZUV4dGVudFdpZHRoKTtcbiAgfVxuXG4gIHJldHVybiB3b3JsZHNBd2F5O1xufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyZXIvTWFwXG4gKi9cblxuXG5pbXBvcnQgRGlzcG9zYWJsZSBmcm9tICcuLi9EaXNwb3NhYmxlLmpzJztcbmltcG9ydCB7IFRSVUUgfSBmcm9tICcuLi9mdW5jdGlvbnMuanMnO1xuaW1wb3J0IHsgYWJzdHJhY3QgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IGNvbXBvc2UgYXMgY29tcG9zZVRyYW5zZm9ybSwgbWFrZUludmVyc2UgfSBmcm9tICcuLi90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHsgZ2V0V2lkdGggfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgc2hhcmVkIGFzIGljb25JbWFnZUNhY2hlIH0gZnJvbSAnLi4vc3R5bGUvSWNvbkltYWdlQ2FjaGUuanMnO1xuaW1wb3J0IHsgaW5WaWV3IH0gZnJvbSAnLi4vbGF5ZXIvTGF5ZXIuanMnO1xuaW1wb3J0IHsgd3JhcFggfSBmcm9tICcuLi9jb29yZGluYXRlLmpzJztcbi8qKlxuICogQHR5cGVkZWYgSGl0TWF0Y2hcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0fSBsYXllclxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5XG4gKiBAcHJvcGVydHkge251bWJlcn0gZGlzdGFuY2VTcVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL3ZlY3Rvci5qc1wiKS5GZWF0dXJlQ2FsbGJhY2s8VD59IGNhbGxiYWNrXG4gKiBAdGVtcGxhdGUgVFxuICovXG5cbi8qKlxuICogQGFic3RyYWN0XG4gKi9cblxudmFyIE1hcFJlbmRlcmVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKE1hcFJlbmRlcmVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIE1hcC5cbiAgICovXG5cblxuICBmdW5jdGlvbiBNYXBSZW5kZXJlcihtYXApIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5tYXBfID0gbWFwO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL0V2ZW50VHlwZS5qc1wiKS5kZWZhdWx0fSB0eXBlIEV2ZW50IHR5cGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqL1xuXG5cbiAgTWFwUmVuZGVyZXIucHJvdG90eXBlLmRpc3BhdGNoUmVuZGVyRXZlbnQgPSBmdW5jdGlvbiAodHlwZSwgZnJhbWVTdGF0ZSkge1xuICAgIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lU3RhdGUuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBNYXBSZW5kZXJlci5wcm90b3R5cGUuY2FsY3VsYXRlTWF0cmljZXMyRCA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgdmFyIHZpZXdTdGF0ZSA9IGZyYW1lU3RhdGUudmlld1N0YXRlO1xuICAgIHZhciBjb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybSA9IGZyYW1lU3RhdGUuY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm07XG4gICAgdmFyIHBpeGVsVG9Db29yZGluYXRlVHJhbnNmb3JtID0gZnJhbWVTdGF0ZS5waXhlbFRvQ29vcmRpbmF0ZVRyYW5zZm9ybTtcbiAgICBjb21wb3NlVHJhbnNmb3JtKGNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtLCBmcmFtZVN0YXRlLnNpemVbMF0gLyAyLCBmcmFtZVN0YXRlLnNpemVbMV0gLyAyLCAxIC8gdmlld1N0YXRlLnJlc29sdXRpb24sIC0xIC8gdmlld1N0YXRlLnJlc29sdXRpb24sIC12aWV3U3RhdGUucm90YXRpb24sIC12aWV3U3RhdGUuY2VudGVyWzBdLCAtdmlld1N0YXRlLmNlbnRlclsxXSk7XG4gICAgbWFrZUludmVyc2UocGl4ZWxUb0Nvb3JkaW5hdGVUcmFuc2Zvcm0sIGNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWVTdGF0ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGhpdFRvbGVyYW5jZSBIaXQgdG9sZXJhbmNlIGluIHBpeGVscy5cbiAgICogQHBhcmFtIHtib29sZWFufSBjaGVja1dyYXBwZWQgQ2hlY2sgZm9yIHdyYXBwZWQgZ2VvbWV0cmllcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3ZlY3Rvci5qc1wiKS5GZWF0dXJlQ2FsbGJhY2s8VD59IGNhbGxiYWNrIEZlYXR1cmUgY2FsbGJhY2suXG4gICAqIEBwYXJhbSB7U30gdGhpc0FyZyBWYWx1ZSB0byB1c2UgYXMgYHRoaXNgIHdoZW4gZXhlY3V0aW5nIGBjYWxsYmFja2AuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczogVSwgaW1wb3J0KFwiLi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdCk6IGJvb2xlYW59IGxheWVyRmlsdGVyIExheWVyIGZpbHRlclxuICAgKiAgICAgZnVuY3Rpb24sIG9ubHkgbGF5ZXJzIHdoaWNoIGFyZSB2aXNpYmxlIGFuZCBmb3Igd2hpY2ggdGhpcyBmdW5jdGlvblxuICAgKiAgICAgcmV0dXJucyBgdHJ1ZWAgd2lsbCBiZSB0ZXN0ZWQgZm9yIGZlYXR1cmVzLiAgQnkgZGVmYXVsdCwgYWxsIHZpc2libGVcbiAgICogICAgIGxheWVycyB3aWxsIGJlIHRlc3RlZC5cbiAgICogQHBhcmFtIHtVfSB0aGlzQXJnMiBWYWx1ZSB0byB1c2UgYXMgYHRoaXNgIHdoZW4gZXhlY3V0aW5nIGBsYXllckZpbHRlcmAuXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQuXG4gICAqIEB0ZW1wbGF0ZSBTLFQsVVxuICAgKi9cblxuXG4gIE1hcFJlbmRlcmVyLnByb3RvdHlwZS5mb3JFYWNoRmVhdHVyZUF0Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uIChjb29yZGluYXRlLCBmcmFtZVN0YXRlLCBoaXRUb2xlcmFuY2UsIGNoZWNrV3JhcHBlZCwgY2FsbGJhY2ssIHRoaXNBcmcsIGxheWVyRmlsdGVyLCB0aGlzQXJnMikge1xuICAgIHZhciByZXN1bHQ7XG4gICAgdmFyIHZpZXdTdGF0ZSA9IGZyYW1lU3RhdGUudmlld1N0YXRlO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gbWFuYWdlZCBNYW5hZ2VkIGxheWVyLlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gbGF5ZXIgTGF5ZXIuXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICAgICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQuXG4gICAgICovXG5cbiAgICBmdW5jdGlvbiBmb3JFYWNoRmVhdHVyZUF0Q29vcmRpbmF0ZShtYW5hZ2VkLCBmZWF0dXJlLCBsYXllciwgZ2VvbWV0cnkpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHRoaXNBcmcsIGZlYXR1cmUsIG1hbmFnZWQgPyBsYXllciA6IG51bGwsIGdlb21ldHJ5KTtcbiAgICB9XG5cbiAgICB2YXIgcHJvamVjdGlvbiA9IHZpZXdTdGF0ZS5wcm9qZWN0aW9uO1xuICAgIHZhciB0cmFuc2xhdGVkQ29vcmRpbmF0ZSA9IHdyYXBYKGNvb3JkaW5hdGUuc2xpY2UoKSwgcHJvamVjdGlvbik7XG4gICAgdmFyIG9mZnNldHMgPSBbWzAsIDBdXTtcblxuICAgIGlmIChwcm9qZWN0aW9uLmNhbldyYXBYKCkgJiYgY2hlY2tXcmFwcGVkKSB7XG4gICAgICB2YXIgcHJvamVjdGlvbkV4dGVudCA9IHByb2plY3Rpb24uZ2V0RXh0ZW50KCk7XG4gICAgICB2YXIgd29ybGRXaWR0aCA9IGdldFdpZHRoKHByb2plY3Rpb25FeHRlbnQpO1xuICAgICAgb2Zmc2V0cy5wdXNoKFstd29ybGRXaWR0aCwgMF0sIFt3b3JsZFdpZHRoLCAwXSk7XG4gICAgfVxuXG4gICAgdmFyIGxheWVyU3RhdGVzID0gZnJhbWVTdGF0ZS5sYXllclN0YXRlc0FycmF5O1xuICAgIHZhciBudW1MYXllcnMgPSBsYXllclN0YXRlcy5sZW5ndGg7XG4gICAgdmFyIG1hdGNoZXMgPVxuICAgIC8qKiBAdHlwZSB7QXJyYXk8SGl0TWF0Y2g8VD4+fSAqL1xuICAgIFtdO1xuICAgIHZhciB0bXBDb29yZCA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvZmZzZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBmb3IgKHZhciBqID0gbnVtTGF5ZXJzIC0gMTsgaiA+PSAwOyAtLWopIHtcbiAgICAgICAgdmFyIGxheWVyU3RhdGUgPSBsYXllclN0YXRlc1tqXTtcbiAgICAgICAgdmFyIGxheWVyID0gbGF5ZXJTdGF0ZS5sYXllcjtcblxuICAgICAgICBpZiAobGF5ZXIuaGFzUmVuZGVyZXIoKSAmJiBpblZpZXcobGF5ZXJTdGF0ZSwgdmlld1N0YXRlKSAmJiBsYXllckZpbHRlci5jYWxsKHRoaXNBcmcyLCBsYXllcikpIHtcbiAgICAgICAgICB2YXIgbGF5ZXJSZW5kZXJlciA9IGxheWVyLmdldFJlbmRlcmVyKCk7XG4gICAgICAgICAgdmFyIHNvdXJjZSA9IGxheWVyLmdldFNvdXJjZSgpO1xuXG4gICAgICAgICAgaWYgKGxheWVyUmVuZGVyZXIgJiYgc291cmNlKSB7XG4gICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXMgPSBzb3VyY2UuZ2V0V3JhcFgoKSA/IHRyYW5zbGF0ZWRDb29yZGluYXRlIDogY29vcmRpbmF0ZTtcbiAgICAgICAgICAgIHZhciBjYWxsYmFja18xID0gZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGUuYmluZChudWxsLCBsYXllclN0YXRlLm1hbmFnZWQpO1xuICAgICAgICAgICAgdG1wQ29vcmRbMF0gPSBjb29yZGluYXRlc1swXSArIG9mZnNldHNbaV1bMF07XG4gICAgICAgICAgICB0bXBDb29yZFsxXSA9IGNvb3JkaW5hdGVzWzFdICsgb2Zmc2V0c1tpXVsxXTtcbiAgICAgICAgICAgIHJlc3VsdCA9IGxheWVyUmVuZGVyZXIuZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGUodG1wQ29vcmQsIGZyYW1lU3RhdGUsIGhpdFRvbGVyYW5jZSwgY2FsbGJhY2tfMSwgbWF0Y2hlcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWF0Y2hlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdmFyIG9yZGVyID0gMSAvIG1hdGNoZXMubGVuZ3RoO1xuICAgIG1hdGNoZXMuZm9yRWFjaChmdW5jdGlvbiAobSwgaSkge1xuICAgICAgcmV0dXJuIG0uZGlzdGFuY2VTcSArPSBpICogb3JkZXI7XG4gICAgfSk7XG4gICAgbWF0Y2hlcy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICByZXR1cm4gYS5kaXN0YW5jZVNxIC0gYi5kaXN0YW5jZVNxO1xuICAgIH0pO1xuICAgIG1hdGNoZXMuc29tZShmdW5jdGlvbiAobSkge1xuICAgICAgcmV0dXJuIHJlc3VsdCA9IG0uY2FsbGJhY2sobS5mZWF0dXJlLCBtLmxheWVyLCBtLmdlb21ldHJ5KTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lU3RhdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoaXRUb2xlcmFuY2UgSGl0IHRvbGVyYW5jZSBpbiBwaXhlbHMuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdCwgKFVpbnQ4Q2xhbXBlZEFycmF5fFVpbnQ4QXJyYXkpKTogVH0gY2FsbGJhY2sgTGF5ZXJcbiAgICogICAgIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHQpOiBib29sZWFufSBsYXllckZpbHRlciBMYXllciBmaWx0ZXJcbiAgICogICAgIGZ1bmN0aW9uLCBvbmx5IGxheWVycyB3aGljaCBhcmUgdmlzaWJsZSBhbmQgZm9yIHdoaWNoIHRoaXMgZnVuY3Rpb25cbiAgICogICAgIHJldHVybnMgYHRydWVgIHdpbGwgYmUgdGVzdGVkIGZvciBmZWF0dXJlcy4gIEJ5IGRlZmF1bHQsIGFsbCB2aXNpYmxlXG4gICAqICAgICBsYXllcnMgd2lsbCBiZSB0ZXN0ZWQuXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqL1xuXG5cbiAgTWFwUmVuZGVyZXIucHJvdG90eXBlLmZvckVhY2hMYXllckF0UGl4ZWwgPSBmdW5jdGlvbiAocGl4ZWwsIGZyYW1lU3RhdGUsIGhpdFRvbGVyYW5jZSwgY2FsbGJhY2ssIGxheWVyRmlsdGVyKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lU3RhdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoaXRUb2xlcmFuY2UgSGl0IHRvbGVyYW5jZSBpbiBwaXhlbHMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gY2hlY2tXcmFwcGVkIENoZWNrIGZvciB3cmFwcGVkIGdlb21ldHJpZXMuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczogVSwgaW1wb3J0KFwiLi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdCk6IGJvb2xlYW59IGxheWVyRmlsdGVyIExheWVyIGZpbHRlclxuICAgKiAgICAgZnVuY3Rpb24sIG9ubHkgbGF5ZXJzIHdoaWNoIGFyZSB2aXNpYmxlIGFuZCBmb3Igd2hpY2ggdGhpcyBmdW5jdGlvblxuICAgKiAgICAgcmV0dXJucyBgdHJ1ZWAgd2lsbCBiZSB0ZXN0ZWQgZm9yIGZlYXR1cmVzLiAgQnkgZGVmYXVsdCwgYWxsIHZpc2libGVcbiAgICogICAgIGxheWVycyB3aWxsIGJlIHRlc3RlZC5cbiAgICogQHBhcmFtIHtVfSB0aGlzQXJnIFZhbHVlIHRvIHVzZSBhcyBgdGhpc2Agd2hlbiBleGVjdXRpbmcgYGxheWVyRmlsdGVyYC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSXMgdGhlcmUgYSBmZWF0dXJlIGF0IHRoZSBnaXZlbiBjb29yZGluYXRlP1xuICAgKiBAdGVtcGxhdGUgVVxuICAgKi9cblxuXG4gIE1hcFJlbmRlcmVyLnByb3RvdHlwZS5oYXNGZWF0dXJlQXRDb29yZGluYXRlID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUsIGZyYW1lU3RhdGUsIGhpdFRvbGVyYW5jZSwgY2hlY2tXcmFwcGVkLCBsYXllckZpbHRlciwgdGhpc0FyZykge1xuICAgIHZhciBoYXNGZWF0dXJlID0gdGhpcy5mb3JFYWNoRmVhdHVyZUF0Q29vcmRpbmF0ZShjb29yZGluYXRlLCBmcmFtZVN0YXRlLCBoaXRUb2xlcmFuY2UsIGNoZWNrV3JhcHBlZCwgVFJVRSwgdGhpcywgbGF5ZXJGaWx0ZXIsIHRoaXNBcmcpO1xuICAgIHJldHVybiBoYXNGZWF0dXJlICE9PSB1bmRlZmluZWQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gTWFwLlxuICAgKi9cblxuXG4gIE1hcFJlbmRlcmVyLnByb3RvdHlwZS5nZXRNYXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwXztcbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlci5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7P2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKi9cblxuXG4gIE1hcFJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJGcmFtZSA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBNYXBSZW5kZXJlci5wcm90b3R5cGUuc2NoZWR1bGVFeHBpcmVJY29uQ2FjaGUgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgIGlmIChpY29uSW1hZ2VDYWNoZS5jYW5FeHBpcmVDYWNoZSgpKSB7XG4gICAgICBmcmFtZVN0YXRlLnBvc3RSZW5kZXJGdW5jdGlvbnMucHVzaChleHBpcmVJY29uQ2FjaGUpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gTWFwUmVuZGVyZXI7XG59KERpc3Bvc2FibGUpO1xuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fSBtYXAgTWFwLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAqL1xuXG5cbmZ1bmN0aW9uIGV4cGlyZUljb25DYWNoZShtYXAsIGZyYW1lU3RhdGUpIHtcbiAgaWNvbkltYWdlQ2FjaGUuZXhwaXJlKCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IE1hcFJlbmRlcmVyOyIsIi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXIvRXZlbnRcbiAqL1xudmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcblxuaW1wb3J0IEV2ZW50IGZyb20gJy4uL2V2ZW50cy9FdmVudC5qcyc7XG5cbnZhciBSZW5kZXJFdmVudCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhSZW5kZXJFdmVudCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9FdmVudFR5cGUuanNcIikuZGVmYXVsdH0gdHlwZSBUeXBlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm09fSBvcHRfaW52ZXJzZVBpeGVsVHJhbnNmb3JtIFRyYW5zZm9ybSBmb3JcbiAgICogICAgIENTUyBwaXhlbHMgdG8gcmVuZGVyZWQgcGl4ZWxzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlPX0gb3B0X2ZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7P0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRD19IG9wdF9jb250ZXh0IENvbnRleHQuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gUmVuZGVyRXZlbnQodHlwZSwgb3B0X2ludmVyc2VQaXhlbFRyYW5zZm9ybSwgb3B0X2ZyYW1lU3RhdGUsIG9wdF9jb250ZXh0KSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdHlwZSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm0gZnJvbSBDU1MgcGl4ZWxzIChyZWxhdGl2ZSB0byB0aGUgdG9wLWxlZnQgY29ybmVyIG9mIHRoZSBtYXAgdmlld3BvcnQpXG4gICAgICogdG8gcmVuZGVyZWQgcGl4ZWxzIG9uIHRoaXMgZXZlbnQncyBgY29udGV4dGAuIE9ubHkgYXZhaWxhYmxlIHdoZW4gYSBDYW52YXMgcmVuZGVyZXIgaXMgdXNlZCwgbnVsbCBvdGhlcndpc2UuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm18dW5kZWZpbmVkfVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuXG4gICAgX3RoaXMuaW52ZXJzZVBpeGVsVHJhbnNmb3JtID0gb3B0X2ludmVyc2VQaXhlbFRyYW5zZm9ybTtcbiAgICAvKipcbiAgICAgKiBBbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IHJlbmRlciBmcmFtZSBzdGF0ZS5cbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV8dW5kZWZpbmVkfVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICAgIF90aGlzLmZyYW1lU3RhdGUgPSBvcHRfZnJhbWVTdGF0ZTtcbiAgICAvKipcbiAgICAgKiBDYW52YXMgY29udGV4dC4gTm90IGF2YWlsYWJsZSB3aGVuIHRoZSBldmVudCBpcyBkaXNwYXRjaGVkIGJ5IHRoZSBtYXAuIE9ubHkgYXZhaWxhYmxlXG4gICAgICogd2hlbiBhIENhbnZhcyByZW5kZXJlciBpcyB1c2VkLCBudWxsIG90aGVyd2lzZS5cbiAgICAgKiBAdHlwZSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfG51bGx8dW5kZWZpbmVkfVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICAgIF90aGlzLmNvbnRleHQgPSBvcHRfY29udGV4dDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICByZXR1cm4gUmVuZGVyRXZlbnQ7XG59KEV2ZW50KTtcblxuZXhwb3J0IGRlZmF1bHQgUmVuZGVyRXZlbnQ7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2Nzc1xuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gRm9udFBhcmFtZXRlcnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdHlsZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IHZhcmlhbnRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB3ZWlnaHRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzaXplXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbGluZUhlaWdodFxuICogQHByb3BlcnR5IHtzdHJpbmd9IGZhbWlseVxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSBmYW1pbGllc1xuICovXG5cbi8qKlxuICogVGhlIENTUyBjbGFzcyBmb3IgaGlkZGVuIGZlYXR1cmUuXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5leHBvcnQgdmFyIENMQVNTX0hJRERFTiA9ICdvbC1oaWRkZW4nO1xuLyoqXG4gKiBUaGUgQ1NTIGNsYXNzIHRoYXQgd2UnbGwgZ2l2ZSB0aGUgRE9NIGVsZW1lbnRzIHRvIGhhdmUgdGhlbSBzZWxlY3RhYmxlLlxuICpcbiAqIEBjb25zdFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuXG5leHBvcnQgdmFyIENMQVNTX1NFTEVDVEFCTEUgPSAnb2wtc2VsZWN0YWJsZSc7XG4vKipcbiAqIFRoZSBDU1MgY2xhc3MgdGhhdCB3ZSdsbCBnaXZlIHRoZSBET00gZWxlbWVudHMgdG8gaGF2ZSB0aGVtIHVuc2VsZWN0YWJsZS5cbiAqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cblxuZXhwb3J0IHZhciBDTEFTU19VTlNFTEVDVEFCTEUgPSAnb2wtdW5zZWxlY3RhYmxlJztcbi8qKlxuICogVGhlIENTUyBjbGFzcyBmb3IgdW5zdXBwb3J0ZWQgZmVhdHVyZS5cbiAqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cblxuZXhwb3J0IHZhciBDTEFTU19VTlNVUFBPUlRFRCA9ICdvbC11bnN1cHBvcnRlZCc7XG4vKipcbiAqIFRoZSBDU1MgY2xhc3MgZm9yIGNvbnRyb2xzLlxuICpcbiAqIEBjb25zdFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuXG5leHBvcnQgdmFyIENMQVNTX0NPTlRST0wgPSAnb2wtY29udHJvbCc7XG4vKipcbiAqIFRoZSBDU1MgY2xhc3MgdGhhdCB3ZSdsbCBnaXZlIHRoZSBET00gZWxlbWVudHMgdGhhdCBhcmUgY29sbGFwc2VkLCBpLmUuXG4gKiB0byB0aG9zZSBlbGVtZW50cyB3aGljaCB1c3VhbGx5IGNhbiBiZSBleHBhbmRlZC5cbiAqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cblxuZXhwb3J0IHZhciBDTEFTU19DT0xMQVBTRUQgPSAnb2wtY29sbGFwc2VkJztcbi8qKlxuICogRnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwMTM1Njk3L3JlZ2V4LXRvLXBhcnNlLWFueS1jc3MtZm9udFxuICogQHR5cGUge1JlZ0V4cH1cbiAqL1xuXG52YXIgZm9udFJlZ0V4ID0gbmV3IFJlZ0V4cChbJ15cXFxccyooPz0oPzooPzpbLWEtel0rXFxcXHMqKXswLDJ9KGl0YWxpY3xvYmxpcXVlKSk/KScsICcoPz0oPzooPzpbLWEtel0rXFxcXHMqKXswLDJ9KHNtYWxsLWNhcHMpKT8pJywgJyg/PSg/Oig/OlstYS16XStcXFxccyopezAsMn0oYm9sZCg/OmVyKT98bGlnaHRlcnxbMS05XTAwICkpPyknLCAnKD86KD86bm9ybWFsfFxcXFwxfFxcXFwyfFxcXFwzKVxcXFxzKil7MCwzfSgoPzp4eD8tKT8nLCAnKD86c21hbGx8bGFyZ2UpfG1lZGl1bXxzbWFsbGVyfGxhcmdlcnxbXFxcXC5cXFxcZF0rKD86XFxcXCV8aW58W2NlbV1tfGV4fHBbY3R4XSkpJywgJyg/OlxcXFxzKlxcXFwvXFxcXHMqKG5vcm1hbHxbXFxcXC5cXFxcZF0rKD86XFxcXCV8aW58W2NlbV1tfGV4fHBbY3R4XSk/KSknLCAnP1xcXFxzKihbLSxcXFxcXCJcXFxcXFwnXFxcXHNhLXpdKz8pXFxcXHMqJCddLmpvaW4oJycpLCAnaScpO1xudmFyIGZvbnRSZWdFeE1hdGNoSW5kZXggPSBbJ3N0eWxlJywgJ3ZhcmlhbnQnLCAnd2VpZ2h0JywgJ3NpemUnLCAnbGluZUhlaWdodCcsICdmYW1pbHknXTtcbi8qKlxuICogR2V0IHRoZSBsaXN0IG9mIGZvbnQgZmFtaWxpZXMgZnJvbSBhIGZvbnQgc3BlYy4gIE5vdGUgdGhhdCB0aGlzIGRvZXNuJ3Qgd29ya1xuICogZm9yIGZvbnQgZmFtaWxpZXMgdGhhdCBoYXZlIGNvbW1hcyBpbiB0aGVtLlxuICogQHBhcmFtIHtzdHJpbmd9IGZvbnRTcGVjIFRoZSBDU1MgZm9udCBwcm9wZXJ0eS5cbiAqIEByZXR1cm4ge0ZvbnRQYXJhbWV0ZXJzfSBUaGUgZm9udCBwYXJhbWV0ZXJzIChvciBudWxsIGlmIHRoZSBpbnB1dCBzcGVjIGlzIGludmFsaWQpLlxuICovXG5cbmV4cG9ydCB2YXIgZ2V0Rm9udFBhcmFtZXRlcnMgPSBmdW5jdGlvbiBnZXRGb250UGFyYW1ldGVycyhmb250U3BlYykge1xuICB2YXIgbWF0Y2ggPSBmb250U3BlYy5tYXRjaChmb250UmVnRXgpO1xuXG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBzdHlsZSA9XG4gIC8qKiBAdHlwZSB7Rm9udFBhcmFtZXRlcnN9ICovXG4gIHtcbiAgICBsaW5lSGVpZ2h0OiAnbm9ybWFsJyxcbiAgICBzaXplOiAnMS4yZW0nLFxuICAgIHN0eWxlOiAnbm9ybWFsJyxcbiAgICB3ZWlnaHQ6ICdub3JtYWwnLFxuICAgIHZhcmlhbnQ6ICdub3JtYWwnXG4gIH07XG5cbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZm9udFJlZ0V4TWF0Y2hJbmRleC5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIHZhbHVlID0gbWF0Y2hbaSArIDFdO1xuXG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHN0eWxlW2ZvbnRSZWdFeE1hdGNoSW5kZXhbaV1dID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgc3R5bGUuZmFtaWxpZXMgPSBzdHlsZS5mYW1pbHkuc3BsaXQoLyxcXHM/Lyk7XG4gIHJldHVybiBzdHlsZTtcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2hhc1xuICovXG52YXIgdWEgPSB0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgbmF2aWdhdG9yLnVzZXJBZ2VudCAhPT0gJ3VuZGVmaW5lZCcgPyBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkgOiAnJztcbi8qKlxuICogVXNlciBhZ2VudCBzdHJpbmcgc2F5cyB3ZSBhcmUgZGVhbGluZyB3aXRoIEZpcmVmb3ggYXMgYnJvd3Nlci5cbiAqIEB0eXBlIHtib29sZWFufVxuICovXG5cbmV4cG9ydCB2YXIgRklSRUZPWCA9IHVhLmluZGV4T2YoJ2ZpcmVmb3gnKSAhPT0gLTE7XG4vKipcbiAqIFVzZXIgYWdlbnQgc3RyaW5nIHNheXMgd2UgYXJlIGRlYWxpbmcgd2l0aCBTYWZhcmkgYXMgYnJvd3Nlci5cbiAqIEB0eXBlIHtib29sZWFufVxuICovXG5cbmV4cG9ydCB2YXIgU0FGQVJJID0gdWEuaW5kZXhPZignc2FmYXJpJykgIT09IC0xICYmIHVhLmluZGV4T2YoJ2Nocm9tJykgPT0gLTE7XG4vKipcbiAqIFVzZXIgYWdlbnQgc3RyaW5nIHNheXMgd2UgYXJlIGRlYWxpbmcgd2l0aCBhIFdlYktpdCBlbmdpbmUuXG4gKiBAdHlwZSB7Ym9vbGVhbn1cbiAqL1xuXG5leHBvcnQgdmFyIFdFQktJVCA9IHVhLmluZGV4T2YoJ3dlYmtpdCcpICE9PSAtMSAmJiB1YS5pbmRleE9mKCdlZGdlJykgPT0gLTE7XG4vKipcbiAqIFVzZXIgYWdlbnQgc3RyaW5nIHNheXMgd2UgYXJlIGRlYWxpbmcgd2l0aCBhIE1hYyBhcyBwbGF0Zm9ybS5cbiAqIEB0eXBlIHtib29sZWFufVxuICovXG5cbmV4cG9ydCB2YXIgTUFDID0gdWEuaW5kZXhPZignbWFjaW50b3NoJykgIT09IC0xO1xuLyoqXG4gKiBUaGUgcmF0aW8gYmV0d2VlbiBwaHlzaWNhbCBwaXhlbHMgYW5kIGRldmljZS1pbmRlcGVuZGVudCBwaXhlbHNcbiAqIChkaXBzKSBvbiB0aGUgZGV2aWNlIChgd2luZG93LmRldmljZVBpeGVsUmF0aW9gKS5cbiAqIEBjb25zdFxuICogQHR5cGUge251bWJlcn1cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIERFVklDRV9QSVhFTF9SQVRJTyA9IHR5cGVvZiBkZXZpY2VQaXhlbFJhdGlvICE9PSAndW5kZWZpbmVkJyA/IGRldmljZVBpeGVsUmF0aW8gOiAxO1xuLyoqXG4gKiBUaGUgZXhlY3V0aW9uIGNvbnRleHQgaXMgYSB3b3JrZXIgd2l0aCBPZmZzY3JlZW5DYW52YXMgYXZhaWxhYmxlLlxuICogQGNvbnN0XG4gKiBAdHlwZSB7Ym9vbGVhbn1cbiAqL1xuXG5leHBvcnQgdmFyIFdPUktFUl9PRkZTQ1JFRU5fQ0FOVkFTID0gdHlwZW9mIFdvcmtlckdsb2JhbFNjb3BlICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgT2Zmc2NyZWVuQ2FudmFzICE9PSAndW5kZWZpbmVkJyAmJiBzZWxmIGluc3RhbmNlb2YgV29ya2VyR2xvYmFsU2NvcGU7IC8vZXNsaW50LWRpc2FibGUtbGluZVxuXG4vKipcbiAqIEltYWdlLnByb3RvdHlwZS5kZWNvZGUoKSBpcyBzdXBwb3J0ZWQuXG4gKiBAdHlwZSB7Ym9vbGVhbn1cbiAqL1xuXG5leHBvcnQgdmFyIElNQUdFX0RFQ09ERSA9IHR5cGVvZiBJbWFnZSAhPT0gJ3VuZGVmaW5lZCcgJiYgSW1hZ2UucHJvdG90eXBlLmRlY29kZTtcbi8qKlxuICogQHR5cGUge2Jvb2xlYW59XG4gKi9cblxuZXhwb3J0IHZhciBQQVNTSVZFX0VWRU5UX0xJU1RFTkVSUyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHBhc3NpdmUgPSBmYWxzZTtcblxuICB0cnkge1xuICAgIHZhciBvcHRpb25zID0gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAncGFzc2l2ZScsIHtcbiAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICBwYXNzaXZlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignXycsIG51bGwsIG9wdGlvbnMpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdfJywgbnVsbCwgb3B0aW9ucyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7Ly8gcGFzc2l2ZSBub3Qgc3VwcG9ydGVkXG4gIH1cblxuICByZXR1cm4gcGFzc2l2ZTtcbn0oKTsiLCJpbXBvcnQgeyBXT1JLRVJfT0ZGU0NSRUVOX0NBTlZBUyB9IGZyb20gJy4vaGFzLmpzJztcbi8qKlxuICogQG1vZHVsZSBvbC9kb21cbiAqL1xuLy9GSVhNRSBNb3ZlIHRoaXMgZnVuY3Rpb24gdG8gdGhlIGNhbnZhcyBtb2R1bGVcblxuLyoqXG4gKiBDcmVhdGUgYW4gaHRtbCBjYW52YXMgZWxlbWVudCBhbmQgcmV0dXJucyBpdHMgMmQgY29udGV4dC5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3dpZHRoIENhbnZhcyB3aWR0aC5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2hlaWdodCBDYW52YXMgaGVpZ2h0LlxuICogQHBhcmFtIHtBcnJheTxIVE1MQ2FudmFzRWxlbWVudD49fSBvcHRfY2FudmFzUG9vbCBDYW52YXMgcG9vbCB0byB0YWtlIGV4aXN0aW5nIGNhbnZhcyBmcm9tLlxuICogQHJldHVybiB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBUaGUgY29udGV4dC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2FudmFzQ29udGV4dDJEKG9wdF93aWR0aCwgb3B0X2hlaWdodCwgb3B0X2NhbnZhc1Bvb2wpIHtcbiAgdmFyIGNhbnZhcyA9IG9wdF9jYW52YXNQb29sICYmIG9wdF9jYW52YXNQb29sLmxlbmd0aCA/IG9wdF9jYW52YXNQb29sLnNoaWZ0KCkgOiBXT1JLRVJfT0ZGU0NSRUVOX0NBTlZBUyA/IG5ldyBPZmZzY3JlZW5DYW52YXMob3B0X3dpZHRoIHx8IDMwMCwgb3B0X2hlaWdodCB8fCAzMDApIDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG5cbiAgaWYgKG9wdF93aWR0aCkge1xuICAgIGNhbnZhcy53aWR0aCA9IG9wdF93aWR0aDtcbiAgfVxuXG4gIGlmIChvcHRfaGVpZ2h0KSB7XG4gICAgY2FudmFzLmhlaWdodCA9IG9wdF9oZWlnaHQ7XG4gIH0gLy9GSVhNRSBBbGxvdyBPZmZzY3JlZW5DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQgYXMgcmV0dXJuIHR5cGVcblxuXG4gIHJldHVybiAoXG4gICAgLyoqIEB0eXBlIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9ICovXG4gICAgY2FudmFzLmdldENvbnRleHQoJzJkJylcbiAgKTtcbn1cbi8qKlxuICogR2V0IHRoZSBjdXJyZW50IGNvbXB1dGVkIHdpZHRoIGZvciB0aGUgZ2l2ZW4gZWxlbWVudCBpbmNsdWRpbmcgbWFyZ2luLFxuICogcGFkZGluZyBhbmQgYm9yZGVyLlxuICogRXF1aXZhbGVudCB0byBqUXVlcnkncyBgJChlbCkub3V0ZXJXaWR0aCh0cnVlKWAuXG4gKiBAcGFyYW0geyFIVE1MRWxlbWVudH0gZWxlbWVudCBFbGVtZW50LlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgd2lkdGguXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG91dGVyV2lkdGgoZWxlbWVudCkge1xuICB2YXIgd2lkdGggPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xuICB2YXIgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICB3aWR0aCArPSBwYXJzZUludChzdHlsZS5tYXJnaW5MZWZ0LCAxMCkgKyBwYXJzZUludChzdHlsZS5tYXJnaW5SaWdodCwgMTApO1xuICByZXR1cm4gd2lkdGg7XG59XG4vKipcbiAqIEdldCB0aGUgY3VycmVudCBjb21wdXRlZCBoZWlnaHQgZm9yIHRoZSBnaXZlbiBlbGVtZW50IGluY2x1ZGluZyBtYXJnaW4sXG4gKiBwYWRkaW5nIGFuZCBib3JkZXIuXG4gKiBFcXVpdmFsZW50IHRvIGpRdWVyeSdzIGAkKGVsKS5vdXRlckhlaWdodCh0cnVlKWAuXG4gKiBAcGFyYW0geyFIVE1MRWxlbWVudH0gZWxlbWVudCBFbGVtZW50LlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgaGVpZ2h0LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBvdXRlckhlaWdodChlbGVtZW50KSB7XG4gIHZhciBoZWlnaHQgPSBlbGVtZW50Lm9mZnNldEhlaWdodDtcbiAgdmFyIHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbiAgaGVpZ2h0ICs9IHBhcnNlSW50KHN0eWxlLm1hcmdpblRvcCwgMTApICsgcGFyc2VJbnQoc3R5bGUubWFyZ2luQm90dG9tLCAxMCk7XG4gIHJldHVybiBoZWlnaHQ7XG59XG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbmV3Tm9kZSBOb2RlIHRvIHJlcGxhY2Ugb2xkIG5vZGVcbiAqIEBwYXJhbSB7Tm9kZX0gb2xkTm9kZSBUaGUgbm9kZSB0byBiZSByZXBsYWNlZFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByZXBsYWNlTm9kZShuZXdOb2RlLCBvbGROb2RlKSB7XG4gIHZhciBwYXJlbnQgPSBvbGROb2RlLnBhcmVudE5vZGU7XG5cbiAgaWYgKHBhcmVudCkge1xuICAgIHBhcmVudC5yZXBsYWNlQ2hpbGQobmV3Tm9kZSwgb2xkTm9kZSk7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlIFRoZSBub2RlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtOb2RlfSBUaGUgbm9kZSB0aGF0IHdhcyByZW1vdmVkIG9yIG51bGwuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZU5vZGUobm9kZSkge1xuICByZXR1cm4gbm9kZSAmJiBub2RlLnBhcmVudE5vZGUgPyBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSkgOiBudWxsO1xufVxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgVGhlIG5vZGUgdG8gcmVtb3ZlIHRoZSBjaGlsZHJlbiBmcm9tLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVDaGlsZHJlbihub2RlKSB7XG4gIHdoaWxlIChub2RlLmxhc3RDaGlsZCkge1xuICAgIG5vZGUucmVtb3ZlQ2hpbGQobm9kZS5sYXN0Q2hpbGQpO1xuICB9XG59XG4vKipcbiAqIFRyYW5zZm9ybSB0aGUgY2hpbGRyZW4gb2YgYSBwYXJlbnQgbm9kZSBzbyB0aGV5IG1hdGNoIHRoZVxuICogcHJvdmlkZWQgbGlzdCBvZiBjaGlsZHJlbi4gIFRoaXMgZnVuY3Rpb24gYWltcyB0byBlZmZpY2llbnRseVxuICogcmVtb3ZlLCBhZGQsIGFuZCByZW9yZGVyIGNoaWxkIG5vZGVzIHdoaWxlIG1haW50YWluaW5nIGEgc2ltcGxlXG4gKiBpbXBsZW1lbnRhdGlvbiAoaXQgaXMgbm90IGd1YXJhbnRlZWQgdG8gbWluaW1pemUgRE9NIG9wZXJhdGlvbnMpLlxuICogQHBhcmFtIHtOb2RlfSBub2RlIFRoZSBwYXJlbnQgbm9kZSB3aG9zZSBjaGlsZHJlbiBuZWVkIHJld29ya2luZy5cbiAqIEBwYXJhbSB7QXJyYXk8Tm9kZT59IGNoaWxkcmVuIFRoZSBkZXNpcmVkIGNoaWxkcmVuLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByZXBsYWNlQ2hpbGRyZW4obm9kZSwgY2hpbGRyZW4pIHtcbiAgdmFyIG9sZENoaWxkcmVuID0gbm9kZS5jaGlsZE5vZGVzO1xuXG4gIGZvciAodmFyIGkgPSAwOyB0cnVlOyArK2kpIHtcbiAgICB2YXIgb2xkQ2hpbGQgPSBvbGRDaGlsZHJlbltpXTtcbiAgICB2YXIgbmV3Q2hpbGQgPSBjaGlsZHJlbltpXTsgLy8gY2hlY2sgaWYgb3VyIHdvcmsgaXMgZG9uZVxuXG4gICAgaWYgKCFvbGRDaGlsZCAmJiAhbmV3Q2hpbGQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gLy8gY2hlY2sgaWYgY2hpbGRyZW4gbWF0Y2hcblxuXG4gICAgaWYgKG9sZENoaWxkID09PSBuZXdDaGlsZCkge1xuICAgICAgY29udGludWU7XG4gICAgfSAvLyBjaGVjayBpZiBhIG5ldyBjaGlsZCBuZWVkcyB0byBiZSBhZGRlZFxuXG5cbiAgICBpZiAoIW9sZENoaWxkKSB7XG4gICAgICBub2RlLmFwcGVuZENoaWxkKG5ld0NoaWxkKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gLy8gY2hlY2sgaWYgYW4gb2xkIGNoaWxkIG5lZWRzIHRvIGJlIHJlbW92ZWRcblxuXG4gICAgaWYgKCFuZXdDaGlsZCkge1xuICAgICAgbm9kZS5yZW1vdmVDaGlsZChvbGRDaGlsZCk7XG4gICAgICAtLWk7XG4gICAgICBjb250aW51ZTtcbiAgICB9IC8vIHJlb3JkZXJcblxuXG4gICAgbm9kZS5pbnNlcnRCZWZvcmUobmV3Q2hpbGQsIG9sZENoaWxkKTtcbiAgfVxufSIsIi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXIvY2FudmFzXG4gKi9cbmltcG9ydCBCYXNlT2JqZWN0IGZyb20gJy4uL09iamVjdC5qcyc7XG5pbXBvcnQgRXZlbnRUYXJnZXQgZnJvbSAnLi4vZXZlbnRzL1RhcmdldC5qcyc7XG5pbXBvcnQgeyBXT1JLRVJfT0ZGU0NSRUVOX0NBTlZBUyB9IGZyb20gJy4uL2hhcy5qcyc7XG5pbXBvcnQgeyBjbGVhciB9IGZyb20gJy4uL29iai5qcyc7XG5pbXBvcnQgeyBjcmVhdGVDYW52YXNDb250ZXh0MkQgfSBmcm9tICcuLi9kb20uanMnO1xuaW1wb3J0IHsgZ2V0Rm9udFBhcmFtZXRlcnMgfSBmcm9tICcuLi9jc3MuanMnO1xuaW1wb3J0IHsgdG9TdHJpbmcgfSBmcm9tICcuLi90cmFuc2Zvcm0uanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBGaWxsU3RhdGVcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gZmlsbFN0eWxlXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiBMYWJlbFxuICogQHByb3BlcnR5IHtudW1iZXJ9IHdpZHRoXG4gKiBAcHJvcGVydHkge251bWJlcn0gaGVpZ2h0XG4gKiBAcHJvcGVydHkge0FycmF5PHN0cmluZ3xudW1iZXI+fSBjb250ZXh0SW5zdHJ1Y3Rpb25zXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBGaWxsU3Ryb2tlU3RhdGVcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gW2N1cnJlbnRGaWxsU3R5bGVdXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9IFtjdXJyZW50U3Ryb2tlU3R5bGVdXG4gKiBAcHJvcGVydHkge0NhbnZhc0xpbmVDYXB9IFtjdXJyZW50TGluZUNhcF1cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gY3VycmVudExpbmVEYXNoXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2N1cnJlbnRMaW5lRGFzaE9mZnNldF1cbiAqIEBwcm9wZXJ0eSB7Q2FudmFzTGluZUpvaW59IFtjdXJyZW50TGluZUpvaW5dXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2N1cnJlbnRMaW5lV2lkdGhdXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2N1cnJlbnRNaXRlckxpbWl0XVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtsYXN0U3Ryb2tlXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9jb2xvcmxpa2UuanNcIikuQ29sb3JMaWtlfSBbZmlsbFN0eWxlXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9jb2xvcmxpa2UuanNcIikuQ29sb3JMaWtlfSBbc3Ryb2tlU3R5bGVdXG4gKiBAcHJvcGVydHkge0NhbnZhc0xpbmVDYXB9IFtsaW5lQ2FwXVxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBsaW5lRGFzaFxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtsaW5lRGFzaE9mZnNldF1cbiAqIEBwcm9wZXJ0eSB7Q2FudmFzTGluZUpvaW59IFtsaW5lSm9pbl1cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbGluZVdpZHRoXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaXRlckxpbWl0XVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gU3Ryb2tlU3RhdGVcbiAqIEBwcm9wZXJ0eSB7Q2FudmFzTGluZUNhcH0gbGluZUNhcFxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBsaW5lRGFzaFxuICogQHByb3BlcnR5IHtudW1iZXJ9IGxpbmVEYXNoT2Zmc2V0XG4gKiBAcHJvcGVydHkge0NhbnZhc0xpbmVKb2lufSBsaW5lSm9pblxuICogQHByb3BlcnR5IHtudW1iZXJ9IGxpbmVXaWR0aFxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1pdGVyTGltaXRcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gc3Ryb2tlU3R5bGVcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFRleHRTdGF0ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGZvbnRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdGV4dEFsaWduXVxuICogQHByb3BlcnR5IHtzdHJpbmd9IHRleHRCYXNlbGluZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtwbGFjZW1lbnRdXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heEFuZ2xlXVxuICogQHByb3BlcnR5IHtib29sZWFufSBbb3ZlcmZsb3ddXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3N0eWxlL0ZpbGwuanNcIikuZGVmYXVsdH0gW2JhY2tncm91bmRGaWxsXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zdHlsZS9TdHJva2UuanNcIikuZGVmYXVsdH0gW2JhY2tncm91bmRTdHJva2VdXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gW3NjYWxlXVxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBbcGFkZGluZ11cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFNlcmlhbGl6YWJsZUluc3RydWN0aW9uc1xuICogQHByb3BlcnR5IHtBcnJheTwqPn0gaW5zdHJ1Y3Rpb25zIFRoZSByZW5kZXJpbmcgaW5zdHJ1Y3Rpb25zLlxuICogQHByb3BlcnR5IHtBcnJheTwqPn0gaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zIFRoZSByZW5kZXJpbmcgaGl0IGRldGVjdGlvbiBpbnN0cnVjdGlvbnMuXG4gKiBAcHJvcGVydHkge0FycmF5PG51bWJlcj59IGNvb3JkaW5hdGVzIFRoZSBhcnJheSBvZiBhbGwgY29vcmRpbmF0ZXMuXG4gKiBAcHJvcGVydHkgeyFPYmplY3Q8c3RyaW5nLCBUZXh0U3RhdGU+fSBbdGV4dFN0YXRlc10gVGhlIHRleHQgc3RhdGVzIChkZWNsdXR0ZXJpbmcpLlxuICogQHByb3BlcnR5IHshT2JqZWN0PHN0cmluZywgRmlsbFN0YXRlPn0gW2ZpbGxTdGF0ZXNdIFRoZSBmaWxsIHN0YXRlcyAoZGVjbHV0dGVyaW5nKS5cbiAqIEBwcm9wZXJ0eSB7IU9iamVjdDxzdHJpbmcsIFN0cm9rZVN0YXRlPn0gW3N0cm9rZVN0YXRlc10gVGhlIHN0cm9rZSBzdGF0ZXMgKGRlY2x1dHRlcmluZykuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0PG51bWJlciwgaW1wb3J0KFwiLi9jYW52YXMvRXhlY3V0b3IuanNcIikuUmVwbGF5SW1hZ2VPckxhYmVsQXJncz59IERlY2x1dHRlckltYWdlV2l0aFRleHRcbiAqL1xuXG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuXG5leHBvcnQgdmFyIGRlZmF1bHRGb250ID0gJzEwcHggc2Fucy1zZXJpZic7XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge2ltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9XG4gKi9cblxuZXhwb3J0IHZhciBkZWZhdWx0RmlsbFN0eWxlID0gJyMwMDAnO1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtDYW52YXNMaW5lQ2FwfVxuICovXG5cbmV4cG9ydCB2YXIgZGVmYXVsdExpbmVDYXAgPSAncm91bmQnO1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICovXG5cbmV4cG9ydCB2YXIgZGVmYXVsdExpbmVEYXNoID0gW107XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIGRlZmF1bHRMaW5lRGFzaE9mZnNldCA9IDA7XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge0NhbnZhc0xpbmVKb2lufVxuICovXG5cbmV4cG9ydCB2YXIgZGVmYXVsdExpbmVKb2luID0gJ3JvdW5kJztcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5cbmV4cG9ydCB2YXIgZGVmYXVsdE1pdGVyTGltaXQgPSAxMDtcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX1cbiAqL1xuXG5leHBvcnQgdmFyIGRlZmF1bHRTdHJva2VTdHlsZSA9ICcjMDAwJztcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5cbmV4cG9ydCB2YXIgZGVmYXVsdFRleHRBbGlnbiA9ICdjZW50ZXInO1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cblxuZXhwb3J0IHZhciBkZWZhdWx0VGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gKi9cblxuZXhwb3J0IHZhciBkZWZhdWx0UGFkZGluZyA9IFswLCAwLCAwLCAwXTtcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5cbmV4cG9ydCB2YXIgZGVmYXVsdExpbmVXaWR0aCA9IDE7XG4vKipcbiAqIEB0eXBlIHtCYXNlT2JqZWN0fVxuICovXG5cbmV4cG9ydCB2YXIgY2hlY2tlZEZvbnRzID0gbmV3IEJhc2VPYmplY3QoKTtcbi8qKlxuICogVGhlIGxhYmVsIGNhY2hlIGZvciB0ZXh0IHJlbmRlcmluZy4gVG8gY2hhbmdlIHRoZSBkZWZhdWx0IGNhY2hlIHNpemUgb2YgMjA0OFxuICogZW50cmllcywgdXNlIHtAbGluayBtb2R1bGU6b2wvc3RydWN0cy9MUlVDYWNoZSNzZXRTaXplfS5cbiAqIERlcHJlY2F0ZWQgLSB0aGVyZSBpcyBubyBsYWJlbCBjYWNoZSBhbnkgbW9yZS5cbiAqIEB0eXBlIHs/fVxuICogQGFwaVxuICogQGRlcHJlY2F0ZWRcbiAqL1xuXG5leHBvcnQgdmFyIGxhYmVsQ2FjaGUgPSBuZXcgRXZlbnRUYXJnZXQoKTtcblxubGFiZWxDYWNoZS5zZXRTaXplID0gZnVuY3Rpb24gKCkge1xuICBjb25zb2xlLndhcm4oJ2xhYmVsQ2FjaGUgaXMgZGVwcmVjYXRlZC4nKTsgLy9lc2xpbnQtZGlzYWJsZS1saW5lXG59O1xuLyoqXG4gKiBAdHlwZSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfVxuICovXG5cblxudmFyIG1lYXN1cmVDb250ZXh0ID0gbnVsbDtcbi8qKlxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuXG52YXIgbWVhc3VyZUZvbnQ7XG4vKipcbiAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgbnVtYmVyPn1cbiAqL1xuXG5leHBvcnQgdmFyIHRleHRIZWlnaHRzID0ge307XG4vKipcbiAqIENsZWFycyB0aGUgbGFiZWwgY2FjaGUgd2hlbiBhIGZvbnQgYmVjb21lcyBhdmFpbGFibGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZm9udFNwZWMgQ1NTIGZvbnQgc3BlYy5cbiAqL1xuXG5leHBvcnQgdmFyIHJlZ2lzdGVyRm9udCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHJldHJpZXMgPSAxMDA7XG4gIHZhciBzaXplID0gJzMycHggJztcbiAgdmFyIHJlZmVyZW5jZUZvbnRzID0gWydtb25vc3BhY2UnLCAnc2VyaWYnXTtcbiAgdmFyIGxlbiA9IHJlZmVyZW5jZUZvbnRzLmxlbmd0aDtcbiAgdmFyIHRleHQgPSBcIndteXR6aWxXTVlUWklMQCMvJj8kJTEwXFx1RjAxM1wiO1xuICB2YXIgaW50ZXJ2YWwsIHJlZmVyZW5jZVdpZHRoO1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZvbnRTdHlsZSBDc3MgZm9udC1zdHlsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZm9udFdlaWdodCBDc3MgZm9udC13ZWlnaHRcbiAgICogQHBhcmFtIHsqfSBmb250RmFtaWx5IENzcyBmb250LWZhbWlseVxuICAgKiBAcmV0dXJuIHtib29sZWFufSBGb250IHdpdGggc3R5bGUgYW5kIHdlaWdodCBpcyBhdmFpbGFibGVcbiAgICovXG5cbiAgZnVuY3Rpb24gaXNBdmFpbGFibGUoZm9udFN0eWxlLCBmb250V2VpZ2h0LCBmb250RmFtaWx5KSB7XG4gICAgdmFyIGF2YWlsYWJsZSA9IHRydWU7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICB2YXIgcmVmZXJlbmNlRm9udCA9IHJlZmVyZW5jZUZvbnRzW2ldO1xuICAgICAgcmVmZXJlbmNlV2lkdGggPSBtZWFzdXJlVGV4dFdpZHRoKGZvbnRTdHlsZSArICcgJyArIGZvbnRXZWlnaHQgKyAnICcgKyBzaXplICsgcmVmZXJlbmNlRm9udCwgdGV4dCk7XG5cbiAgICAgIGlmIChmb250RmFtaWx5ICE9IHJlZmVyZW5jZUZvbnQpIHtcbiAgICAgICAgdmFyIHdpZHRoID0gbWVhc3VyZVRleHRXaWR0aChmb250U3R5bGUgKyAnICcgKyBmb250V2VpZ2h0ICsgJyAnICsgc2l6ZSArIGZvbnRGYW1pbHkgKyAnLCcgKyByZWZlcmVuY2VGb250LCB0ZXh0KTsgLy8gSWYgd2lkdGggYW5kIHJlZmVyZW5jZVdpZHRoIGFyZSB0aGUgc2FtZSwgdGhlbiB0aGUgZmFsbGJhY2sgd2FzIHVzZWRcbiAgICAgICAgLy8gaW5zdGVhZCBvZiB0aGUgZm9udCB3ZSB3YW50ZWQsIHNvIHRoZSBmb250IGlzIG5vdCBhdmFpbGFibGUuXG5cbiAgICAgICAgYXZhaWxhYmxlID0gYXZhaWxhYmxlICYmIHdpZHRoICE9IHJlZmVyZW5jZVdpZHRoO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChhdmFpbGFibGUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNoZWNrKCkge1xuICAgIHZhciBkb25lID0gdHJ1ZTtcbiAgICB2YXIgZm9udHMgPSBjaGVja2VkRm9udHMuZ2V0S2V5cygpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZm9udHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdmFyIGZvbnQgPSBmb250c1tpXTtcblxuICAgICAgaWYgKGNoZWNrZWRGb250cy5nZXQoZm9udCkgPCByZXRyaWVzKSB7XG4gICAgICAgIGlmIChpc0F2YWlsYWJsZS5hcHBseSh0aGlzLCBmb250LnNwbGl0KCdcXG4nKSkpIHtcbiAgICAgICAgICBjbGVhcih0ZXh0SGVpZ2h0cyk7IC8vIE1ha2Ugc3VyZSB0aGF0IGxvYWRlZCBmb250cyBhcmUgcGlja2VkIHVwIGJ5IFNhZmFyaVxuXG4gICAgICAgICAgbWVhc3VyZUNvbnRleHQgPSBudWxsO1xuICAgICAgICAgIG1lYXN1cmVGb250ID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGNoZWNrZWRGb250cy5zZXQoZm9udCwgcmV0cmllcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2hlY2tlZEZvbnRzLnNldChmb250LCBjaGVja2VkRm9udHMuZ2V0KGZvbnQpICsgMSwgdHJ1ZSk7XG4gICAgICAgICAgZG9uZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRvbmUpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgaW50ZXJ2YWwgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChmb250U3BlYykge1xuICAgIHZhciBmb250ID0gZ2V0Rm9udFBhcmFtZXRlcnMoZm9udFNwZWMpO1xuXG4gICAgaWYgKCFmb250KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGZhbWlsaWVzID0gZm9udC5mYW1pbGllcztcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZhbWlsaWVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBmYW1pbHkgPSBmYW1pbGllc1tpXTtcbiAgICAgIHZhciBrZXkgPSBmb250LnN0eWxlICsgJ1xcbicgKyBmb250LndlaWdodCArICdcXG4nICsgZmFtaWx5O1xuXG4gICAgICBpZiAoY2hlY2tlZEZvbnRzLmdldChrZXkpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2hlY2tlZEZvbnRzLnNldChrZXksIHJldHJpZXMsIHRydWUpO1xuXG4gICAgICAgIGlmICghaXNBdmFpbGFibGUoZm9udC5zdHlsZSwgZm9udC53ZWlnaHQsIGZhbWlseSkpIHtcbiAgICAgICAgICBjaGVja2VkRm9udHMuc2V0KGtleSwgMCwgdHJ1ZSk7XG5cbiAgICAgICAgICBpZiAoaW50ZXJ2YWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChjaGVjaywgMzIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcbn0oKTtcbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGZvbnQgRm9udCB0byB1c2UgZm9yIG1lYXN1cmluZy5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gTWVhc3VyZW1lbnQuXG4gKi9cblxuZXhwb3J0IHZhciBtZWFzdXJlVGV4dEhlaWdodCA9IGZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEB0eXBlIHtIVE1MRGl2RWxlbWVudH1cbiAgICovXG4gIHZhciBkaXY7XG4gIHJldHVybiBmdW5jdGlvbiAoZm9udFNwZWMpIHtcbiAgICB2YXIgaGVpZ2h0ID0gdGV4dEhlaWdodHNbZm9udFNwZWNdO1xuXG4gICAgaWYgKGhlaWdodCA9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChXT1JLRVJfT0ZGU0NSRUVOX0NBTlZBUykge1xuICAgICAgICB2YXIgZm9udCA9IGdldEZvbnRQYXJhbWV0ZXJzKGZvbnRTcGVjKTtcbiAgICAgICAgdmFyIG1ldHJpY3MgPSBtZWFzdXJlVGV4dChmb250U3BlYywgJ8W9ZycpO1xuICAgICAgICB2YXIgbGluZUhlaWdodCA9IGlzTmFOKE51bWJlcihmb250LmxpbmVIZWlnaHQpKSA/IDEuMiA6IE51bWJlcihmb250LmxpbmVIZWlnaHQpO1xuICAgICAgICBoZWlnaHQgPSBsaW5lSGVpZ2h0ICogKG1ldHJpY3MuYWN0dWFsQm91bmRpbmdCb3hBc2NlbnQgKyBtZXRyaWNzLmFjdHVhbEJvdW5kaW5nQm94RGVzY2VudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIWRpdikge1xuICAgICAgICAgIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgIGRpdi5pbm5lckhUTUwgPSAnTSc7XG4gICAgICAgICAgZGl2LnN0eWxlLm1hcmdpbiA9ICcwICFpbXBvcnRhbnQnO1xuICAgICAgICAgIGRpdi5zdHlsZS5wYWRkaW5nID0gJzAgIWltcG9ydGFudCc7XG4gICAgICAgICAgZGl2LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlICFpbXBvcnRhbnQnO1xuICAgICAgICAgIGRpdi5zdHlsZS5sZWZ0ID0gJy05OTk5OXB4ICFpbXBvcnRhbnQnO1xuICAgICAgICB9XG5cbiAgICAgICAgZGl2LnN0eWxlLmZvbnQgPSBmb250U3BlYztcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkaXYpO1xuICAgICAgICBoZWlnaHQgPSBkaXYub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGRpdik7XG4gICAgICB9XG5cbiAgICAgIHRleHRIZWlnaHRzW2ZvbnRTcGVjXSA9IGhlaWdodDtcbiAgICB9XG5cbiAgICByZXR1cm4gaGVpZ2h0O1xuICB9O1xufSgpO1xuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gZm9udCBGb250LlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGV4dC5cbiAqIEByZXR1cm4ge1RleHRNZXRyaWNzfSBUZXh0IG1ldHJpY3MuXG4gKi9cblxuZnVuY3Rpb24gbWVhc3VyZVRleHQoZm9udCwgdGV4dCkge1xuICBpZiAoIW1lYXN1cmVDb250ZXh0KSB7XG4gICAgbWVhc3VyZUNvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0MkQoMSwgMSk7XG4gIH1cblxuICBpZiAoZm9udCAhPSBtZWFzdXJlRm9udCkge1xuICAgIG1lYXN1cmVDb250ZXh0LmZvbnQgPSBmb250O1xuICAgIG1lYXN1cmVGb250ID0gbWVhc3VyZUNvbnRleHQuZm9udDtcbiAgfVxuXG4gIHJldHVybiBtZWFzdXJlQ29udGV4dC5tZWFzdXJlVGV4dCh0ZXh0KTtcbn1cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGZvbnQgRm9udC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRleHQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFdpZHRoLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIG1lYXN1cmVUZXh0V2lkdGgoZm9udCwgdGV4dCkge1xuICByZXR1cm4gbWVhc3VyZVRleHQoZm9udCwgdGV4dCkud2lkdGg7XG59XG4vKipcbiAqIE1lYXN1cmUgdGV4dCB3aWR0aCB1c2luZyBhIGNhY2hlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZvbnQgVGhlIGZvbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCBUaGUgdGV4dCB0byBtZWFzdXJlLlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCBudW1iZXI+fSBjYWNoZSBBIGxvb2t1cCBvZiBjYWNoZWQgd2lkdGhzIGJ5IHRleHQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgdGV4dCB3aWR0aC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbWVhc3VyZUFuZENhY2hlVGV4dFdpZHRoKGZvbnQsIHRleHQsIGNhY2hlKSB7XG4gIGlmICh0ZXh0IGluIGNhY2hlKSB7XG4gICAgcmV0dXJuIGNhY2hlW3RleHRdO1xuICB9XG5cbiAgdmFyIHdpZHRoID0gbWVhc3VyZVRleHRXaWR0aChmb250LCB0ZXh0KTtcbiAgY2FjaGVbdGV4dF0gPSB3aWR0aDtcbiAgcmV0dXJuIHdpZHRoO1xufVxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gZm9udCBGb250IHRvIHVzZSBmb3IgbWVhc3VyaW5nLlxuICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSBsaW5lcyBMaW5lcyB0byBtZWFzdXJlLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSB3aWR0aHMgQXJyYXkgd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCB0aGUgd2lkdGhzIG9mXG4gKiBlYWNoIGxpbmUuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFdpZHRoIG9mIHRoZSB3aG9sZSB0ZXh0LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtZWFzdXJlVGV4dFdpZHRocyhmb250LCBsaW5lcywgd2lkdGhzKSB7XG4gIHZhciBudW1MaW5lcyA9IGxpbmVzLmxlbmd0aDtcbiAgdmFyIHdpZHRoID0gMDtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IG51bUxpbmVzOyArK2kpIHtcbiAgICB2YXIgY3VycmVudFdpZHRoID0gbWVhc3VyZVRleHRXaWR0aChmb250LCBsaW5lc1tpXSk7XG4gICAgd2lkdGggPSBNYXRoLm1heCh3aWR0aCwgY3VycmVudFdpZHRoKTtcbiAgICB3aWR0aHMucHVzaChjdXJyZW50V2lkdGgpO1xuICB9XG5cbiAgcmV0dXJuIHdpZHRoO1xufVxuLyoqXG4gKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFggWCBvZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0WSBZIG9mZnNldC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlQXRPZmZzZXQoY29udGV4dCwgcm90YXRpb24sIG9mZnNldFgsIG9mZnNldFkpIHtcbiAgaWYgKHJvdGF0aW9uICE9PSAwKSB7XG4gICAgY29udGV4dC50cmFuc2xhdGUob2Zmc2V0WCwgb2Zmc2V0WSk7XG4gICAgY29udGV4dC5yb3RhdGUocm90YXRpb24pO1xuICAgIGNvbnRleHQudHJhbnNsYXRlKC1vZmZzZXRYLCAtb2Zmc2V0WSk7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybXxudWxsfSB0cmFuc2Zvcm0gVHJhbnNmb3JtLlxuICogQHBhcmFtIHtudW1iZXJ9IG9wYWNpdHkgT3BhY2l0eS5cbiAqIEBwYXJhbSB7TGFiZWx8SFRNTENhbnZhc0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fSBsYWJlbE9ySW1hZ2UgTGFiZWwuXG4gKiBAcGFyYW0ge251bWJlcn0gb3JpZ2luWCBPcmlnaW4gWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvcmlnaW5ZIE9yaWdpbiBZLlxuICogQHBhcmFtIHtudW1iZXJ9IHcgV2lkdGguXG4gKiBAcGFyYW0ge251bWJlcn0gaCBIZWlnaHQuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBzY2FsZSBTY2FsZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZHJhd0ltYWdlT3JMYWJlbChjb250ZXh0LCB0cmFuc2Zvcm0sIG9wYWNpdHksIGxhYmVsT3JJbWFnZSwgb3JpZ2luWCwgb3JpZ2luWSwgdywgaCwgeCwgeSwgc2NhbGUpIHtcbiAgY29udGV4dC5zYXZlKCk7XG5cbiAgaWYgKG9wYWNpdHkgIT09IDEpIHtcbiAgICBjb250ZXh0Lmdsb2JhbEFscGhhICo9IG9wYWNpdHk7XG4gIH1cblxuICBpZiAodHJhbnNmb3JtKSB7XG4gICAgY29udGV4dC5zZXRUcmFuc2Zvcm0uYXBwbHkoY29udGV4dCwgdHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlmIChcbiAgLyoqIEB0eXBlIHsqfSAqL1xuICBsYWJlbE9ySW1hZ2UuY29udGV4dEluc3RydWN0aW9ucykge1xuICAgIC8vIGxhYmVsXG4gICAgY29udGV4dC50cmFuc2xhdGUoeCwgeSk7XG4gICAgY29udGV4dC5zY2FsZShzY2FsZVswXSwgc2NhbGVbMV0pO1xuICAgIGV4ZWN1dGVMYWJlbEluc3RydWN0aW9ucyhcbiAgICAvKiogQHR5cGUge0xhYmVsfSAqL1xuICAgIGxhYmVsT3JJbWFnZSwgY29udGV4dCk7XG4gIH0gZWxzZSBpZiAoc2NhbGVbMF0gPCAwIHx8IHNjYWxlWzFdIDwgMCkge1xuICAgIC8vIGZsaXBwZWQgaW1hZ2VcbiAgICBjb250ZXh0LnRyYW5zbGF0ZSh4LCB5KTtcbiAgICBjb250ZXh0LnNjYWxlKHNjYWxlWzBdLCBzY2FsZVsxXSk7XG4gICAgY29udGV4dC5kcmF3SW1hZ2UoXG4gICAgLyoqIEB0eXBlIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR9ICovXG4gICAgbGFiZWxPckltYWdlLCBvcmlnaW5YLCBvcmlnaW5ZLCB3LCBoLCAwLCAwLCB3LCBoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBpZiBpbWFnZSBub3QgZmxpcHBlZCB0cmFuc2xhdGUgYW5kIHNjYWxlIGNhbiBiZSBhdm9pZGVkXG4gICAgY29udGV4dC5kcmF3SW1hZ2UoXG4gICAgLyoqIEB0eXBlIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR9ICovXG4gICAgbGFiZWxPckltYWdlLCBvcmlnaW5YLCBvcmlnaW5ZLCB3LCBoLCB4LCB5LCB3ICogc2NhbGVbMF0sIGggKiBzY2FsZVsxXSk7XG4gIH1cblxuICBjb250ZXh0LnJlc3RvcmUoKTtcbn1cbi8qKlxuICogQHBhcmFtIHtMYWJlbH0gbGFiZWwgTGFiZWwuXG4gKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICovXG5cbmZ1bmN0aW9uIGV4ZWN1dGVMYWJlbEluc3RydWN0aW9ucyhsYWJlbCwgY29udGV4dCkge1xuICB2YXIgY29udGV4dEluc3RydWN0aW9ucyA9IGxhYmVsLmNvbnRleHRJbnN0cnVjdGlvbnM7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gY29udGV4dEluc3RydWN0aW9ucy5sZW5ndGg7IGkgPCBpaTsgaSArPSAyKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoY29udGV4dEluc3RydWN0aW9uc1tpICsgMV0pKSB7XG4gICAgICBjb250ZXh0W2NvbnRleHRJbnN0cnVjdGlvbnNbaV1dLmFwcGx5KGNvbnRleHQsIGNvbnRleHRJbnN0cnVjdGlvbnNbaSArIDFdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dFtjb250ZXh0SW5zdHJ1Y3Rpb25zW2ldXSA9IGNvbnRleHRJbnN0cnVjdGlvbnNbaSArIDFdO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAdHlwZSB7SFRNTENhbnZhc0VsZW1lbnR9XG4gKiBAcHJpdmF0ZVxuICovXG5cblxudmFyIGNyZWF0ZVRyYW5zZm9ybVN0cmluZ0NhbnZhcyA9IG51bGw7XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAqIEByZXR1cm4ge3N0cmluZ30gQ1NTIHRyYW5zZm9ybS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVHJhbnNmb3JtU3RyaW5nKHRyYW5zZm9ybSkge1xuICBpZiAoV09SS0VSX09GRlNDUkVFTl9DQU5WQVMpIHtcbiAgICByZXR1cm4gdG9TdHJpbmcodHJhbnNmb3JtKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoIWNyZWF0ZVRyYW5zZm9ybVN0cmluZ0NhbnZhcykge1xuICAgICAgY3JlYXRlVHJhbnNmb3JtU3RyaW5nQ2FudmFzID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKDEsIDEpLmNhbnZhcztcbiAgICB9XG5cbiAgICBjcmVhdGVUcmFuc2Zvcm1TdHJpbmdDYW52YXMuc3R5bGUudHJhbnNmb3JtID0gdG9TdHJpbmcodHJhbnNmb3JtKTtcbiAgICByZXR1cm4gY3JlYXRlVHJhbnNmb3JtU3RyaW5nQ2FudmFzLnN0eWxlLnRyYW5zZm9ybTtcbiAgfVxufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyZXIvQ29tcG9zaXRlXG4gKi9cblxuXG5pbXBvcnQgTWFwUmVuZGVyZXIgZnJvbSAnLi9NYXAuanMnO1xuaW1wb3J0IE9iamVjdEV2ZW50VHlwZSBmcm9tICcuLi9PYmplY3RFdmVudFR5cGUuanMnO1xuaW1wb3J0IFJlbmRlckV2ZW50IGZyb20gJy4uL3JlbmRlci9FdmVudC5qcyc7XG5pbXBvcnQgUmVuZGVyRXZlbnRUeXBlIGZyb20gJy4uL3JlbmRlci9FdmVudFR5cGUuanMnO1xuaW1wb3J0IFNvdXJjZVN0YXRlIGZyb20gJy4uL3NvdXJjZS9TdGF0ZS5qcyc7XG5pbXBvcnQgeyBDTEFTU19VTlNFTEVDVEFCTEUgfSBmcm9tICcuLi9jc3MuanMnO1xuaW1wb3J0IHsgY2hlY2tlZEZvbnRzIH0gZnJvbSAnLi4vcmVuZGVyL2NhbnZhcy5qcyc7XG5pbXBvcnQgeyBpblZpZXcgfSBmcm9tICcuLi9sYXllci9MYXllci5qcyc7XG5pbXBvcnQgeyBsaXN0ZW4sIHVubGlzdGVuQnlLZXkgfSBmcm9tICcuLi9ldmVudHMuanMnO1xuaW1wb3J0IHsgcmVwbGFjZUNoaWxkcmVuIH0gZnJvbSAnLi4vZG9tLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQ2FudmFzIG1hcCByZW5kZXJlci5cbiAqIEBhcGlcbiAqL1xuXG52YXIgQ29tcG9zaXRlTWFwUmVuZGVyZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ29tcG9zaXRlTWFwUmVuZGVyZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fSBtYXAgTWFwLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIENvbXBvc2l0ZU1hcFJlbmRlcmVyKG1hcCkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIG1hcCkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleX1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuZm9udENoYW5nZUxpc3RlbmVyS2V5XyA9IGxpc3RlbihjaGVja2VkRm9udHMsIE9iamVjdEV2ZW50VHlwZS5QUk9QRVJUWUNIQU5HRSwgbWFwLnJlZHJhd1RleHQuYmluZChtYXApKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtIVE1MRGl2RWxlbWVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLmVsZW1lbnRfID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdmFyIHN0eWxlID0gX3RoaXMuZWxlbWVudF8uc3R5bGU7XG4gICAgc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIHN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgIHN0eWxlLmhlaWdodCA9ICcxMDAlJztcbiAgICBzdHlsZS56SW5kZXggPSAnMCc7XG4gICAgX3RoaXMuZWxlbWVudF8uY2xhc3NOYW1lID0gQ0xBU1NfVU5TRUxFQ1RBQkxFICsgJyBvbC1sYXllcnMnO1xuICAgIHZhciBjb250YWluZXIgPSBtYXAuZ2V0Vmlld3BvcnQoKTtcbiAgICBjb250YWluZXIuaW5zZXJ0QmVmb3JlKF90aGlzLmVsZW1lbnRfLCBjb250YWluZXIuZmlyc3RDaGlsZCB8fCBudWxsKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxIVE1MRWxlbWVudD59XG4gICAgICovXG5cbiAgICBfdGhpcy5jaGlsZHJlbl8gPSBbXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRWaXNpYmxlXyA9IHRydWU7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9FdmVudFR5cGUuanNcIikuZGVmYXVsdH0gdHlwZSBFdmVudCB0eXBlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKi9cblxuXG4gIENvbXBvc2l0ZU1hcFJlbmRlcmVyLnByb3RvdHlwZS5kaXNwYXRjaFJlbmRlckV2ZW50ID0gZnVuY3Rpb24gKHR5cGUsIGZyYW1lU3RhdGUpIHtcbiAgICB2YXIgbWFwID0gdGhpcy5nZXRNYXAoKTtcblxuICAgIGlmIChtYXAuaGFzTGlzdGVuZXIodHlwZSkpIHtcbiAgICAgIHZhciBldmVudF8xID0gbmV3IFJlbmRlckV2ZW50KHR5cGUsIHVuZGVmaW5lZCwgZnJhbWVTdGF0ZSk7XG4gICAgICBtYXAuZGlzcGF0Y2hFdmVudChldmVudF8xKTtcbiAgICB9XG4gIH07XG5cbiAgQ29tcG9zaXRlTWFwUmVuZGVyZXIucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB1bmxpc3RlbkJ5S2V5KHRoaXMuZm9udENoYW5nZUxpc3RlbmVyS2V5Xyk7XG4gICAgdGhpcy5lbGVtZW50Xy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudF8pO1xuXG4gICAgX3N1cGVyLnByb3RvdHlwZS5kaXNwb3NlSW50ZXJuYWwuY2FsbCh0aGlzKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlci5cbiAgICogQHBhcmFtIHs/aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqL1xuXG5cbiAgQ29tcG9zaXRlTWFwUmVuZGVyZXIucHJvdG90eXBlLnJlbmRlckZyYW1lID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUpIHtcbiAgICBpZiAoIWZyYW1lU3RhdGUpIHtcbiAgICAgIGlmICh0aGlzLnJlbmRlcmVkVmlzaWJsZV8pIHtcbiAgICAgICAgdGhpcy5lbGVtZW50Xy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICB0aGlzLnJlbmRlcmVkVmlzaWJsZV8gPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuY2FsY3VsYXRlTWF0cmljZXMyRChmcmFtZVN0YXRlKTtcbiAgICB0aGlzLmRpc3BhdGNoUmVuZGVyRXZlbnQoUmVuZGVyRXZlbnRUeXBlLlBSRUNPTVBPU0UsIGZyYW1lU3RhdGUpO1xuICAgIHZhciBsYXllclN0YXRlc0FycmF5ID0gZnJhbWVTdGF0ZS5sYXllclN0YXRlc0FycmF5LnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIHJldHVybiBhLnpJbmRleCAtIGIuekluZGV4O1xuICAgIH0pO1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICB0aGlzLmNoaWxkcmVuXy5sZW5ndGggPSAwO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuLi9sYXllci9CYXNlVmVjdG9yLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqL1xuXG4gICAgdmFyIGRlY2x1dHRlckxheWVycyA9IFtdO1xuICAgIHZhciBwcmV2aW91c0VsZW1lbnQgPSBudWxsO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbGF5ZXJTdGF0ZXNBcnJheS5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgbGF5ZXJTdGF0ZSA9IGxheWVyU3RhdGVzQXJyYXlbaV07XG4gICAgICBmcmFtZVN0YXRlLmxheWVySW5kZXggPSBpO1xuXG4gICAgICBpZiAoIWluVmlldyhsYXllclN0YXRlLCB2aWV3U3RhdGUpIHx8IGxheWVyU3RhdGUuc291cmNlU3RhdGUgIT0gU291cmNlU3RhdGUuUkVBRFkgJiYgbGF5ZXJTdGF0ZS5zb3VyY2VTdGF0ZSAhPSBTb3VyY2VTdGF0ZS5VTkRFRklORUQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBsYXllciA9IGxheWVyU3RhdGUubGF5ZXI7XG4gICAgICB2YXIgZWxlbWVudCA9IGxheWVyLnJlbmRlcihmcmFtZVN0YXRlLCBwcmV2aW91c0VsZW1lbnQpO1xuXG4gICAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChlbGVtZW50ICE9PSBwcmV2aW91c0VsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5jaGlsZHJlbl8ucHVzaChlbGVtZW50KTtcbiAgICAgICAgcHJldmlvdXNFbGVtZW50ID0gZWxlbWVudDtcbiAgICAgIH1cblxuICAgICAgaWYgKCdnZXREZWNsdXR0ZXInIGluIGxheWVyKSB7XG4gICAgICAgIGRlY2x1dHRlckxheWVycy5wdXNoKGxheWVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gZGVjbHV0dGVyTGF5ZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBkZWNsdXR0ZXJMYXllcnNbaV0ucmVuZGVyRGVjbHV0dGVyKGZyYW1lU3RhdGUpO1xuICAgIH1cblxuICAgIHJlcGxhY2VDaGlsZHJlbih0aGlzLmVsZW1lbnRfLCB0aGlzLmNoaWxkcmVuXyk7XG4gICAgdGhpcy5kaXNwYXRjaFJlbmRlckV2ZW50KFJlbmRlckV2ZW50VHlwZS5QT1NUQ09NUE9TRSwgZnJhbWVTdGF0ZSk7XG5cbiAgICBpZiAoIXRoaXMucmVuZGVyZWRWaXNpYmxlXykge1xuICAgICAgdGhpcy5lbGVtZW50Xy5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICB0aGlzLnJlbmRlcmVkVmlzaWJsZV8gPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMuc2NoZWR1bGVFeHBpcmVJY29uQ2FjaGUoZnJhbWVTdGF0ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3BpeGVsLmpzXCIpLlBpeGVsfSBwaXhlbCBQaXhlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZVN0YXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaGl0VG9sZXJhbmNlIEhpdCB0b2xlcmFuY2UgaW4gcGl4ZWxzLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHQsIChVaW50OENsYW1wZWRBcnJheXxVaW50OEFycmF5KSk6IFR9IGNhbGxiYWNrIExheWVyXG4gICAqICAgICBjYWxsYmFjay5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0KTogYm9vbGVhbn0gbGF5ZXJGaWx0ZXIgTGF5ZXIgZmlsdGVyXG4gICAqICAgICBmdW5jdGlvbiwgb25seSBsYXllcnMgd2hpY2ggYXJlIHZpc2libGUgYW5kIGZvciB3aGljaCB0aGlzIGZ1bmN0aW9uXG4gICAqICAgICByZXR1cm5zIGB0cnVlYCB3aWxsIGJlIHRlc3RlZCBmb3IgZmVhdHVyZXMuICBCeSBkZWZhdWx0LCBhbGwgdmlzaWJsZVxuICAgKiAgICAgbGF5ZXJzIHdpbGwgYmUgdGVzdGVkLlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKi9cblxuXG4gIENvbXBvc2l0ZU1hcFJlbmRlcmVyLnByb3RvdHlwZS5mb3JFYWNoTGF5ZXJBdFBpeGVsID0gZnVuY3Rpb24gKHBpeGVsLCBmcmFtZVN0YXRlLCBoaXRUb2xlcmFuY2UsIGNhbGxiYWNrLCBsYXllckZpbHRlcikge1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICB2YXIgbGF5ZXJTdGF0ZXMgPSBmcmFtZVN0YXRlLmxheWVyU3RhdGVzQXJyYXk7XG4gICAgdmFyIG51bUxheWVycyA9IGxheWVyU3RhdGVzLmxlbmd0aDtcblxuICAgIGZvciAodmFyIGkgPSBudW1MYXllcnMgLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdmFyIGxheWVyU3RhdGUgPSBsYXllclN0YXRlc1tpXTtcbiAgICAgIHZhciBsYXllciA9IGxheWVyU3RhdGUubGF5ZXI7XG5cbiAgICAgIGlmIChsYXllci5oYXNSZW5kZXJlcigpICYmIGluVmlldyhsYXllclN0YXRlLCB2aWV3U3RhdGUpICYmIGxheWVyRmlsdGVyKGxheWVyKSkge1xuICAgICAgICB2YXIgbGF5ZXJSZW5kZXJlciA9IGxheWVyLmdldFJlbmRlcmVyKCk7XG4gICAgICAgIHZhciBkYXRhID0gbGF5ZXJSZW5kZXJlci5nZXREYXRhQXRQaXhlbChwaXhlbCwgZnJhbWVTdGF0ZSwgaGl0VG9sZXJhbmNlKTtcblxuICAgICAgICBpZiAoZGF0YSkge1xuICAgICAgICAgIHZhciByZXN1bHQgPSBjYWxsYmFjayhsYXllciwgZGF0YSk7XG5cbiAgICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG5cbiAgcmV0dXJuIENvbXBvc2l0ZU1hcFJlbmRlcmVyO1xufShNYXBSZW5kZXJlcik7XG5cbmV4cG9ydCBkZWZhdWx0IENvbXBvc2l0ZU1hcFJlbmRlcmVyOyIsIi8qKlxuICogQG1vZHVsZSBvbC9Db2xsZWN0aW9uRXZlbnRUeXBlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBhbiBpdGVtIGlzIGFkZGVkIHRvIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL0NvbGxlY3Rpb24uQ29sbGVjdGlvbkV2ZW50I2FkZFxuICAgKiBAYXBpXG4gICAqL1xuICBBREQ6ICdhZGQnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBhbiBpdGVtIGlzIHJlbW92ZWQgZnJvbSB0aGUgY29sbGVjdGlvbi5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9Db2xsZWN0aW9uLkNvbGxlY3Rpb25FdmVudCNyZW1vdmVcbiAgICogQGFwaVxuICAgKi9cbiAgUkVNT1ZFOiAncmVtb3ZlJ1xufTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL0NvbGxlY3Rpb25cbiAqL1xuXG5cbmltcG9ydCBBc3NlcnRpb25FcnJvciBmcm9tICcuL0Fzc2VydGlvbkVycm9yLmpzJztcbmltcG9ydCBCYXNlT2JqZWN0IGZyb20gJy4vT2JqZWN0LmpzJztcbmltcG9ydCBDb2xsZWN0aW9uRXZlbnRUeXBlIGZyb20gJy4vQ29sbGVjdGlvbkV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgRXZlbnQgZnJvbSAnLi9ldmVudHMvRXZlbnQuanMnO1xuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQHByaXZhdGVcbiAqL1xuXG52YXIgUHJvcGVydHkgPSB7XG4gIExFTkdUSDogJ2xlbmd0aCdcbn07XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEV2ZW50cyBlbWl0dGVkIGJ5IHtAbGluayBtb2R1bGU6b2wvQ29sbGVjdGlvbn5Db2xsZWN0aW9ufSBpbnN0YW5jZXMgYXJlIGluc3RhbmNlcyBvZiB0aGlzXG4gKiB0eXBlLlxuICovXG5cbnZhciBDb2xsZWN0aW9uRXZlbnQgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ29sbGVjdGlvbkV2ZW50LCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0NvbGxlY3Rpb25FdmVudFR5cGUuanNcIikuZGVmYXVsdH0gdHlwZSBUeXBlLlxuICAgKiBAcGFyYW0geyo9fSBvcHRfZWxlbWVudCBFbGVtZW50LlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9pbmRleCBUaGUgaW5kZXggb2YgdGhlIGFkZGVkIG9yIHJlbW92ZWQgZWxlbWVudC5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDb2xsZWN0aW9uRXZlbnQodHlwZSwgb3B0X2VsZW1lbnQsIG9wdF9pbmRleCkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHR5cGUpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogVGhlIGVsZW1lbnQgdGhhdCBpcyBhZGRlZCB0byBvciByZW1vdmVkIGZyb20gdGhlIGNvbGxlY3Rpb24uXG4gICAgICogQHR5cGUgeyp9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5lbGVtZW50ID0gb3B0X2VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogVGhlIGluZGV4IG9mIHRoZSBhZGRlZCBvciByZW1vdmVkIGVsZW1lbnQuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgICBfdGhpcy5pbmRleCA9IG9wdF9pbmRleDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICByZXR1cm4gQ29sbGVjdGlvbkV2ZW50O1xufShFdmVudCk7XG5cbmV4cG9ydCB7IENvbGxlY3Rpb25FdmVudCB9O1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt1bmlxdWU9ZmFsc2VdIERpc2FsbG93IHRoZSBzYW1lIGl0ZW0gZnJvbSBiZWluZyBhZGRlZCB0b1xuICogdGhlIGNvbGxlY3Rpb24gdHdpY2UuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBbiBleHBhbmRlZCB2ZXJzaW9uIG9mIHN0YW5kYXJkIEpTIEFycmF5LCBhZGRpbmcgY29udmVuaWVuY2UgbWV0aG9kcyBmb3JcbiAqIG1hbmlwdWxhdGlvbi4gQWRkIGFuZCByZW1vdmUgY2hhbmdlcyB0byB0aGUgQ29sbGVjdGlvbiB0cmlnZ2VyIGEgQ29sbGVjdGlvblxuICogZXZlbnQuIE5vdGUgdGhhdCB0aGlzIGRvZXMgbm90IGNvdmVyIGNoYW5nZXMgdG8gdGhlIG9iamVjdHMgX3dpdGhpbl8gdGhlXG4gKiBDb2xsZWN0aW9uOyB0aGV5IHRyaWdnZXIgZXZlbnRzIG9uIHRoZSBhcHByb3ByaWF0ZSBvYmplY3QsIG5vdCBvbiB0aGVcbiAqIENvbGxlY3Rpb24gYXMgYSB3aG9sZS5cbiAqXG4gKiBAZmlyZXMgQ29sbGVjdGlvbkV2ZW50XG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEBhcGlcbiAqL1xuXG52YXIgQ29sbGVjdGlvbiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhDb2xsZWN0aW9uLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxUPj19IG9wdF9hcnJheSBBcnJheS5cbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgQ29sbGVjdGlvbiBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIENvbGxlY3Rpb24ob3B0X2FycmF5LCBvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zIHx8IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy51bmlxdWVfID0gISFvcHRpb25zLnVuaXF1ZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshQXJyYXk8VD59XG4gICAgICovXG5cbiAgICBfdGhpcy5hcnJheV8gPSBvcHRfYXJyYXkgPyBvcHRfYXJyYXkgOiBbXTtcblxuICAgIGlmIChfdGhpcy51bmlxdWVfKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBfdGhpcy5hcnJheV8ubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICBfdGhpcy5hc3NlcnRVbmlxdWVfKF90aGlzLmFycmF5X1tpXSwgaSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX3RoaXMudXBkYXRlTGVuZ3RoXygpO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBSZW1vdmUgYWxsIGVsZW1lbnRzIGZyb20gdGhlIGNvbGxlY3Rpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDb2xsZWN0aW9uLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICB3aGlsZSAodGhpcy5nZXRMZW5ndGgoKSA+IDApIHtcbiAgICAgIHRoaXMucG9wKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQWRkIGVsZW1lbnRzIHRvIHRoZSBjb2xsZWN0aW9uLiAgVGhpcyBwdXNoZXMgZWFjaCBpdGVtIGluIHRoZSBwcm92aWRlZCBhcnJheVxuICAgKiB0byB0aGUgZW5kIG9mIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0geyFBcnJheTxUPn0gYXJyIEFycmF5LlxuICAgKiBAcmV0dXJuIHtDb2xsZWN0aW9uPFQ+fSBUaGlzIGNvbGxlY3Rpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDb2xsZWN0aW9uLnByb3RvdHlwZS5leHRlbmQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gYXJyLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHRoaXMucHVzaChhcnJbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICAvKipcbiAgICogSXRlcmF0ZSBvdmVyIGVhY2ggZWxlbWVudCwgY2FsbGluZyB0aGUgcHJvdmlkZWQgY2FsbGJhY2suXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oVCwgbnVtYmVyLCBBcnJheTxUPik6ICp9IGYgVGhlIGZ1bmN0aW9uIHRvIGNhbGxcbiAgICogICAgIGZvciBldmVyeSBlbGVtZW50LiBUaGlzIGZ1bmN0aW9uIHRha2VzIDMgYXJndW1lbnRzICh0aGUgZWxlbWVudCwgdGhlXG4gICAqICAgICBpbmRleCBhbmQgdGhlIGFycmF5KS4gVGhlIHJldHVybiB2YWx1ZSBpcyBpZ25vcmVkLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29sbGVjdGlvbi5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uIChmKSB7XG4gICAgdmFyIGFycmF5ID0gdGhpcy5hcnJheV87XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBhcnJheS5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBmKGFycmF5W2ldLCBpLCBhcnJheSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogR2V0IGEgcmVmZXJlbmNlIHRvIHRoZSB1bmRlcmx5aW5nIEFycmF5IG9iamVjdC4gV2FybmluZzogaWYgdGhlIGFycmF5XG4gICAqIGlzIG11dGF0ZWQsIG5vIGV2ZW50cyB3aWxsIGJlIGRpc3BhdGNoZWQgYnkgdGhlIGNvbGxlY3Rpb24sIGFuZCB0aGVcbiAgICogY29sbGVjdGlvbidzIFwibGVuZ3RoXCIgcHJvcGVydHkgd29uJ3QgYmUgaW4gc3luYyB3aXRoIHRoZSBhY3R1YWwgbGVuZ3RoXG4gICAqIG9mIHRoZSBhcnJheS5cbiAgICogQHJldHVybiB7IUFycmF5PFQ+fSBBcnJheS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENvbGxlY3Rpb24ucHJvdG90eXBlLmdldEFycmF5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmFycmF5XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZWxlbWVudCBhdCB0aGUgcHJvdmlkZWQgaW5kZXguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleC5cbiAgICogQHJldHVybiB7VH0gRWxlbWVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENvbGxlY3Rpb24ucHJvdG90eXBlLml0ZW0gPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpcy5hcnJheV9baW5kZXhdO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBsZW5ndGggb2YgdGhpcyBjb2xsZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBsZW5ndGggb2YgdGhlIGFycmF5LlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29sbGVjdGlvbi5wcm90b3R5cGUuZ2V0TGVuZ3RoID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdldChQcm9wZXJ0eS5MRU5HVEgpO1xuICB9O1xuICAvKipcbiAgICogSW5zZXJ0IGFuIGVsZW1lbnQgYXQgdGhlIHByb3ZpZGVkIGluZGV4LlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kZXguXG4gICAqIEBwYXJhbSB7VH0gZWxlbSBFbGVtZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29sbGVjdGlvbi5wcm90b3R5cGUuaW5zZXJ0QXQgPSBmdW5jdGlvbiAoaW5kZXgsIGVsZW0pIHtcbiAgICBpZiAodGhpcy51bmlxdWVfKSB7XG4gICAgICB0aGlzLmFzc2VydFVuaXF1ZV8oZWxlbSk7XG4gICAgfVxuXG4gICAgdGhpcy5hcnJheV8uc3BsaWNlKGluZGV4LCAwLCBlbGVtKTtcbiAgICB0aGlzLnVwZGF0ZUxlbmd0aF8oKTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IENvbGxlY3Rpb25FdmVudChDb2xsZWN0aW9uRXZlbnRUeXBlLkFERCwgZWxlbSwgaW5kZXgpKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgbGFzdCBlbGVtZW50IG9mIHRoZSBjb2xsZWN0aW9uIGFuZCByZXR1cm4gaXQuXG4gICAqIFJldHVybiBgdW5kZWZpbmVkYCBpZiB0aGUgY29sbGVjdGlvbiBpcyBlbXB0eS5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IEVsZW1lbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDb2xsZWN0aW9uLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVtb3ZlQXQodGhpcy5nZXRMZW5ndGgoKSAtIDEpO1xuICB9O1xuICAvKipcbiAgICogSW5zZXJ0IHRoZSBwcm92aWRlZCBlbGVtZW50IGF0IHRoZSBlbmQgb2YgdGhlIGNvbGxlY3Rpb24uXG4gICAqIEBwYXJhbSB7VH0gZWxlbSBFbGVtZW50LlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE5ldyBsZW5ndGggb2YgdGhlIGNvbGxlY3Rpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDb2xsZWN0aW9uLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGVsZW0pIHtcbiAgICBpZiAodGhpcy51bmlxdWVfKSB7XG4gICAgICB0aGlzLmFzc2VydFVuaXF1ZV8oZWxlbSk7XG4gICAgfVxuXG4gICAgdmFyIG4gPSB0aGlzLmdldExlbmd0aCgpO1xuICAgIHRoaXMuaW5zZXJ0QXQobiwgZWxlbSk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TGVuZ3RoKCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYW4gZWxlbWVudCBmcm9tIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0ge1R9IGVsZW0gRWxlbWVudC5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IFRoZSByZW1vdmVkIGVsZW1lbnQgb3IgdW5kZWZpbmVkIGlmIG5vbmUgZm91bmQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDb2xsZWN0aW9uLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoZWxlbSkge1xuICAgIHZhciBhcnIgPSB0aGlzLmFycmF5XztcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGFyci5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBpZiAoYXJyW2ldID09PSBlbGVtKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlbW92ZUF0KGkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIGVsZW1lbnQgYXQgdGhlIHByb3ZpZGVkIGluZGV4IGFuZCByZXR1cm4gaXQuXG4gICAqIFJldHVybiBgdW5kZWZpbmVkYCBpZiB0aGUgY29sbGVjdGlvbiBkb2VzIG5vdCBjb250YWluIHRoaXMgaW5kZXguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleC5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IFZhbHVlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29sbGVjdGlvbi5wcm90b3R5cGUucmVtb3ZlQXQgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICB2YXIgcHJldiA9IHRoaXMuYXJyYXlfW2luZGV4XTtcbiAgICB0aGlzLmFycmF5Xy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHRoaXMudXBkYXRlTGVuZ3RoXygpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgQ29sbGVjdGlvbkV2ZW50KENvbGxlY3Rpb25FdmVudFR5cGUuUkVNT1ZFLCBwcmV2LCBpbmRleCkpO1xuICAgIHJldHVybiBwcmV2O1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBlbGVtZW50IGF0IHRoZSBwcm92aWRlZCBpbmRleC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IEluZGV4LlxuICAgKiBAcGFyYW0ge1R9IGVsZW0gRWxlbWVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENvbGxlY3Rpb24ucHJvdG90eXBlLnNldEF0ID0gZnVuY3Rpb24gKGluZGV4LCBlbGVtKSB7XG4gICAgdmFyIG4gPSB0aGlzLmdldExlbmd0aCgpO1xuXG4gICAgaWYgKGluZGV4IDwgbikge1xuICAgICAgaWYgKHRoaXMudW5pcXVlXykge1xuICAgICAgICB0aGlzLmFzc2VydFVuaXF1ZV8oZWxlbSwgaW5kZXgpO1xuICAgICAgfVxuXG4gICAgICB2YXIgcHJldiA9IHRoaXMuYXJyYXlfW2luZGV4XTtcbiAgICAgIHRoaXMuYXJyYXlfW2luZGV4XSA9IGVsZW07XG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IENvbGxlY3Rpb25FdmVudChDb2xsZWN0aW9uRXZlbnRUeXBlLlJFTU9WRSwgcHJldiwgaW5kZXgpKTtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgQ29sbGVjdGlvbkV2ZW50KENvbGxlY3Rpb25FdmVudFR5cGUuQURELCBlbGVtLCBpbmRleCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBqID0gbjsgaiA8IGluZGV4OyArK2opIHtcbiAgICAgICAgdGhpcy5pbnNlcnRBdChqLCB1bmRlZmluZWQpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmluc2VydEF0KGluZGV4LCBlbGVtKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIENvbGxlY3Rpb24ucHJvdG90eXBlLnVwZGF0ZUxlbmd0aF8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zZXQoUHJvcGVydHkuTEVOR1RILCB0aGlzLmFycmF5Xy5sZW5ndGgpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtUfSBlbGVtIEVsZW1lbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2V4Y2VwdCBPcHRpb25hbCBpbmRleCB0byBpZ25vcmUuXG4gICAqL1xuXG5cbiAgQ29sbGVjdGlvbi5wcm90b3R5cGUuYXNzZXJ0VW5pcXVlXyA9IGZ1bmN0aW9uIChlbGVtLCBvcHRfZXhjZXB0KSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5hcnJheV8ubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgaWYgKHRoaXMuYXJyYXlfW2ldID09PSBlbGVtICYmIGkgIT09IG9wdF9leGNlcHQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKDU4KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIENvbGxlY3Rpb247XG59KEJhc2VPYmplY3QpO1xuXG5leHBvcnQgZGVmYXVsdCBDb2xsZWN0aW9uOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvbGF5ZXIvR3JvdXBcbiAqL1xuXG5cbmltcG9ydCBCYXNlTGF5ZXIgZnJvbSAnLi9CYXNlLmpzJztcbmltcG9ydCBDb2xsZWN0aW9uIGZyb20gJy4uL0NvbGxlY3Rpb24uanMnO1xuaW1wb3J0IENvbGxlY3Rpb25FdmVudFR5cGUgZnJvbSAnLi4vQ29sbGVjdGlvbkV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IE9iamVjdEV2ZW50VHlwZSBmcm9tICcuLi9PYmplY3RFdmVudFR5cGUuanMnO1xuaW1wb3J0IFNvdXJjZVN0YXRlIGZyb20gJy4uL3NvdXJjZS9TdGF0ZS5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGFzc2lnbiwgY2xlYXIgfSBmcm9tICcuLi9vYmouanMnO1xuaW1wb3J0IHsgZ2V0Q2hhbmdlRXZlbnRUeXBlIH0gZnJvbSAnLi4vT2JqZWN0LmpzJztcbmltcG9ydCB7IGdldEludGVyc2VjdGlvbiB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBnZXRVaWQgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IGxpc3RlbiwgdW5saXN0ZW5CeUtleSB9IGZyb20gJy4uL2V2ZW50cy5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbb3BhY2l0eT0xXSBPcGFjaXR5ICgwLCAxKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3Zpc2libGU9dHJ1ZV0gVmlzaWJpbGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF0gVGhlIGJvdW5kaW5nIGV4dGVudCBmb3IgbGF5ZXIgcmVuZGVyaW5nLiAgVGhlIGxheWVyIHdpbGwgbm90IGJlXG4gKiByZW5kZXJlZCBvdXRzaWRlIG9mIHRoaXMgZXh0ZW50LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6SW5kZXhdIFRoZSB6LWluZGV4IGZvciBsYXllciByZW5kZXJpbmcuICBBdCByZW5kZXJpbmcgdGltZSwgdGhlIGxheWVyc1xuICogd2lsbCBiZSBvcmRlcmVkLCBmaXJzdCBieSBaLWluZGV4IGFuZCB0aGVuIGJ5IHBvc2l0aW9uLiBXaGVuIGB1bmRlZmluZWRgLCBhIGB6SW5kZXhgIG9mIDAgaXMgYXNzdW1lZFxuICogZm9yIGxheWVycyB0aGF0IGFyZSBhZGRlZCB0byB0aGUgbWFwJ3MgYGxheWVyc2AgY29sbGVjdGlvbiwgb3IgYEluZmluaXR5YCB3aGVuIHRoZSBsYXllcidzIGBzZXRNYXAoKWBcbiAqIG1ldGhvZCB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluUmVzb2x1dGlvbl0gVGhlIG1pbmltdW0gcmVzb2x1dGlvbiAoaW5jbHVzaXZlKSBhdCB3aGljaCB0aGlzIGxheWVyIHdpbGwgYmVcbiAqIHZpc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFJlc29sdXRpb25dIFRoZSBtYXhpbXVtIHJlc29sdXRpb24gKGV4Y2x1c2l2ZSkgYmVsb3cgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5ab29tXSBUaGUgbWluaW11bSB2aWV3IHpvb20gbGV2ZWwgKGV4Y2x1c2l2ZSkgYWJvdmUgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhab29tXSBUaGUgbWF4aW11bSB2aWV3IHpvb20gbGV2ZWwgKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5ab29tXSBUaGUgbWluaW11bSB2aWV3IHpvb20gbGV2ZWwgKGV4Y2x1c2l2ZSkgYWJvdmUgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhab29tXSBUaGUgbWF4aW11bSB2aWV3IHpvb20gbGV2ZWwgKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtBcnJheTxpbXBvcnQoXCIuL0Jhc2UuanNcIikuZGVmYXVsdD58aW1wb3J0KFwiLi4vQ29sbGVjdGlvbi5qc1wiKS5kZWZhdWx0PGltcG9ydChcIi4vQmFzZS5qc1wiKS5kZWZhdWx0Pn0gW2xheWVyc10gQ2hpbGQgbGF5ZXJzLlxuICovXG5cbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIFByb3BlcnR5ID0ge1xuICBMQVlFUlM6ICdsYXllcnMnXG59O1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBIHtAbGluayBtb2R1bGU6b2wvQ29sbGVjdGlvbn5Db2xsZWN0aW9ufSBvZiBsYXllcnMgdGhhdCBhcmUgaGFuZGxlZCB0b2dldGhlci5cbiAqXG4gKiBBIGdlbmVyaWMgYGNoYW5nZWAgZXZlbnQgaXMgdHJpZ2dlcmVkIHdoZW4gdGhlIGdyb3VwL0NvbGxlY3Rpb24gY2hhbmdlcy5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIExheWVyR3JvdXAgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoTGF5ZXJHcm91cCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIExheWVyIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gTGF5ZXJHcm91cChvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zIHx8IHt9O1xuICAgIHZhciBiYXNlT3B0aW9ucyA9XG4gICAgLyoqIEB0eXBlIHtPcHRpb25zfSAqL1xuICAgIGFzc2lnbih7fSwgb3B0aW9ucyk7XG4gICAgZGVsZXRlIGJhc2VPcHRpb25zLmxheWVycztcbiAgICB2YXIgbGF5ZXJzID0gb3B0aW9ucy5sYXllcnM7XG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBiYXNlT3B0aW9ucykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuLi9ldmVudHMuanNcIikuRXZlbnRzS2V5Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxheWVyc0xpc3RlbmVyS2V5c18gPSBbXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBBcnJheTxpbXBvcnQoXCIuLi9ldmVudHMuanNcIikuRXZlbnRzS2V5Pj59XG4gICAgICovXG5cbiAgICBfdGhpcy5saXN0ZW5lcktleXNfID0ge307XG5cbiAgICBfdGhpcy5hZGRFdmVudExpc3RlbmVyKGdldENoYW5nZUV2ZW50VHlwZShQcm9wZXJ0eS5MQVlFUlMpLCBfdGhpcy5oYW5kbGVMYXllcnNDaGFuZ2VkXyk7XG5cbiAgICBpZiAobGF5ZXJzKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShsYXllcnMpKSB7XG4gICAgICAgIGxheWVycyA9IG5ldyBDb2xsZWN0aW9uKGxheWVycy5zbGljZSgpLCB7XG4gICAgICAgICAgdW5pcXVlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXNzZXJ0KHR5cGVvZlxuICAgICAgICAvKiogQHR5cGUgez99ICovXG4gICAgICAgIGxheWVycy5nZXRBcnJheSA9PT0gJ2Z1bmN0aW9uJywgNDMpOyAvLyBFeHBlY3RlZCBgbGF5ZXJzYCB0byBiZSBhbiBhcnJheSBvciBhIGBDb2xsZWN0aW9uYFxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBsYXllcnMgPSBuZXcgQ29sbGVjdGlvbih1bmRlZmluZWQsIHtcbiAgICAgICAgdW5pcXVlOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBfdGhpcy5zZXRMYXllcnMobGF5ZXJzKTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBMYXllckdyb3VwLnByb3RvdHlwZS5oYW5kbGVMYXllckNoYW5nZV8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIExheWVyR3JvdXAucHJvdG90eXBlLmhhbmRsZUxheWVyc0NoYW5nZWRfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMubGF5ZXJzTGlzdGVuZXJLZXlzXy5mb3JFYWNoKHVubGlzdGVuQnlLZXkpO1xuICAgIHRoaXMubGF5ZXJzTGlzdGVuZXJLZXlzXy5sZW5ndGggPSAwO1xuICAgIHZhciBsYXllcnMgPSB0aGlzLmdldExheWVycygpO1xuICAgIHRoaXMubGF5ZXJzTGlzdGVuZXJLZXlzXy5wdXNoKGxpc3RlbihsYXllcnMsIENvbGxlY3Rpb25FdmVudFR5cGUuQURELCB0aGlzLmhhbmRsZUxheWVyc0FkZF8sIHRoaXMpLCBsaXN0ZW4obGF5ZXJzLCBDb2xsZWN0aW9uRXZlbnRUeXBlLlJFTU9WRSwgdGhpcy5oYW5kbGVMYXllcnNSZW1vdmVfLCB0aGlzKSk7XG5cbiAgICBmb3IgKHZhciBpZCBpbiB0aGlzLmxpc3RlbmVyS2V5c18pIHtcbiAgICAgIHRoaXMubGlzdGVuZXJLZXlzX1tpZF0uZm9yRWFjaCh1bmxpc3RlbkJ5S2V5KTtcbiAgICB9XG5cbiAgICBjbGVhcih0aGlzLmxpc3RlbmVyS2V5c18pO1xuICAgIHZhciBsYXllcnNBcnJheSA9IGxheWVycy5nZXRBcnJheSgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbGF5ZXJzQXJyYXkubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgdmFyIGxheWVyID0gbGF5ZXJzQXJyYXlbaV07XG4gICAgICB0aGlzLmxpc3RlbmVyS2V5c19bZ2V0VWlkKGxheWVyKV0gPSBbbGlzdGVuKGxheWVyLCBPYmplY3RFdmVudFR5cGUuUFJPUEVSVFlDSEFOR0UsIHRoaXMuaGFuZGxlTGF5ZXJDaGFuZ2VfLCB0aGlzKSwgbGlzdGVuKGxheWVyLCBFdmVudFR5cGUuQ0hBTkdFLCB0aGlzLmhhbmRsZUxheWVyQ2hhbmdlXywgdGhpcyldO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9Db2xsZWN0aW9uLmpzXCIpLkNvbGxlY3Rpb25FdmVudH0gY29sbGVjdGlvbkV2ZW50IENvbGxlY3Rpb25FdmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBMYXllckdyb3VwLnByb3RvdHlwZS5oYW5kbGVMYXllcnNBZGRfID0gZnVuY3Rpb24gKGNvbGxlY3Rpb25FdmVudCkge1xuICAgIHZhciBsYXllciA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL0Jhc2UuanNcIikuZGVmYXVsdH0gKi9cbiAgICBjb2xsZWN0aW9uRXZlbnQuZWxlbWVudDtcbiAgICB0aGlzLmxpc3RlbmVyS2V5c19bZ2V0VWlkKGxheWVyKV0gPSBbbGlzdGVuKGxheWVyLCBPYmplY3RFdmVudFR5cGUuUFJPUEVSVFlDSEFOR0UsIHRoaXMuaGFuZGxlTGF5ZXJDaGFuZ2VfLCB0aGlzKSwgbGlzdGVuKGxheWVyLCBFdmVudFR5cGUuQ0hBTkdFLCB0aGlzLmhhbmRsZUxheWVyQ2hhbmdlXywgdGhpcyldO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9Db2xsZWN0aW9uLmpzXCIpLkNvbGxlY3Rpb25FdmVudH0gY29sbGVjdGlvbkV2ZW50IENvbGxlY3Rpb25FdmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBMYXllckdyb3VwLnByb3RvdHlwZS5oYW5kbGVMYXllcnNSZW1vdmVfID0gZnVuY3Rpb24gKGNvbGxlY3Rpb25FdmVudCkge1xuICAgIHZhciBsYXllciA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL0Jhc2UuanNcIikuZGVmYXVsdH0gKi9cbiAgICBjb2xsZWN0aW9uRXZlbnQuZWxlbWVudDtcbiAgICB2YXIga2V5ID0gZ2V0VWlkKGxheWVyKTtcbiAgICB0aGlzLmxpc3RlbmVyS2V5c19ba2V5XS5mb3JFYWNoKHVubGlzdGVuQnlLZXkpO1xuICAgIGRlbGV0ZSB0aGlzLmxpc3RlbmVyS2V5c19ba2V5XTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHtAbGluayBtb2R1bGU6b2wvQ29sbGVjdGlvbiBjb2xsZWN0aW9ufSBvZiB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0xheWVyfkxheWVyIGxheWVyc31cbiAgICogaW4gdGhpcyBncm91cC5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uL0NvbGxlY3Rpb24uanNcIikuZGVmYXVsdDxpbXBvcnQoXCIuL0Jhc2UuanNcIikuZGVmYXVsdD59IENvbGxlY3Rpb24gb2ZcbiAgICogICB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0Jhc2UgbGF5ZXJzfSB0aGF0IGFyZSBwYXJ0IG9mIHRoaXMgZ3JvdXAuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMYXllckdyb3VwLnByb3RvdHlwZS5nZXRMYXllcnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7IWltcG9ydChcIi4uL0NvbGxlY3Rpb24uanNcIikuZGVmYXVsdDxpbXBvcnQoXCIuL0Jhc2UuanNcIikuZGVmYXVsdD59ICovXG4gICAgICB0aGlzLmdldChQcm9wZXJ0eS5MQVlFUlMpXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUge0BsaW5rIG1vZHVsZTpvbC9Db2xsZWN0aW9uIGNvbGxlY3Rpb259IG9mIHtAbGluayBtb2R1bGU6b2wvbGF5ZXIvTGF5ZXJ+TGF5ZXIgbGF5ZXJzfVxuICAgKiBpbiB0aGlzIGdyb3VwLlxuICAgKiBAcGFyYW0geyFpbXBvcnQoXCIuLi9Db2xsZWN0aW9uLmpzXCIpLmRlZmF1bHQ8aW1wb3J0KFwiLi9CYXNlLmpzXCIpLmRlZmF1bHQ+fSBsYXllcnMgQ29sbGVjdGlvbiBvZlxuICAgKiAgIHtAbGluayBtb2R1bGU6b2wvbGF5ZXIvQmFzZSBsYXllcnN9IHRoYXQgYXJlIHBhcnQgb2YgdGhpcyBncm91cC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExheWVyR3JvdXAucHJvdG90eXBlLnNldExheWVycyA9IGZ1bmN0aW9uIChsYXllcnMpIHtcbiAgICB0aGlzLnNldChQcm9wZXJ0eS5MQVlFUlMsIGxheWVycyk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vTGF5ZXIuanNcIikuZGVmYXVsdD49fSBvcHRfYXJyYXkgQXJyYXkgb2YgbGF5ZXJzICh0byBiZSBtb2RpZmllZCBpbiBwbGFjZSkuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4vTGF5ZXIuanNcIikuZGVmYXVsdD59IEFycmF5IG9mIGxheWVycy5cbiAgICovXG5cblxuICBMYXllckdyb3VwLnByb3RvdHlwZS5nZXRMYXllcnNBcnJheSA9IGZ1bmN0aW9uIChvcHRfYXJyYXkpIHtcbiAgICB2YXIgYXJyYXkgPSBvcHRfYXJyYXkgIT09IHVuZGVmaW5lZCA/IG9wdF9hcnJheSA6IFtdO1xuICAgIHRoaXMuZ2V0TGF5ZXJzKCkuZm9yRWFjaChmdW5jdGlvbiAobGF5ZXIpIHtcbiAgICAgIGxheWVyLmdldExheWVyc0FycmF5KGFycmF5KTtcbiAgICB9KTtcbiAgICByZXR1cm4gYXJyYXk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vTGF5ZXIuanNcIikuU3RhdGU+PX0gb3B0X3N0YXRlcyBPcHRpb25hbCBsaXN0IG9mIGxheWVyIHN0YXRlcyAodG8gYmUgbW9kaWZpZWQgaW4gcGxhY2UpLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuL0xheWVyLmpzXCIpLlN0YXRlPn0gTGlzdCBvZiBsYXllciBzdGF0ZXMuXG4gICAqL1xuXG5cbiAgTGF5ZXJHcm91cC5wcm90b3R5cGUuZ2V0TGF5ZXJTdGF0ZXNBcnJheSA9IGZ1bmN0aW9uIChvcHRfc3RhdGVzKSB7XG4gICAgdmFyIHN0YXRlcyA9IG9wdF9zdGF0ZXMgIT09IHVuZGVmaW5lZCA/IG9wdF9zdGF0ZXMgOiBbXTtcbiAgICB2YXIgcG9zID0gc3RhdGVzLmxlbmd0aDtcbiAgICB0aGlzLmdldExheWVycygpLmZvckVhY2goZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgICBsYXllci5nZXRMYXllclN0YXRlc0FycmF5KHN0YXRlcyk7XG4gICAgfSk7XG4gICAgdmFyIG93bkxheWVyU3RhdGUgPSB0aGlzLmdldExheWVyU3RhdGUoKTtcblxuICAgIGZvciAodmFyIGkgPSBwb3MsIGlpID0gc3RhdGVzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgIHZhciBsYXllclN0YXRlID0gc3RhdGVzW2ldO1xuICAgICAgbGF5ZXJTdGF0ZS5vcGFjaXR5ICo9IG93bkxheWVyU3RhdGUub3BhY2l0eTtcbiAgICAgIGxheWVyU3RhdGUudmlzaWJsZSA9IGxheWVyU3RhdGUudmlzaWJsZSAmJiBvd25MYXllclN0YXRlLnZpc2libGU7XG4gICAgICBsYXllclN0YXRlLm1heFJlc29sdXRpb24gPSBNYXRoLm1pbihsYXllclN0YXRlLm1heFJlc29sdXRpb24sIG93bkxheWVyU3RhdGUubWF4UmVzb2x1dGlvbik7XG4gICAgICBsYXllclN0YXRlLm1pblJlc29sdXRpb24gPSBNYXRoLm1heChsYXllclN0YXRlLm1pblJlc29sdXRpb24sIG93bkxheWVyU3RhdGUubWluUmVzb2x1dGlvbik7XG4gICAgICBsYXllclN0YXRlLm1pblpvb20gPSBNYXRoLm1heChsYXllclN0YXRlLm1pblpvb20sIG93bkxheWVyU3RhdGUubWluWm9vbSk7XG4gICAgICBsYXllclN0YXRlLm1heFpvb20gPSBNYXRoLm1pbihsYXllclN0YXRlLm1heFpvb20sIG93bkxheWVyU3RhdGUubWF4Wm9vbSk7XG5cbiAgICAgIGlmIChvd25MYXllclN0YXRlLmV4dGVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChsYXllclN0YXRlLmV4dGVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbGF5ZXJTdGF0ZS5leHRlbnQgPSBnZXRJbnRlcnNlY3Rpb24obGF5ZXJTdGF0ZS5leHRlbnQsIG93bkxheWVyU3RhdGUuZXh0ZW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsYXllclN0YXRlLmV4dGVudCA9IG93bkxheWVyU3RhdGUuZXh0ZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXRlcztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NvdXJjZS9TdGF0ZS5qc1wiKS5kZWZhdWx0fSBTb3VyY2Ugc3RhdGUuXG4gICAqL1xuXG5cbiAgTGF5ZXJHcm91cC5wcm90b3R5cGUuZ2V0U291cmNlU3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFNvdXJjZVN0YXRlLlJFQURZO1xuICB9O1xuXG4gIHJldHVybiBMYXllckdyb3VwO1xufShCYXNlTGF5ZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBMYXllckdyb3VwOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvTWFwRXZlbnRcbiAqL1xuXG5cbmltcG9ydCBFdmVudCBmcm9tICcuL2V2ZW50cy9FdmVudC5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEV2ZW50cyBlbWl0dGVkIGFzIG1hcCBldmVudHMgYXJlIGluc3RhbmNlcyBvZiB0aGlzIHR5cGUuXG4gKiBTZWUge0BsaW5rIG1vZHVsZTpvbC9QbHVnZ2FibGVNYXB+UGx1Z2dhYmxlTWFwfSBmb3Igd2hpY2ggZXZlbnRzIHRyaWdnZXIgYSBtYXAgZXZlbnQuXG4gKi9cblxudmFyIE1hcEV2ZW50ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKE1hcEV2ZW50LCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgRXZlbnQgdHlwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fSBtYXAgTWFwLlxuICAgKiBAcGFyYW0gez9pbXBvcnQoXCIuL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlPX0gb3B0X2ZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gTWFwRXZlbnQodHlwZSwgbWFwLCBvcHRfZnJhbWVTdGF0ZSkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHR5cGUpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogVGhlIG1hcCB3aGVyZSB0aGUgZXZlbnQgb2NjdXJyZWQuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5tYXAgPSBtYXA7XG4gICAgLyoqXG4gICAgICogVGhlIGZyYW1lIHN0YXRlIGF0IHRoZSB0aW1lIG9mIHRoZSBldmVudC5cbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG4gICAgX3RoaXMuZnJhbWVTdGF0ZSA9IG9wdF9mcmFtZVN0YXRlICE9PSB1bmRlZmluZWQgPyBvcHRfZnJhbWVTdGF0ZSA6IG51bGw7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIE1hcEV2ZW50O1xufShFdmVudCk7XG5cbmV4cG9ydCBkZWZhdWx0IE1hcEV2ZW50OyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvTWFwQnJvd3NlckV2ZW50XG4gKi9cblxuXG5pbXBvcnQgTWFwRXZlbnQgZnJvbSAnLi9NYXBFdmVudC5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEV2ZW50cyBlbWl0dGVkIGFzIG1hcCBicm93c2VyIGV2ZW50cyBhcmUgaW5zdGFuY2VzIG9mIHRoaXMgdHlwZS5cbiAqIFNlZSB7QGxpbmsgbW9kdWxlOm9sL1BsdWdnYWJsZU1hcH5QbHVnZ2FibGVNYXB9IGZvciB3aGljaCBldmVudHMgdHJpZ2dlciBhIG1hcCBicm93c2VyIGV2ZW50LlxuICogQHRlbXBsYXRlIHtVSUV2ZW50fSBFVkVOVFxuICovXG5cbnZhciBNYXBCcm93c2VyRXZlbnQgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoTWFwQnJvd3NlckV2ZW50LCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgRXZlbnQgdHlwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fSBtYXAgTWFwLlxuICAgKiBAcGFyYW0ge0VWRU5UfSBvcmlnaW5hbEV2ZW50IE9yaWdpbmFsIGV2ZW50LlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfZHJhZ2dpbmcgSXMgdGhlIG1hcCBjdXJyZW50bHkgYmVpbmcgZHJhZ2dlZD9cbiAgICogQHBhcmFtIHs/aW1wb3J0KFwiLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZT19IG9wdF9mcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIE1hcEJyb3dzZXJFdmVudCh0eXBlLCBtYXAsIG9yaWdpbmFsRXZlbnQsIG9wdF9kcmFnZ2luZywgb3B0X2ZyYW1lU3RhdGUpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0eXBlLCBtYXAsIG9wdF9mcmFtZVN0YXRlKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIFRoZSBvcmlnaW5hbCBicm93c2VyIGV2ZW50LlxuICAgICAqIEBjb25zdFxuICAgICAqIEB0eXBlIHtFVkVOVH1cbiAgICAgKiBAYXBpXG4gICAgICovXG5cblxuICAgIF90aGlzLm9yaWdpbmFsRXZlbnQgPSBvcmlnaW5hbEV2ZW50O1xuICAgIC8qKlxuICAgICAqIFRoZSBtYXAgcGl4ZWwgcmVsYXRpdmUgdG8gdGhlIHZpZXdwb3J0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIG9yaWdpbmFsIGJyb3dzZXIgZXZlbnQuXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuL3BpeGVsLmpzXCIpLlBpeGVsfVxuICAgICAqL1xuXG4gICAgX3RoaXMucGl4ZWxfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBUaGUgY29vcmRpbmF0ZSBpbiB0aGUgdXNlciBwcm9qZWN0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG9yaWdpbmFsIGJyb3dzZXIgZXZlbnQuXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvb3JkaW5hdGVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIG1hcCBpcyBjdXJyZW50bHkgYmVpbmcgZHJhZ2dlZC4gT25seSBzZXQgZm9yXG4gICAgICogYFBPSU5URVJEUkFHYCBhbmQgYFBPSU5URVJNT1ZFYCBldmVudHMuIERlZmF1bHQgaXMgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICAgIF90aGlzLmRyYWdnaW5nID0gb3B0X2RyYWdnaW5nICE9PSB1bmRlZmluZWQgPyBvcHRfZHJhZ2dpbmcgOiBmYWxzZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTWFwQnJvd3NlckV2ZW50LnByb3RvdHlwZSwgXCJwaXhlbFwiLCB7XG4gICAgLyoqXG4gICAgICogVGhlIG1hcCBwaXhlbCByZWxhdGl2ZSB0byB0aGUgdmlld3BvcnQgY29ycmVzcG9uZGluZyB0byB0aGUgb3JpZ2luYWwgZXZlbnQuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9XG4gICAgICogQGFwaVxuICAgICAqL1xuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgaWYgKCF0aGlzLnBpeGVsXykge1xuICAgICAgICB0aGlzLnBpeGVsXyA9IHRoaXMubWFwLmdldEV2ZW50UGl4ZWwodGhpcy5vcmlnaW5hbEV2ZW50KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMucGl4ZWxfO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbiBzZXQocGl4ZWwpIHtcbiAgICAgIHRoaXMucGl4ZWxfID0gcGl4ZWw7XG4gICAgfSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShNYXBCcm93c2VyRXZlbnQucHJvdG90eXBlLCBcImNvb3JkaW5hdGVcIiwge1xuICAgIC8qKlxuICAgICAqIFRoZSBjb29yZGluYXRlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG9yaWdpbmFsIGJyb3dzZXIgZXZlbnQuICBUaGlzIHdpbGwgYmUgaW4gdGhlIHVzZXJcbiAgICAgKiBwcm9qZWN0aW9uIGlmIG9uZSBpcyBzZXQuICBPdGhlcndpc2UgaXQgd2lsbCBiZSBpbiB0aGUgdmlldyBwcm9qZWN0aW9uLlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX1cbiAgICAgKiBAYXBpXG4gICAgICovXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICBpZiAoIXRoaXMuY29vcmRpbmF0ZV8pIHtcbiAgICAgICAgdGhpcy5jb29yZGluYXRlXyA9IHRoaXMubWFwLmdldENvb3JkaW5hdGVGcm9tUGl4ZWwodGhpcy5waXhlbCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmNvb3JkaW5hdGVfO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbiBzZXQoY29vcmRpbmF0ZSkge1xuICAgICAgdGhpcy5jb29yZGluYXRlXyA9IGNvb3JkaW5hdGU7XG4gICAgfSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG4gIC8qKlxuICAgKiBQcmV2ZW50cyB0aGUgZGVmYXVsdCBicm93c2VyIGFjdGlvbi5cbiAgICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9ldmVudC5wcmV2ZW50RGVmYXVsdC5cbiAgICogQGFwaVxuICAgKi9cblxuICBNYXBCcm93c2VyRXZlbnQucHJvdG90eXBlLnByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgIF9zdXBlci5wcm90b3R5cGUucHJldmVudERlZmF1bHQuY2FsbCh0aGlzKTtcblxuICAgIHRoaXMub3JpZ2luYWxFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9O1xuICAvKipcbiAgICogUHJldmVudHMgZnVydGhlciBwcm9wYWdhdGlvbiBvZiB0aGUgY3VycmVudCBldmVudC5cbiAgICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9ldmVudC5zdG9wUHJvcGFnYXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNYXBCcm93c2VyRXZlbnQucHJvdG90eXBlLnN0b3BQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICBfc3VwZXIucHJvdG90eXBlLnN0b3BQcm9wYWdhdGlvbi5jYWxsKHRoaXMpO1xuXG4gICAgdGhpcy5vcmlnaW5hbEV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9O1xuXG4gIHJldHVybiBNYXBCcm93c2VyRXZlbnQ7XG59KE1hcEV2ZW50KTtcblxuZXhwb3J0IGRlZmF1bHQgTWFwQnJvd3NlckV2ZW50OyIsIi8qKlxuICogQG1vZHVsZSBvbC9NYXBCcm93c2VyRXZlbnRUeXBlXG4gKi9cbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbi8qKlxuICogQ29uc3RhbnRzIGZvciBldmVudCBuYW1lcy5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cblxuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogQSB0cnVlIHNpbmdsZSBjbGljayB3aXRoIG5vIGRyYWdnaW5nIGFuZCBubyBkb3VibGUgY2xpY2suIE5vdGUgdGhhdCB0aGlzXG4gICAqIGV2ZW50IGlzIGRlbGF5ZWQgYnkgMjUwIG1zIHRvIGVuc3VyZSB0aGF0IGl0IGlzIG5vdCBhIGRvdWJsZSBjbGljay5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR+TWFwQnJvd3NlckV2ZW50I3NpbmdsZWNsaWNrXG4gICAqIEBhcGlcbiAgICovXG4gIFNJTkdMRUNMSUNLOiAnc2luZ2xlY2xpY2snLFxuXG4gIC8qKlxuICAgKiBBIGNsaWNrIHdpdGggbm8gZHJhZ2dpbmcuIEEgZG91YmxlIGNsaWNrIHdpbGwgZmlyZSB0d28gb2YgdGhpcy5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR+TWFwQnJvd3NlckV2ZW50I2NsaWNrXG4gICAqIEBhcGlcbiAgICovXG4gIENMSUNLOiBFdmVudFR5cGUuQ0xJQ0ssXG5cbiAgLyoqXG4gICAqIEEgdHJ1ZSBkb3VibGUgY2xpY2ssIHdpdGggbm8gZHJhZ2dpbmcuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudCNkYmxjbGlja1xuICAgKiBAYXBpXG4gICAqL1xuICBEQkxDTElDSzogRXZlbnRUeXBlLkRCTENMSUNLLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBhIHBvaW50ZXIgaXMgZHJhZ2dlZC5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR+TWFwQnJvd3NlckV2ZW50I3BvaW50ZXJkcmFnXG4gICAqIEBhcGlcbiAgICovXG4gIFBPSU5URVJEUkFHOiAncG9pbnRlcmRyYWcnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBhIHBvaW50ZXIgaXMgbW92ZWQuIE5vdGUgdGhhdCBvbiB0b3VjaCBkZXZpY2VzIHRoaXMgaXNcbiAgICogdHJpZ2dlcmVkIHdoZW4gdGhlIG1hcCBpcyBwYW5uZWQsIHNvIGlzIG5vdCB0aGUgc2FtZSBhcyBtb3VzZW1vdmUuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudCNwb2ludGVybW92ZVxuICAgKiBAYXBpXG4gICAqL1xuICBQT0lOVEVSTU9WRTogJ3BvaW50ZXJtb3ZlJyxcbiAgUE9JTlRFUkRPV046ICdwb2ludGVyZG93bicsXG4gIFBPSU5URVJVUDogJ3BvaW50ZXJ1cCcsXG4gIFBPSU5URVJPVkVSOiAncG9pbnRlcm92ZXInLFxuICBQT0lOVEVST1VUOiAncG9pbnRlcm91dCcsXG4gIFBPSU5URVJFTlRFUjogJ3BvaW50ZXJlbnRlcicsXG4gIFBPSU5URVJMRUFWRTogJ3BvaW50ZXJsZWF2ZScsXG4gIFBPSU5URVJDQU5DRUw6ICdwb2ludGVyY2FuY2VsJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcG9pbnRlci9FdmVudFR5cGVcbiAqL1xuXG4vKipcbiAqIENvbnN0YW50cyBmb3IgZXZlbnQgbmFtZXMuXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIFBPSU5URVJNT1ZFOiAncG9pbnRlcm1vdmUnLFxuICBQT0lOVEVSRE9XTjogJ3BvaW50ZXJkb3duJyxcbiAgUE9JTlRFUlVQOiAncG9pbnRlcnVwJyxcbiAgUE9JTlRFUk9WRVI6ICdwb2ludGVyb3ZlcicsXG4gIFBPSU5URVJPVVQ6ICdwb2ludGVyb3V0JyxcbiAgUE9JTlRFUkVOVEVSOiAncG9pbnRlcmVudGVyJyxcbiAgUE9JTlRFUkxFQVZFOiAncG9pbnRlcmxlYXZlJyxcbiAgUE9JTlRFUkNBTkNFTDogJ3BvaW50ZXJjYW5jZWwnXG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC9NYXBCcm93c2VyRXZlbnRIYW5kbGVyXG4gKi9cbnZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG5cbmltcG9ydCBFdmVudFRhcmdldCBmcm9tICcuL2V2ZW50cy9UYXJnZXQuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IE1hcEJyb3dzZXJFdmVudCBmcm9tICcuL01hcEJyb3dzZXJFdmVudC5qcyc7XG5pbXBvcnQgTWFwQnJvd3NlckV2ZW50VHlwZSBmcm9tICcuL01hcEJyb3dzZXJFdmVudFR5cGUuanMnO1xuaW1wb3J0IFBvaW50ZXJFdmVudFR5cGUgZnJvbSAnLi9wb2ludGVyL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgeyBERVZJQ0VfUElYRUxfUkFUSU8sIFBBU1NJVkVfRVZFTlRfTElTVEVORVJTIH0gZnJvbSAnLi9oYXMuanMnO1xuaW1wb3J0IHsgbGlzdGVuLCB1bmxpc3RlbkJ5S2V5IH0gZnJvbSAnLi9ldmVudHMuanMnO1xuXG52YXIgTWFwQnJvd3NlckV2ZW50SGFuZGxlciA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhNYXBCcm93c2VyRXZlbnRIYW5kbGVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fSBtYXAgVGhlIG1hcCB3aXRoIHRoZSB2aWV3cG9ydCB0byBsaXN0ZW4gdG8gZXZlbnRzIG9uLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG1vdmVUb2xlcmFuY2UgVGhlIG1pbmltYWwgZGlzdGFuY2UgdGhlIHBvaW50ZXIgbXVzdCB0cmF2ZWwgdG8gdHJpZ2dlciBhIG1vdmUuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gTWFwQnJvd3NlckV2ZW50SGFuZGxlcihtYXAsIG1vdmVUb2xlcmFuY2UpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBtYXApIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogVGhpcyBpcyB0aGUgZWxlbWVudCB0aGF0IHdlIHdpbGwgbGlzdGVuIHRvIHRoZSByZWFsIGV2ZW50cyBvbi5cbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5tYXBfID0gbWFwO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHthbnl9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmNsaWNrVGltZW91dElkXztcbiAgICAvKipcbiAgICAgKiBFbXVsYXRlIGRibGNsaWNrIGFuZCBzaW5nbGVjbGljay4gV2lsbCBiZSB0cnVlIHdoZW4gb25seSBvbmUgcG9pbnRlciBpcyBhY3RpdmUuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5lbXVsYXRlQ2xpY2tzXyA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5kcmFnZ2luZ18gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IUFycmF5PGltcG9ydChcIi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleT59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmRyYWdMaXN0ZW5lcktleXNfID0gW107XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMubW92ZVRvbGVyYW5jZV8gPSBtb3ZlVG9sZXJhbmNlID8gbW92ZVRvbGVyYW5jZSAqIERFVklDRV9QSVhFTF9SQVRJTyA6IERFVklDRV9QSVhFTF9SQVRJTztcbiAgICAvKipcbiAgICAgKiBUaGUgbW9zdCByZWNlbnQgXCJkb3duXCIgdHlwZSBldmVudCAob3IgbnVsbCBpZiBub25lIGhhdmUgb2NjdXJyZWQpLlxuICAgICAqIFNldCBvbiBwb2ludGVyZG93bi5cbiAgICAgKiBAdHlwZSB7UG9pbnRlckV2ZW50fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5kb3duXyA9IG51bGw7XG5cbiAgICB2YXIgZWxlbWVudCA9IF90aGlzLm1hcF8uZ2V0Vmlld3BvcnQoKTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cblxuICAgIF90aGlzLmFjdGl2ZVBvaW50ZXJzXyA9IDA7XG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFPYmplY3Q8bnVtYmVyLCBib29sZWFuPn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMudHJhY2tlZFRvdWNoZXNfID0ge307XG4gICAgX3RoaXMuZWxlbWVudF8gPSBlbGVtZW50O1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5wb2ludGVyZG93bkxpc3RlbmVyS2V5XyA9IGxpc3RlbihlbGVtZW50LCBQb2ludGVyRXZlbnRUeXBlLlBPSU5URVJET1dOLCBfdGhpcy5oYW5kbGVQb2ludGVyRG93bl8sIF90aGlzKTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7UG9pbnRlckV2ZW50fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5vcmlnaW5hbFBvaW50ZXJNb3ZlRXZlbnRfO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5yZWxheWVkTGlzdGVuZXJLZXlfID0gbGlzdGVuKGVsZW1lbnQsIFBvaW50ZXJFdmVudFR5cGUuUE9JTlRFUk1PVkUsIF90aGlzLnJlbGF5RXZlbnRfLCBfdGhpcyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmJvdW5kSGFuZGxlVG91Y2hNb3ZlXyA9IF90aGlzLmhhbmRsZVRvdWNoTW92ZV8uYmluZChfdGhpcyk7XG5cbiAgICBfdGhpcy5lbGVtZW50Xy5hZGRFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5UT1VDSE1PVkUsIF90aGlzLmJvdW5kSGFuZGxlVG91Y2hNb3ZlXywgUEFTU0lWRV9FVkVOVF9MSVNURU5FUlMgPyB7XG4gICAgICBwYXNzaXZlOiBmYWxzZVxuICAgIH0gOiBmYWxzZSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7UG9pbnRlckV2ZW50fSBwb2ludGVyRXZlbnQgUG9pbnRlclxuICAgKiBldmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBNYXBCcm93c2VyRXZlbnRIYW5kbGVyLnByb3RvdHlwZS5lbXVsYXRlQ2xpY2tfID0gZnVuY3Rpb24gKHBvaW50ZXJFdmVudCkge1xuICAgIHZhciBuZXdFdmVudCA9IG5ldyBNYXBCcm93c2VyRXZlbnQoTWFwQnJvd3NlckV2ZW50VHlwZS5DTElDSywgdGhpcy5tYXBfLCBwb2ludGVyRXZlbnQpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXdFdmVudCk7XG5cbiAgICBpZiAodGhpcy5jbGlja1RpbWVvdXRJZF8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gZG91YmxlLWNsaWNrXG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5jbGlja1RpbWVvdXRJZF8pO1xuICAgICAgdGhpcy5jbGlja1RpbWVvdXRJZF8gPSB1bmRlZmluZWQ7XG4gICAgICBuZXdFdmVudCA9IG5ldyBNYXBCcm93c2VyRXZlbnQoTWFwQnJvd3NlckV2ZW50VHlwZS5EQkxDTElDSywgdGhpcy5tYXBfLCBwb2ludGVyRXZlbnQpO1xuICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ld0V2ZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gY2xpY2tcbiAgICAgIHRoaXMuY2xpY2tUaW1lb3V0SWRfID0gc2V0VGltZW91dChcbiAgICAgIC8qKiBAdGhpcyB7TWFwQnJvd3NlckV2ZW50SGFuZGxlcn0gKi9cbiAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jbGlja1RpbWVvdXRJZF8gPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBuZXdFdmVudCA9IG5ldyBNYXBCcm93c2VyRXZlbnQoTWFwQnJvd3NlckV2ZW50VHlwZS5TSU5HTEVDTElDSywgdGhpcy5tYXBfLCBwb2ludGVyRXZlbnQpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3RXZlbnQpO1xuICAgICAgfS5iaW5kKHRoaXMpLCAyNTApO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEtlZXBzIHRyYWNrIG9uIGhvdyBtYW55IHBvaW50ZXJzIGFyZSBjdXJyZW50bHkgYWN0aXZlLlxuICAgKlxuICAgKiBAcGFyYW0ge1BvaW50ZXJFdmVudH0gcG9pbnRlckV2ZW50IFBvaW50ZXJcbiAgICogZXZlbnQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTWFwQnJvd3NlckV2ZW50SGFuZGxlci5wcm90b3R5cGUudXBkYXRlQWN0aXZlUG9pbnRlcnNfID0gZnVuY3Rpb24gKHBvaW50ZXJFdmVudCkge1xuICAgIHZhciBldmVudCA9IHBvaW50ZXJFdmVudDtcblxuICAgIGlmIChldmVudC50eXBlID09IE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUlVQIHx8IGV2ZW50LnR5cGUgPT0gTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSQ0FOQ0VMKSB7XG4gICAgICBkZWxldGUgdGhpcy50cmFja2VkVG91Y2hlc19bZXZlbnQucG9pbnRlcklkXTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT0gTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSRE9XTikge1xuICAgICAgdGhpcy50cmFja2VkVG91Y2hlc19bZXZlbnQucG9pbnRlcklkXSA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy5hY3RpdmVQb2ludGVyc18gPSBPYmplY3Qua2V5cyh0aGlzLnRyYWNrZWRUb3VjaGVzXykubGVuZ3RoO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtQb2ludGVyRXZlbnR9IHBvaW50ZXJFdmVudCBQb2ludGVyXG4gICAqIGV2ZW50LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIE1hcEJyb3dzZXJFdmVudEhhbmRsZXIucHJvdG90eXBlLmhhbmRsZVBvaW50ZXJVcF8gPSBmdW5jdGlvbiAocG9pbnRlckV2ZW50KSB7XG4gICAgdGhpcy51cGRhdGVBY3RpdmVQb2ludGVyc18ocG9pbnRlckV2ZW50KTtcbiAgICB2YXIgbmV3RXZlbnQgPSBuZXcgTWFwQnJvd3NlckV2ZW50KE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUlVQLCB0aGlzLm1hcF8sIHBvaW50ZXJFdmVudCk7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ld0V2ZW50KTsgLy8gV2UgZW11bGF0ZSBjbGljayBldmVudHMgb24gbGVmdCBtb3VzZSBidXR0b24gY2xpY2ssIHRvdWNoIGNvbnRhY3QsIGFuZCBwZW5cbiAgICAvLyBjb250YWN0LiBpc01vdXNlQWN0aW9uQnV0dG9uIHJldHVybnMgdHJ1ZSBpbiB0aGVzZSBjYXNlcyAoZXZ0LmJ1dHRvbiBpcyBzZXRcbiAgICAvLyB0byAwKS5cbiAgICAvLyBTZWUgaHR0cDovL3d3dy53My5vcmcvVFIvcG9pbnRlcmV2ZW50cy8jYnV0dG9uLXN0YXRlc1xuICAgIC8vIFdlIG9ubHkgZmlyZSBjbGljaywgc2luZ2xlY2xpY2ssIGFuZCBkb3VibGVjbGljayBpZiBub2JvZHkgaGFzIGNhbGxlZFxuICAgIC8vIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpIG9yIGV2ZW50LnByZXZlbnREZWZhdWx0KCkuXG5cbiAgICBpZiAodGhpcy5lbXVsYXRlQ2xpY2tzXyAmJiAhbmV3RXZlbnQucHJvcGFnYXRpb25TdG9wcGVkICYmICF0aGlzLmRyYWdnaW5nXyAmJiB0aGlzLmlzTW91c2VBY3Rpb25CdXR0b25fKHBvaW50ZXJFdmVudCkpIHtcbiAgICAgIHRoaXMuZW11bGF0ZUNsaWNrXyh0aGlzLmRvd25fKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hY3RpdmVQb2ludGVyc18gPT09IDApIHtcbiAgICAgIHRoaXMuZHJhZ0xpc3RlbmVyS2V5c18uZm9yRWFjaCh1bmxpc3RlbkJ5S2V5KTtcbiAgICAgIHRoaXMuZHJhZ0xpc3RlbmVyS2V5c18ubGVuZ3RoID0gMDtcbiAgICAgIHRoaXMuZHJhZ2dpbmdfID0gZmFsc2U7XG4gICAgICB0aGlzLmRvd25fID0gbnVsbDtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge1BvaW50ZXJFdmVudH0gcG9pbnRlckV2ZW50IFBvaW50ZXJcbiAgICogZXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBsZWZ0IG1vdXNlIGJ1dHRvbiB3YXMgcHJlc3NlZC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBNYXBCcm93c2VyRXZlbnRIYW5kbGVyLnByb3RvdHlwZS5pc01vdXNlQWN0aW9uQnV0dG9uXyA9IGZ1bmN0aW9uIChwb2ludGVyRXZlbnQpIHtcbiAgICByZXR1cm4gcG9pbnRlckV2ZW50LmJ1dHRvbiA9PT0gMDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7UG9pbnRlckV2ZW50fSBwb2ludGVyRXZlbnQgUG9pbnRlclxuICAgKiBldmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBNYXBCcm93c2VyRXZlbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVQb2ludGVyRG93bl8gPSBmdW5jdGlvbiAocG9pbnRlckV2ZW50KSB7XG4gICAgdGhpcy5lbXVsYXRlQ2xpY2tzXyA9IHRoaXMuYWN0aXZlUG9pbnRlcnNfID09PSAwO1xuICAgIHRoaXMudXBkYXRlQWN0aXZlUG9pbnRlcnNfKHBvaW50ZXJFdmVudCk7XG4gICAgdmFyIG5ld0V2ZW50ID0gbmV3IE1hcEJyb3dzZXJFdmVudChNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJET1dOLCB0aGlzLm1hcF8sIHBvaW50ZXJFdmVudCk7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ld0V2ZW50KTtcbiAgICB0aGlzLmRvd25fID0gcG9pbnRlckV2ZW50O1xuXG4gICAgaWYgKHRoaXMuZHJhZ0xpc3RlbmVyS2V5c18ubGVuZ3RoID09PSAwKSB7XG4gICAgICB2YXIgZG9jID0gdGhpcy5tYXBfLmdldE93bmVyRG9jdW1lbnQoKTtcbiAgICAgIHRoaXMuZHJhZ0xpc3RlbmVyS2V5c18ucHVzaChsaXN0ZW4oZG9jLCBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJNT1ZFLCB0aGlzLmhhbmRsZVBvaW50ZXJNb3ZlXywgdGhpcyksIGxpc3Rlbihkb2MsIE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUlVQLCB0aGlzLmhhbmRsZVBvaW50ZXJVcF8sIHRoaXMpLFxuICAgICAgLyogTm90ZSB0aGF0IHRoZSBsaXN0ZW5lciBmb3IgYHBvaW50ZXJjYW5jZWwgaXMgc2V0IHVwIG9uXG4gICAgICAgKiBgcG9pbnRlckV2ZW50SGFuZGxlcl9gIGFuZCBub3QgYGRvY3VtZW50UG9pbnRlckV2ZW50SGFuZGxlcl9gIGxpa2VcbiAgICAgICAqIHRoZSBgcG9pbnRlcnVwYCBhbmQgYHBvaW50ZXJtb3ZlYCBsaXN0ZW5lcnMuXG4gICAgICAgKlxuICAgICAgICogVGhlIHJlYXNvbiBmb3IgdGhpcyBpcyB0aGUgZm9sbG93aW5nOiBgVG91Y2hTb3VyY2UudmFjdXVtVG91Y2hlc18oKWBcbiAgICAgICAqIGlzc3VlcyBgcG9pbnRlcmNhbmNlbGAgZXZlbnRzLCB3aGVuIHRoZXJlIHdhcyBubyBgdG91Y2hlbmRgIGZvciBhXG4gICAgICAgKiBgdG91Y2hzdGFydGAuIE5vdywgbGV0J3Mgc2F5IGEgZmlyc3QgYHRvdWNoc3RhcnRgIGlzIHJlZ2lzdGVyZWQgb25cbiAgICAgICAqIGBwb2ludGVyRXZlbnRIYW5kbGVyX2AuIFRoZSBgZG9jdW1lbnRQb2ludGVyRXZlbnRIYW5kbGVyX2AgaXMgc2V0IHVwLlxuICAgICAgICogQnV0IGBkb2N1bWVudFBvaW50ZXJFdmVudEhhbmRsZXJfYCBkb2Vzbid0IGtub3cgYWJvdXQgdGhlIGZpcnN0XG4gICAgICAgKiBgdG91Y2hzdGFydGAuIElmIHRoZXJlIGlzIG5vIGB0b3VjaGVuZGAgZm9yIHRoZSBgdG91Y2hzdGFydGAsIHdlIGNhblxuICAgICAgICogb25seSByZWNlaXZlIGEgYHRvdWNoY2FuY2VsYCBmcm9tIGBwb2ludGVyRXZlbnRIYW5kbGVyX2AsIGJlY2F1c2UgaXQgaXNcbiAgICAgICAqIG9ubHkgcmVnaXN0ZXJlZCB0aGVyZS5cbiAgICAgICAqL1xuICAgICAgbGlzdGVuKHRoaXMuZWxlbWVudF8sIE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUkNBTkNFTCwgdGhpcy5oYW5kbGVQb2ludGVyVXBfLCB0aGlzKSk7XG5cbiAgICAgIGlmICh0aGlzLmVsZW1lbnRfLmdldFJvb3ROb2RlICYmIHRoaXMuZWxlbWVudF8uZ2V0Um9vdE5vZGUoKSAhPT0gZG9jKSB7XG4gICAgICAgIHRoaXMuZHJhZ0xpc3RlbmVyS2V5c18ucHVzaChsaXN0ZW4odGhpcy5lbGVtZW50Xy5nZXRSb290Tm9kZSgpLCBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJVUCwgdGhpcy5oYW5kbGVQb2ludGVyVXBfLCB0aGlzKSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtQb2ludGVyRXZlbnR9IHBvaW50ZXJFdmVudCBQb2ludGVyXG4gICAqIGV2ZW50LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIE1hcEJyb3dzZXJFdmVudEhhbmRsZXIucHJvdG90eXBlLmhhbmRsZVBvaW50ZXJNb3ZlXyA9IGZ1bmN0aW9uIChwb2ludGVyRXZlbnQpIHtcbiAgICAvLyBCZXR3ZWVuIHBvaW50ZXJkb3duIGFuZCBwb2ludGVydXAsIHBvaW50ZXJtb3ZlIGV2ZW50cyBhcmUgdHJpZ2dlcmVkLlxuICAgIC8vIFRvIGF2b2lkIGEgJ2ZhbHNlJyB0b3VjaG1vdmUgZXZlbnQgdG8gYmUgZGlzcGF0Y2hlZCwgd2UgdGVzdCBpZiB0aGUgcG9pbnRlclxuICAgIC8vIG1vdmVkIGEgc2lnbmlmaWNhbnQgZGlzdGFuY2UuXG4gICAgaWYgKHRoaXMuaXNNb3ZpbmdfKHBvaW50ZXJFdmVudCkpIHtcbiAgICAgIHRoaXMuZHJhZ2dpbmdfID0gdHJ1ZTtcbiAgICAgIHZhciBuZXdFdmVudCA9IG5ldyBNYXBCcm93c2VyRXZlbnQoTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSRFJBRywgdGhpcy5tYXBfLCBwb2ludGVyRXZlbnQsIHRoaXMuZHJhZ2dpbmdfKTtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXdFdmVudCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogV3JhcCBhbmQgcmVsYXkgYSBwb2ludGVyIGV2ZW50LiAgTm90ZSB0aGF0IHRoaXMgcmVxdWlyZXMgdGhhdCB0aGUgdHlwZVxuICAgKiBzdHJpbmcgZm9yIHRoZSBNYXBCcm93c2VyRXZlbnQgbWF0Y2hlcyB0aGUgUG9pbnRlckV2ZW50IHR5cGUuXG4gICAqIEBwYXJhbSB7UG9pbnRlckV2ZW50fSBwb2ludGVyRXZlbnQgUG9pbnRlclxuICAgKiBldmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBNYXBCcm93c2VyRXZlbnRIYW5kbGVyLnByb3RvdHlwZS5yZWxheUV2ZW50XyA9IGZ1bmN0aW9uIChwb2ludGVyRXZlbnQpIHtcbiAgICB0aGlzLm9yaWdpbmFsUG9pbnRlck1vdmVFdmVudF8gPSBwb2ludGVyRXZlbnQ7XG4gICAgdmFyIGRyYWdnaW5nID0gISEodGhpcy5kb3duXyAmJiB0aGlzLmlzTW92aW5nXyhwb2ludGVyRXZlbnQpKTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IE1hcEJyb3dzZXJFdmVudChwb2ludGVyRXZlbnQudHlwZSwgdGhpcy5tYXBfLCBwb2ludGVyRXZlbnQsIGRyYWdnaW5nKSk7XG4gIH07XG4gIC8qKlxuICAgKiBGbGV4aWJsZSBoYW5kbGluZyBvZiBhIGB0b3VjaC1hY3Rpb246IG5vbmVgIGNzcyBlcXVpdmFsZW50OiBiZWNhdXNlIGNhbGxpbmdcbiAgICogYHByZXZlbnREZWZhdWx0KClgIG9uIGEgYHBvaW50ZXJtb3ZlYCBldmVudCBkb2VzIG5vdCBzdG9wIG5hdGl2ZSBwYWdlIHNjcm9sbGluZ1xuICAgKiBhbmQgem9vbWluZywgd2UgYWxzbyBsaXN0ZW4gZm9yIGB0b3VjaG1vdmVgIGFuZCBjYWxsIGBwcmV2ZW50RGVmYXVsdCgpYCBvbiBpdFxuICAgKiB3aGVuIGFuIGludGVyYWN0aW9uIChjdXJyZW50bHkgYERyYWdQYW5gIGhhbmRsZXMgdGhlIGV2ZW50LlxuICAgKiBAcGFyYW0ge1RvdWNoRXZlbnR9IGV2ZW50IEV2ZW50LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIE1hcEJyb3dzZXJFdmVudEhhbmRsZXIucHJvdG90eXBlLmhhbmRsZVRvdWNoTW92ZV8gPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAvLyBEdWUgdG8gaHR0cHM6Ly9naXRodWIuY29tL21waXplbmJlcmcvZWxtLXBlcC9pc3N1ZXMvMiwgYHRoaXMub3JpZ2luYWxQb2ludGVyTW92ZUV2ZW50X2BcbiAgICAvLyBtYXkgbm90IGJlIGluaXRpYWxpemVkIHlldCB3aGVuIHdlIGdldCBoZXJlIG9uIGEgcGxhdGZvcm0gd2l0aG91dCBuYXRpdmUgcG9pbnRlciBldmVudHMuXG4gICAgaWYgKCF0aGlzLm9yaWdpbmFsUG9pbnRlck1vdmVFdmVudF8gfHwgdGhpcy5vcmlnaW5hbFBvaW50ZXJNb3ZlRXZlbnRfLmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtQb2ludGVyRXZlbnR9IHBvaW50ZXJFdmVudCBQb2ludGVyXG4gICAqIGV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJcyBtb3ZpbmcuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTWFwQnJvd3NlckV2ZW50SGFuZGxlci5wcm90b3R5cGUuaXNNb3ZpbmdfID0gZnVuY3Rpb24gKHBvaW50ZXJFdmVudCkge1xuICAgIHJldHVybiB0aGlzLmRyYWdnaW5nXyB8fCBNYXRoLmFicyhwb2ludGVyRXZlbnQuY2xpZW50WCAtIHRoaXMuZG93bl8uY2xpZW50WCkgPiB0aGlzLm1vdmVUb2xlcmFuY2VfIHx8IE1hdGguYWJzKHBvaW50ZXJFdmVudC5jbGllbnRZIC0gdGhpcy5kb3duXy5jbGllbnRZKSA+IHRoaXMubW92ZVRvbGVyYW5jZV87XG4gIH07XG4gIC8qKlxuICAgKiBDbGVhbiB1cC5cbiAgICovXG5cblxuICBNYXBCcm93c2VyRXZlbnRIYW5kbGVyLnByb3RvdHlwZS5kaXNwb3NlSW50ZXJuYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMucmVsYXllZExpc3RlbmVyS2V5Xykge1xuICAgICAgdW5saXN0ZW5CeUtleSh0aGlzLnJlbGF5ZWRMaXN0ZW5lcktleV8pO1xuICAgICAgdGhpcy5yZWxheWVkTGlzdGVuZXJLZXlfID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLmVsZW1lbnRfLnJlbW92ZUV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLlRPVUNITU9WRSwgdGhpcy5ib3VuZEhhbmRsZVRvdWNoTW92ZV8pO1xuXG4gICAgaWYgKHRoaXMucG9pbnRlcmRvd25MaXN0ZW5lcktleV8pIHtcbiAgICAgIHVubGlzdGVuQnlLZXkodGhpcy5wb2ludGVyZG93bkxpc3RlbmVyS2V5Xyk7XG4gICAgICB0aGlzLnBvaW50ZXJkb3duTGlzdGVuZXJLZXlfID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLmRyYWdMaXN0ZW5lcktleXNfLmZvckVhY2godW5saXN0ZW5CeUtleSk7XG4gICAgdGhpcy5kcmFnTGlzdGVuZXJLZXlzXy5sZW5ndGggPSAwO1xuICAgIHRoaXMuZWxlbWVudF8gPSBudWxsO1xuXG4gICAgX3N1cGVyLnByb3RvdHlwZS5kaXNwb3NlSW50ZXJuYWwuY2FsbCh0aGlzKTtcbiAgfTtcblxuICByZXR1cm4gTWFwQnJvd3NlckV2ZW50SGFuZGxlcjtcbn0oRXZlbnRUYXJnZXQpO1xuXG5leHBvcnQgZGVmYXVsdCBNYXBCcm93c2VyRXZlbnRIYW5kbGVyOyIsIi8qKlxuICogQG1vZHVsZSBvbC9NYXBFdmVudFR5cGVcbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFRyaWdnZXJlZCBhZnRlciBhIG1hcCBmcmFtZSBpcyByZW5kZXJlZC5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9NYXBFdmVudH5NYXBFdmVudCNwb3N0cmVuZGVyXG4gICAqIEBhcGlcbiAgICovXG4gIFBPU1RSRU5ERVI6ICdwb3N0cmVuZGVyJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIHdoZW4gdGhlIG1hcCBzdGFydHMgbW92aW5nLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL01hcEV2ZW50fk1hcEV2ZW50I21vdmVzdGFydFxuICAgKiBAYXBpXG4gICAqL1xuICBNT1ZFU1RBUlQ6ICdtb3Zlc3RhcnQnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgYWZ0ZXIgdGhlIG1hcCBpcyBtb3ZlZC5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9NYXBFdmVudH5NYXBFdmVudCNtb3ZlZW5kXG4gICAqIEBhcGlcbiAgICovXG4gIE1PVkVFTkQ6ICdtb3ZlZW5kJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvTWFwUHJvcGVydHlcbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgTEFZRVJHUk9VUDogJ2xheWVyZ3JvdXAnLFxuICBTSVpFOiAnc2l6ZScsXG4gIFRBUkdFVDogJ3RhcmdldCcsXG4gIFZJRVc6ICd2aWV3J1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvc3RydWN0cy9Qcmlvcml0eVF1ZXVlXG4gKi9cbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uL2Fzc2VydHMuanMnO1xuaW1wb3J0IHsgY2xlYXIgfSBmcm9tICcuLi9vYmouanMnO1xuLyoqXG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5cbmV4cG9ydCB2YXIgRFJPUCA9IEluZmluaXR5O1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBQcmlvcml0eSBxdWV1ZS5cbiAqXG4gKiBUaGUgaW1wbGVtZW50YXRpb24gaXMgaW5zcGlyZWQgZnJvbSB0aGUgQ2xvc3VyZSBMaWJyYXJ5J3MgSGVhcCBjbGFzcyBhbmRcbiAqIFB5dGhvbidzIGhlYXBxIG1vZHVsZS5cbiAqXG4gKiBTZWUgaHR0cDovL2Nsb3N1cmUtbGlicmFyeS5nb29nbGVjb2RlLmNvbS9zdm4vZG9jcy9jbG9zdXJlX2dvb2dfc3RydWN0c19oZWFwLmpzLnNvdXJjZS5odG1sXG4gKiBhbmQgaHR0cDovL2hnLnB5dGhvbi5vcmcvY3B5dGhvbi9maWxlLzIuNy9MaWIvaGVhcHEucHkuXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqL1xuXG52YXIgUHJpb3JpdHlRdWV1ZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKFQpOiBudW1iZXJ9IHByaW9yaXR5RnVuY3Rpb24gUHJpb3JpdHkgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oVCk6IHN0cmluZ30ga2V5RnVuY3Rpb24gS2V5IGZ1bmN0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gUHJpb3JpdHlRdWV1ZShwcmlvcml0eUZ1bmN0aW9uLCBrZXlGdW5jdGlvbikge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtmdW5jdGlvbihUKTogbnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgdGhpcy5wcmlvcml0eUZ1bmN0aW9uXyA9IHByaW9yaXR5RnVuY3Rpb247XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Z1bmN0aW9uKFQpOiBzdHJpbmd9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIHRoaXMua2V5RnVuY3Rpb25fID0ga2V5RnVuY3Rpb247XG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PFQ+fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLmVsZW1lbnRzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLnByaW9yaXRpZXNfID0gW107XG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBib29sZWFuPn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgdGhpcy5xdWV1ZWRFbGVtZW50c18gPSB7fTtcbiAgfVxuICAvKipcbiAgICogRklYTUUgZW1wdHkgZGVzY3JpcHRpb24gZm9yIGpzZG9jXG4gICAqL1xuXG5cbiAgUHJpb3JpdHlRdWV1ZS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5lbGVtZW50c18ubGVuZ3RoID0gMDtcbiAgICB0aGlzLnByaW9yaXRpZXNfLmxlbmd0aCA9IDA7XG4gICAgY2xlYXIodGhpcy5xdWV1ZWRFbGVtZW50c18pO1xuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIGFuZCByZXR1cm4gdGhlIGhpZ2hlc3QtcHJpb3JpdHkgZWxlbWVudC4gTyhsb2cgTikuXG4gICAqIEByZXR1cm4ge1R9IEVsZW1lbnQuXG4gICAqL1xuXG5cbiAgUHJpb3JpdHlRdWV1ZS5wcm90b3R5cGUuZGVxdWV1ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZWxlbWVudHMgPSB0aGlzLmVsZW1lbnRzXztcbiAgICB2YXIgcHJpb3JpdGllcyA9IHRoaXMucHJpb3JpdGllc187XG4gICAgdmFyIGVsZW1lbnQgPSBlbGVtZW50c1swXTtcblxuICAgIGlmIChlbGVtZW50cy5sZW5ndGggPT0gMSkge1xuICAgICAgZWxlbWVudHMubGVuZ3RoID0gMDtcbiAgICAgIHByaW9yaXRpZXMubGVuZ3RoID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudHNbMF0gPSBlbGVtZW50cy5wb3AoKTtcbiAgICAgIHByaW9yaXRpZXNbMF0gPSBwcmlvcml0aWVzLnBvcCgpO1xuICAgICAgdGhpcy5zaWZ0VXBfKDApO1xuICAgIH1cblxuICAgIHZhciBlbGVtZW50S2V5ID0gdGhpcy5rZXlGdW5jdGlvbl8oZWxlbWVudCk7XG4gICAgZGVsZXRlIHRoaXMucXVldWVkRWxlbWVudHNfW2VsZW1lbnRLZXldO1xuICAgIHJldHVybiBlbGVtZW50O1xuICB9O1xuICAvKipcbiAgICogRW5xdWV1ZSBhbiBlbGVtZW50LiBPKGxvZyBOKS5cbiAgICogQHBhcmFtIHtUfSBlbGVtZW50IEVsZW1lbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBlbGVtZW50IHdhcyBhZGRlZCB0byB0aGUgcXVldWUuXG4gICAqL1xuXG5cbiAgUHJpb3JpdHlRdWV1ZS5wcm90b3R5cGUuZW5xdWV1ZSA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgYXNzZXJ0KCEodGhpcy5rZXlGdW5jdGlvbl8oZWxlbWVudCkgaW4gdGhpcy5xdWV1ZWRFbGVtZW50c18pLCAzMSk7IC8vIFRyaWVkIHRvIGVucXVldWUgYW4gYGVsZW1lbnRgIHRoYXQgd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhlIHF1ZXVlXG5cbiAgICB2YXIgcHJpb3JpdHkgPSB0aGlzLnByaW9yaXR5RnVuY3Rpb25fKGVsZW1lbnQpO1xuXG4gICAgaWYgKHByaW9yaXR5ICE9IERST1ApIHtcbiAgICAgIHRoaXMuZWxlbWVudHNfLnB1c2goZWxlbWVudCk7XG4gICAgICB0aGlzLnByaW9yaXRpZXNfLnB1c2gocHJpb3JpdHkpO1xuICAgICAgdGhpcy5xdWV1ZWRFbGVtZW50c19bdGhpcy5rZXlGdW5jdGlvbl8oZWxlbWVudCldID0gdHJ1ZTtcbiAgICAgIHRoaXMuc2lmdERvd25fKDAsIHRoaXMuZWxlbWVudHNfLmxlbmd0aCAtIDEpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBDb3VudC5cbiAgICovXG5cblxuICBQcmlvcml0eVF1ZXVlLnByb3RvdHlwZS5nZXRDb3VudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50c18ubGVuZ3RoO1xuICB9O1xuICAvKipcbiAgICogR2V0cyB0aGUgaW5kZXggb2YgdGhlIGxlZnQgY2hpbGQgb2YgdGhlIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4LlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBub2RlIHRvIGdldCB0aGUgbGVmdCBjaGlsZCBmb3IuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBsZWZ0IGNoaWxkLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLmdldExlZnRDaGlsZEluZGV4XyA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgIHJldHVybiBpbmRleCAqIDIgKyAxO1xuICB9O1xuICAvKipcbiAgICogR2V0cyB0aGUgaW5kZXggb2YgdGhlIHJpZ2h0IGNoaWxkIG9mIHRoZSBub2RlIGF0IHRoZSBnaXZlbiBpbmRleC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbm9kZSB0byBnZXQgdGhlIHJpZ2h0IGNoaWxkIGZvci5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgaW5kZXggb2YgdGhlIHJpZ2h0IGNoaWxkLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLmdldFJpZ2h0Q2hpbGRJbmRleF8gPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICByZXR1cm4gaW5kZXggKiAyICsgMjtcbiAgfTtcbiAgLyoqXG4gICAqIEdldHMgdGhlIGluZGV4IG9mIHRoZSBwYXJlbnQgb2YgdGhlIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4LlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBub2RlIHRvIGdldCB0aGUgcGFyZW50IGZvci5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgaW5kZXggb2YgdGhlIHBhcmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQcmlvcml0eVF1ZXVlLnByb3RvdHlwZS5nZXRQYXJlbnRJbmRleF8gPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICByZXR1cm4gaW5kZXggLSAxID4+IDE7XG4gIH07XG4gIC8qKlxuICAgKiBNYWtlIHRoaXMgYSBoZWFwLiBPKE4pLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLmhlYXBpZnlfID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBpO1xuXG4gICAgZm9yIChpID0gKHRoaXMuZWxlbWVudHNfLmxlbmd0aCA+PiAxKSAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB0aGlzLnNpZnRVcF8oaSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSXMgZW1wdHkuXG4gICAqL1xuXG5cbiAgUHJpb3JpdHlRdWV1ZS5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50c18ubGVuZ3RoID09PSAwO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElzIGtleSBxdWV1ZWQuXG4gICAqL1xuXG5cbiAgUHJpb3JpdHlRdWV1ZS5wcm90b3R5cGUuaXNLZXlRdWV1ZWQgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIGtleSBpbiB0aGlzLnF1ZXVlZEVsZW1lbnRzXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7VH0gZWxlbWVudCBFbGVtZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJcyBxdWV1ZWQuXG4gICAqL1xuXG5cbiAgUHJpb3JpdHlRdWV1ZS5wcm90b3R5cGUuaXNRdWV1ZWQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHJldHVybiB0aGlzLmlzS2V5UXVldWVkKHRoaXMua2V5RnVuY3Rpb25fKGVsZW1lbnQpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIG5vZGUgdG8gbW92ZSBkb3duLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLnNpZnRVcF8gPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICB2YXIgZWxlbWVudHMgPSB0aGlzLmVsZW1lbnRzXztcbiAgICB2YXIgcHJpb3JpdGllcyA9IHRoaXMucHJpb3JpdGllc187XG4gICAgdmFyIGNvdW50ID0gZWxlbWVudHMubGVuZ3RoO1xuICAgIHZhciBlbGVtZW50ID0gZWxlbWVudHNbaW5kZXhdO1xuICAgIHZhciBwcmlvcml0eSA9IHByaW9yaXRpZXNbaW5kZXhdO1xuICAgIHZhciBzdGFydEluZGV4ID0gaW5kZXg7XG5cbiAgICB3aGlsZSAoaW5kZXggPCBjb3VudCA+PiAxKSB7XG4gICAgICB2YXIgbEluZGV4ID0gdGhpcy5nZXRMZWZ0Q2hpbGRJbmRleF8oaW5kZXgpO1xuICAgICAgdmFyIHJJbmRleCA9IHRoaXMuZ2V0UmlnaHRDaGlsZEluZGV4XyhpbmRleCk7XG4gICAgICB2YXIgc21hbGxlckNoaWxkSW5kZXggPSBySW5kZXggPCBjb3VudCAmJiBwcmlvcml0aWVzW3JJbmRleF0gPCBwcmlvcml0aWVzW2xJbmRleF0gPyBySW5kZXggOiBsSW5kZXg7XG4gICAgICBlbGVtZW50c1tpbmRleF0gPSBlbGVtZW50c1tzbWFsbGVyQ2hpbGRJbmRleF07XG4gICAgICBwcmlvcml0aWVzW2luZGV4XSA9IHByaW9yaXRpZXNbc21hbGxlckNoaWxkSW5kZXhdO1xuICAgICAgaW5kZXggPSBzbWFsbGVyQ2hpbGRJbmRleDtcbiAgICB9XG5cbiAgICBlbGVtZW50c1tpbmRleF0gPSBlbGVtZW50O1xuICAgIHByaW9yaXRpZXNbaW5kZXhdID0gcHJpb3JpdHk7XG4gICAgdGhpcy5zaWZ0RG93bl8oc3RhcnRJbmRleCwgaW5kZXgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0SW5kZXggVGhlIGluZGV4IG9mIHRoZSByb290LlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBub2RlIHRvIG1vdmUgdXAuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgUHJpb3JpdHlRdWV1ZS5wcm90b3R5cGUuc2lmdERvd25fID0gZnVuY3Rpb24gKHN0YXJ0SW5kZXgsIGluZGV4KSB7XG4gICAgdmFyIGVsZW1lbnRzID0gdGhpcy5lbGVtZW50c187XG4gICAgdmFyIHByaW9yaXRpZXMgPSB0aGlzLnByaW9yaXRpZXNfO1xuICAgIHZhciBlbGVtZW50ID0gZWxlbWVudHNbaW5kZXhdO1xuICAgIHZhciBwcmlvcml0eSA9IHByaW9yaXRpZXNbaW5kZXhdO1xuXG4gICAgd2hpbGUgKGluZGV4ID4gc3RhcnRJbmRleCkge1xuICAgICAgdmFyIHBhcmVudEluZGV4ID0gdGhpcy5nZXRQYXJlbnRJbmRleF8oaW5kZXgpO1xuXG4gICAgICBpZiAocHJpb3JpdGllc1twYXJlbnRJbmRleF0gPiBwcmlvcml0eSkge1xuICAgICAgICBlbGVtZW50c1tpbmRleF0gPSBlbGVtZW50c1twYXJlbnRJbmRleF07XG4gICAgICAgIHByaW9yaXRpZXNbaW5kZXhdID0gcHJpb3JpdGllc1twYXJlbnRJbmRleF07XG4gICAgICAgIGluZGV4ID0gcGFyZW50SW5kZXg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBlbGVtZW50c1tpbmRleF0gPSBlbGVtZW50O1xuICAgIHByaW9yaXRpZXNbaW5kZXhdID0gcHJpb3JpdHk7XG4gIH07XG4gIC8qKlxuICAgKiBGSVhNRSBlbXB0eSBkZXNjcmlwdGlvbiBmb3IganNkb2NcbiAgICovXG5cblxuICBQcmlvcml0eVF1ZXVlLnByb3RvdHlwZS5yZXByaW9yaXRpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHByaW9yaXR5RnVuY3Rpb24gPSB0aGlzLnByaW9yaXR5RnVuY3Rpb25fO1xuICAgIHZhciBlbGVtZW50cyA9IHRoaXMuZWxlbWVudHNfO1xuICAgIHZhciBwcmlvcml0aWVzID0gdGhpcy5wcmlvcml0aWVzXztcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBuID0gZWxlbWVudHMubGVuZ3RoO1xuICAgIHZhciBlbGVtZW50LCBpLCBwcmlvcml0eTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGVsZW1lbnQgPSBlbGVtZW50c1tpXTtcbiAgICAgIHByaW9yaXR5ID0gcHJpb3JpdHlGdW5jdGlvbihlbGVtZW50KTtcblxuICAgICAgaWYgKHByaW9yaXR5ID09IERST1ApIHtcbiAgICAgICAgZGVsZXRlIHRoaXMucXVldWVkRWxlbWVudHNfW3RoaXMua2V5RnVuY3Rpb25fKGVsZW1lbnQpXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByaW9yaXRpZXNbaW5kZXhdID0gcHJpb3JpdHk7XG4gICAgICAgIGVsZW1lbnRzW2luZGV4KytdID0gZWxlbWVudDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBlbGVtZW50cy5sZW5ndGggPSBpbmRleDtcbiAgICBwcmlvcml0aWVzLmxlbmd0aCA9IGluZGV4O1xuICAgIHRoaXMuaGVhcGlmeV8oKTtcbiAgfTtcblxuICByZXR1cm4gUHJpb3JpdHlRdWV1ZTtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgUHJpb3JpdHlRdWV1ZTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvVGlsZVN0YXRlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7bnVtYmVyfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIElETEU6IDAsXG4gIExPQURJTkc6IDEsXG4gIExPQURFRDogMixcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgdGlsZSBsb2FkaW5nIGZhaWxlZFxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgRVJST1I6IDMsXG4gIEVNUFRZOiA0XG59OyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvVGlsZVF1ZXVlXG4gKi9cblxuXG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4vZXZlbnRzL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgUHJpb3JpdHlRdWV1ZSwgeyBEUk9QIH0gZnJvbSAnLi9zdHJ1Y3RzL1ByaW9yaXR5UXVldWUuanMnO1xuaW1wb3J0IFRpbGVTdGF0ZSBmcm9tICcuL1RpbGVTdGF0ZS5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihpbXBvcnQoXCIuL1RpbGUuanNcIikuZGVmYXVsdCwgc3RyaW5nLCBpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSwgbnVtYmVyKTogbnVtYmVyfSBQcmlvcml0eUZ1bmN0aW9uXG4gKi9cblxudmFyIFRpbGVRdWV1ZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhUaWxlUXVldWUsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1ByaW9yaXR5RnVuY3Rpb259IHRpbGVQcmlvcml0eUZ1bmN0aW9uIFRpbGUgcHJpb3JpdHkgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oKTogP30gdGlsZUNoYW5nZUNhbGxiYWNrIEZ1bmN0aW9uIGNhbGxlZCBvbiBlYWNoIHRpbGUgY2hhbmdlIGV2ZW50LlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFRpbGVRdWV1ZSh0aWxlUHJpb3JpdHlGdW5jdGlvbiwgdGlsZUNoYW5nZUNhbGxiYWNrKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcyxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBlbGVtZW50IEVsZW1lbnQuXG4gICAgICogQHJldHVybiB7bnVtYmVyfSBQcmlvcml0eS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgcmV0dXJuIHRpbGVQcmlvcml0eUZ1bmN0aW9uLmFwcGx5KG51bGwsIGVsZW1lbnQpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBcnJheX0gZWxlbWVudCBFbGVtZW50LlxuICAgICAqIEByZXR1cm4ge3N0cmluZ30gS2V5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBlbGVtZW50WzBdLmdldEtleSgpXG4gICAgICApO1xuICAgIH0pIHx8IHRoaXM7XG4gICAgLyoqIEBwcml2YXRlICovXG5cblxuICAgIF90aGlzLmJvdW5kSGFuZGxlVGlsZUNoYW5nZV8gPSBfdGhpcy5oYW5kbGVUaWxlQ2hhbmdlLmJpbmQoX3RoaXMpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Z1bmN0aW9uKCk6ID99XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlQ2hhbmdlQ2FsbGJhY2tfID0gdGlsZUNoYW5nZUNhbGxiYWNrO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVzTG9hZGluZ18gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLGJvb2xlYW4+fVxuICAgICAqL1xuXG4gICAgX3RoaXMudGlsZXNMb2FkaW5nS2V5c18gPSB7fTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXl9IGVsZW1lbnQgRWxlbWVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIGVsZW1lbnQgd2FzIGFkZGVkIHRvIHRoZSBxdWV1ZS5cbiAgICovXG5cblxuICBUaWxlUXVldWUucHJvdG90eXBlLmVucXVldWUgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHZhciBhZGRlZCA9IF9zdXBlci5wcm90b3R5cGUuZW5xdWV1ZS5jYWxsKHRoaXMsIGVsZW1lbnQpO1xuXG4gICAgaWYgKGFkZGVkKSB7XG4gICAgICB2YXIgdGlsZSA9IGVsZW1lbnRbMF07XG4gICAgICB0aWxlLmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5ib3VuZEhhbmRsZVRpbGVDaGFuZ2VfKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYWRkZWQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE51bWJlciBvZiB0aWxlcyBsb2FkaW5nLlxuICAgKi9cblxuXG4gIFRpbGVRdWV1ZS5wcm90b3R5cGUuZ2V0VGlsZXNMb2FkaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnRpbGVzTG9hZGluZ187XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHR9IGV2ZW50IEV2ZW50LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgVGlsZVF1ZXVlLnByb3RvdHlwZS5oYW5kbGVUaWxlQ2hhbmdlID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdmFyIHRpbGUgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9UaWxlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgZXZlbnQudGFyZ2V0O1xuICAgIHZhciBzdGF0ZSA9IHRpbGUuZ2V0U3RhdGUoKTtcblxuICAgIGlmICh0aWxlLmhpZmkgJiYgc3RhdGUgPT09IFRpbGVTdGF0ZS5MT0FERUQgfHwgc3RhdGUgPT09IFRpbGVTdGF0ZS5FUlJPUiB8fCBzdGF0ZSA9PT0gVGlsZVN0YXRlLkVNUFRZKSB7XG4gICAgICB0aWxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5ib3VuZEhhbmRsZVRpbGVDaGFuZ2VfKTtcbiAgICAgIHZhciB0aWxlS2V5ID0gdGlsZS5nZXRLZXkoKTtcblxuICAgICAgaWYgKHRpbGVLZXkgaW4gdGhpcy50aWxlc0xvYWRpbmdLZXlzXykge1xuICAgICAgICBkZWxldGUgdGhpcy50aWxlc0xvYWRpbmdLZXlzX1t0aWxlS2V5XTtcbiAgICAgICAgLS10aGlzLnRpbGVzTG9hZGluZ187XG4gICAgICB9XG5cbiAgICAgIHRoaXMudGlsZUNoYW5nZUNhbGxiYWNrXygpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhUb3RhbExvYWRpbmcgTWF4aW11bSBudW1iZXIgdGlsZXMgdG8gbG9hZCBzaW11bHRhbmVvdXNseS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1heE5ld0xvYWRzIE1heGltdW0gbnVtYmVyIG9mIG5ldyB0aWxlcyB0byBsb2FkLlxuICAgKi9cblxuXG4gIFRpbGVRdWV1ZS5wcm90b3R5cGUubG9hZE1vcmVUaWxlcyA9IGZ1bmN0aW9uIChtYXhUb3RhbExvYWRpbmcsIG1heE5ld0xvYWRzKSB7XG4gICAgdmFyIG5ld0xvYWRzID0gMDtcbiAgICB2YXIgc3RhdGUsIHRpbGUsIHRpbGVLZXk7XG5cbiAgICB3aGlsZSAodGhpcy50aWxlc0xvYWRpbmdfIDwgbWF4VG90YWxMb2FkaW5nICYmIG5ld0xvYWRzIDwgbWF4TmV3TG9hZHMgJiYgdGhpcy5nZXRDb3VudCgpID4gMCkge1xuICAgICAgdGlsZSA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgdGhpcy5kZXF1ZXVlKClbMF07XG4gICAgICB0aWxlS2V5ID0gdGlsZS5nZXRLZXkoKTtcbiAgICAgIHN0YXRlID0gdGlsZS5nZXRTdGF0ZSgpO1xuXG4gICAgICBpZiAoc3RhdGUgPT09IFRpbGVTdGF0ZS5JRExFICYmICEodGlsZUtleSBpbiB0aGlzLnRpbGVzTG9hZGluZ0tleXNfKSkge1xuICAgICAgICB0aGlzLnRpbGVzTG9hZGluZ0tleXNfW3RpbGVLZXldID0gdHJ1ZTtcbiAgICAgICAgKyt0aGlzLnRpbGVzTG9hZGluZ187XG4gICAgICAgICsrbmV3TG9hZHM7XG4gICAgICAgIHRpbGUubG9hZCgpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gVGlsZVF1ZXVlO1xufShQcmlvcml0eVF1ZXVlKTtcblxuZXhwb3J0IGRlZmF1bHQgVGlsZVF1ZXVlO1xuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydCgnLi9QbHVnZ2FibGVNYXAuanMnKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL1RpbGUuanNcIikuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICogQHBhcmFtIHtzdHJpbmd9IHRpbGVTb3VyY2VLZXkgVGlsZSBzb3VyY2Uga2V5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gdGlsZUNlbnRlciBUaWxlIGNlbnRlci5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0aWxlUmVzb2x1dGlvbiBUaWxlIHJlc29sdXRpb24uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRpbGUgcHJpb3JpdHkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRpbGVQcmlvcml0eShmcmFtZVN0YXRlLCB0aWxlLCB0aWxlU291cmNlS2V5LCB0aWxlQ2VudGVyLCB0aWxlUmVzb2x1dGlvbikge1xuICAvLyBGaWx0ZXIgb3V0IHRpbGVzIGF0IGhpZ2hlciB6b29tIGxldmVscyB0aGFuIHRoZSBjdXJyZW50IHpvb20gbGV2ZWwsIG9yIHRoYXRcbiAgLy8gYXJlIG91dHNpZGUgdGhlIHZpc2libGUgZXh0ZW50LlxuICBpZiAoIWZyYW1lU3RhdGUgfHwgISh0aWxlU291cmNlS2V5IGluIGZyYW1lU3RhdGUud2FudGVkVGlsZXMpKSB7XG4gICAgcmV0dXJuIERST1A7XG4gIH1cblxuICBpZiAoIWZyYW1lU3RhdGUud2FudGVkVGlsZXNbdGlsZVNvdXJjZUtleV1bdGlsZS5nZXRLZXkoKV0pIHtcbiAgICByZXR1cm4gRFJPUDtcbiAgfSAvLyBQcmlvcml0aXplIHRoZSBoaWdoZXN0IHpvb20gbGV2ZWwgdGlsZXMgY2xvc2VzdCB0byB0aGUgZm9jdXMuXG4gIC8vIFRpbGVzIGF0IGhpZ2hlciB6b29tIGxldmVscyBhcmUgcHJpb3JpdGl6ZWQgdXNpbmcgTWF0aC5sb2codGlsZVJlc29sdXRpb24pLlxuICAvLyBXaXRoaW4gYSB6b29tIGxldmVsLCB0aWxlcyBhcmUgcHJpb3JpdGl6ZWQgYnkgdGhlIGRpc3RhbmNlIGluIHBpeGVscyBiZXR3ZWVuXG4gIC8vIHRoZSBjZW50ZXIgb2YgdGhlIHRpbGUgYW5kIHRoZSBjZW50ZXIgb2YgdGhlIHZpZXdwb3J0LiAgVGhlIGZhY3RvciBvZiA2NTUzNlxuICAvLyBtZWFucyB0aGF0IHRoZSBwcmlvcml0aXphdGlvbiBzaG91bGQgYmVoYXZlIGFzIGRlc2lyZWQgZm9yIHRpbGVzIHVwIHRvXG4gIC8vIDY1NTM2ICogTWF0aC5sb2coMikgPSA0NTQyNiBwaXhlbHMgZnJvbSB0aGUgZm9jdXMuXG5cblxuICB2YXIgY2VudGVyID0gZnJhbWVTdGF0ZS52aWV3U3RhdGUuY2VudGVyO1xuICB2YXIgZGVsdGFYID0gdGlsZUNlbnRlclswXSAtIGNlbnRlclswXTtcbiAgdmFyIGRlbHRhWSA9IHRpbGVDZW50ZXJbMV0gLSBjZW50ZXJbMV07XG4gIHJldHVybiA2NTUzNiAqIE1hdGgubG9nKHRpbGVSZXNvbHV0aW9uKSArIE1hdGguc3FydChkZWx0YVggKiBkZWx0YVggKyBkZWx0YVkgKiBkZWx0YVkpIC8gdGlsZVJlc29sdXRpb247XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vR2VvbWV0cnlUeXBlXG4gKi9cblxuLyoqXG4gKiBUaGUgZ2VvbWV0cnkgdHlwZS4gT25lIG9mIGAnUG9pbnQnYCwgYCdMaW5lU3RyaW5nJ2AsIGAnTGluZWFyUmluZydgLFxuICogYCdQb2x5Z29uJ2AsIGAnTXVsdGlQb2ludCdgLCBgJ011bHRpTGluZVN0cmluZydgLCBgJ011bHRpUG9seWdvbidgLFxuICogYCdHZW9tZXRyeUNvbGxlY3Rpb24nYCwgYCdDaXJjbGUnYC5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgUE9JTlQ6ICdQb2ludCcsXG4gIExJTkVfU1RSSU5HOiAnTGluZVN0cmluZycsXG4gIExJTkVBUl9SSU5HOiAnTGluZWFyUmluZycsXG4gIFBPTFlHT046ICdQb2x5Z29uJyxcbiAgTVVMVElfUE9JTlQ6ICdNdWx0aVBvaW50JyxcbiAgTVVMVElfTElORV9TVFJJTkc6ICdNdWx0aUxpbmVTdHJpbmcnLFxuICBNVUxUSV9QT0xZR09OOiAnTXVsdGlQb2x5Z29uJyxcbiAgR0VPTUVUUllfQ09MTEVDVElPTjogJ0dlb21ldHJ5Q29sbGVjdGlvbicsXG4gIENJUkNMRTogJ0NpcmNsZSdcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3Byb2ovVW5pdHNcbiAqL1xuXG4vKipcbiAqIFByb2plY3Rpb24gdW5pdHM6IGAnZGVncmVlcydgLCBgJ2Z0J2AsIGAnbSdgLCBgJ3BpeGVscydgLCBgJ3RpbGUtcGl4ZWxzJ2Agb3JcbiAqIGAndXMtZnQnYC5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbnZhciBVbml0cyA9IHtcbiAgLyoqXG4gICAqIERlZ3JlZXNcbiAgICogQGFwaVxuICAgKi9cbiAgREVHUkVFUzogJ2RlZ3JlZXMnLFxuXG4gIC8qKlxuICAgKiBGZWV0XG4gICAqIEBhcGlcbiAgICovXG4gIEZFRVQ6ICdmdCcsXG5cbiAgLyoqXG4gICAqIE1ldGVyc1xuICAgKiBAYXBpXG4gICAqL1xuICBNRVRFUlM6ICdtJyxcblxuICAvKipcbiAgICogUGl4ZWxzXG4gICAqIEBhcGlcbiAgICovXG4gIFBJWEVMUzogJ3BpeGVscycsXG5cbiAgLyoqXG4gICAqIFRpbGUgUGl4ZWxzXG4gICAqIEBhcGlcbiAgICovXG4gIFRJTEVfUElYRUxTOiAndGlsZS1waXhlbHMnLFxuXG4gIC8qKlxuICAgKiBVUyBGZWV0XG4gICAqIEBhcGlcbiAgICovXG4gIFVTRkVFVDogJ3VzLWZ0J1xufTtcbi8qKlxuICogTWV0ZXJzIHBlciB1bml0IGxvb2t1cCB0YWJsZS5cbiAqIEBjb25zdFxuICogQHR5cGUge09iamVjdDxVbml0cywgbnVtYmVyPn1cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIE1FVEVSU19QRVJfVU5JVCA9IHt9OyAvLyB1c2UgdGhlIHJhZGl1cyBvZiB0aGUgTm9ybWFsIHNwaGVyZVxuXG5NRVRFUlNfUEVSX1VOSVRbVW5pdHMuREVHUkVFU10gPSAyICogTWF0aC5QSSAqIDYzNzA5OTcgLyAzNjA7XG5NRVRFUlNfUEVSX1VOSVRbVW5pdHMuRkVFVF0gPSAwLjMwNDg7XG5NRVRFUlNfUEVSX1VOSVRbVW5pdHMuTUVURVJTXSA9IDE7XG5NRVRFUlNfUEVSX1VOSVRbVW5pdHMuVVNGRUVUXSA9IDEyMDAgLyAzOTM3O1xuZXhwb3J0IGRlZmF1bHQgVW5pdHM7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL1ZpZXdIaW50XG4gKi9cblxuLyoqXG4gKiBAZW51bSB7bnVtYmVyfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIEFOSU1BVElORzogMCxcbiAgSU5URVJBQ1RJTkc6IDFcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL1ZpZXdQcm9wZXJ0eVxuICovXG5cbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBDRU5URVI6ICdjZW50ZXInLFxuICBSRVNPTFVUSU9OOiAncmVzb2x1dGlvbicsXG4gIFJPVEFUSU9OOiAncm90YXRpb24nXG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC90aWxlZ3JpZC9jb21tb25cbiAqL1xuXG4vKipcbiAqIERlZmF1bHQgbWF4aW11bSB6b29tIGZvciBkZWZhdWx0IHRpbGUgZ3JpZHMuXG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5leHBvcnQgdmFyIERFRkFVTFRfTUFYX1pPT00gPSA0Mjtcbi8qKlxuICogRGVmYXVsdCB0aWxlIHNpemUuXG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5cbmV4cG9ydCB2YXIgREVGQVVMVF9USUxFX1NJWkUgPSAyNTY7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3Byb2ovUHJvamVjdGlvblxuICovXG5pbXBvcnQgeyBNRVRFUlNfUEVSX1VOSVQgfSBmcm9tICcuL1VuaXRzLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IGNvZGUgVGhlIFNSUyBpZGVudGlmaWVyIGNvZGUsIGUuZy4gYEVQU0c6NDMyNmAuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vVW5pdHMuanNcIikuZGVmYXVsdHxzdHJpbmd9IFt1bml0c10gVW5pdHMuIFJlcXVpcmVkIHVubGVzcyBhXG4gKiBwcm9qNCBwcm9qZWN0aW9uIGlzIGRlZmluZWQgZm9yIGBjb2RlYC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF0gVGhlIHZhbGlkaXR5IGV4dGVudCBmb3IgdGhlIFNSUy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbYXhpc09yaWVudGF0aW9uPSdlbnUnXSBUaGUgYXhpcyBvcmllbnRhdGlvbiBhcyBzcGVjaWZpZWQgaW4gUHJvajQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtnbG9iYWw9ZmFsc2VdIFdoZXRoZXIgdGhlIHByb2plY3Rpb24gaXMgdmFsaWQgZm9yIHRoZSB3aG9sZSBnbG9iZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWV0ZXJzUGVyVW5pdF0gVGhlIG1ldGVycyBwZXIgdW5pdCBmb3IgdGhlIFNSUy5cbiAqIElmIG5vdCBwcm92aWRlZCwgdGhlIGB1bml0c2AgYXJlIHVzZWQgdG8gZ2V0IHRoZSBtZXRlcnMgcGVyIHVuaXQgZnJvbSB0aGUge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1VuaXRzfk1FVEVSU19QRVJfVU5JVH1cbiAqIGxvb2t1cCB0YWJsZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW3dvcmxkRXh0ZW50XSBUaGUgd29ybGQgZXh0ZW50IGZvciB0aGUgU1JTLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXIsIGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6bnVtYmVyfSBbZ2V0UG9pbnRSZXNvbHV0aW9uXVxuICogRnVuY3Rpb24gdG8gZGV0ZXJtaW5lIHJlc29sdXRpb24gYXQgYSBwb2ludC4gVGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIGFcbiAqIGB7bnVtYmVyfWAgdmlldyByZXNvbHV0aW9uIGFuZCBhbiBge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX1gIGFzIGFyZ3VtZW50cywgYW5kIHJldHVybnNcbiAqIHRoZSBge251bWJlcn1gIHJlc29sdXRpb24gaW4gcHJvamVjdGlvbiB1bml0cyBhdCB0aGUgcGFzc2VkIGNvb3JkaW5hdGUuIElmIHRoaXMgaXMgYHVuZGVmaW5lZGAsXG4gKiB0aGUgZGVmYXVsdCB7QGxpbmsgbW9kdWxlOm9sL3Byb2ojZ2V0UG9pbnRSZXNvbHV0aW9ufSBmdW5jdGlvbiB3aWxsIGJlIHVzZWQuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBQcm9qZWN0aW9uIGRlZmluaXRpb24gY2xhc3MuIE9uZSBvZiB0aGVzZSBpcyBjcmVhdGVkIGZvciBlYWNoIHByb2plY3Rpb25cbiAqIHN1cHBvcnRlZCBpbiB0aGUgYXBwbGljYXRpb24gYW5kIHN0b3JlZCBpbiB0aGUge0BsaW5rIG1vZHVsZTpvbC9wcm9qfSBuYW1lc3BhY2UuXG4gKiBZb3UgY2FuIHVzZSB0aGVzZSBpbiBhcHBsaWNhdGlvbnMsIGJ1dCB0aGlzIGlzIG5vdCByZXF1aXJlZCwgYXMgQVBJIHBhcmFtc1xuICogYW5kIG9wdGlvbnMgdXNlIHtAbGluayBtb2R1bGU6b2wvcHJvan5Qcm9qZWN0aW9uTGlrZX0gd2hpY2ggbWVhbnMgdGhlIHNpbXBsZSBzdHJpbmdcbiAqIGNvZGUgd2lsbCBzdWZmaWNlLlxuICpcbiAqIFlvdSBjYW4gdXNlIHtAbGluayBtb2R1bGU6b2wvcHJvan5nZXR9IHRvIHJldHJpZXZlIHRoZSBvYmplY3QgZm9yIGEgcGFydGljdWxhclxuICogcHJvamVjdGlvbi5cbiAqXG4gKiBUaGUgbGlicmFyeSBpbmNsdWRlcyBkZWZpbml0aW9ucyBmb3IgYEVQU0c6NDMyNmAgYW5kIGBFUFNHOjM4NTdgLCB0b2dldGhlclxuICogd2l0aCB0aGUgZm9sbG93aW5nIGFsaWFzZXM6XG4gKiAqIGBFUFNHOjQzMjZgOiBDUlM6ODQsIHVybjpvZ2M6ZGVmOmNyczpFUFNHOjYuNjo0MzI2LFxuICogICAgIHVybjpvZ2M6ZGVmOmNyczpPR0M6MS4zOkNSUzg0LCB1cm46b2djOmRlZjpjcnM6T0dDOjI6ODQsXG4gKiAgICAgaHR0cDovL3d3dy5vcGVuZ2lzLm5ldC9nbWwvc3JzL2Vwc2cueG1sIzQzMjYsXG4gKiAgICAgdXJuOngtb2djOmRlZjpjcnM6RVBTRzo0MzI2XG4gKiAqIGBFUFNHOjM4NTdgOiBFUFNHOjEwMjEwMCwgRVBTRzoxMDIxMTMsIEVQU0c6OTAwOTEzLFxuICogICAgIHVybjpvZ2M6ZGVmOmNyczpFUFNHOjYuMTg6MzozODU3LFxuICogICAgIGh0dHA6Ly93d3cub3Blbmdpcy5uZXQvZ21sL3Nycy9lcHNnLnhtbCMzODU3XG4gKlxuICogSWYgeW91IHVzZSBbcHJvajRqc10oaHR0cHM6Ly9naXRodWIuY29tL3Byb2o0anMvcHJvajRqcyksIGFsaWFzZXMgY2FuXG4gKiBiZSBhZGRlZCB1c2luZyBgcHJvajQuZGVmcygpYC4gQWZ0ZXIgYWxsIHJlcXVpcmVkIHByb2plY3Rpb24gZGVmaW5pdGlvbnMgYXJlXG4gKiBhZGRlZCwgY2FsbCB0aGUge0BsaW5rIG1vZHVsZTpvbC9wcm9qL3Byb2o0fnJlZ2lzdGVyfSBmdW5jdGlvbi5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIFByb2plY3Rpb24gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIFByb2plY3Rpb24gb3B0aW9ucy5cbiAgICovXG4gIGZ1bmN0aW9uIFByb2plY3Rpb24ob3B0aW9ucykge1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0aGlzLmNvZGVfID0gb3B0aW9ucy5jb2RlO1xuICAgIC8qKlxuICAgICAqIFVuaXRzIG9mIHByb2plY3RlZCBjb29yZGluYXRlcy4gV2hlbiBzZXQgdG8gYFRJTEVfUElYRUxTYCwgYVxuICAgICAqIGB0aGlzLmV4dGVudF9gIGFuZCBgdGhpcy53b3JsZEV4dGVudF9gIG11c3QgYmUgY29uZmlndXJlZCBwcm9wZXJseSBmb3IgZWFjaFxuICAgICAqIHRpbGUuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9Vbml0cy5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgdGhpcy51bml0c18gPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9Vbml0cy5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIG9wdGlvbnMudW5pdHM7XG4gICAgLyoqXG4gICAgICogVmFsaWRpdHkgZXh0ZW50IG9mIHRoZSBwcm9qZWN0aW9uIGluIHByb2plY3RlZCBjb29yZGluYXRlcy4gRm9yIHByb2plY3Rpb25zXG4gICAgICogd2l0aCBgVElMRV9QSVhFTFNgIHVuaXRzLCB0aGlzIGlzIHRoZSBleHRlbnQgb2YgdGhlIHRpbGUgaW5cbiAgICAgKiB0aWxlIHBpeGVsIHNwYWNlLlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG5cbiAgICB0aGlzLmV4dGVudF8gPSBvcHRpb25zLmV4dGVudCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5leHRlbnQgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEV4dGVudCBvZiB0aGUgd29ybGQgaW4gRVBTRzo0MzI2LiBGb3IgcHJvamVjdGlvbnMgd2l0aFxuICAgICAqIGBUSUxFX1BJWEVMU2AgdW5pdHMsIHRoaXMgaXMgdGhlIGV4dGVudCBvZiB0aGUgdGlsZSBpblxuICAgICAqIHByb2plY3RlZCBjb29yZGluYXRlIHNwYWNlLlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG5cbiAgICB0aGlzLndvcmxkRXh0ZW50XyA9IG9wdGlvbnMud29ybGRFeHRlbnQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMud29ybGRFeHRlbnQgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cblxuICAgIHRoaXMuYXhpc09yaWVudGF0aW9uXyA9IG9wdGlvbnMuYXhpc09yaWVudGF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmF4aXNPcmllbnRhdGlvbiA6ICdlbnUnO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICB0aGlzLmdsb2JhbF8gPSBvcHRpb25zLmdsb2JhbCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5nbG9iYWwgOiBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgdGhpcy5jYW5XcmFwWF8gPSAhISh0aGlzLmdsb2JhbF8gJiYgdGhpcy5leHRlbnRfKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtmdW5jdGlvbihudW1iZXIsIGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHRoaXMuZ2V0UG9pbnRSZXNvbHV0aW9uRnVuY18gPSBvcHRpb25zLmdldFBvaW50UmVzb2x1dGlvbjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgdGhpcy5kZWZhdWx0VGlsZUdyaWRfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgdGhpcy5tZXRlcnNQZXJVbml0XyA9IG9wdGlvbnMubWV0ZXJzUGVyVW5pdDtcbiAgfVxuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHByb2plY3Rpb24gaXMgc3VpdGFibGUgZm9yIHdyYXBwaW5nIHRoZSB4LWF4aXNcbiAgICovXG5cblxuICBQcm9qZWN0aW9uLnByb3RvdHlwZS5jYW5XcmFwWCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jYW5XcmFwWF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGNvZGUgZm9yIHRoaXMgcHJvamVjdGlvbiwgZS5nLiAnRVBTRzo0MzI2Jy5cbiAgICogQHJldHVybiB7c3RyaW5nfSBDb2RlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuZ2V0Q29kZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jb2RlXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdmFsaWRpdHkgZXh0ZW50IGZvciB0aGlzIHByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFByb2plY3Rpb24ucHJvdG90eXBlLmdldEV4dGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5leHRlbnRfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB1bml0cyBvZiB0aGlzIHByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vVW5pdHMuanNcIikuZGVmYXVsdH0gVW5pdHMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQcm9qZWN0aW9uLnByb3RvdHlwZS5nZXRVbml0cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy51bml0c187XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGFtb3VudCBvZiBtZXRlcnMgcGVyIHVuaXQgb2YgdGhpcyBwcm9qZWN0aW9uLiAgSWYgdGhlIHByb2plY3Rpb24gaXNcbiAgICogbm90IGNvbmZpZ3VyZWQgd2l0aCBgbWV0ZXJzUGVyVW5pdGAgb3IgYSB1bml0cyBpZGVudGlmaWVyLCB0aGUgcmV0dXJuIGlzXG4gICAqIGB1bmRlZmluZWRgLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBNZXRlcnMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQcm9qZWN0aW9uLnByb3RvdHlwZS5nZXRNZXRlcnNQZXJVbml0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm1ldGVyc1BlclVuaXRfIHx8IE1FVEVSU19QRVJfVU5JVFt0aGlzLnVuaXRzX107XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHdvcmxkIGV4dGVudCBmb3IgdGhpcyBwcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBFeHRlbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQcm9qZWN0aW9uLnByb3RvdHlwZS5nZXRXb3JsZEV4dGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy53b3JsZEV4dGVudF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGF4aXMgb3JpZW50YXRpb24gb2YgdGhpcyBwcm9qZWN0aW9uLlxuICAgKiBFeGFtcGxlIHZhbHVlcyBhcmU6XG4gICAqIGVudSAtIHRoZSBkZWZhdWx0IGVhc3RpbmcsIG5vcnRoaW5nLCBlbGV2YXRpb24uXG4gICAqIG5ldSAtIG5vcnRoaW5nLCBlYXN0aW5nLCB1cCAtIHVzZWZ1bCBmb3IgXCJsYXQvbG9uZ1wiIGdlb2dyYXBoaWMgY29vcmRpbmF0ZXMsXG4gICAqICAgICBvciBzb3V0aCBvcmllbnRhdGVkIHRyYW5zdmVyc2UgbWVyY2F0b3IuXG4gICAqIHdudSAtIHdlc3RpbmcsIG5vcnRoaW5nLCB1cCAtIHNvbWUgcGxhbmV0YXJ5IGNvb3JkaW5hdGUgc3lzdGVtcyBoYXZlXG4gICAqICAgICBcIndlc3QgcG9zaXRpdmVcIiBjb29yZGluYXRlIHN5c3RlbXNcbiAgICogQHJldHVybiB7c3RyaW5nfSBBeGlzIG9yaWVudGF0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuZ2V0QXhpc09yaWVudGF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmF4aXNPcmllbnRhdGlvbl87XG4gIH07XG4gIC8qKlxuICAgKiBJcyB0aGlzIHByb2plY3Rpb24gYSBnbG9iYWwgcHJvamVjdGlvbiB3aGljaCBzcGFucyB0aGUgd2hvbGUgd29ybGQ/XG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHByb2plY3Rpb24gaXMgZ2xvYmFsLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuaXNHbG9iYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2xvYmFsXztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCBpZiB0aGUgcHJvamVjdGlvbiBpcyBhIGdsb2JhbCBwcm9qZWN0aW9uIHdoaWNoIHNwYW5zIHRoZSB3aG9sZSB3b3JsZFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGdsb2JhbCBXaGV0aGVyIHRoZSBwcm9qZWN0aW9uIGlzIGdsb2JhbC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFByb2plY3Rpb24ucHJvdG90eXBlLnNldEdsb2JhbCA9IGZ1bmN0aW9uIChnbG9iYWwpIHtcbiAgICB0aGlzLmdsb2JhbF8gPSBnbG9iYWw7XG4gICAgdGhpcy5jYW5XcmFwWF8gPSAhIShnbG9iYWwgJiYgdGhpcy5leHRlbnRfKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IFRoZSBkZWZhdWx0IHRpbGUgZ3JpZC5cbiAgICovXG5cblxuICBQcm9qZWN0aW9uLnByb3RvdHlwZS5nZXREZWZhdWx0VGlsZUdyaWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVmYXVsdFRpbGVHcmlkXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gdGlsZUdyaWQgVGhlIGRlZmF1bHQgdGlsZSBncmlkLlxuICAgKi9cblxuXG4gIFByb2plY3Rpb24ucHJvdG90eXBlLnNldERlZmF1bHRUaWxlR3JpZCA9IGZ1bmN0aW9uICh0aWxlR3JpZCkge1xuICAgIHRoaXMuZGVmYXVsdFRpbGVHcmlkXyA9IHRpbGVHcmlkO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB2YWxpZGl0eSBleHRlbnQgZm9yIHRoaXMgcHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuc2V0RXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCkge1xuICAgIHRoaXMuZXh0ZW50XyA9IGV4dGVudDtcbiAgICB0aGlzLmNhbldyYXBYXyA9ICEhKHRoaXMuZ2xvYmFsXyAmJiBleHRlbnQpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB3b3JsZCBleHRlbnQgZm9yIHRoaXMgcHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSB3b3JsZEV4dGVudCBXb3JsZCBleHRlbnRcbiAgICogICAgIFttaW5sb24sIG1pbmxhdCwgbWF4bG9uLCBtYXhsYXRdLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuc2V0V29ybGRFeHRlbnQgPSBmdW5jdGlvbiAod29ybGRFeHRlbnQpIHtcbiAgICB0aGlzLndvcmxkRXh0ZW50XyA9IHdvcmxkRXh0ZW50O1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBnZXRQb2ludFJlc29sdXRpb24gZnVuY3Rpb24gKHNlZSB7QGxpbmsgbW9kdWxlOm9sL3Byb2p+Z2V0UG9pbnRSZXNvbHV0aW9ufVxuICAgKiBmb3IgdGhpcyBwcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKG51bWJlciwgaW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlKTpudW1iZXJ9IGZ1bmMgRnVuY3Rpb25cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFByb2plY3Rpb24ucHJvdG90eXBlLnNldEdldFBvaW50UmVzb2x1dGlvbiA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gICAgdGhpcy5nZXRQb2ludFJlc29sdXRpb25GdW5jXyA9IGZ1bmM7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1c3RvbSBwb2ludCByZXNvbHV0aW9uIGZ1bmN0aW9uIGZvciB0aGlzIHByb2plY3Rpb24gKGlmIHNldCkuXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9uKG51bWJlciwgaW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlKTpudW1iZXJ8dW5kZWZpbmVkfSBUaGUgY3VzdG9tIHBvaW50XG4gICAqIHJlc29sdXRpb24gZnVuY3Rpb24gKGlmIHNldCkuXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuZ2V0UG9pbnRSZXNvbHV0aW9uRnVuYyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRQb2ludFJlc29sdXRpb25GdW5jXztcbiAgfTtcblxuICByZXR1cm4gUHJvamVjdGlvbjtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgUHJvamVjdGlvbjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3Byb2ovZXBzZzM4NTdcbiAqL1xuXG5cbmltcG9ydCBQcm9qZWN0aW9uIGZyb20gJy4vUHJvamVjdGlvbi5qcyc7XG5pbXBvcnQgVW5pdHMgZnJvbSAnLi9Vbml0cy5qcyc7XG5pbXBvcnQgeyBjb3NoIH0gZnJvbSAnLi4vbWF0aC5qcyc7XG4vKipcbiAqIFJhZGl1cyBvZiBXR1M4NCBzcGhlcmVcbiAqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cblxuZXhwb3J0IHZhciBSQURJVVMgPSA2Mzc4MTM3O1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cblxuZXhwb3J0IHZhciBIQUxGX1NJWkUgPSBNYXRoLlBJICogUkFESVVTO1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICovXG5cbmV4cG9ydCB2YXIgRVhURU5UID0gWy1IQUxGX1NJWkUsIC1IQUxGX1NJWkUsIEhBTEZfU0laRSwgSEFMRl9TSVpFXTtcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAqL1xuXG5leHBvcnQgdmFyIFdPUkxEX0VYVEVOVCA9IFstMTgwLCAtODUsIDE4MCwgODVdO1xuLyoqXG4gKiBNYXhpbXVtIHNhZmUgdmFsdWUgaW4geSBkaXJlY3Rpb25cbiAqIEBjb25zdFxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIE1BWF9TQUZFX1kgPSBSQURJVVMgKiBNYXRoLmxvZyhNYXRoLnRhbihNYXRoLlBJIC8gMikpO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBQcm9qZWN0aW9uIG9iamVjdCBmb3Igd2ViL3NwaGVyaWNhbCBNZXJjYXRvciAoRVBTRzozODU3KS5cbiAqL1xuXG52YXIgRVBTRzM4NTdQcm9qZWN0aW9uID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEVQU0czODU3UHJvamVjdGlvbiwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb2RlIENvZGUuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gRVBTRzM4NTdQcm9qZWN0aW9uKGNvZGUpIHtcbiAgICByZXR1cm4gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgY29kZTogY29kZSxcbiAgICAgIHVuaXRzOiBVbml0cy5NRVRFUlMsXG4gICAgICBleHRlbnQ6IEVYVEVOVCxcbiAgICAgIGdsb2JhbDogdHJ1ZSxcbiAgICAgIHdvcmxkRXh0ZW50OiBXT1JMRF9FWFRFTlQsXG4gICAgICBnZXRQb2ludFJlc29sdXRpb246IGZ1bmN0aW9uIGdldFBvaW50UmVzb2x1dGlvbihyZXNvbHV0aW9uLCBwb2ludCkge1xuICAgICAgICByZXR1cm4gcmVzb2x1dGlvbiAvIGNvc2gocG9pbnRbMV0gLyBSQURJVVMpO1xuICAgICAgfVxuICAgIH0pIHx8IHRoaXM7XG4gIH1cblxuICByZXR1cm4gRVBTRzM4NTdQcm9qZWN0aW9uO1xufShQcm9qZWN0aW9uKTtcbi8qKlxuICogUHJvamVjdGlvbnMgZXF1YWwgdG8gRVBTRzozODU3LlxuICpcbiAqIEBjb25zdFxuICogQHR5cGUge0FycmF5PGltcG9ydChcIi4vUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0Pn1cbiAqL1xuXG5cbmV4cG9ydCB2YXIgUFJPSkVDVElPTlMgPSBbbmV3IEVQU0czODU3UHJvamVjdGlvbignRVBTRzozODU3JyksIG5ldyBFUFNHMzg1N1Byb2plY3Rpb24oJ0VQU0c6MTAyMTAwJyksIG5ldyBFUFNHMzg1N1Byb2plY3Rpb24oJ0VQU0c6MTAyMTEzJyksIG5ldyBFUFNHMzg1N1Byb2plY3Rpb24oJ0VQU0c6OTAwOTEzJyksIG5ldyBFUFNHMzg1N1Byb2plY3Rpb24oJ2h0dHA6Ly93d3cub3Blbmdpcy5uZXQvZ21sL3Nycy9lcHNnLnhtbCMzODU3JyldO1xuLyoqXG4gKiBUcmFuc2Zvcm1hdGlvbiBmcm9tIEVQU0c6NDMyNiB0byBFUFNHOjM4NTcuXG4gKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBpbnB1dCBJbnB1dCBhcnJheSBvZiBjb29yZGluYXRlIHZhbHVlcy5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9vdXRwdXQgT3V0cHV0IGFycmF5IG9mIGNvb3JkaW5hdGUgdmFsdWVzLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZGltZW5zaW9uIERpbWVuc2lvbiAoZGVmYXVsdCBpcyBgMmApLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gT3V0cHV0IGFycmF5IG9mIGNvb3JkaW5hdGUgdmFsdWVzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tRVBTRzQzMjYoaW5wdXQsIG9wdF9vdXRwdXQsIG9wdF9kaW1lbnNpb24pIHtcbiAgdmFyIGxlbmd0aCA9IGlucHV0Lmxlbmd0aDtcbiAgdmFyIGRpbWVuc2lvbiA9IG9wdF9kaW1lbnNpb24gPiAxID8gb3B0X2RpbWVuc2lvbiA6IDI7XG4gIHZhciBvdXRwdXQgPSBvcHRfb3V0cHV0O1xuXG4gIGlmIChvdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChkaW1lbnNpb24gPiAyKSB7XG4gICAgICAvLyBwcmVzZXJ2ZSB2YWx1ZXMgYmV5b25kIHNlY29uZCBkaW1lbnNpb25cbiAgICAgIG91dHB1dCA9IGlucHV0LnNsaWNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dCA9IG5ldyBBcnJheShsZW5ndGgpO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IGRpbWVuc2lvbikge1xuICAgIG91dHB1dFtpXSA9IEhBTEZfU0laRSAqIGlucHV0W2ldIC8gMTgwO1xuICAgIHZhciB5ID0gUkFESVVTICogTWF0aC5sb2coTWF0aC50YW4oTWF0aC5QSSAqICgraW5wdXRbaSArIDFdICsgOTApIC8gMzYwKSk7XG5cbiAgICBpZiAoeSA+IE1BWF9TQUZFX1kpIHtcbiAgICAgIHkgPSBNQVhfU0FGRV9ZO1xuICAgIH0gZWxzZSBpZiAoeSA8IC1NQVhfU0FGRV9ZKSB7XG4gICAgICB5ID0gLU1BWF9TQUZFX1k7XG4gICAgfVxuXG4gICAgb3V0cHV0W2kgKyAxXSA9IHk7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1hdGlvbiBmcm9tIEVQU0c6Mzg1NyB0byBFUFNHOjQzMjYuXG4gKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBpbnB1dCBJbnB1dCBhcnJheSBvZiBjb29yZGluYXRlIHZhbHVlcy5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9vdXRwdXQgT3V0cHV0IGFycmF5IG9mIGNvb3JkaW5hdGUgdmFsdWVzLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZGltZW5zaW9uIERpbWVuc2lvbiAoZGVmYXVsdCBpcyBgMmApLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gT3V0cHV0IGFycmF5IG9mIGNvb3JkaW5hdGUgdmFsdWVzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0b0VQU0c0MzI2KGlucHV0LCBvcHRfb3V0cHV0LCBvcHRfZGltZW5zaW9uKSB7XG4gIHZhciBsZW5ndGggPSBpbnB1dC5sZW5ndGg7XG4gIHZhciBkaW1lbnNpb24gPSBvcHRfZGltZW5zaW9uID4gMSA/IG9wdF9kaW1lbnNpb24gOiAyO1xuICB2YXIgb3V0cHV0ID0gb3B0X291dHB1dDtcblxuICBpZiAob3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoZGltZW5zaW9uID4gMikge1xuICAgICAgLy8gcHJlc2VydmUgdmFsdWVzIGJleW9uZCBzZWNvbmQgZGltZW5zaW9uXG4gICAgICBvdXRwdXQgPSBpbnB1dC5zbGljZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQgPSBuZXcgQXJyYXkobGVuZ3RoKTtcbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSBkaW1lbnNpb24pIHtcbiAgICBvdXRwdXRbaV0gPSAxODAgKiBpbnB1dFtpXSAvIEhBTEZfU0laRTtcbiAgICBvdXRwdXRbaSArIDFdID0gMzYwICogTWF0aC5hdGFuKE1hdGguZXhwKGlucHV0W2kgKyAxXSAvIFJBRElVUykpIC8gTWF0aC5QSSAtIDkwO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn0iLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3Byb2ovZXBzZzQzMjZcbiAqL1xuXG5cbmltcG9ydCBQcm9qZWN0aW9uIGZyb20gJy4vUHJvamVjdGlvbi5qcyc7XG5pbXBvcnQgVW5pdHMgZnJvbSAnLi9Vbml0cy5qcyc7XG4vKipcbiAqIFNlbWktbWFqb3IgcmFkaXVzIG9mIHRoZSBXR1M4NCBlbGxpcHNvaWQuXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5cbmV4cG9ydCB2YXIgUkFESVVTID0gNjM3ODEzNztcbi8qKlxuICogRXh0ZW50IG9mIHRoZSBFUFNHOjQzMjYgcHJvamVjdGlvbiB3aGljaCBpcyB0aGUgd2hvbGUgd29ybGQuXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAqL1xuXG5leHBvcnQgdmFyIEVYVEVOVCA9IFstMTgwLCAtOTAsIDE4MCwgOTBdO1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cblxuZXhwb3J0IHZhciBNRVRFUlNfUEVSX1VOSVQgPSBNYXRoLlBJICogUkFESVVTIC8gMTgwO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBQcm9qZWN0aW9uIG9iamVjdCBmb3IgV0dTODQgZ2VvZ3JhcGhpYyBjb29yZGluYXRlcyAoRVBTRzo0MzI2KS5cbiAqXG4gKiBOb3RlIHRoYXQgT3BlbkxheWVycyBkb2VzIG5vdCBzdHJpY3RseSBjb21wbHkgd2l0aCB0aGUgRVBTRyBkZWZpbml0aW9uLlxuICogVGhlIEVQU0cgcmVnaXN0cnkgZGVmaW5lcyA0MzI2IGFzIGEgQ1JTIGZvciBMYXRpdHVkZSxMb25naXR1ZGUgKHkseCkuXG4gKiBPcGVuTGF5ZXJzIHRyZWF0cyBFUFNHOjQzMjYgYXMgYSBwc2V1ZG8tcHJvamVjdGlvbiwgd2l0aCB4LHkgY29vcmRpbmF0ZXMuXG4gKi9cblxudmFyIEVQU0c0MzI2UHJvamVjdGlvbiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhFUFNHNDMyNlByb2plY3Rpb24sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29kZSBDb2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZz19IG9wdF9heGlzT3JpZW50YXRpb24gQXhpcyBvcmllbnRhdGlvbi5cbiAgICovXG5cblxuICBmdW5jdGlvbiBFUFNHNDMyNlByb2plY3Rpb24oY29kZSwgb3B0X2F4aXNPcmllbnRhdGlvbikge1xuICAgIHJldHVybiBfc3VwZXIuY2FsbCh0aGlzLCB7XG4gICAgICBjb2RlOiBjb2RlLFxuICAgICAgdW5pdHM6IFVuaXRzLkRFR1JFRVMsXG4gICAgICBleHRlbnQ6IEVYVEVOVCxcbiAgICAgIGF4aXNPcmllbnRhdGlvbjogb3B0X2F4aXNPcmllbnRhdGlvbixcbiAgICAgIGdsb2JhbDogdHJ1ZSxcbiAgICAgIG1ldGVyc1BlclVuaXQ6IE1FVEVSU19QRVJfVU5JVCxcbiAgICAgIHdvcmxkRXh0ZW50OiBFWFRFTlRcbiAgICB9KSB8fCB0aGlzO1xuICB9XG5cbiAgcmV0dXJuIEVQU0c0MzI2UHJvamVjdGlvbjtcbn0oUHJvamVjdGlvbik7XG4vKipcbiAqIFByb2plY3Rpb25zIGVxdWFsIHRvIEVQU0c6NDMyNi5cbiAqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdD59XG4gKi9cblxuXG5leHBvcnQgdmFyIFBST0pFQ1RJT05TID0gW25ldyBFUFNHNDMyNlByb2plY3Rpb24oJ0NSUzo4NCcpLCBuZXcgRVBTRzQzMjZQcm9qZWN0aW9uKCdFUFNHOjQzMjYnLCAnbmV1JyksIG5ldyBFUFNHNDMyNlByb2plY3Rpb24oJ3VybjpvZ2M6ZGVmOmNyczpPR0M6MS4zOkNSUzg0JyksIG5ldyBFUFNHNDMyNlByb2plY3Rpb24oJ3VybjpvZ2M6ZGVmOmNyczpPR0M6Mjo4NCcpLCBuZXcgRVBTRzQzMjZQcm9qZWN0aW9uKCdodHRwOi8vd3d3Lm9wZW5naXMubmV0L2dtbC9zcnMvZXBzZy54bWwjNDMyNicsICduZXUnKV07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3Byb2ovcHJvamVjdGlvbnNcbiAqL1xuXG4vKipcbiAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdD59XG4gKi9cbnZhciBjYWNoZSA9IHt9O1xuLyoqXG4gKiBDbGVhciB0aGUgcHJvamVjdGlvbnMgY2FjaGUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyKCkge1xuICBjYWNoZSA9IHt9O1xufVxuLyoqXG4gKiBHZXQgYSBjYWNoZWQgcHJvamVjdGlvbiBieSBjb2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGNvZGUgVGhlIGNvZGUgZm9yIHRoZSBwcm9qZWN0aW9uLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IFRoZSBwcm9qZWN0aW9uIChpZiBjYWNoZWQpLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXQoY29kZSkge1xuICByZXR1cm4gY2FjaGVbY29kZV0gfHwgY2FjaGVbY29kZS5yZXBsYWNlKC91cm46KHgtKT9vZ2M6ZGVmOmNyczpFUFNHOiguKjopPyhcXHcrKSQvLCAnRVBTRzokMycpXSB8fCBudWxsO1xufVxuLyoqXG4gKiBBZGQgYSBwcm9qZWN0aW9uIHRvIHRoZSBjYWNoZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb2RlIFRoZSBwcm9qZWN0aW9uIGNvZGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFRoZSBwcm9qZWN0aW9uIHRvIGNhY2hlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGQoY29kZSwgcHJvamVjdGlvbikge1xuICBjYWNoZVtjb2RlXSA9IHByb2plY3Rpb247XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3Byb2ovdHJhbnNmb3Jtc1xuICovXG5pbXBvcnQgeyBpc0VtcHR5IH0gZnJvbSAnLi4vb2JqLmpzJztcbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbj4+fVxuICovXG5cbnZhciB0cmFuc2Zvcm1zID0ge307XG4vKipcbiAqIENsZWFyIHRoZSB0cmFuc2Zvcm0gY2FjaGUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyKCkge1xuICB0cmFuc2Zvcm1zID0ge307XG59XG4vKipcbiAqIFJlZ2lzdGVycyBhIGNvbnZlcnNpb24gZnVuY3Rpb24gdG8gY29udmVydCBjb29yZGluYXRlcyBmcm9tIHRoZSBzb3VyY2VcbiAqIHByb2plY3Rpb24gdG8gdGhlIGRlc3RpbmF0aW9uIHByb2plY3Rpb24uXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gc291cmNlIFNvdXJjZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IGRlc3RpbmF0aW9uIERlc3RpbmF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufSB0cmFuc2Zvcm1GbiBUcmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZChzb3VyY2UsIGRlc3RpbmF0aW9uLCB0cmFuc2Zvcm1Gbikge1xuICB2YXIgc291cmNlQ29kZSA9IHNvdXJjZS5nZXRDb2RlKCk7XG4gIHZhciBkZXN0aW5hdGlvbkNvZGUgPSBkZXN0aW5hdGlvbi5nZXRDb2RlKCk7XG5cbiAgaWYgKCEoc291cmNlQ29kZSBpbiB0cmFuc2Zvcm1zKSkge1xuICAgIHRyYW5zZm9ybXNbc291cmNlQ29kZV0gPSB7fTtcbiAgfVxuXG4gIHRyYW5zZm9ybXNbc291cmNlQ29kZV1bZGVzdGluYXRpb25Db2RlXSA9IHRyYW5zZm9ybUZuO1xufVxuLyoqXG4gKiBVbnJlZ2lzdGVycyB0aGUgY29udmVyc2lvbiBmdW5jdGlvbiB0byBjb252ZXJ0IGNvb3JkaW5hdGVzIGZyb20gdGhlIHNvdXJjZVxuICogcHJvamVjdGlvbiB0byB0aGUgZGVzdGluYXRpb24gcHJvamVjdGlvbi4gIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gY2xlYW4gdXBcbiAqIGNhY2hlZCB0cmFuc2Zvcm1zIGR1cmluZyB0ZXN0aW5nLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHNvdXJjZSBTb3VyY2UgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IGRlc3RpbmF0aW9uIERlc3RpbmF0aW9uIHByb2plY3Rpb24uXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufSB0cmFuc2Zvcm1GbiBUaGUgdW5yZWdpc3RlcmVkIHRyYW5zZm9ybS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlKHNvdXJjZSwgZGVzdGluYXRpb24pIHtcbiAgdmFyIHNvdXJjZUNvZGUgPSBzb3VyY2UuZ2V0Q29kZSgpO1xuICB2YXIgZGVzdGluYXRpb25Db2RlID0gZGVzdGluYXRpb24uZ2V0Q29kZSgpO1xuICB2YXIgdHJhbnNmb3JtID0gdHJhbnNmb3Jtc1tzb3VyY2VDb2RlXVtkZXN0aW5hdGlvbkNvZGVdO1xuICBkZWxldGUgdHJhbnNmb3Jtc1tzb3VyY2VDb2RlXVtkZXN0aW5hdGlvbkNvZGVdO1xuXG4gIGlmIChpc0VtcHR5KHRyYW5zZm9ybXNbc291cmNlQ29kZV0pKSB7XG4gICAgZGVsZXRlIHRyYW5zZm9ybXNbc291cmNlQ29kZV07XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtO1xufVxuLyoqXG4gKiBHZXQgYSB0cmFuc2Zvcm0gZ2l2ZW4gYSBzb3VyY2UgY29kZSBhbmQgYSBkZXN0aW5hdGlvbiBjb2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZUNvZGUgVGhlIGNvZGUgZm9yIHRoZSBzb3VyY2UgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXN0aW5hdGlvbkNvZGUgVGhlIGNvZGUgZm9yIHRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbnx1bmRlZmluZWR9IFRoZSB0cmFuc2Zvcm0gZnVuY3Rpb24gKGlmIGZvdW5kKS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0KHNvdXJjZUNvZGUsIGRlc3RpbmF0aW9uQ29kZSkge1xuICB2YXIgdHJhbnNmb3JtO1xuXG4gIGlmIChzb3VyY2VDb2RlIGluIHRyYW5zZm9ybXMgJiYgZGVzdGluYXRpb25Db2RlIGluIHRyYW5zZm9ybXNbc291cmNlQ29kZV0pIHtcbiAgICB0cmFuc2Zvcm0gPSB0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdW2Rlc3RpbmF0aW9uQ29kZV07XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9zcGhlcmVcbiAqL1xuaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICcuL2dlb20vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCB7IHRvRGVncmVlcywgdG9SYWRpYW5zIH0gZnJvbSAnLi9tYXRoLmpzJztcbi8qKlxuICogT2JqZWN0IGxpdGVyYWwgd2l0aCBvcHRpb25zIGZvciB0aGUge0BsaW5rIGdldExlbmd0aH0gb3Ige0BsaW5rIGdldEFyZWF9XG4gKiBmdW5jdGlvbnMuXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTcGhlcmVNZXRyaWNPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gW3Byb2plY3Rpb249J0VQU0c6Mzg1NyddXG4gKiBQcm9qZWN0aW9uIG9mIHRoZSAgZ2VvbWV0cnkuICBCeSBkZWZhdWx0LCB0aGUgZ2VvbWV0cnkgaXMgYXNzdW1lZCB0byBiZSBpblxuICogV2ViIE1lcmNhdG9yLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyYWRpdXM9NjM3MTAwOC44XSBTcGhlcmUgcmFkaXVzLiAgQnkgZGVmYXVsdCwgdGhlXG4gKiBbbWVhbiBFYXJ0aCByYWRpdXNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0VhcnRoX3JhZGl1cyNNZWFuX3JhZGl1cylcbiAqIGZvciB0aGUgV0dTODQgZWxsaXBzb2lkIGlzIHVzZWQuXG4gKi9cblxuLyoqXG4gKiBUaGUgbWVhbiBFYXJ0aCByYWRpdXMgKDEvMyAqICgyYSArIGIpKSBmb3IgdGhlIFdHUzg0IGVsbGlwc29pZC5cbiAqIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0VhcnRoX3JhZGl1cyNNZWFuX3JhZGl1c1xuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIERFRkFVTFRfUkFESVVTID0gNjM3MTAwOC44O1xuLyoqXG4gKiBHZXQgdGhlIGdyZWF0IGNpcmNsZSBkaXN0YW5jZSAoaW4gbWV0ZXJzKSBiZXR3ZWVuIHR3byBnZW9ncmFwaGljIGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtBcnJheX0gYzEgU3RhcnRpbmcgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7QXJyYXl9IGMyIEVuZGluZyBjb29yZGluYXRlLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfcmFkaXVzIFRoZSBzcGhlcmUgcmFkaXVzIHRvIHVzZS4gIERlZmF1bHRzIHRvIHRoZSBFYXJ0aCdzXG4gKiAgICAgbWVhbiByYWRpdXMgdXNpbmcgdGhlIFdHUzg0IGVsbGlwc29pZC5cbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIGdyZWF0IGNpcmNsZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludHMgKGluIG1ldGVycykuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERpc3RhbmNlKGMxLCBjMiwgb3B0X3JhZGl1cykge1xuICB2YXIgcmFkaXVzID0gb3B0X3JhZGl1cyB8fCBERUZBVUxUX1JBRElVUztcbiAgdmFyIGxhdDEgPSB0b1JhZGlhbnMoYzFbMV0pO1xuICB2YXIgbGF0MiA9IHRvUmFkaWFucyhjMlsxXSk7XG4gIHZhciBkZWx0YUxhdEJ5MiA9IChsYXQyIC0gbGF0MSkgLyAyO1xuICB2YXIgZGVsdGFMb25CeTIgPSB0b1JhZGlhbnMoYzJbMF0gLSBjMVswXSkgLyAyO1xuICB2YXIgYSA9IE1hdGguc2luKGRlbHRhTGF0QnkyKSAqIE1hdGguc2luKGRlbHRhTGF0QnkyKSArIE1hdGguc2luKGRlbHRhTG9uQnkyKSAqIE1hdGguc2luKGRlbHRhTG9uQnkyKSAqIE1hdGguY29zKGxhdDEpICogTWF0aC5jb3MobGF0Mik7XG4gIHJldHVybiAyICogcmFkaXVzICogTWF0aC5hdGFuMihNYXRoLnNxcnQoYSksIE1hdGguc3FydCgxIC0gYSkpO1xufVxuLyoqXG4gKiBHZXQgdGhlIGN1bXVsYXRpdmUgZ3JlYXQgY2lyY2xlIGxlbmd0aCBvZiBsaW5lc3RyaW5nIGNvb3JkaW5hdGVzIChnZW9ncmFwaGljKS5cbiAqIEBwYXJhbSB7QXJyYXl9IGNvb3JkaW5hdGVzIExpbmVzdHJpbmcgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkaXVzIFRoZSBzcGhlcmUgcmFkaXVzIHRvIHVzZS5cbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIGxlbmd0aCAoaW4gbWV0ZXJzKS5cbiAqL1xuXG5mdW5jdGlvbiBnZXRMZW5ndGhJbnRlcm5hbChjb29yZGluYXRlcywgcmFkaXVzKSB7XG4gIHZhciBsZW5ndGggPSAwO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGNvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpIC0gMTsgKytpKSB7XG4gICAgbGVuZ3RoICs9IGdldERpc3RhbmNlKGNvb3JkaW5hdGVzW2ldLCBjb29yZGluYXRlc1tpICsgMV0sIHJhZGl1cyk7XG4gIH1cblxuICByZXR1cm4gbGVuZ3RoO1xufVxuLyoqXG4gKiBHZXQgdGhlIHNwaGVyaWNhbCBsZW5ndGggb2YgYSBnZW9tZXRyeS4gIFRoaXMgbGVuZ3RoIGlzIHRoZSBzdW0gb2YgdGhlXG4gKiBncmVhdCBjaXJjbGUgZGlzdGFuY2VzIGJldHdlZW4gY29vcmRpbmF0ZXMuICBGb3IgcG9seWdvbnMsIHRoZSBsZW5ndGggaXNcbiAqIHRoZSBzdW0gb2YgYWxsIHJpbmdzLiAgRm9yIHBvaW50cywgdGhlIGxlbmd0aCBpcyB6ZXJvLiAgRm9yIG11bHRpLXBhcnRcbiAqIGdlb21ldHJpZXMsIHRoZSBsZW5ndGggaXMgdGhlIHN1bSBvZiB0aGUgbGVuZ3RoIG9mIGVhY2ggcGFydC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEEgZ2VvbWV0cnkuXG4gKiBAcGFyYW0ge1NwaGVyZU1ldHJpY09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zIGZvciB0aGVcbiAqIGxlbmd0aCBjYWxjdWxhdGlvbi4gIEJ5IGRlZmF1bHQsIGdlb21ldHJpZXMgYXJlIGFzc3VtZWQgdG8gYmUgaW4gJ0VQU0c6Mzg1NycuXG4gKiBZb3UgY2FuIGNoYW5nZSB0aGlzIGJ5IHByb3ZpZGluZyBhIGBwcm9qZWN0aW9uYCBvcHRpb24uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBzcGhlcmljYWwgbGVuZ3RoIChpbiBtZXRlcnMpLlxuICogQGFwaVxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExlbmd0aChnZW9tZXRyeSwgb3B0X29wdGlvbnMpIHtcbiAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyB8fCB7fTtcbiAgdmFyIHJhZGl1cyA9IG9wdGlvbnMucmFkaXVzIHx8IERFRkFVTFRfUkFESVVTO1xuICB2YXIgcHJvamVjdGlvbiA9IG9wdGlvbnMucHJvamVjdGlvbiB8fCAnRVBTRzozODU3JztcbiAgdmFyIHR5cGUgPSBnZW9tZXRyeS5nZXRUeXBlKCk7XG5cbiAgaWYgKHR5cGUgIT09IEdlb21ldHJ5VHlwZS5HRU9NRVRSWV9DT0xMRUNUSU9OKSB7XG4gICAgZ2VvbWV0cnkgPSBnZW9tZXRyeS5jbG9uZSgpLnRyYW5zZm9ybShwcm9qZWN0aW9uLCAnRVBTRzo0MzI2Jyk7XG4gIH1cblxuICB2YXIgbGVuZ3RoID0gMDtcbiAgdmFyIGNvb3JkaW5hdGVzLCBjb29yZHMsIGksIGlpLCBqLCBqajtcblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5QT0lOVDpcbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9QT0lOVDpcbiAgICAgIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5MSU5FX1NUUklORzpcbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5MSU5FQVJfUklORzpcbiAgICAgIHtcbiAgICAgICAgY29vcmRpbmF0ZXMgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeS5nZXRDb29yZGluYXRlcygpO1xuICAgICAgICBsZW5ndGggPSBnZXRMZW5ndGhJbnRlcm5hbChjb29yZGluYXRlcywgcmFkaXVzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9MSU5FX1NUUklORzpcbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5QT0xZR09OOlxuICAgICAge1xuICAgICAgICBjb29yZGluYXRlcyA9XG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5LmdldENvb3JkaW5hdGVzKCk7XG5cbiAgICAgICAgZm9yIChpID0gMCwgaWkgPSBjb29yZGluYXRlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgICAgbGVuZ3RoICs9IGdldExlbmd0aEludGVybmFsKGNvb3JkaW5hdGVzW2ldLCByYWRpdXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9QT0xZR09OOlxuICAgICAge1xuICAgICAgICBjb29yZGluYXRlcyA9XG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5LmdldENvb3JkaW5hdGVzKCk7XG5cbiAgICAgICAgZm9yIChpID0gMCwgaWkgPSBjb29yZGluYXRlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgICAgY29vcmRzID0gY29vcmRpbmF0ZXNbaV07XG5cbiAgICAgICAgICBmb3IgKGogPSAwLCBqaiA9IGNvb3Jkcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgICAgICAgICBsZW5ndGggKz0gZ2V0TGVuZ3RoSW50ZXJuYWwoY29vcmRzW2pdLCByYWRpdXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuR0VPTUVUUllfQ09MTEVDVElPTjpcbiAgICAgIHtcbiAgICAgICAgdmFyIGdlb21ldHJpZXMgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZ2VvbS9HZW9tZXRyeUNvbGxlY3Rpb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnkuZ2V0R2VvbWV0cmllcygpO1xuXG4gICAgICAgIGZvciAoaSA9IDAsIGlpID0gZ2VvbWV0cmllcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgICAgbGVuZ3RoICs9IGdldExlbmd0aChnZW9tZXRyaWVzW2ldLCBvcHRfb3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgZ2VvbWV0cnkgdHlwZTogJyArIHR5cGUpO1xuICAgICAgfVxuICB9XG5cbiAgcmV0dXJuIGxlbmd0aDtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgc3BoZXJpY2FsIGFyZWEgZm9yIGEgbGlzdCBvZiBjb29yZGluYXRlcy5cbiAqXG4gKiBbUmVmZXJlbmNlXShodHRwczovL3Rycy1uZXcuanBsLm5hc2EuZ292L2hhbmRsZS8yMDE0LzQwNDA5KVxuICogUm9iZXJ0LiBHLiBDaGFtYmVybGFpbiBhbmQgV2lsbGlhbSBILiBEdXF1ZXR0ZSwgXCJTb21lIEFsZ29yaXRobXMgZm9yXG4gKiBQb2x5Z29ucyBvbiBhIFNwaGVyZVwiLCBKUEwgUHVibGljYXRpb24gMDctMDMsIEpldCBQcm9wdWxzaW9uXG4gKiBMYWJvcmF0b3J5LCBQYXNhZGVuYSwgQ0EsIEp1bmUgMjAwN1xuICpcbiAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSBjb29yZGluYXRlcyBMaXN0IG9mIGNvb3JkaW5hdGVzIG9mIGEgbGluZWFyXG4gKiByaW5nLiBJZiB0aGUgcmluZyBpcyBvcmllbnRlZCBjbG9ja3dpc2UsIHRoZSBhcmVhIHdpbGwgYmUgcG9zaXRpdmUsXG4gKiBvdGhlcndpc2UgaXQgd2lsbCBiZSBuZWdhdGl2ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSByYWRpdXMgVGhlIHNwaGVyZSByYWRpdXMuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEFyZWEgKGluIHNxdWFyZSBtZXRlcnMpLlxuICovXG5cbmZ1bmN0aW9uIGdldEFyZWFJbnRlcm5hbChjb29yZGluYXRlcywgcmFkaXVzKSB7XG4gIHZhciBhcmVhID0gMDtcbiAgdmFyIGxlbiA9IGNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgdmFyIHgxID0gY29vcmRpbmF0ZXNbbGVuIC0gMV1bMF07XG4gIHZhciB5MSA9IGNvb3JkaW5hdGVzW2xlbiAtIDFdWzFdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgeDIgPSBjb29yZGluYXRlc1tpXVswXTtcbiAgICB2YXIgeTIgPSBjb29yZGluYXRlc1tpXVsxXTtcbiAgICBhcmVhICs9IHRvUmFkaWFucyh4MiAtIHgxKSAqICgyICsgTWF0aC5zaW4odG9SYWRpYW5zKHkxKSkgKyBNYXRoLnNpbih0b1JhZGlhbnMoeTIpKSk7XG4gICAgeDEgPSB4MjtcbiAgICB5MSA9IHkyO1xuICB9XG5cbiAgcmV0dXJuIGFyZWEgKiByYWRpdXMgKiByYWRpdXMgLyAyLjA7XG59XG4vKipcbiAqIEdldCB0aGUgc3BoZXJpY2FsIGFyZWEgb2YgYSBnZW9tZXRyeS4gIFRoaXMgaXMgdGhlIGFyZWEgKGluIG1ldGVycykgYXNzdW1pbmdcbiAqIHRoYXQgcG9seWdvbiBlZGdlcyBhcmUgc2VnbWVudHMgb2YgZ3JlYXQgY2lyY2xlcyBvbiBhIHNwaGVyZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEEgZ2VvbWV0cnkuXG4gKiBAcGFyYW0ge1NwaGVyZU1ldHJpY09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgYXJlYVxuICogICAgIGNhbGN1bGF0aW9uLiAgQnkgZGVmYXVsdCwgZ2VvbWV0cmllcyBhcmUgYXNzdW1lZCB0byBiZSBpbiAnRVBTRzozODU3Jy5cbiAqICAgICBZb3UgY2FuIGNoYW5nZSB0aGlzIGJ5IHByb3ZpZGluZyBhIGBwcm9qZWN0aW9uYCBvcHRpb24uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBzcGhlcmljYWwgYXJlYSAoaW4gc3F1YXJlIG1ldGVycykuXG4gKiBAYXBpXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXJlYShnZW9tZXRyeSwgb3B0X29wdGlvbnMpIHtcbiAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyB8fCB7fTtcbiAgdmFyIHJhZGl1cyA9IG9wdGlvbnMucmFkaXVzIHx8IERFRkFVTFRfUkFESVVTO1xuICB2YXIgcHJvamVjdGlvbiA9IG9wdGlvbnMucHJvamVjdGlvbiB8fCAnRVBTRzozODU3JztcbiAgdmFyIHR5cGUgPSBnZW9tZXRyeS5nZXRUeXBlKCk7XG5cbiAgaWYgKHR5cGUgIT09IEdlb21ldHJ5VHlwZS5HRU9NRVRSWV9DT0xMRUNUSU9OKSB7XG4gICAgZ2VvbWV0cnkgPSBnZW9tZXRyeS5jbG9uZSgpLnRyYW5zZm9ybShwcm9qZWN0aW9uLCAnRVBTRzo0MzI2Jyk7XG4gIH1cblxuICB2YXIgYXJlYSA9IDA7XG4gIHZhciBjb29yZGluYXRlcywgY29vcmRzLCBpLCBpaSwgaiwgamo7XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuUE9JTlQ6XG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfUE9JTlQ6XG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTElORV9TVFJJTkc6XG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfTElORV9TVFJJTkc6XG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTElORUFSX1JJTkc6XG4gICAgICB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuUE9MWUdPTjpcbiAgICAgIHtcbiAgICAgICAgY29vcmRpbmF0ZXMgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZ2VvbS9Qb2x5Z29uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5LmdldENvb3JkaW5hdGVzKCk7XG4gICAgICAgIGFyZWEgPSBNYXRoLmFicyhnZXRBcmVhSW50ZXJuYWwoY29vcmRpbmF0ZXNbMF0sIHJhZGl1cykpO1xuXG4gICAgICAgIGZvciAoaSA9IDEsIGlpID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICAgIGFyZWEgLT0gTWF0aC5hYnMoZ2V0QXJlYUludGVybmFsKGNvb3JkaW5hdGVzW2ldLCByYWRpdXMpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfUE9MWUdPTjpcbiAgICAgIHtcbiAgICAgICAgY29vcmRpbmF0ZXMgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeS5nZXRDb29yZGluYXRlcygpO1xuXG4gICAgICAgIGZvciAoaSA9IDAsIGlpID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICAgIGNvb3JkcyA9IGNvb3JkaW5hdGVzW2ldO1xuICAgICAgICAgIGFyZWEgKz0gTWF0aC5hYnMoZ2V0QXJlYUludGVybmFsKGNvb3Jkc1swXSwgcmFkaXVzKSk7XG5cbiAgICAgICAgICBmb3IgKGogPSAxLCBqaiA9IGNvb3Jkcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgICAgICAgICBhcmVhIC09IE1hdGguYWJzKGdldEFyZWFJbnRlcm5hbChjb29yZHNbal0sIHJhZGl1cykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuR0VPTUVUUllfQ09MTEVDVElPTjpcbiAgICAgIHtcbiAgICAgICAgdmFyIGdlb21ldHJpZXMgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZ2VvbS9HZW9tZXRyeUNvbGxlY3Rpb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnkuZ2V0R2VvbWV0cmllcygpO1xuXG4gICAgICAgIGZvciAoaSA9IDAsIGlpID0gZ2VvbWV0cmllcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgICAgYXJlYSArPSBnZXRBcmVhKGdlb21ldHJpZXNbaV0sIG9wdF9vcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBnZW9tZXRyeSB0eXBlOiAnICsgdHlwZSk7XG4gICAgICB9XG4gIH1cblxuICByZXR1cm4gYXJlYTtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgY29vcmRpbmF0ZSBhdCB0aGUgZ2l2ZW4gZGlzdGFuY2UgYW5kIGJlYXJpbmcgZnJvbSBgYzFgLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGMxIFRoZSBvcmlnaW4gcG9pbnQgKGBbbG9uLCBsYXRdYCBpbiBkZWdyZWVzKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkaXN0YW5jZSBUaGUgZ3JlYXQtY2lyY2xlIGRpc3RhbmNlIGJldHdlZW4gdGhlIG9yaWdpblxuICogICAgIHBvaW50IGFuZCB0aGUgdGFyZ2V0IHBvaW50LlxuICogQHBhcmFtIHtudW1iZXJ9IGJlYXJpbmcgVGhlIGJlYXJpbmcgKGluIHJhZGlhbnMpLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfcmFkaXVzIFRoZSBzcGhlcmUgcmFkaXVzIHRvIHVzZS4gIERlZmF1bHRzIHRvIHRoZSBFYXJ0aCdzXG4gKiAgICAgbWVhbiByYWRpdXMgdXNpbmcgdGhlIFdHUzg0IGVsbGlwc29pZC5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBUaGUgdGFyZ2V0IHBvaW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBvZmZzZXQoYzEsIGRpc3RhbmNlLCBiZWFyaW5nLCBvcHRfcmFkaXVzKSB7XG4gIHZhciByYWRpdXMgPSBvcHRfcmFkaXVzIHx8IERFRkFVTFRfUkFESVVTO1xuICB2YXIgbGF0MSA9IHRvUmFkaWFucyhjMVsxXSk7XG4gIHZhciBsb24xID0gdG9SYWRpYW5zKGMxWzBdKTtcbiAgdmFyIGRCeVIgPSBkaXN0YW5jZSAvIHJhZGl1cztcbiAgdmFyIGxhdCA9IE1hdGguYXNpbihNYXRoLnNpbihsYXQxKSAqIE1hdGguY29zKGRCeVIpICsgTWF0aC5jb3MobGF0MSkgKiBNYXRoLnNpbihkQnlSKSAqIE1hdGguY29zKGJlYXJpbmcpKTtcbiAgdmFyIGxvbiA9IGxvbjEgKyBNYXRoLmF0YW4yKE1hdGguc2luKGJlYXJpbmcpICogTWF0aC5zaW4oZEJ5UikgKiBNYXRoLmNvcyhsYXQxKSwgTWF0aC5jb3MoZEJ5UikgLSBNYXRoLnNpbihsYXQxKSAqIE1hdGguc2luKGxhdCkpO1xuICByZXR1cm4gW3RvRGVncmVlcyhsb24pLCB0b0RlZ3JlZXMobGF0KV07XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3Byb2pcbiAqL1xuXG4vKipcbiAqIFRoZSBvbC9wcm9qIG1vZHVsZSBzdG9yZXM6XG4gKiAqIGEgbGlzdCBvZiB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn1cbiAqIG9iamVjdHMsIG9uZSBmb3IgZWFjaCBwcm9qZWN0aW9uIHN1cHBvcnRlZCBieSB0aGUgYXBwbGljYXRpb25cbiAqICogYSBsaXN0IG9mIHRyYW5zZm9ybSBmdW5jdGlvbnMgbmVlZGVkIHRvIGNvbnZlcnQgY29vcmRpbmF0ZXMgaW4gb25lIHByb2plY3Rpb25cbiAqIGludG8gYW5vdGhlci5cbiAqXG4gKiBUaGUgc3RhdGljIGZ1bmN0aW9ucyBhcmUgdGhlIG1ldGhvZHMgdXNlZCB0byBtYWludGFpbiB0aGVzZS5cbiAqIEVhY2ggdHJhbnNmb3JtIGZ1bmN0aW9uIGNhbiBoYW5kbGUgbm90IG9ubHkgc2ltcGxlIGNvb3JkaW5hdGUgcGFpcnMsIGJ1dCBhbHNvXG4gKiBsYXJnZSBhcnJheXMgb2YgY29vcmRpbmF0ZXMgc3VjaCBhcyB2ZWN0b3IgZ2VvbWV0cmllcy5cbiAqXG4gKiBXaGVuIGxvYWRlZCwgdGhlIGxpYnJhcnkgYWRkcyBwcm9qZWN0aW9uIG9iamVjdHMgZm9yIEVQU0c6NDMyNiAoV0dTODRcbiAqIGdlb2dyYXBoaWMgY29vcmRpbmF0ZXMpIGFuZCBFUFNHOjM4NTcgKFdlYiBvciBTcGhlcmljYWwgTWVyY2F0b3IsIGFzIHVzZWRcbiAqIGZvciBleGFtcGxlIGJ5IEJpbmcgTWFwcyBvciBPcGVuU3RyZWV0TWFwKSwgdG9nZXRoZXIgd2l0aCB0aGUgcmVsZXZhbnRcbiAqIHRyYW5zZm9ybSBmdW5jdGlvbnMuXG4gKlxuICogQWRkaXRpb25hbCB0cmFuc2Zvcm1zIG1heSBiZSBhZGRlZCBieSB1c2luZyB0aGUgaHR0cDovL3Byb2o0anMub3JnL1xuICogbGlicmFyeSAodmVyc2lvbiAyLjIgb3IgbGF0ZXIpLiBZb3UgY2FuIHVzZSB0aGUgZnVsbCBidWlsZCBzdXBwbGllZCBieVxuICogUHJvajRqcywgb3IgY3JlYXRlIGEgY3VzdG9tIGJ1aWxkIHRvIHN1cHBvcnQgdGhvc2UgcHJvamVjdGlvbnMgeW91IG5lZWQ7IHNlZVxuICogdGhlIFByb2o0anMgd2Vic2l0ZSBmb3IgaG93IHRvIGRvIHRoaXMuIFlvdSBhbHNvIG5lZWQgdGhlIFByb2o0anMgZGVmaW5pdGlvbnNcbiAqIGZvciB0aGUgcmVxdWlyZWQgcHJvamVjdGlvbnMuIFRoZXNlIGRlZmluaXRpb25zIGNhbiBiZSBvYnRhaW5lZCBmcm9tXG4gKiBodHRwczovL2Vwc2cuaW8vLCBhbmQgYXJlIGEgSlMgZnVuY3Rpb24sIHNvIGNhbiBiZSBsb2FkZWQgaW4gYSBzY3JpcHRcbiAqIHRhZyAoYXMgaW4gdGhlIGV4YW1wbGVzKSBvciBwYXN0ZWQgaW50byB5b3VyIGFwcGxpY2F0aW9uLlxuICpcbiAqIEFmdGVyIGFsbCByZXF1aXJlZCBwcm9qZWN0aW9uIGRlZmluaXRpb25zIGFyZSBhZGRlZCB0byBwcm9qNCdzIHJlZ2lzdHJ5IChieVxuICogdXNpbmcgYHByb2o0LmRlZnMoKWApLCBzaW1wbHkgY2FsbCBgcmVnaXN0ZXIocHJvajQpYCBmcm9tIHRoZSBgb2wvcHJvai9wcm9qNGBcbiAqIHBhY2thZ2UuIEV4aXN0aW5nIHRyYW5zZm9ybXMgYXJlIG5vdCBjaGFuZ2VkIGJ5IHRoaXMgZnVuY3Rpb24uIFNlZVxuICogZXhhbXBsZXMvd21zLWltYWdlLWN1c3RvbS1wcm9qIGZvciBhbiBleGFtcGxlIG9mIHRoaXMuXG4gKlxuICogQWRkaXRpb25hbCBwcm9qZWN0aW9uIGRlZmluaXRpb25zIGNhbiBiZSByZWdpc3RlcmVkIHdpdGggYHByb2o0LmRlZnMoKWAgYW55XG4gKiB0aW1lLiBKdXN0IG1ha2Ugc3VyZSB0byBjYWxsIGByZWdpc3Rlcihwcm9qNClgIGFnYWluOyBmb3IgZXhhbXBsZSwgd2l0aCB1c2VyLXN1cHBsaWVkIGRhdGEgd2hlcmUgeW91IGRvbid0XG4gKiBrbm93IGluIGFkdmFuY2Ugd2hhdCBwcm9qZWN0aW9ucyBhcmUgbmVlZGVkLCB5b3UgY2FuIGluaXRpYWxseSBsb2FkIG1pbmltYWxcbiAqIHN1cHBvcnQgYW5kIHRoZW4gbG9hZCB3aGljaGV2ZXIgYXJlIHJlcXVlc3RlZC5cbiAqXG4gKiBOb3RlIHRoYXQgUHJvajRqcyBkb2VzIG5vdCBzdXBwb3J0IHByb2plY3Rpb24gZXh0ZW50cy4gSWYgeW91IHdhbnQgdG8gYWRkXG4gKiBvbmUgZm9yIGNyZWF0aW5nIGRlZmF1bHQgdGlsZSBncmlkcywgeW91IGNhbiBhZGQgaXQgYWZ0ZXIgdGhlIFByb2plY3Rpb25cbiAqIG9iamVjdCBoYXMgYmVlbiBjcmVhdGVkIHdpdGggYHNldEV4dGVudGAsIGZvciBleGFtcGxlLFxuICogYGdldCgnRVBTRzoxMjM0Jykuc2V0RXh0ZW50KGV4dGVudClgLlxuICpcbiAqIEluIGFkZGl0aW9uIHRvIFByb2o0anMgc3VwcG9ydCwgYW55IHRyYW5zZm9ybSBmdW5jdGlvbnMgY2FuIGJlIGFkZGVkIHdpdGhcbiAqIHtAbGluayBtb2R1bGU6b2wvcHJvan5hZGRDb29yZGluYXRlVHJhbnNmb3Jtc30uIFRvIHVzZSB0aGlzLCB5b3UgbXVzdCBmaXJzdCBjcmVhdGVcbiAqIGEge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1Byb2plY3Rpb259IG9iamVjdCBmb3IgdGhlIG5ldyBwcm9qZWN0aW9uIGFuZCBhZGQgaXQgd2l0aFxuICoge0BsaW5rIG1vZHVsZTpvbC9wcm9qfmFkZFByb2plY3Rpb259LiBZb3UgY2FuIHRoZW4gYWRkIHRoZSBmb3J3YXJkIGFuZCBpbnZlcnNlXG4gKiBmdW5jdGlvbnMgd2l0aCB7QGxpbmsgbW9kdWxlOm9sL3Byb2p+YWRkQ29vcmRpbmF0ZVRyYW5zZm9ybXN9LiBTZWVcbiAqIGV4YW1wbGVzL3dtcy1jdXN0b20tcHJvaiBmb3IgYW4gZXhhbXBsZSBvZiB0aGlzLlxuICpcbiAqIE5vdGUgdGhhdCBpZiBubyB0cmFuc2Zvcm1zIGFyZSBuZWVkZWQgYW5kIHlvdSBvbmx5IG5lZWQgdG8gZGVmaW5lIHRoZVxuICogcHJvamVjdGlvbiwganVzdCBhZGQgYSB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn0gd2l0aFxuICoge0BsaW5rIG1vZHVsZTpvbC9wcm9qfmFkZFByb2plY3Rpb259LiBTZWUgZXhhbXBsZXMvd21zLW5vLXByb2ogZm9yIGFuIGV4YW1wbGUgb2ZcbiAqIHRoaXMuXG4gKi9cbmltcG9ydCBQcm9qZWN0aW9uIGZyb20gJy4vcHJvai9Qcm9qZWN0aW9uLmpzJztcbmltcG9ydCBVbml0cywgeyBNRVRFUlNfUEVSX1VOSVQgfSBmcm9tICcuL3Byb2ovVW5pdHMuanMnO1xuaW1wb3J0IHsgUFJPSkVDVElPTlMgYXMgRVBTRzM4NTdfUFJPSkVDVElPTlMsIGZyb21FUFNHNDMyNiwgdG9FUFNHNDMyNiB9IGZyb20gJy4vcHJvai9lcHNnMzg1Ny5qcyc7XG5pbXBvcnQgeyBQUk9KRUNUSU9OUyBhcyBFUFNHNDMyNl9QUk9KRUNUSU9OUyB9IGZyb20gJy4vcHJvai9lcHNnNDMyNi5qcyc7XG5pbXBvcnQgeyBhZGQgYXMgYWRkUHJvaiwgY2xlYXIgYXMgY2xlYXJQcm9qLCBnZXQgYXMgZ2V0UHJvaiB9IGZyb20gJy4vcHJvai9wcm9qZWN0aW9ucy5qcyc7XG5pbXBvcnQgeyBhZGQgYXMgYWRkVHJhbnNmb3JtRnVuYywgY2xlYXIgYXMgY2xlYXJUcmFuc2Zvcm1GdW5jcywgZ2V0IGFzIGdldFRyYW5zZm9ybUZ1bmMgfSBmcm9tICcuL3Byb2ovdHJhbnNmb3Jtcy5qcyc7XG5pbXBvcnQgeyBhcHBseVRyYW5zZm9ybSwgZ2V0V2lkdGggfSBmcm9tICcuL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBjbGFtcCwgbW9kdWxvIH0gZnJvbSAnLi9tYXRoLmpzJztcbmltcG9ydCB7IGdldERpc3RhbmNlIH0gZnJvbSAnLi9zcGhlcmUuanMnO1xuaW1wb3J0IHsgZ2V0V29ybGRzQXdheSB9IGZyb20gJy4vY29vcmRpbmF0ZS5qcyc7XG4vKipcbiAqIEEgcHJvamVjdGlvbiBhcyB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn0sIFNSUyBpZGVudGlmaWVyXG4gKiBzdHJpbmcgb3IgdW5kZWZpbmVkLlxuICogQHR5cGVkZWYge1Byb2plY3Rpb258c3RyaW5nfHVuZGVmaW5lZH0gUHJvamVjdGlvbkxpa2VcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIEEgdHJhbnNmb3JtIGZ1bmN0aW9uIGFjY2VwdHMgYW4gYXJyYXkgb2YgaW5wdXQgY29vcmRpbmF0ZSB2YWx1ZXMsIGFuIG9wdGlvbmFsXG4gKiBvdXRwdXQgYXJyYXksIGFuZCBhbiBvcHRpb25hbCBkaW1lbnNpb24gKGRlZmF1bHQgc2hvdWxkIGJlIDIpLiAgVGhlIGZ1bmN0aW9uXG4gKiB0cmFuc2Zvcm1zIHRoZSBpbnB1dCBjb29yZGluYXRlIHZhbHVlcywgcG9wdWxhdGVzIHRoZSBvdXRwdXQgYXJyYXksIGFuZFxuICogcmV0dXJucyB0aGUgb3V0cHV0IGFycmF5LlxuICpcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihBcnJheTxudW1iZXI+LCBBcnJheTxudW1iZXI+PSwgbnVtYmVyPSk6IEFycmF5PG51bWJlcj59IFRyYW5zZm9ybUZ1bmN0aW9uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHsgTUVURVJTX1BFUl9VTklUIH07XG5leHBvcnQgeyBQcm9qZWN0aW9uIH07XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gaW5wdXQgSW5wdXQgY29vcmRpbmF0ZSBhcnJheS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9vdXRwdXQgT3V0cHV0IGFycmF5IG9mIGNvb3JkaW5hdGUgdmFsdWVzLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZGltZW5zaW9uIERpbWVuc2lvbi5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IE91dHB1dCBjb29yZGluYXRlIGFycmF5IChuZXcgYXJyYXksIHNhbWUgY29vcmRpbmF0ZVxuICogICAgIHZhbHVlcykuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsb25lVHJhbnNmb3JtKGlucHV0LCBvcHRfb3V0cHV0LCBvcHRfZGltZW5zaW9uKSB7XG4gIHZhciBvdXRwdXQ7XG5cbiAgaWYgKG9wdF9vdXRwdXQgIT09IHVuZGVmaW5lZCkge1xuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGlucHV0Lmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIG9wdF9vdXRwdXRbaV0gPSBpbnB1dFtpXTtcbiAgICB9XG5cbiAgICBvdXRwdXQgPSBvcHRfb3V0cHV0O1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IGlucHV0LnNsaWNlKCk7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGlucHV0IElucHV0IGNvb3JkaW5hdGUgYXJyYXkuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfb3V0cHV0IE91dHB1dCBhcnJheSBvZiBjb29yZGluYXRlIHZhbHVlcy5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2RpbWVuc2lvbiBEaW1lbnNpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBJbnB1dCBjb29yZGluYXRlIGFycmF5IChzYW1lIGFycmF5IGFzIGlucHV0KS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpdHlUcmFuc2Zvcm0oaW5wdXQsIG9wdF9vdXRwdXQsIG9wdF9kaW1lbnNpb24pIHtcbiAgaWYgKG9wdF9vdXRwdXQgIT09IHVuZGVmaW5lZCAmJiBpbnB1dCAhPT0gb3B0X291dHB1dCkge1xuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGlucHV0Lmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIG9wdF9vdXRwdXRbaV0gPSBpbnB1dFtpXTtcbiAgICB9XG5cbiAgICBpbnB1dCA9IG9wdF9vdXRwdXQ7XG4gIH1cblxuICByZXR1cm4gaW5wdXQ7XG59XG4vKipcbiAqIEFkZCBhIFByb2plY3Rpb24gb2JqZWN0IHRvIHRoZSBsaXN0IG9mIHN1cHBvcnRlZCBwcm9qZWN0aW9ucyB0aGF0IGNhbiBiZVxuICogbG9va2VkIHVwIGJ5IHRoZWlyIGNvZGUuXG4gKlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufSBwcm9qZWN0aW9uIFByb2plY3Rpb24gaW5zdGFuY2UuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFByb2plY3Rpb24ocHJvamVjdGlvbikge1xuICBhZGRQcm9qKHByb2plY3Rpb24uZ2V0Q29kZSgpLCBwcm9qZWN0aW9uKTtcbiAgYWRkVHJhbnNmb3JtRnVuYyhwcm9qZWN0aW9uLCBwcm9qZWN0aW9uLCBjbG9uZVRyYW5zZm9ybSk7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8UHJvamVjdGlvbj59IHByb2plY3Rpb25zIFByb2plY3Rpb25zLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRQcm9qZWN0aW9ucyhwcm9qZWN0aW9ucykge1xuICBwcm9qZWN0aW9ucy5mb3JFYWNoKGFkZFByb2plY3Rpb24pO1xufVxuLyoqXG4gKiBGZXRjaGVzIGEgUHJvamVjdGlvbiBvYmplY3QgZm9yIHRoZSBjb2RlIHNwZWNpZmllZC5cbiAqXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBwcm9qZWN0aW9uTGlrZSBFaXRoZXIgYSBjb2RlIHN0cmluZyB3aGljaCBpc1xuICogICAgIGEgY29tYmluYXRpb24gb2YgYXV0aG9yaXR5IGFuZCBpZGVudGlmaWVyIHN1Y2ggYXMgXCJFUFNHOjQzMjZcIiwgb3IgYW5cbiAqICAgICBleGlzdGluZyBwcm9qZWN0aW9uIG9iamVjdCwgb3IgdW5kZWZpbmVkLlxuICogQHJldHVybiB7UHJvamVjdGlvbn0gUHJvamVjdGlvbiBvYmplY3QsIG9yIG51bGwgaWYgbm90IGluIGxpc3QuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldChwcm9qZWN0aW9uTGlrZSkge1xuICByZXR1cm4gdHlwZW9mIHByb2plY3Rpb25MaWtlID09PSAnc3RyaW5nJyA/IGdldFByb2ooXG4gIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICBwcm9qZWN0aW9uTGlrZSkgOlxuICAvKiogQHR5cGUge1Byb2plY3Rpb259ICovXG4gIHByb2plY3Rpb25MaWtlIHx8IG51bGw7XG59XG4vKipcbiAqIEdldCB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgcG9pbnQgaW4gZGVncmVlcyBvciBkaXN0YW5jZSB1bml0cy5cbiAqIEZvciBwcm9qZWN0aW9ucyB3aXRoIGRlZ3JlZXMgYXMgdGhlIHVuaXQgdGhpcyB3aWxsIHNpbXBseSByZXR1cm4gdGhlXG4gKiBwcm92aWRlZCByZXNvbHV0aW9uLiBGb3Igb3RoZXIgcHJvamVjdGlvbnMgdGhlIHBvaW50IHJlc29sdXRpb24gaXNcbiAqIGJ5IGRlZmF1bHQgZXN0aW1hdGVkIGJ5IHRyYW5zZm9ybWluZyB0aGUgJ3BvaW50JyBwaXhlbCB0byBFUFNHOjQzMjYsXG4gKiBtZWFzdXJpbmcgaXRzIHdpZHRoIGFuZCBoZWlnaHQgb24gdGhlIG5vcm1hbCBzcGhlcmUsXG4gKiBhbmQgdGFraW5nIHRoZSBhdmVyYWdlIG9mIHRoZSB3aWR0aCBhbmQgaGVpZ2h0LlxuICogQSBjdXN0b20gZnVuY3Rpb24gY2FuIGJlIHByb3ZpZGVkIGZvciBhIHNwZWNpZmljIHByb2plY3Rpb24sIGVpdGhlclxuICogYnkgc2V0dGluZyB0aGUgYGdldFBvaW50UmVzb2x1dGlvbmAgb3B0aW9uIGluIHRoZVxuICoge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1Byb2plY3Rpb25+UHJvamVjdGlvbn0gY29uc3RydWN0b3Igb3IgYnkgdXNpbmdcbiAqIHtAbGluayBtb2R1bGU6b2wvcHJvai9Qcm9qZWN0aW9uflByb2plY3Rpb24jc2V0R2V0UG9pbnRSZXNvbHV0aW9ufSB0byBjaGFuZ2UgYW4gZXhpc3RpbmdcbiAqIHByb2plY3Rpb24gb2JqZWN0LlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gcHJvamVjdGlvbiBUaGUgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIE5vbWluYWwgcmVzb2x1dGlvbiBpbiBwcm9qZWN0aW9uIHVuaXRzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gcG9pbnQgUG9pbnQgdG8gZmluZCBhZGp1c3RlZCByZXNvbHV0aW9uIGF0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovVW5pdHMuanNcIikuZGVmYXVsdD19IG9wdF91bml0cyBVbml0cyB0byBnZXQgdGhlIHBvaW50IHJlc29sdXRpb24gaW4uXG4gKiBEZWZhdWx0IGlzIHRoZSBwcm9qZWN0aW9uJ3MgdW5pdHMuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFBvaW50IHJlc29sdXRpb24uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBvaW50UmVzb2x1dGlvbihwcm9qZWN0aW9uLCByZXNvbHV0aW9uLCBwb2ludCwgb3B0X3VuaXRzKSB7XG4gIHByb2plY3Rpb24gPSBnZXQocHJvamVjdGlvbik7XG4gIHZhciBwb2ludFJlc29sdXRpb247XG4gIHZhciBnZXR0ZXIgPSBwcm9qZWN0aW9uLmdldFBvaW50UmVzb2x1dGlvbkZ1bmMoKTtcblxuICBpZiAoZ2V0dGVyKSB7XG4gICAgcG9pbnRSZXNvbHV0aW9uID0gZ2V0dGVyKHJlc29sdXRpb24sIHBvaW50KTtcblxuICAgIGlmIChvcHRfdW5pdHMgJiYgb3B0X3VuaXRzICE9PSBwcm9qZWN0aW9uLmdldFVuaXRzKCkpIHtcbiAgICAgIHZhciBtZXRlcnNQZXJVbml0ID0gcHJvamVjdGlvbi5nZXRNZXRlcnNQZXJVbml0KCk7XG5cbiAgICAgIGlmIChtZXRlcnNQZXJVbml0KSB7XG4gICAgICAgIHBvaW50UmVzb2x1dGlvbiA9IHBvaW50UmVzb2x1dGlvbiAqIG1ldGVyc1BlclVuaXQgLyBNRVRFUlNfUEVSX1VOSVRbb3B0X3VuaXRzXTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIHVuaXRzID0gcHJvamVjdGlvbi5nZXRVbml0cygpO1xuXG4gICAgaWYgKHVuaXRzID09IFVuaXRzLkRFR1JFRVMgJiYgIW9wdF91bml0cyB8fCBvcHRfdW5pdHMgPT0gVW5pdHMuREVHUkVFUykge1xuICAgICAgcG9pbnRSZXNvbHV0aW9uID0gcmVzb2x1dGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRXN0aW1hdGUgcG9pbnQgcmVzb2x1dGlvbiBieSB0cmFuc2Zvcm1pbmcgdGhlIGNlbnRlciBwaXhlbCB0byBFUFNHOjQzMjYsXG4gICAgICAvLyBtZWFzdXJpbmcgaXRzIHdpZHRoIGFuZCBoZWlnaHQgb24gdGhlIG5vcm1hbCBzcGhlcmUsIGFuZCB0YWtpbmcgdGhlXG4gICAgICAvLyBhdmVyYWdlIG9mIHRoZSB3aWR0aCBhbmQgaGVpZ2h0LlxuICAgICAgdmFyIHRvRVBTRzQzMjZfMSA9IGdldFRyYW5zZm9ybUZyb21Qcm9qZWN0aW9ucyhwcm9qZWN0aW9uLCBnZXQoJ0VQU0c6NDMyNicpKTtcblxuICAgICAgaWYgKHRvRVBTRzQzMjZfMSA9PT0gaWRlbnRpdHlUcmFuc2Zvcm0gJiYgdW5pdHMgIT09IFVuaXRzLkRFR1JFRVMpIHtcbiAgICAgICAgLy8gbm8gdHJhbnNmb3JtIGlzIGF2YWlsYWJsZVxuICAgICAgICBwb2ludFJlc29sdXRpb24gPSByZXNvbHV0aW9uICogcHJvamVjdGlvbi5nZXRNZXRlcnNQZXJVbml0KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdmVydGljZXMgPSBbcG9pbnRbMF0gLSByZXNvbHV0aW9uIC8gMiwgcG9pbnRbMV0sIHBvaW50WzBdICsgcmVzb2x1dGlvbiAvIDIsIHBvaW50WzFdLCBwb2ludFswXSwgcG9pbnRbMV0gLSByZXNvbHV0aW9uIC8gMiwgcG9pbnRbMF0sIHBvaW50WzFdICsgcmVzb2x1dGlvbiAvIDJdO1xuICAgICAgICB2ZXJ0aWNlcyA9IHRvRVBTRzQzMjZfMSh2ZXJ0aWNlcywgdmVydGljZXMsIDIpO1xuICAgICAgICB2YXIgd2lkdGggPSBnZXREaXN0YW5jZSh2ZXJ0aWNlcy5zbGljZSgwLCAyKSwgdmVydGljZXMuc2xpY2UoMiwgNCkpO1xuICAgICAgICB2YXIgaGVpZ2h0ID0gZ2V0RGlzdGFuY2UodmVydGljZXMuc2xpY2UoNCwgNiksIHZlcnRpY2VzLnNsaWNlKDYsIDgpKTtcbiAgICAgICAgcG9pbnRSZXNvbHV0aW9uID0gKHdpZHRoICsgaGVpZ2h0KSAvIDI7XG4gICAgICB9XG5cbiAgICAgIHZhciBtZXRlcnNQZXJVbml0ID0gb3B0X3VuaXRzID8gTUVURVJTX1BFUl9VTklUW29wdF91bml0c10gOiBwcm9qZWN0aW9uLmdldE1ldGVyc1BlclVuaXQoKTtcblxuICAgICAgaWYgKG1ldGVyc1BlclVuaXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwb2ludFJlc29sdXRpb24gLz0gbWV0ZXJzUGVyVW5pdDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcG9pbnRSZXNvbHV0aW9uO1xufVxuLyoqXG4gKiBSZWdpc3RlcnMgdHJhbnNmb3JtYXRpb24gZnVuY3Rpb25zIHRoYXQgZG9uJ3QgYWx0ZXIgY29vcmRpbmF0ZXMuIFRob3NlIGFsbG93XG4gKiB0byB0cmFuc2Zvcm0gYmV0d2VlbiBwcm9qZWN0aW9ucyB3aXRoIGVxdWFsIG1lYW5pbmcuXG4gKlxuICogQHBhcmFtIHtBcnJheTxQcm9qZWN0aW9uPn0gcHJvamVjdGlvbnMgUHJvamVjdGlvbnMuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEVxdWl2YWxlbnRQcm9qZWN0aW9ucyhwcm9qZWN0aW9ucykge1xuICBhZGRQcm9qZWN0aW9ucyhwcm9qZWN0aW9ucyk7XG4gIHByb2plY3Rpb25zLmZvckVhY2goZnVuY3Rpb24gKHNvdXJjZSkge1xuICAgIHByb2plY3Rpb25zLmZvckVhY2goZnVuY3Rpb24gKGRlc3RpbmF0aW9uKSB7XG4gICAgICBpZiAoc291cmNlICE9PSBkZXN0aW5hdGlvbikge1xuICAgICAgICBhZGRUcmFuc2Zvcm1GdW5jKHNvdXJjZSwgZGVzdGluYXRpb24sIGNsb25lVHJhbnNmb3JtKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59XG4vKipcbiAqIFJlZ2lzdGVycyB0cmFuc2Zvcm1hdGlvbiBmdW5jdGlvbnMgdG8gY29udmVydCBjb29yZGluYXRlcyBpbiBhbnkgcHJvamVjdGlvblxuICogaW4gcHJvamVjdGlvbjEgdG8gYW55IHByb2plY3Rpb24gaW4gcHJvamVjdGlvbjIuXG4gKlxuICogQHBhcmFtIHtBcnJheTxQcm9qZWN0aW9uPn0gcHJvamVjdGlvbnMxIFByb2plY3Rpb25zIHdpdGggZXF1YWxcbiAqICAgICBtZWFuaW5nLlxuICogQHBhcmFtIHtBcnJheTxQcm9qZWN0aW9uPn0gcHJvamVjdGlvbnMyIFByb2plY3Rpb25zIHdpdGggZXF1YWxcbiAqICAgICBtZWFuaW5nLlxuICogQHBhcmFtIHtUcmFuc2Zvcm1GdW5jdGlvbn0gZm9yd2FyZFRyYW5zZm9ybSBUcmFuc2Zvcm1hdGlvbiBmcm9tIGFueVxuICogICBwcm9qZWN0aW9uIGluIHByb2plY3Rpb24xIHRvIGFueSBwcm9qZWN0aW9uIGluIHByb2plY3Rpb24yLlxuICogQHBhcmFtIHtUcmFuc2Zvcm1GdW5jdGlvbn0gaW52ZXJzZVRyYW5zZm9ybSBUcmFuc2Zvcm0gZnJvbSBhbnkgcHJvamVjdGlvblxuICogICBpbiBwcm9qZWN0aW9uMiB0byBhbnkgcHJvamVjdGlvbiBpbiBwcm9qZWN0aW9uMS4uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEVxdWl2YWxlbnRUcmFuc2Zvcm1zKHByb2plY3Rpb25zMSwgcHJvamVjdGlvbnMyLCBmb3J3YXJkVHJhbnNmb3JtLCBpbnZlcnNlVHJhbnNmb3JtKSB7XG4gIHByb2plY3Rpb25zMS5mb3JFYWNoKGZ1bmN0aW9uIChwcm9qZWN0aW9uMSkge1xuICAgIHByb2plY3Rpb25zMi5mb3JFYWNoKGZ1bmN0aW9uIChwcm9qZWN0aW9uMikge1xuICAgICAgYWRkVHJhbnNmb3JtRnVuYyhwcm9qZWN0aW9uMSwgcHJvamVjdGlvbjIsIGZvcndhcmRUcmFuc2Zvcm0pO1xuICAgICAgYWRkVHJhbnNmb3JtRnVuYyhwcm9qZWN0aW9uMiwgcHJvamVjdGlvbjEsIGludmVyc2VUcmFuc2Zvcm0pO1xuICAgIH0pO1xuICB9KTtcbn1cbi8qKlxuICogQ2xlYXIgYWxsIGNhY2hlZCBwcm9qZWN0aW9ucyBhbmQgdHJhbnNmb3Jtcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJBbGxQcm9qZWN0aW9ucygpIHtcbiAgY2xlYXJQcm9qKCk7XG4gIGNsZWFyVHJhbnNmb3JtRnVuY3MoKTtcbn1cbi8qKlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufHN0cmluZ3x1bmRlZmluZWR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkZWZhdWx0Q29kZSBEZWZhdWx0IGNvZGUuXG4gKiBAcmV0dXJuIHtQcm9qZWN0aW9ufSBQcm9qZWN0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQcm9qZWN0aW9uKHByb2plY3Rpb24sIGRlZmF1bHRDb2RlKSB7XG4gIGlmICghcHJvamVjdGlvbikge1xuICAgIHJldHVybiBnZXQoZGVmYXVsdENvZGUpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBwcm9qZWN0aW9uID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBnZXQocHJvamVjdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7UHJvamVjdGlvbn0gKi9cbiAgICAgIHByb2plY3Rpb25cbiAgICApO1xuICB9XG59XG4vKipcbiAqIENyZWF0ZXMgYSB7QGxpbmsgbW9kdWxlOm9sL3Byb2p+VHJhbnNmb3JtRnVuY3Rpb259IGZyb20gYSBzaW1wbGUgMkQgY29vcmRpbmF0ZSB0cmFuc2Zvcm1cbiAqIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6IGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZFRyYW5zZm9ybSBDb29yZGluYXRlXG4gKiAgICAgdHJhbnNmb3JtLlxuICogQHJldHVybiB7VHJhbnNmb3JtRnVuY3Rpb259IFRyYW5zZm9ybSBmdW5jdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVHJhbnNmb3JtRnJvbUNvb3JkaW5hdGVUcmFuc2Zvcm0oY29vcmRUcmFuc2Zvcm0pIHtcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGlucHV0IElucHV0LlxuICAgICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9vdXRwdXQgT3V0cHV0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2RpbWVuc2lvbiBEaW1lbnNpb24uXG4gICAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gT3V0cHV0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChpbnB1dCwgb3B0X291dHB1dCwgb3B0X2RpbWVuc2lvbikge1xuICAgICAgdmFyIGxlbmd0aCA9IGlucHV0Lmxlbmd0aDtcbiAgICAgIHZhciBkaW1lbnNpb24gPSBvcHRfZGltZW5zaW9uICE9PSB1bmRlZmluZWQgPyBvcHRfZGltZW5zaW9uIDogMjtcbiAgICAgIHZhciBvdXRwdXQgPSBvcHRfb3V0cHV0ICE9PSB1bmRlZmluZWQgPyBvcHRfb3V0cHV0IDogbmV3IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IGRpbWVuc2lvbikge1xuICAgICAgICB2YXIgcG9pbnQgPSBjb29yZFRyYW5zZm9ybShbaW5wdXRbaV0sIGlucHV0W2kgKyAxXV0pO1xuICAgICAgICBvdXRwdXRbaV0gPSBwb2ludFswXTtcbiAgICAgICAgb3V0cHV0W2kgKyAxXSA9IHBvaW50WzFdO1xuXG4gICAgICAgIGZvciAodmFyIGogPSBkaW1lbnNpb24gLSAxOyBqID49IDI7IC0taikge1xuICAgICAgICAgIG91dHB1dFtpICsgal0gPSBpbnB1dFtpICsgal07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9XG4gICk7XG59XG4vKipcbiAqIFJlZ2lzdGVycyBjb29yZGluYXRlIHRyYW5zZm9ybSBmdW5jdGlvbnMgdG8gY29udmVydCBjb29yZGluYXRlcyBiZXR3ZWVuIHRoZVxuICogc291cmNlIHByb2plY3Rpb24gYW5kIHRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICogVGhlIGZvcndhcmQgYW5kIGludmVyc2UgZnVuY3Rpb25zIGNvbnZlcnQgY29vcmRpbmF0ZSBwYWlyczsgdGhpcyBmdW5jdGlvblxuICogY29udmVydHMgdGhlc2UgaW50byB0aGUgZnVuY3Rpb25zIHVzZWQgaW50ZXJuYWxseSB3aGljaCBhbHNvIGhhbmRsZVxuICogZXh0ZW50cyBhbmQgY29vcmRpbmF0ZSBhcnJheXMuXG4gKlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gc291cmNlIFNvdXJjZSBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gZGVzdGluYXRpb24gRGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOiBpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gZm9yd2FyZCBUaGUgZm9yd2FyZCB0cmFuc2Zvcm1cbiAqICAgICBmdW5jdGlvbiAodGhhdCBpcywgZnJvbSB0aGUgc291cmNlIHByb2plY3Rpb24gdG8gdGhlIGRlc3RpbmF0aW9uXG4gKiAgICAgcHJvamVjdGlvbikgdGhhdCB0YWtlcyBhIHtAbGluayBtb2R1bGU6b2wvY29vcmRpbmF0ZX5Db29yZGluYXRlfSBhcyBhcmd1bWVudCBhbmQgcmV0dXJuc1xuICogICAgIHRoZSB0cmFuc2Zvcm1lZCB7QGxpbmsgbW9kdWxlOm9sL2Nvb3JkaW5hdGV+Q29vcmRpbmF0ZX0uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlKTogaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGludmVyc2UgVGhlIGludmVyc2UgdHJhbnNmb3JtXG4gKiAgICAgZnVuY3Rpb24gKHRoYXQgaXMsIGZyb20gdGhlIGRlc3RpbmF0aW9uIHByb2plY3Rpb24gdG8gdGhlIHNvdXJjZVxuICogICAgIHByb2plY3Rpb24pIHRoYXQgdGFrZXMgYSB7QGxpbmsgbW9kdWxlOm9sL2Nvb3JkaW5hdGV+Q29vcmRpbmF0ZX0gYXMgYXJndW1lbnQgYW5kIHJldHVybnNcbiAqICAgICB0aGUgdHJhbnNmb3JtZWQge0BsaW5rIG1vZHVsZTpvbC9jb29yZGluYXRlfkNvb3JkaW5hdGV9LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb29yZGluYXRlVHJhbnNmb3Jtcyhzb3VyY2UsIGRlc3RpbmF0aW9uLCBmb3J3YXJkLCBpbnZlcnNlKSB7XG4gIHZhciBzb3VyY2VQcm9qID0gZ2V0KHNvdXJjZSk7XG4gIHZhciBkZXN0UHJvaiA9IGdldChkZXN0aW5hdGlvbik7XG4gIGFkZFRyYW5zZm9ybUZ1bmMoc291cmNlUHJvaiwgZGVzdFByb2osIGNyZWF0ZVRyYW5zZm9ybUZyb21Db29yZGluYXRlVHJhbnNmb3JtKGZvcndhcmQpKTtcbiAgYWRkVHJhbnNmb3JtRnVuYyhkZXN0UHJvaiwgc291cmNlUHJvaiwgY3JlYXRlVHJhbnNmb3JtRnJvbUNvb3JkaW5hdGVUcmFuc2Zvcm0oaW52ZXJzZSkpO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIGEgY29vcmRpbmF0ZSBmcm9tIGxvbmdpdHVkZS9sYXRpdHVkZSB0byBhIGRpZmZlcmVudCBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlIGFzIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUsIGkuZS5cbiAqICAgICBhbiBhcnJheSB3aXRoIGxvbmdpdHVkZSBhcyAxc3QgYW5kIGxhdGl0dWRlIGFzIDJuZCBlbGVtZW50LlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZT19IG9wdF9wcm9qZWN0aW9uIFRhcmdldCBwcm9qZWN0aW9uLiBUaGVcbiAqICAgICBkZWZhdWx0IGlzIFdlYiBNZXJjYXRvciwgaS5lLiAnRVBTRzozODU3Jy5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb29yZGluYXRlIHByb2plY3RlZCB0byB0aGUgdGFyZ2V0IHByb2plY3Rpb24uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21Mb25MYXQoY29vcmRpbmF0ZSwgb3B0X3Byb2plY3Rpb24pIHtcbiAgcmV0dXJuIHRyYW5zZm9ybShjb29yZGluYXRlLCAnRVBTRzo0MzI2Jywgb3B0X3Byb2plY3Rpb24gIT09IHVuZGVmaW5lZCA/IG9wdF9wcm9qZWN0aW9uIDogJ0VQU0c6Mzg1NycpO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIGEgY29vcmRpbmF0ZSB0byBsb25naXR1ZGUvbGF0aXR1ZGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIFByb2plY3RlZCBjb29yZGluYXRlLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZT19IG9wdF9wcm9qZWN0aW9uIFByb2plY3Rpb24gb2YgdGhlIGNvb3JkaW5hdGUuXG4gKiAgICAgVGhlIGRlZmF1bHQgaXMgV2ViIE1lcmNhdG9yLCBpLmUuICdFUFNHOjM4NTcnLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IENvb3JkaW5hdGUgYXMgbG9uZ2l0dWRlIGFuZCBsYXRpdHVkZSwgaS5lLiBhbiBhcnJheVxuICogICAgIHdpdGggbG9uZ2l0dWRlIGFzIDFzdCBhbmQgbGF0aXR1ZGUgYXMgMm5kIGVsZW1lbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvTG9uTGF0KGNvb3JkaW5hdGUsIG9wdF9wcm9qZWN0aW9uKSB7XG4gIHZhciBsb25MYXQgPSB0cmFuc2Zvcm0oY29vcmRpbmF0ZSwgb3B0X3Byb2plY3Rpb24gIT09IHVuZGVmaW5lZCA/IG9wdF9wcm9qZWN0aW9uIDogJ0VQU0c6Mzg1NycsICdFUFNHOjQzMjYnKTtcbiAgdmFyIGxvbiA9IGxvbkxhdFswXTtcblxuICBpZiAobG9uIDwgLTE4MCB8fCBsb24gPiAxODApIHtcbiAgICBsb25MYXRbMF0gPSBtb2R1bG8obG9uICsgMTgwLCAzNjApIC0gMTgwO1xuICB9XG5cbiAgcmV0dXJuIGxvbkxhdDtcbn1cbi8qKlxuICogQ2hlY2tzIGlmIHR3byBwcm9qZWN0aW9ucyBhcmUgdGhlIHNhbWUsIHRoYXQgaXMgZXZlcnkgY29vcmRpbmF0ZSBpbiBvbmVcbiAqIHByb2plY3Rpb24gZG9lcyByZXByZXNlbnQgdGhlIHNhbWUgZ2VvZ3JhcGhpYyBwb2ludCBhcyB0aGUgc2FtZSBjb29yZGluYXRlIGluXG4gKiB0aGUgb3RoZXIgcHJvamVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1Byb2plY3Rpb259IHByb2plY3Rpb24xIFByb2plY3Rpb24gMS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbn0gcHJvamVjdGlvbjIgUHJvamVjdGlvbiAyLlxuICogQHJldHVybiB7Ym9vbGVhbn0gRXF1aXZhbGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXF1aXZhbGVudChwcm9qZWN0aW9uMSwgcHJvamVjdGlvbjIpIHtcbiAgaWYgKHByb2plY3Rpb24xID09PSBwcm9qZWN0aW9uMikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgdmFyIGVxdWFsVW5pdHMgPSBwcm9qZWN0aW9uMS5nZXRVbml0cygpID09PSBwcm9qZWN0aW9uMi5nZXRVbml0cygpO1xuXG4gIGlmIChwcm9qZWN0aW9uMS5nZXRDb2RlKCkgPT09IHByb2plY3Rpb24yLmdldENvZGUoKSkge1xuICAgIHJldHVybiBlcXVhbFVuaXRzO1xuICB9IGVsc2Uge1xuICAgIHZhciB0cmFuc2Zvcm1GdW5jID0gZ2V0VHJhbnNmb3JtRnJvbVByb2plY3Rpb25zKHByb2plY3Rpb24xLCBwcm9qZWN0aW9uMik7XG4gICAgcmV0dXJuIHRyYW5zZm9ybUZ1bmMgPT09IGNsb25lVHJhbnNmb3JtICYmIGVxdWFsVW5pdHM7XG4gIH1cbn1cbi8qKlxuICogU2VhcmNoZXMgaW4gdGhlIGxpc3Qgb2YgdHJhbnNmb3JtIGZ1bmN0aW9ucyBmb3IgdGhlIGZ1bmN0aW9uIGZvciBjb252ZXJ0aW5nXG4gKiBjb29yZGluYXRlcyBmcm9tIHRoZSBzb3VyY2UgcHJvamVjdGlvbiB0byB0aGUgZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1Byb2plY3Rpb259IHNvdXJjZVByb2plY3Rpb24gU291cmNlIFByb2plY3Rpb24gb2JqZWN0LlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufSBkZXN0aW5hdGlvblByb2plY3Rpb24gRGVzdGluYXRpb24gUHJvamVjdGlvblxuICogICAgIG9iamVjdC5cbiAqIEByZXR1cm4ge1RyYW5zZm9ybUZ1bmN0aW9ufSBUcmFuc2Zvcm0gZnVuY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRyYW5zZm9ybUZyb21Qcm9qZWN0aW9ucyhzb3VyY2VQcm9qZWN0aW9uLCBkZXN0aW5hdGlvblByb2plY3Rpb24pIHtcbiAgdmFyIHNvdXJjZUNvZGUgPSBzb3VyY2VQcm9qZWN0aW9uLmdldENvZGUoKTtcbiAgdmFyIGRlc3RpbmF0aW9uQ29kZSA9IGRlc3RpbmF0aW9uUHJvamVjdGlvbi5nZXRDb2RlKCk7XG4gIHZhciB0cmFuc2Zvcm1GdW5jID0gZ2V0VHJhbnNmb3JtRnVuYyhzb3VyY2VDb2RlLCBkZXN0aW5hdGlvbkNvZGUpO1xuXG4gIGlmICghdHJhbnNmb3JtRnVuYykge1xuICAgIHRyYW5zZm9ybUZ1bmMgPSBpZGVudGl0eVRyYW5zZm9ybTtcbiAgfVxuXG4gIHJldHVybiB0cmFuc2Zvcm1GdW5jO1xufVxuLyoqXG4gKiBHaXZlbiB0aGUgcHJvamVjdGlvbi1saWtlIG9iamVjdHMsIHNlYXJjaGVzIGZvciBhIHRyYW5zZm9ybWF0aW9uXG4gKiBmdW5jdGlvbiB0byBjb252ZXJ0IGEgY29vcmRpbmF0ZXMgYXJyYXkgZnJvbSB0aGUgc291cmNlIHByb2plY3Rpb24gdG8gdGhlXG4gKiBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IHNvdXJjZSBTb3VyY2UuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBkZXN0aW5hdGlvbiBEZXN0aW5hdGlvbi5cbiAqIEByZXR1cm4ge1RyYW5zZm9ybUZ1bmN0aW9ufSBUcmFuc2Zvcm0gZnVuY3Rpb24uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRyYW5zZm9ybShzb3VyY2UsIGRlc3RpbmF0aW9uKSB7XG4gIHZhciBzb3VyY2VQcm9qZWN0aW9uID0gZ2V0KHNvdXJjZSk7XG4gIHZhciBkZXN0aW5hdGlvblByb2plY3Rpb24gPSBnZXQoZGVzdGluYXRpb24pO1xuICByZXR1cm4gZ2V0VHJhbnNmb3JtRnJvbVByb2plY3Rpb25zKHNvdXJjZVByb2plY3Rpb24sIGRlc3RpbmF0aW9uUHJvamVjdGlvbik7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgYSBjb29yZGluYXRlIGZyb20gc291cmNlIHByb2plY3Rpb24gdG8gZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIFRoaXMgcmV0dXJucyBhIG5ldyBjb29yZGluYXRlIChhbmQgZG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCkuXG4gKlxuICogU2VlIHtAbGluayBtb2R1bGU6b2wvcHJvan50cmFuc2Zvcm1FeHRlbnR9IGZvciBleHRlbnQgdHJhbnNmb3JtYXRpb24uXG4gKiBTZWUgdGhlIHRyYW5zZm9ybSBtZXRob2Qgb2Yge0BsaW5rIG1vZHVsZTpvbC9nZW9tL0dlb21ldHJ5fkdlb21ldHJ5fSBhbmQgaXRzXG4gKiBzdWJjbGFzc2VzIGZvciBnZW9tZXRyeSB0cmFuc2Zvcm1zLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IHNvdXJjZSBTb3VyY2UgcHJvamVjdGlvbi1saWtlLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gZGVzdGluYXRpb24gRGVzdGluYXRpb24gcHJvamVjdGlvbi1saWtlLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IENvb3JkaW5hdGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybShjb29yZGluYXRlLCBzb3VyY2UsIGRlc3RpbmF0aW9uKSB7XG4gIHZhciB0cmFuc2Zvcm1GdW5jID0gZ2V0VHJhbnNmb3JtKHNvdXJjZSwgZGVzdGluYXRpb24pO1xuICByZXR1cm4gdHJhbnNmb3JtRnVuYyhjb29yZGluYXRlLCB1bmRlZmluZWQsIGNvb3JkaW5hdGUubGVuZ3RoKTtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyBhbiBleHRlbnQgZnJvbSBzb3VyY2UgcHJvamVjdGlvbiB0byBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLiAgVGhpc1xuICogcmV0dXJucyBhIG5ldyBleHRlbnQgKGFuZCBkb2VzIG5vdCBtb2RpZnkgdGhlIG9yaWdpbmFsKS5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IFRoZSBleHRlbnQgdG8gdHJhbnNmb3JtLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gc291cmNlIFNvdXJjZSBwcm9qZWN0aW9uLWxpa2UuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBkZXN0aW5hdGlvbiBEZXN0aW5hdGlvbiBwcm9qZWN0aW9uLWxpa2UuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9zdG9wcyBOdW1iZXIgb2Ygc3RvcHMgcGVyIHNpZGUgdXNlZCBmb3IgdGhlIHRyYW5zZm9ybS5cbiAqIEJ5IGRlZmF1bHQgb25seSB0aGUgY29ybmVycyBhcmUgdXNlZC5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gVGhlIHRyYW5zZm9ybWVkIGV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtRXh0ZW50KGV4dGVudCwgc291cmNlLCBkZXN0aW5hdGlvbiwgb3B0X3N0b3BzKSB7XG4gIHZhciB0cmFuc2Zvcm1GdW5jID0gZ2V0VHJhbnNmb3JtKHNvdXJjZSwgZGVzdGluYXRpb24pO1xuICByZXR1cm4gYXBwbHlUcmFuc2Zvcm0oZXh0ZW50LCB0cmFuc2Zvcm1GdW5jLCB1bmRlZmluZWQsIG9wdF9zdG9wcyk7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIGdpdmVuIHBvaW50IHRvIHRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHBvaW50IFBvaW50LlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufSBzb3VyY2VQcm9qZWN0aW9uIFNvdXJjZSBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufSBkZXN0aW5hdGlvblByb2plY3Rpb24gRGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBQb2ludC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtV2l0aFByb2plY3Rpb25zKHBvaW50LCBzb3VyY2VQcm9qZWN0aW9uLCBkZXN0aW5hdGlvblByb2plY3Rpb24pIHtcbiAgdmFyIHRyYW5zZm9ybUZ1bmMgPSBnZXRUcmFuc2Zvcm1Gcm9tUHJvamVjdGlvbnMoc291cmNlUHJvamVjdGlvbiwgZGVzdGluYXRpb25Qcm9qZWN0aW9uKTtcbiAgcmV0dXJuIHRyYW5zZm9ybUZ1bmMocG9pbnQpO1xufVxuLyoqXG4gKiBAdHlwZSB7P1Byb2plY3Rpb259XG4gKi9cblxudmFyIHVzZXJQcm9qZWN0aW9uID0gbnVsbDtcbi8qKlxuICogU2V0IHRoZSBwcm9qZWN0aW9uIGZvciBjb29yZGluYXRlcyBzdXBwbGllZCBmcm9tIGFuZCByZXR1cm5lZCBieSBBUEkgbWV0aG9kcy5cbiAqIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBpcyBub3QgeWV0IGEgcGFydCBvZiB0aGUgc3RhYmxlIEFQSS4gIFN1cHBvcnQgZm9yIHVzZXJcbiAqIHByb2plY3Rpb25zIGlzIG5vdCB5ZXQgY29tcGxldGUgYW5kIHNob3VsZCBiZSBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbC5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IHByb2plY3Rpb24gVGhlIHVzZXIgcHJvamVjdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0VXNlclByb2plY3Rpb24ocHJvamVjdGlvbikge1xuICB1c2VyUHJvamVjdGlvbiA9IGdldChwcm9qZWN0aW9uKTtcbn1cbi8qKlxuICogQ2xlYXIgdGhlIHVzZXIgcHJvamVjdGlvbiBpZiBzZXQuICBOb3RlIHRoYXQgdGhpcyBtZXRob2QgaXMgbm90IHlldCBhIHBhcnQgb2ZcbiAqIHRoZSBzdGFibGUgQVBJLiAgU3VwcG9ydCBmb3IgdXNlciBwcm9qZWN0aW9ucyBpcyBub3QgeWV0IGNvbXBsZXRlIGFuZCBzaG91bGRcbiAqIGJlIGNvbnNpZGVyZWQgZXhwZXJpbWVudGFsLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhclVzZXJQcm9qZWN0aW9uKCkge1xuICB1c2VyUHJvamVjdGlvbiA9IG51bGw7XG59XG4vKipcbiAqIEdldCB0aGUgcHJvamVjdGlvbiBmb3IgY29vcmRpbmF0ZXMgc3VwcGxpZWQgZnJvbSBhbmQgcmV0dXJuZWQgYnkgQVBJIG1ldGhvZHMuXG4gKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgaXMgbm90IHlldCBhIHBhcnQgb2YgdGhlIHN0YWJsZSBBUEkuICBTdXBwb3J0IGZvciB1c2VyXG4gKiBwcm9qZWN0aW9ucyBpcyBub3QgeWV0IGNvbXBsZXRlIGFuZCBzaG91bGQgYmUgY29uc2lkZXJlZCBleHBlcmltZW50YWwuXG4gKiBAcmV0dXJucyB7P1Byb2plY3Rpb259IFRoZSB1c2VyIHByb2plY3Rpb24gKG9yIG51bGwgaWYgbm90IHNldCkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVzZXJQcm9qZWN0aW9uKCkge1xuICByZXR1cm4gdXNlclByb2plY3Rpb247XG59XG4vKipcbiAqIFVzZSBnZW9ncmFwaGljIGNvb3JkaW5hdGVzIChXR1MtODQgZGF0dW0pIGluIEFQSSBtZXRob2RzLiAgTm90ZSB0aGF0IHRoaXNcbiAqIG1ldGhvZCBpcyBub3QgeWV0IGEgcGFydCBvZiB0aGUgc3RhYmxlIEFQSS4gIFN1cHBvcnQgZm9yIHVzZXIgcHJvamVjdGlvbnMgaXNcbiAqIG5vdCB5ZXQgY29tcGxldGUgYW5kIHNob3VsZCBiZSBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlR2VvZ3JhcGhpYygpIHtcbiAgc2V0VXNlclByb2plY3Rpb24oJ0VQU0c6NDMyNicpO1xufVxuLyoqXG4gKiBSZXR1cm4gYSBjb29yZGluYXRlIHRyYW5zZm9ybWVkIGludG8gdGhlIHVzZXIgcHJvamVjdGlvbi4gIElmIG5vIHVzZXIgcHJvamVjdGlvblxuICogaXMgc2V0LCB0aGUgb3JpZ2luYWwgY29vcmRpbmF0ZSBpcyByZXR1cm5lZC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gY29vcmRpbmF0ZSBJbnB1dCBjb29yZGluYXRlLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gc291cmNlUHJvamVjdGlvbiBUaGUgaW5wdXQgY29vcmRpbmF0ZSBwcm9qZWN0aW9uLlxuICogQHJldHVybnMge0FycmF5PG51bWJlcj59IFRoZSBpbnB1dCBjb29yZGluYXRlIGluIHRoZSB1c2VyIHByb2plY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvVXNlckNvb3JkaW5hdGUoY29vcmRpbmF0ZSwgc291cmNlUHJvamVjdGlvbikge1xuICBpZiAoIXVzZXJQcm9qZWN0aW9uKSB7XG4gICAgcmV0dXJuIGNvb3JkaW5hdGU7XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtKGNvb3JkaW5hdGUsIHNvdXJjZVByb2plY3Rpb24sIHVzZXJQcm9qZWN0aW9uKTtcbn1cbi8qKlxuICogUmV0dXJuIGEgY29vcmRpbmF0ZSB0cmFuc2Zvcm1lZCBmcm9tIHRoZSB1c2VyIHByb2plY3Rpb24uICBJZiBubyB1c2VyIHByb2plY3Rpb25cbiAqIGlzIHNldCwgdGhlIG9yaWdpbmFsIGNvb3JkaW5hdGUgaXMgcmV0dXJuZWQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGNvb3JkaW5hdGUgSW5wdXQgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IGRlc3RQcm9qZWN0aW9uIFRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICogQHJldHVybnMge0FycmF5PG51bWJlcj59IFRoZSBpbnB1dCBjb29yZGluYXRlIHRyYW5zZm9ybWVkLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tVXNlckNvb3JkaW5hdGUoY29vcmRpbmF0ZSwgZGVzdFByb2plY3Rpb24pIHtcbiAgaWYgKCF1c2VyUHJvamVjdGlvbikge1xuICAgIHJldHVybiBjb29yZGluYXRlO1xuICB9XG5cbiAgcmV0dXJuIHRyYW5zZm9ybShjb29yZGluYXRlLCB1c2VyUHJvamVjdGlvbiwgZGVzdFByb2plY3Rpb24pO1xufVxuLyoqXG4gKiBSZXR1cm4gYW4gZXh0ZW50IHRyYW5zZm9ybWVkIGludG8gdGhlIHVzZXIgcHJvamVjdGlvbi4gIElmIG5vIHVzZXIgcHJvamVjdGlvblxuICogaXMgc2V0LCB0aGUgb3JpZ2luYWwgZXh0ZW50IGlzIHJldHVybmVkLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBJbnB1dCBleHRlbnQuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBzb3VyY2VQcm9qZWN0aW9uIFRoZSBpbnB1dCBleHRlbnQgcHJvamVjdGlvbi5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IFRoZSBpbnB1dCBleHRlbnQgaW4gdGhlIHVzZXIgcHJvamVjdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdG9Vc2VyRXh0ZW50KGV4dGVudCwgc291cmNlUHJvamVjdGlvbikge1xuICBpZiAoIXVzZXJQcm9qZWN0aW9uKSB7XG4gICAgcmV0dXJuIGV4dGVudDtcbiAgfVxuXG4gIHJldHVybiB0cmFuc2Zvcm1FeHRlbnQoZXh0ZW50LCBzb3VyY2VQcm9qZWN0aW9uLCB1c2VyUHJvamVjdGlvbik7XG59XG4vKipcbiAqIFJldHVybiBhbiBleHRlbnQgdHJhbnNmb3JtZWQgZnJvbSB0aGUgdXNlciBwcm9qZWN0aW9uLiAgSWYgbm8gdXNlciBwcm9qZWN0aW9uXG4gKiBpcyBzZXQsIHRoZSBvcmlnaW5hbCBleHRlbnQgaXMgcmV0dXJuZWQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IElucHV0IGV4dGVudC5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IGRlc3RQcm9qZWN0aW9uIFRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gVGhlIGlucHV0IGV4dGVudCB0cmFuc2Zvcm1lZC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVVzZXJFeHRlbnQoZXh0ZW50LCBkZXN0UHJvamVjdGlvbikge1xuICBpZiAoIXVzZXJQcm9qZWN0aW9uKSB7XG4gICAgcmV0dXJuIGV4dGVudDtcbiAgfVxuXG4gIHJldHVybiB0cmFuc2Zvcm1FeHRlbnQoZXh0ZW50LCB1c2VyUHJvamVjdGlvbiwgZGVzdFByb2plY3Rpb24pO1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgc2FmZSBjb29yZGluYXRlIHRyYW5zZm9ybSBmdW5jdGlvbiBmcm9tIGEgY29vcmRpbmF0ZSB0cmFuc2Zvcm0gZnVuY3Rpb24uXG4gKiBcIlNhZmVcIiBtZWFucyB0aGF0IGl0IGNhbiBoYW5kbGUgd3JhcHBpbmcgb2YgeC1jb29yZGluYXRlcyBmb3IgZ2xvYmFsIHByb2plY3Rpb25zLFxuICogYW5kIHRoYXQgY29vcmRpbmF0ZXMgZXhjZWVkaW5nIHRoZSBzb3VyY2UgcHJvamVjdGlvbiB2YWxpZGl0eSBleHRlbnQncyByYW5nZSB3aWxsIGJlXG4gKiBjbGFtcGVkIHRvIHRoZSB2YWxpZGl0eSByYW5nZS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbn0gc291cmNlUHJvaiBTb3VyY2UgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbn0gZGVzdFByb2ogRGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOiBpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gdHJhbnNmb3JtIFRyYW5zZm9ybSBmdW5jdGlvbiAoc291cmNlIHRvIGRlc3RpYXRpb24pLlxuICogQHJldHVybiB7ZnVuY3Rpb24oaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOiBpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gU2FmZSB0cmFuc2Zvcm0gZnVuY3Rpb24gKHNvdXJjZSB0byBkZXN0aWF0aW9uKS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU2FmZUNvb3JkaW5hdGVUcmFuc2Zvcm0oc291cmNlUHJvaiwgZGVzdFByb2osIHRyYW5zZm9ybSkge1xuICByZXR1cm4gZnVuY3Rpb24gKGNvb3JkKSB7XG4gICAgdmFyIHNvdXJjZVggPSBjb29yZFswXTtcbiAgICB2YXIgc291cmNlWSA9IGNvb3JkWzFdO1xuICAgIHZhciB0cmFuc2Zvcm1lZCwgd29ybGRzQXdheTtcblxuICAgIGlmIChzb3VyY2VQcm9qLmNhbldyYXBYKCkpIHtcbiAgICAgIHZhciBzb3VyY2VFeHRlbnQgPSBzb3VyY2VQcm9qLmdldEV4dGVudCgpO1xuICAgICAgdmFyIHNvdXJjZUV4dGVudFdpZHRoID0gZ2V0V2lkdGgoc291cmNlRXh0ZW50KTtcbiAgICAgIHdvcmxkc0F3YXkgPSBnZXRXb3JsZHNBd2F5KGNvb3JkLCBzb3VyY2VQcm9qLCBzb3VyY2VFeHRlbnRXaWR0aCk7XG5cbiAgICAgIGlmICh3b3JsZHNBd2F5KSB7XG4gICAgICAgIC8vIE1vdmUgeCB0byB0aGUgcmVhbCB3b3JsZFxuICAgICAgICBzb3VyY2VYID0gc291cmNlWCAtIHdvcmxkc0F3YXkgKiBzb3VyY2VFeHRlbnRXaWR0aDtcbiAgICAgIH1cblxuICAgICAgc291cmNlWCA9IGNsYW1wKHNvdXJjZVgsIHNvdXJjZUV4dGVudFswXSwgc291cmNlRXh0ZW50WzJdKTtcbiAgICAgIHNvdXJjZVkgPSBjbGFtcChzb3VyY2VZLCBzb3VyY2VFeHRlbnRbMV0sIHNvdXJjZUV4dGVudFszXSk7XG4gICAgICB0cmFuc2Zvcm1lZCA9IHRyYW5zZm9ybShbc291cmNlWCwgc291cmNlWV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cmFuc2Zvcm1lZCA9IHRyYW5zZm9ybShjb29yZCk7XG4gICAgfVxuXG4gICAgaWYgKHdvcmxkc0F3YXkgJiYgZGVzdFByb2ouY2FuV3JhcFgoKSkge1xuICAgICAgLy8gTW92ZSB0cmFuc2Zvcm1lZCBjb29yZGluYXRlIGJhY2sgdG8gdGhlIG9mZnNldCB3b3JsZFxuICAgICAgdHJhbnNmb3JtZWRbMF0gKz0gd29ybGRzQXdheSAqIGdldFdpZHRoKGRlc3RQcm9qLmdldEV4dGVudCgpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJhbnNmb3JtZWQ7XG4gIH07XG59XG4vKipcbiAqIEFkZCB0cmFuc2Zvcm1zIHRvIGFuZCBmcm9tIEVQU0c6NDMyNiBhbmQgRVBTRzozODU3LiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWRcbiAqIGJ5IHdoZW4gdGhpcyBtb2R1bGUgaXMgZXhlY3V0ZWQgYW5kIHNob3VsZCBvbmx5IG5lZWQgdG8gYmUgY2FsbGVkIGFnYWluIGFmdGVyXG4gKiBgY2xlYXJBbGxQcm9qZWN0aW9ucygpYCBpcyBjYWxsZWQgKGUuZy4gaW4gdGVzdHMpLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb21tb24oKSB7XG4gIC8vIEFkZCB0cmFuc2Zvcm1hdGlvbnMgdGhhdCBkb24ndCBhbHRlciBjb29yZGluYXRlcyB0byBjb252ZXJ0IHdpdGhpbiBzZXQgb2ZcbiAgLy8gcHJvamVjdGlvbnMgd2l0aCBlcXVhbCBtZWFuaW5nLlxuICBhZGRFcXVpdmFsZW50UHJvamVjdGlvbnMoRVBTRzM4NTdfUFJPSkVDVElPTlMpO1xuICBhZGRFcXVpdmFsZW50UHJvamVjdGlvbnMoRVBTRzQzMjZfUFJPSkVDVElPTlMpOyAvLyBBZGQgdHJhbnNmb3JtYXRpb25zIHRvIGNvbnZlcnQgRVBTRzo0MzI2IGxpa2UgY29vcmRpbmF0ZXMgdG8gRVBTRzozODU3IGxpa2VcbiAgLy8gY29vcmRpbmF0ZXMgYW5kIGJhY2suXG5cbiAgYWRkRXF1aXZhbGVudFRyYW5zZm9ybXMoRVBTRzQzMjZfUFJPSkVDVElPTlMsIEVQU0czODU3X1BST0pFQ1RJT05TLCBmcm9tRVBTRzQzMjYsIHRvRVBTRzQzMjYpO1xufVxuYWRkQ29tbW9uKCk7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2NlbnRlcmNvbnN0cmFpbnRcbiAqL1xuaW1wb3J0IHsgY2xhbXAgfSBmcm9tICcuL21hdGguanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oKGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZCksIG51bWJlciwgaW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemUsIGJvb2xlYW49LCBBcnJheTxudW1iZXI+PSk6IChpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWQpfSBUeXBlXG4gKi9cblxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gb25seUNlbnRlciBJZiB0cnVlLCB0aGUgY29uc3RyYWludCB3aWxsIG9ubHkgYXBwbHkgdG8gdGhlIHZpZXcgY2VudGVyLlxuICogQHBhcmFtIHtib29sZWFufSBzbW9vdGggSWYgdHJ1ZSwgdGhlIHZpZXcgd2lsbCBiZSBhYmxlIHRvIGdvIHNsaWdodGx5IG91dCBvZiB0aGUgZ2l2ZW4gZXh0ZW50XG4gKiAob25seSBkdXJpbmcgaW50ZXJhY3Rpb24gYW5kIGFuaW1hdGlvbikuXG4gKiBAcmV0dXJuIHtUeXBlfSBUaGUgY29uc3RyYWludC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRXh0ZW50KGV4dGVudCwgb25seUNlbnRlciwgc21vb3RoKSB7XG4gIHJldHVybiAoXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IGNlbnRlciBDZW50ZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIFZpZXdwb3J0IHNpemU7IHVudXNlZCBpZiBgb25seUNlbnRlcmAgd2FzIHNwZWNpZmllZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfaXNNb3ZpbmcgVHJ1ZSBpZiBhbiBpbnRlcmFjdGlvbiBvciBhbmltYXRpb24gaXMgaW4gcHJvZ3Jlc3MuXG4gICAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X2NlbnRlclNoaWZ0IFNoaWZ0IGJldHdlZW4gbWFwIGNlbnRlciBhbmQgdmlld3BvcnQgY2VudGVyLlxuICAgICAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH0gQ2VudGVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChjZW50ZXIsIHJlc29sdXRpb24sIHNpemUsIG9wdF9pc01vdmluZywgb3B0X2NlbnRlclNoaWZ0KSB7XG4gICAgICBpZiAoY2VudGVyKSB7XG4gICAgICAgIHZhciB2aWV3V2lkdGggPSBvbmx5Q2VudGVyID8gMCA6IHNpemVbMF0gKiByZXNvbHV0aW9uO1xuICAgICAgICB2YXIgdmlld0hlaWdodCA9IG9ubHlDZW50ZXIgPyAwIDogc2l6ZVsxXSAqIHJlc29sdXRpb247XG4gICAgICAgIHZhciBzaGlmdFggPSBvcHRfY2VudGVyU2hpZnQgPyBvcHRfY2VudGVyU2hpZnRbMF0gOiAwO1xuICAgICAgICB2YXIgc2hpZnRZID0gb3B0X2NlbnRlclNoaWZ0ID8gb3B0X2NlbnRlclNoaWZ0WzFdIDogMDtcbiAgICAgICAgdmFyIG1pblggPSBleHRlbnRbMF0gKyB2aWV3V2lkdGggLyAyICsgc2hpZnRYO1xuICAgICAgICB2YXIgbWF4WCA9IGV4dGVudFsyXSAtIHZpZXdXaWR0aCAvIDIgKyBzaGlmdFg7XG4gICAgICAgIHZhciBtaW5ZID0gZXh0ZW50WzFdICsgdmlld0hlaWdodCAvIDIgKyBzaGlmdFk7XG4gICAgICAgIHZhciBtYXhZID0gZXh0ZW50WzNdIC0gdmlld0hlaWdodCAvIDIgKyBzaGlmdFk7IC8vIG5vdGU6IHdoZW4gem9vbWluZyBvdXQgb2YgYm91bmRzLCBtaW4gYW5kIG1heCB2YWx1ZXMgZm9yIHggYW5kIHkgbWF5XG4gICAgICAgIC8vIGVuZCB1cCBpbnZlcnRlZCAobWluID4gbWF4KTsgdGhpcyBoYXMgdG8gYmUgYWNjb3VudGVkIGZvclxuXG4gICAgICAgIGlmIChtaW5YID4gbWF4WCkge1xuICAgICAgICAgIG1pblggPSAobWF4WCArIG1pblgpIC8gMjtcbiAgICAgICAgICBtYXhYID0gbWluWDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtaW5ZID4gbWF4WSkge1xuICAgICAgICAgIG1pblkgPSAobWF4WSArIG1pblkpIC8gMjtcbiAgICAgICAgICBtYXhZID0gbWluWTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB4ID0gY2xhbXAoY2VudGVyWzBdLCBtaW5YLCBtYXhYKTtcbiAgICAgICAgdmFyIHkgPSBjbGFtcChjZW50ZXJbMV0sIG1pblksIG1heFkpO1xuICAgICAgICB2YXIgcmF0aW8gPSAzMCAqIHJlc29sdXRpb247IC8vIGR1cmluZyBhbiBpbnRlcmFjdGlvbiwgYWxsb3cgc29tZSBvdmVyc2Nyb2xsXG5cbiAgICAgICAgaWYgKG9wdF9pc01vdmluZyAmJiBzbW9vdGgpIHtcbiAgICAgICAgICB4ICs9IC1yYXRpbyAqIE1hdGgubG9nKDEgKyBNYXRoLm1heCgwLCBtaW5YIC0gY2VudGVyWzBdKSAvIHJhdGlvKSArIHJhdGlvICogTWF0aC5sb2coMSArIE1hdGgubWF4KDAsIGNlbnRlclswXSAtIG1heFgpIC8gcmF0aW8pO1xuICAgICAgICAgIHkgKz0gLXJhdGlvICogTWF0aC5sb2coMSArIE1hdGgubWF4KDAsIG1pblkgLSBjZW50ZXJbMV0pIC8gcmF0aW8pICsgcmF0aW8gKiBNYXRoLmxvZygxICsgTWF0aC5tYXgoMCwgY2VudGVyWzFdIC0gbWF4WSkgLyByYXRpbyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gW3gsIHldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU9fSBjZW50ZXIgQ2VudGVyLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkfSBDZW50ZXIuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG5vbmUoY2VudGVyKSB7XG4gIHJldHVybiBjZW50ZXI7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3Jlc29sdXRpb25jb25zdHJhaW50XG4gKi9cbmltcG9ydCB7IGNsYW1wIH0gZnJvbSAnLi9tYXRoLmpzJztcbmltcG9ydCB7IGdldEhlaWdodCwgZ2V0V2lkdGggfSBmcm9tICcuL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBsaW5lYXJGaW5kTmVhcmVzdCB9IGZyb20gJy4vYXJyYXkuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oKG51bWJlcnx1bmRlZmluZWQpLCBudW1iZXIsIGltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplLCBib29sZWFuPSk6IChudW1iZXJ8dW5kZWZpbmVkKX0gVHlwZVxuICovXG5cbi8qKlxuICogUmV0dXJucyBhIG1vZGlmaWVkIHJlc29sdXRpb24gdGFraW5nIGludG8gYWNjb3VudCB0aGUgdmlld3BvcnQgc2l6ZSBhbmQgbWF4aW11bVxuICogYWxsb3dlZCBleHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gbWF4RXh0ZW50IE1heGltdW0gYWxsb3dlZCBleHRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSB2aWV3cG9ydFNpemUgVmlld3BvcnQgc2l6ZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gc2hvd0Z1bGxFeHRlbnQgV2hldGhlciB0byBzaG93IHRoZSBmdWxsIGV4dGVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gQ2FwcGVkIHJlc29sdXRpb24uXG4gKi9cblxuZnVuY3Rpb24gZ2V0Vmlld3BvcnRDbGFtcGVkUmVzb2x1dGlvbihyZXNvbHV0aW9uLCBtYXhFeHRlbnQsIHZpZXdwb3J0U2l6ZSwgc2hvd0Z1bGxFeHRlbnQpIHtcbiAgdmFyIHhSZXNvbHV0aW9uID0gZ2V0V2lkdGgobWF4RXh0ZW50KSAvIHZpZXdwb3J0U2l6ZVswXTtcbiAgdmFyIHlSZXNvbHV0aW9uID0gZ2V0SGVpZ2h0KG1heEV4dGVudCkgLyB2aWV3cG9ydFNpemVbMV07XG5cbiAgaWYgKHNob3dGdWxsRXh0ZW50KSB7XG4gICAgcmV0dXJuIE1hdGgubWluKHJlc29sdXRpb24sIE1hdGgubWF4KHhSZXNvbHV0aW9uLCB5UmVzb2x1dGlvbikpO1xuICB9XG5cbiAgcmV0dXJuIE1hdGgubWluKHJlc29sdXRpb24sIE1hdGgubWluKHhSZXNvbHV0aW9uLCB5UmVzb2x1dGlvbikpO1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgbW9kaWZpZWQgcmVzb2x1dGlvbiB0byBiZSBiZXR3ZWVuIG1heFJlc29sdXRpb24gYW5kIG1pblJlc29sdXRpb24gd2hpbGVcbiAqIHN0aWxsIGFsbG93aW5nIHRoZSB2YWx1ZSB0byBiZSBzbGlnaHRseSBvdXQgb2YgYm91bmRzLlxuICogTm90ZTogdGhlIGNvbXB1dGF0aW9uIGlzIGJhc2VkIG9uIHRoZSBsb2dhcml0aG0gZnVuY3Rpb24gKGxuKTpcbiAqICAtIGF0IDEsIGxuKHgpIGlzIDBcbiAqICAtIGFib3ZlIDEsIGxuKHgpIGtlZXBzIGluY3JlYXNpbmcgYnV0IGF0IGEgbXVjaCBzbG93ZXIgcGFjZSB0aGFuIHhcbiAqIFRoZSBmaW5hbCByZXN1bHQgaXMgY2xhbXBlZCB0byBwcmV2ZW50IGdldHRpbmcgdG9vIGZhciBhd2F5IGZyb20gYm91bmRzLlxuICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhSZXNvbHV0aW9uIE1heCByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IG1pblJlc29sdXRpb24gTWluIHJlc29sdXRpb24uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFNtb290aGVkIHJlc29sdXRpb24uXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRTbW9vdGhDbGFtcGVkUmVzb2x1dGlvbihyZXNvbHV0aW9uLCBtYXhSZXNvbHV0aW9uLCBtaW5SZXNvbHV0aW9uKSB7XG4gIHZhciByZXN1bHQgPSBNYXRoLm1pbihyZXNvbHV0aW9uLCBtYXhSZXNvbHV0aW9uKTtcbiAgdmFyIHJhdGlvID0gNTA7XG4gIHJlc3VsdCAqPSBNYXRoLmxvZygxICsgcmF0aW8gKiBNYXRoLm1heCgwLCByZXNvbHV0aW9uIC8gbWF4UmVzb2x1dGlvbiAtIDEpKSAvIHJhdGlvICsgMTtcblxuICBpZiAobWluUmVzb2x1dGlvbikge1xuICAgIHJlc3VsdCA9IE1hdGgubWF4KHJlc3VsdCwgbWluUmVzb2x1dGlvbik7XG4gICAgcmVzdWx0IC89IE1hdGgubG9nKDEgKyByYXRpbyAqIE1hdGgubWF4KDAsIG1pblJlc29sdXRpb24gLyByZXNvbHV0aW9uIC0gMSkpIC8gcmF0aW8gKyAxO1xuICB9XG5cbiAgcmV0dXJuIGNsYW1wKHJlc3VsdCwgbWluUmVzb2x1dGlvbiAvIDIsIG1heFJlc29sdXRpb24gKiAyKTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSByZXNvbHV0aW9ucyBSZXNvbHV0aW9ucy5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9zbW9vdGggSWYgdHJ1ZSwgdGhlIHZpZXcgd2lsbCBiZSBhYmxlIHRvIHNsaWdodGx5IGV4Y2VlZCByZXNvbHV0aW9uIGxpbWl0cy4gRGVmYXVsdDogdHJ1ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50PX0gb3B0X21heEV4dGVudCBNYXhpbXVtIGFsbG93ZWQgZXh0ZW50LlxuICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3Nob3dGdWxsRXh0ZW50IElmIHRydWUsIGFsbG93cyB1cyB0byBzaG93IHRoZSBmdWxsIGV4dGVudC4gRGVmYXVsdDogZmFsc2UuXG4gKiBAcmV0dXJuIHtUeXBlfSBab29tIGZ1bmN0aW9uLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNuYXBUb1Jlc29sdXRpb25zKHJlc29sdXRpb25zLCBvcHRfc21vb3RoLCBvcHRfbWF4RXh0ZW50LCBvcHRfc2hvd0Z1bGxFeHRlbnQpIHtcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGlyZWN0aW9uIERpcmVjdGlvbi5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIFZpZXdwb3J0IHNpemUuXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2lzTW92aW5nIFRydWUgaWYgYW4gaW50ZXJhY3Rpb24gb3IgYW5pbWF0aW9uIGlzIGluIHByb2dyZXNzLlxuICAgICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFJlc29sdXRpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gKHJlc29sdXRpb24sIGRpcmVjdGlvbiwgc2l6ZSwgb3B0X2lzTW92aW5nKSB7XG4gICAgICBpZiAocmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhciBtYXhSZXNvbHV0aW9uID0gcmVzb2x1dGlvbnNbMF07XG4gICAgICAgIHZhciBtaW5SZXNvbHV0aW9uID0gcmVzb2x1dGlvbnNbcmVzb2x1dGlvbnMubGVuZ3RoIC0gMV07XG4gICAgICAgIHZhciBjYXBwZWRNYXhSZXMgPSBvcHRfbWF4RXh0ZW50ID8gZ2V0Vmlld3BvcnRDbGFtcGVkUmVzb2x1dGlvbihtYXhSZXNvbHV0aW9uLCBvcHRfbWF4RXh0ZW50LCBzaXplLCBvcHRfc2hvd0Z1bGxFeHRlbnQpIDogbWF4UmVzb2x1dGlvbjsgLy8gZHVyaW5nIGludGVyYWN0aW5nIG9yIGFuaW1hdGluZywgYWxsb3cgaW50ZXJtZWRpYXJ5IHZhbHVlc1xuXG4gICAgICAgIGlmIChvcHRfaXNNb3ZpbmcpIHtcbiAgICAgICAgICB2YXIgc21vb3RoID0gb3B0X3Ntb290aCAhPT0gdW5kZWZpbmVkID8gb3B0X3Ntb290aCA6IHRydWU7XG5cbiAgICAgICAgICBpZiAoIXNtb290aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNsYW1wKHJlc29sdXRpb24sIG1pblJlc29sdXRpb24sIGNhcHBlZE1heFJlcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGdldFNtb290aENsYW1wZWRSZXNvbHV0aW9uKHJlc29sdXRpb24sIGNhcHBlZE1heFJlcywgbWluUmVzb2x1dGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2FwcGVkID0gTWF0aC5taW4oY2FwcGVkTWF4UmVzLCByZXNvbHV0aW9uKTtcbiAgICAgICAgdmFyIHogPSBNYXRoLmZsb29yKGxpbmVhckZpbmROZWFyZXN0KHJlc29sdXRpb25zLCBjYXBwZWQsIGRpcmVjdGlvbikpO1xuXG4gICAgICAgIGlmIChyZXNvbHV0aW9uc1t6XSA+IGNhcHBlZE1heFJlcyAmJiB6IDwgcmVzb2x1dGlvbnMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIHJldHVybiByZXNvbHV0aW9uc1t6ICsgMV07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzb2x1dGlvbnNbel07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn1cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHBvd2VyIFBvd2VyLlxuICogQHBhcmFtIHtudW1iZXJ9IG1heFJlc29sdXRpb24gTWF4aW11bSByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfbWluUmVzb2x1dGlvbiBNaW5pbXVtIHJlc29sdXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc21vb3RoIElmIHRydWUsIHRoZSB2aWV3IHdpbGwgYmUgYWJsZSB0byBzbGlnaHRseSBleGNlZWQgcmVzb2x1dGlvbiBsaW1pdHMuIERlZmF1bHQ6IHRydWUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudD19IG9wdF9tYXhFeHRlbnQgTWF4aW11bSBhbGxvd2VkIGV4dGVudC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9zaG93RnVsbEV4dGVudCBJZiB0cnVlLCBhbGxvd3MgdXMgdG8gc2hvdyB0aGUgZnVsbCBleHRlbnQuIERlZmF1bHQ6IGZhbHNlLlxuICogQHJldHVybiB7VHlwZX0gWm9vbSBmdW5jdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU25hcFRvUG93ZXIocG93ZXIsIG1heFJlc29sdXRpb24sIG9wdF9taW5SZXNvbHV0aW9uLCBvcHRfc21vb3RoLCBvcHRfbWF4RXh0ZW50LCBvcHRfc2hvd0Z1bGxFeHRlbnQpIHtcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGlyZWN0aW9uIERpcmVjdGlvbi5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIFZpZXdwb3J0IHNpemUuXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2lzTW92aW5nIFRydWUgaWYgYW4gaW50ZXJhY3Rpb24gb3IgYW5pbWF0aW9uIGlzIGluIHByb2dyZXNzLlxuICAgICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFJlc29sdXRpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gKHJlc29sdXRpb24sIGRpcmVjdGlvbiwgc2l6ZSwgb3B0X2lzTW92aW5nKSB7XG4gICAgICBpZiAocmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhciBjYXBwZWRNYXhSZXMgPSBvcHRfbWF4RXh0ZW50ID8gZ2V0Vmlld3BvcnRDbGFtcGVkUmVzb2x1dGlvbihtYXhSZXNvbHV0aW9uLCBvcHRfbWF4RXh0ZW50LCBzaXplLCBvcHRfc2hvd0Z1bGxFeHRlbnQpIDogbWF4UmVzb2x1dGlvbjtcbiAgICAgICAgdmFyIG1pblJlc29sdXRpb24gPSBvcHRfbWluUmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0X21pblJlc29sdXRpb24gOiAwOyAvLyBkdXJpbmcgaW50ZXJhY3Rpbmcgb3IgYW5pbWF0aW5nLCBhbGxvdyBpbnRlcm1lZGlhcnkgdmFsdWVzXG5cbiAgICAgICAgaWYgKG9wdF9pc01vdmluZykge1xuICAgICAgICAgIHZhciBzbW9vdGggPSBvcHRfc21vb3RoICE9PSB1bmRlZmluZWQgPyBvcHRfc21vb3RoIDogdHJ1ZTtcblxuICAgICAgICAgIGlmICghc21vb3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gY2xhbXAocmVzb2x1dGlvbiwgbWluUmVzb2x1dGlvbiwgY2FwcGVkTWF4UmVzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZ2V0U21vb3RoQ2xhbXBlZFJlc29sdXRpb24ocmVzb2x1dGlvbiwgY2FwcGVkTWF4UmVzLCBtaW5SZXNvbHV0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0b2xlcmFuY2UgPSAxZS05O1xuICAgICAgICB2YXIgbWluWm9vbUxldmVsID0gTWF0aC5jZWlsKE1hdGgubG9nKG1heFJlc29sdXRpb24gLyBjYXBwZWRNYXhSZXMpIC8gTWF0aC5sb2cocG93ZXIpIC0gdG9sZXJhbmNlKTtcbiAgICAgICAgdmFyIG9mZnNldCA9IC1kaXJlY3Rpb24gKiAoMC41IC0gdG9sZXJhbmNlKSArIDAuNTtcbiAgICAgICAgdmFyIGNhcHBlZCA9IE1hdGgubWluKGNhcHBlZE1heFJlcywgcmVzb2x1dGlvbik7XG4gICAgICAgIHZhciBjYXBwZWRab29tTGV2ZWwgPSBNYXRoLmZsb29yKE1hdGgubG9nKG1heFJlc29sdXRpb24gLyBjYXBwZWQpIC8gTWF0aC5sb2cocG93ZXIpICsgb2Zmc2V0KTtcbiAgICAgICAgdmFyIHpvb21MZXZlbCA9IE1hdGgubWF4KG1pblpvb21MZXZlbCwgY2FwcGVkWm9vbUxldmVsKTtcbiAgICAgICAgdmFyIG5ld1Jlc29sdXRpb24gPSBtYXhSZXNvbHV0aW9uIC8gTWF0aC5wb3cocG93ZXIsIHpvb21MZXZlbCk7XG4gICAgICAgIHJldHVybiBjbGFtcChuZXdSZXNvbHV0aW9uLCBtaW5SZXNvbHV0aW9uLCBjYXBwZWRNYXhSZXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhSZXNvbHV0aW9uIE1heCByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IG1pblJlc29sdXRpb24gTWluIHJlc29sdXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc21vb3RoIElmIHRydWUsIHRoZSB2aWV3IHdpbGwgYmUgYWJsZSB0byBzbGlnaHRseSBleGNlZWQgcmVzb2x1dGlvbiBsaW1pdHMuIERlZmF1bHQ6IHRydWUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudD19IG9wdF9tYXhFeHRlbnQgTWF4aW11bSBhbGxvd2VkIGV4dGVudC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9zaG93RnVsbEV4dGVudCBJZiB0cnVlLCBhbGxvd3MgdXMgdG8gc2hvdyB0aGUgZnVsbCBleHRlbnQuIERlZmF1bHQ6IGZhbHNlLlxuICogQHJldHVybiB7VHlwZX0gWm9vbSBmdW5jdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWluTWF4UmVzb2x1dGlvbihtYXhSZXNvbHV0aW9uLCBtaW5SZXNvbHV0aW9uLCBvcHRfc21vb3RoLCBvcHRfbWF4RXh0ZW50LCBvcHRfc2hvd0Z1bGxFeHRlbnQpIHtcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGlyZWN0aW9uIERpcmVjdGlvbi5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIFZpZXdwb3J0IHNpemUuXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2lzTW92aW5nIFRydWUgaWYgYW4gaW50ZXJhY3Rpb24gb3IgYW5pbWF0aW9uIGlzIGluIHByb2dyZXNzLlxuICAgICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFJlc29sdXRpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gKHJlc29sdXRpb24sIGRpcmVjdGlvbiwgc2l6ZSwgb3B0X2lzTW92aW5nKSB7XG4gICAgICBpZiAocmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhciBjYXBwZWRNYXhSZXMgPSBvcHRfbWF4RXh0ZW50ID8gZ2V0Vmlld3BvcnRDbGFtcGVkUmVzb2x1dGlvbihtYXhSZXNvbHV0aW9uLCBvcHRfbWF4RXh0ZW50LCBzaXplLCBvcHRfc2hvd0Z1bGxFeHRlbnQpIDogbWF4UmVzb2x1dGlvbjtcbiAgICAgICAgdmFyIHNtb290aCA9IG9wdF9zbW9vdGggIT09IHVuZGVmaW5lZCA/IG9wdF9zbW9vdGggOiB0cnVlO1xuXG4gICAgICAgIGlmICghc21vb3RoIHx8ICFvcHRfaXNNb3ZpbmcpIHtcbiAgICAgICAgICByZXR1cm4gY2xhbXAocmVzb2x1dGlvbiwgbWluUmVzb2x1dGlvbiwgY2FwcGVkTWF4UmVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBnZXRTbW9vdGhDbGFtcGVkUmVzb2x1dGlvbihyZXNvbHV0aW9uLCBjYXBwZWRNYXhSZXMsIG1pblJlc29sdXRpb24pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JvdGF0aW9uY29uc3RyYWludFxuICovXG5pbXBvcnQgeyB0b1JhZGlhbnMgfSBmcm9tICcuL21hdGguanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oKG51bWJlcnx1bmRlZmluZWQpLCBib29sZWFuPSk6IChudW1iZXJ8dW5kZWZpbmVkKX0gVHlwZVxuICovXG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSByb3RhdGlvbiBSb3RhdGlvbi5cbiAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFJvdGF0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkaXNhYmxlKHJvdGF0aW9uKSB7XG4gIGlmIChyb3RhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIDA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gUm90YXRpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG5vbmUocm90YXRpb24pIHtcbiAgaWYgKHJvdGF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gcm90YXRpb247XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gbiBOLlxuICogQHJldHVybiB7VHlwZX0gUm90YXRpb24gY29uc3RyYWludC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU25hcFRvTihuKSB7XG4gIHZhciB0aGV0YSA9IDIgKiBNYXRoLlBJIC8gbjtcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9pc01vdmluZyBUcnVlIGlmIGFuIGludGVyYWN0aW9uIG9yIGFuaW1hdGlvbiBpcyBpbiBwcm9ncmVzcy5cbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBSb3RhdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAocm90YXRpb24sIG9wdF9pc01vdmluZykge1xuICAgICAgaWYgKG9wdF9pc01vdmluZykge1xuICAgICAgICByZXR1cm4gcm90YXRpb247XG4gICAgICB9XG5cbiAgICAgIGlmIChyb3RhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJvdGF0aW9uID0gTWF0aC5mbG9vcihyb3RhdGlvbiAvIHRoZXRhICsgMC41KSAqIHRoZXRhO1xuICAgICAgICByZXR1cm4gcm90YXRpb247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn1cbi8qKlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfdG9sZXJhbmNlIFRvbGVyYW5jZS5cbiAqIEByZXR1cm4ge1R5cGV9IFJvdGF0aW9uIGNvbnN0cmFpbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNuYXBUb1plcm8ob3B0X3RvbGVyYW5jZSkge1xuICB2YXIgdG9sZXJhbmNlID0gb3B0X3RvbGVyYW5jZSB8fCB0b1JhZGlhbnMoNSk7XG4gIHJldHVybiAoXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSByb3RhdGlvbiBSb3RhdGlvbi5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfaXNNb3ZpbmcgVHJ1ZSBpZiBhbiBpbnRlcmFjdGlvbiBvciBhbmltYXRpb24gaXMgaW4gcHJvZ3Jlc3MuXG4gICAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gUm90YXRpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gKHJvdGF0aW9uLCBvcHRfaXNNb3ZpbmcpIHtcbiAgICAgIGlmIChvcHRfaXNNb3ZpbmcpIHtcbiAgICAgICAgcmV0dXJuIHJvdGF0aW9uO1xuICAgICAgfVxuXG4gICAgICBpZiAocm90YXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoTWF0aC5hYnMocm90YXRpb24pIDw9IHRvbGVyYW5jZSkge1xuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiByb3RhdGlvbjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2Vhc2luZ1xuICovXG5cbi8qKlxuICogU3RhcnQgc2xvdyBhbmQgc3BlZWQgdXAuXG4gKiBAcGFyYW0ge251bWJlcn0gdCBJbnB1dCBiZXR3ZWVuIDAgYW5kIDEuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE91dHB1dCBiZXR3ZWVuIDAgYW5kIDEuXG4gKiBAYXBpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlYXNlSW4odCkge1xuICByZXR1cm4gTWF0aC5wb3codCwgMyk7XG59XG4vKipcbiAqIFN0YXJ0IGZhc3QgYW5kIHNsb3cgZG93bi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0IElucHV0IGJldHdlZW4gMCBhbmQgMS5cbiAqIEByZXR1cm4ge251bWJlcn0gT3V0cHV0IGJldHdlZW4gMCBhbmQgMS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZWFzZU91dCh0KSB7XG4gIHJldHVybiAxIC0gZWFzZUluKDEgLSB0KTtcbn1cbi8qKlxuICogU3RhcnQgc2xvdywgc3BlZWQgdXAsIGFuZCB0aGVuIHNsb3cgZG93biBhZ2Fpbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0IElucHV0IGJldHdlZW4gMCBhbmQgMS5cbiAqIEByZXR1cm4ge251bWJlcn0gT3V0cHV0IGJldHdlZW4gMCBhbmQgMS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW5BbmRPdXQodCkge1xuICByZXR1cm4gMyAqIHQgKiB0IC0gMiAqIHQgKiB0ICogdDtcbn1cbi8qKlxuICogTWFpbnRhaW4gYSBjb25zdGFudCBzcGVlZCBvdmVyIHRpbWUuXG4gKiBAcGFyYW0ge251bWJlcn0gdCBJbnB1dCBiZXR3ZWVuIDAgYW5kIDEuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE91dHB1dCBiZXR3ZWVuIDAgYW5kIDEuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhcih0KSB7XG4gIHJldHVybiB0O1xufVxuLyoqXG4gKiBTdGFydCBzbG93LCBzcGVlZCB1cCwgYW5kIGF0IHRoZSB2ZXJ5IGVuZCBzbG93IGRvd24gYWdhaW4uICBUaGlzIGhhcyB0aGVcbiAqIHNhbWUgZ2VuZXJhbCBiZWhhdmlvciBhcyB7QGxpbmsgbW9kdWxlOm9sL2Vhc2luZ35pbkFuZE91dH0sIGJ1dCB0aGUgZmluYWxcbiAqIHNsb3dkb3duIGlzIGRlbGF5ZWQuXG4gKiBAcGFyYW0ge251bWJlcn0gdCBJbnB1dCBiZXR3ZWVuIDAgYW5kIDEuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE91dHB1dCBiZXR3ZWVuIDAgYW5kIDEuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHVwQW5kRG93bih0KSB7XG4gIGlmICh0IDwgMC41KSB7XG4gICAgcmV0dXJuIGluQW5kT3V0KDIgKiB0KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gMSAtIGluQW5kT3V0KDIgKiAodCAtIDAuNSkpO1xuICB9XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vR2VvbWV0cnlMYXlvdXRcbiAqL1xuXG4vKipcbiAqIFRoZSBjb29yZGluYXRlIGxheW91dCBmb3IgZ2VvbWV0cmllcywgaW5kaWNhdGluZyB3aGV0aGVyIGEgM3JkIG9yIDR0aCB6ICgnWicpXG4gKiBvciBtZWFzdXJlICgnTScpIGNvb3JkaW5hdGUgaXMgYXZhaWxhYmxlLiBTdXBwb3J0ZWQgdmFsdWVzIGFyZSBgJ1hZJ2AsXG4gKiBgJ1hZWidgLCBgJ1hZTSdgLCBgJ1hZWk0nYC5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgWFk6ICdYWScsXG4gIFhZWjogJ1hZWicsXG4gIFhZTTogJ1hZTScsXG4gIFhZWk06ICdYWVpNJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L3RyYW5zZm9ybVxuICovXG5cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9kZXN0IERlc3RpbmF0aW9uLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gVHJhbnNmb3JtZWQgY29vcmRpbmF0ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm0yRChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIHRyYW5zZm9ybSwgb3B0X2Rlc3QpIHtcbiAgdmFyIGRlc3QgPSBvcHRfZGVzdCA/IG9wdF9kZXN0IDogW107XG4gIHZhciBpID0gMDtcblxuICBmb3IgKHZhciBqID0gb2Zmc2V0OyBqIDwgZW5kOyBqICs9IHN0cmlkZSkge1xuICAgIHZhciB4ID0gZmxhdENvb3JkaW5hdGVzW2pdO1xuICAgIHZhciB5ID0gZmxhdENvb3JkaW5hdGVzW2ogKyAxXTtcbiAgICBkZXN0W2krK10gPSB0cmFuc2Zvcm1bMF0gKiB4ICsgdHJhbnNmb3JtWzJdICogeSArIHRyYW5zZm9ybVs0XTtcbiAgICBkZXN0W2krK10gPSB0cmFuc2Zvcm1bMV0gKiB4ICsgdHJhbnNmb3JtWzNdICogeSArIHRyYW5zZm9ybVs1XTtcbiAgfVxuXG4gIGlmIChvcHRfZGVzdCAmJiBkZXN0Lmxlbmd0aCAhPSBpKSB7XG4gICAgZGVzdC5sZW5ndGggPSBpO1xuICB9XG5cbiAgcmV0dXJuIGRlc3Q7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gYW5nbGUgQW5nbGUuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGFuY2hvciBSb3RhdGlvbiBhbmNob3IgcG9pbnQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfZGVzdCBEZXN0aW5hdGlvbi5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFRyYW5zZm9ybWVkIGNvb3JkaW5hdGVzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGUoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBhbmdsZSwgYW5jaG9yLCBvcHRfZGVzdCkge1xuICB2YXIgZGVzdCA9IG9wdF9kZXN0ID8gb3B0X2Rlc3QgOiBbXTtcbiAgdmFyIGNvcyA9IE1hdGguY29zKGFuZ2xlKTtcbiAgdmFyIHNpbiA9IE1hdGguc2luKGFuZ2xlKTtcbiAgdmFyIGFuY2hvclggPSBhbmNob3JbMF07XG4gIHZhciBhbmNob3JZID0gYW5jaG9yWzFdO1xuICB2YXIgaSA9IDA7XG5cbiAgZm9yICh2YXIgaiA9IG9mZnNldDsgaiA8IGVuZDsgaiArPSBzdHJpZGUpIHtcbiAgICB2YXIgZGVsdGFYID0gZmxhdENvb3JkaW5hdGVzW2pdIC0gYW5jaG9yWDtcbiAgICB2YXIgZGVsdGFZID0gZmxhdENvb3JkaW5hdGVzW2ogKyAxXSAtIGFuY2hvclk7XG4gICAgZGVzdFtpKytdID0gYW5jaG9yWCArIGRlbHRhWCAqIGNvcyAtIGRlbHRhWSAqIHNpbjtcbiAgICBkZXN0W2krK10gPSBhbmNob3JZICsgZGVsdGFYICogc2luICsgZGVsdGFZICogY29zO1xuXG4gICAgZm9yICh2YXIgayA9IGogKyAyOyBrIDwgaiArIHN0cmlkZTsgKytrKSB7XG4gICAgICBkZXN0W2krK10gPSBmbGF0Q29vcmRpbmF0ZXNba107XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wdF9kZXN0ICYmIGRlc3QubGVuZ3RoICE9IGkpIHtcbiAgICBkZXN0Lmxlbmd0aCA9IGk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn1cbi8qKlxuICogU2NhbGUgdGhlIGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzeCBTY2FsZSBmYWN0b3IgaW4gdGhlIHgtZGlyZWN0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IHN5IFNjYWxlIGZhY3RvciBpbiB0aGUgeS1kaXJlY3Rpb24uXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGFuY2hvciBTY2FsZSBhbmNob3IgcG9pbnQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfZGVzdCBEZXN0aW5hdGlvbi5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFRyYW5zZm9ybWVkIGNvb3JkaW5hdGVzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIHN4LCBzeSwgYW5jaG9yLCBvcHRfZGVzdCkge1xuICB2YXIgZGVzdCA9IG9wdF9kZXN0ID8gb3B0X2Rlc3QgOiBbXTtcbiAgdmFyIGFuY2hvclggPSBhbmNob3JbMF07XG4gIHZhciBhbmNob3JZID0gYW5jaG9yWzFdO1xuICB2YXIgaSA9IDA7XG5cbiAgZm9yICh2YXIgaiA9IG9mZnNldDsgaiA8IGVuZDsgaiArPSBzdHJpZGUpIHtcbiAgICB2YXIgZGVsdGFYID0gZmxhdENvb3JkaW5hdGVzW2pdIC0gYW5jaG9yWDtcbiAgICB2YXIgZGVsdGFZID0gZmxhdENvb3JkaW5hdGVzW2ogKyAxXSAtIGFuY2hvclk7XG4gICAgZGVzdFtpKytdID0gYW5jaG9yWCArIHN4ICogZGVsdGFYO1xuICAgIGRlc3RbaSsrXSA9IGFuY2hvclkgKyBzeSAqIGRlbHRhWTtcblxuICAgIGZvciAodmFyIGsgPSBqICsgMjsgayA8IGogKyBzdHJpZGU7ICsraykge1xuICAgICAgZGVzdFtpKytdID0gZmxhdENvb3JkaW5hdGVzW2tdO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcHRfZGVzdCAmJiBkZXN0Lmxlbmd0aCAhPSBpKSB7XG4gICAgZGVzdC5sZW5ndGggPSBpO1xuICB9XG5cbiAgcmV0dXJuIGRlc3Q7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gZGVsdGFYIERlbHRhIFguXG4gKiBAcGFyYW0ge251bWJlcn0gZGVsdGFZIERlbHRhIFkuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfZGVzdCBEZXN0aW5hdGlvbi5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFRyYW5zZm9ybWVkIGNvb3JkaW5hdGVzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2xhdGUoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBkZWx0YVgsIGRlbHRhWSwgb3B0X2Rlc3QpIHtcbiAgdmFyIGRlc3QgPSBvcHRfZGVzdCA/IG9wdF9kZXN0IDogW107XG4gIHZhciBpID0gMDtcblxuICBmb3IgKHZhciBqID0gb2Zmc2V0OyBqIDwgZW5kOyBqICs9IHN0cmlkZSkge1xuICAgIGRlc3RbaSsrXSA9IGZsYXRDb29yZGluYXRlc1tqXSArIGRlbHRhWDtcbiAgICBkZXN0W2krK10gPSBmbGF0Q29vcmRpbmF0ZXNbaiArIDFdICsgZGVsdGFZO1xuXG4gICAgZm9yICh2YXIgayA9IGogKyAyOyBrIDwgaiArIHN0cmlkZTsgKytrKSB7XG4gICAgICBkZXN0W2krK10gPSBmbGF0Q29vcmRpbmF0ZXNba107XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wdF9kZXN0ICYmIGRlc3QubGVuZ3RoICE9IGkpIHtcbiAgICBkZXN0Lmxlbmd0aCA9IGk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn0iLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vR2VvbWV0cnlcbiAqL1xuXG5cbmltcG9ydCBCYXNlT2JqZWN0IGZyb20gJy4uL09iamVjdC5qcyc7XG5pbXBvcnQgVW5pdHMgZnJvbSAnLi4vcHJvai9Vbml0cy5qcyc7XG5pbXBvcnQgeyBhYnN0cmFjdCB9IGZyb20gJy4uL3V0aWwuanMnO1xuaW1wb3J0IHsgY29tcG9zZSBhcyBjb21wb3NlVHJhbnNmb3JtLCBjcmVhdGUgYXMgY3JlYXRlVHJhbnNmb3JtIH0gZnJvbSAnLi4vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB7IGNyZWF0ZUVtcHR5LCBjcmVhdGVPclVwZGF0ZUVtcHR5LCBnZXRIZWlnaHQsIHJldHVybk9yVXBkYXRlIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGdldCBhcyBnZXRQcm9qZWN0aW9uLCBnZXRUcmFuc2Zvcm0gfSBmcm9tICcuLi9wcm9qLmpzJztcbmltcG9ydCB7IG1lbW9pemVPbmUgfSBmcm9tICcuLi9mdW5jdGlvbnMuanMnO1xuaW1wb3J0IHsgdHJhbnNmb3JtMkQgfSBmcm9tICcuL2ZsYXQvdHJhbnNmb3JtLmpzJztcbi8qKlxuICogQHR5cGUge2ltcG9ydChcIi4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gKi9cblxudmFyIHRtcFRyYW5zZm9ybSA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBYnN0cmFjdCBiYXNlIGNsYXNzOyBub3JtYWxseSBvbmx5IHVzZWQgZm9yIGNyZWF0aW5nIHN1YmNsYXNzZXMgYW5kIG5vdFxuICogaW5zdGFudGlhdGVkIGluIGFwcHMuXG4gKiBCYXNlIGNsYXNzIGZvciB2ZWN0b3IgZ2VvbWV0cmllcy5cbiAqXG4gKiBUbyBnZXQgbm90aWZpZWQgb2YgY2hhbmdlcyB0byB0aGUgZ2VvbWV0cnksIHJlZ2lzdGVyIGEgbGlzdGVuZXIgZm9yIHRoZVxuICogZ2VuZXJpYyBgY2hhbmdlYCBldmVudCBvbiB5b3VyIGdlb21ldHJ5IGluc3RhbmNlLlxuICpcbiAqIEBhYnN0cmFjdFxuICogQGFwaVxuICovXG5cbnZhciBHZW9tZXRyeSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhHZW9tZXRyeSwgX3N1cGVyKTtcblxuICBmdW5jdGlvbiBHZW9tZXRyeSgpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG5cblxuICAgIF90aGlzLmV4dGVudF8gPSBjcmVhdGVFbXB0eSgpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmV4dGVudFJldmlzaW9uXyA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuc2ltcGxpZmllZEdlb21ldHJ5TWF4TWluU3F1YXJlZFRvbGVyYW5jZSA9IDA7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5zaW1wbGlmaWVkR2VvbWV0cnlSZXZpc2lvbiA9IDA7XG4gICAgLyoqXG4gICAgICogR2V0IGEgdHJhbnNmb3JtZWQgYW5kIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiB0aGUgZ2VvbWV0cnkuXG4gICAgICogQGFic3RyYWN0XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJldmlzaW9uIFRoZSBnZW9tZXRyeSByZXZpc2lvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ouanNcIikuVHJhbnNmb3JtRnVuY3Rpb259IFtvcHRfdHJhbnNmb3JtXSBPcHRpb25hbCB0cmFuc2Zvcm0gZnVuY3Rpb24uXG4gICAgICogQHJldHVybiB7R2VvbWV0cnl9IFNpbXBsaWZpZWQgZ2VvbWV0cnkuXG4gICAgICovXG5cbiAgICBfdGhpcy5zaW1wbGlmeVRyYW5zZm9ybWVkSW50ZXJuYWwgPSBtZW1vaXplT25lKGZ1bmN0aW9uIChyZXZpc2lvbiwgc3F1YXJlZFRvbGVyYW5jZSwgb3B0X3RyYW5zZm9ybSkge1xuICAgICAgaWYgKCFvcHRfdHJhbnNmb3JtKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFNpbXBsaWZpZWRHZW9tZXRyeShzcXVhcmVkVG9sZXJhbmNlKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGNsb25lID0gdGhpcy5jbG9uZSgpO1xuICAgICAgY2xvbmUuYXBwbHlUcmFuc2Zvcm0ob3B0X3RyYW5zZm9ybSk7XG4gICAgICByZXR1cm4gY2xvbmUuZ2V0U2ltcGxpZmllZEdlb21ldHJ5KHNxdWFyZWRUb2xlcmFuY2UpO1xuICAgIH0pO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogR2V0IGEgdHJhbnNmb3JtZWQgYW5kIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiB0aGUgZ2VvbWV0cnkuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufSBbb3B0X3RyYW5zZm9ybV0gT3B0aW9uYWwgdHJhbnNmb3JtIGZ1bmN0aW9uLlxuICAgKiBAcmV0dXJuIHtHZW9tZXRyeX0gU2ltcGxpZmllZCBnZW9tZXRyeS5cbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuc2ltcGxpZnlUcmFuc2Zvcm1lZCA9IGZ1bmN0aW9uIChzcXVhcmVkVG9sZXJhbmNlLCBvcHRfdHJhbnNmb3JtKSB7XG4gICAgcmV0dXJuIHRoaXMuc2ltcGxpZnlUcmFuc2Zvcm1lZEludGVybmFsKHRoaXMuZ2V0UmV2aXNpb24oKSwgc3F1YXJlZFRvbGVyYW5jZSwgb3B0X3RyYW5zZm9ybSk7XG4gIH07XG4gIC8qKlxuICAgKiBNYWtlIGEgY29tcGxldGUgY29weSBvZiB0aGUgZ2VvbWV0cnkuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHshR2VvbWV0cnl9IENsb25lLlxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY2xvc2VzdFBvaW50IENsb3Nlc3QgcG9pbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtaW5TcXVhcmVkRGlzdGFuY2UgTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuY2xvc2VzdFBvaW50WFkgPSBmdW5jdGlvbiAoeCwgeSwgY2xvc2VzdFBvaW50LCBtaW5TcXVhcmVkRGlzdGFuY2UpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IENvbnRhaW5zICh4LCB5KS5cbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuY29udGFpbnNYWSA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgdmFyIGNvb3JkID0gdGhpcy5nZXRDbG9zZXN0UG9pbnQoW3gsIHldKTtcbiAgICByZXR1cm4gY29vcmRbMF0gPT09IHggJiYgY29vcmRbMV0gPT09IHk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGNsb3Nlc3QgcG9pbnQgb2YgdGhlIGdlb21ldHJ5IHRvIHRoZSBwYXNzZWQgcG9pbnQgYXNcbiAgICoge0BsaW5rIG1vZHVsZTpvbC9jb29yZGluYXRlfkNvb3JkaW5hdGUgY29vcmRpbmF0ZX0uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBwb2ludCBQb2ludC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU9fSBvcHRfY2xvc2VzdFBvaW50IENsb3Nlc3QgcG9pbnQuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQ2xvc2VzdCBwb2ludC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS5nZXRDbG9zZXN0UG9pbnQgPSBmdW5jdGlvbiAocG9pbnQsIG9wdF9jbG9zZXN0UG9pbnQpIHtcbiAgICB2YXIgY2xvc2VzdFBvaW50ID0gb3B0X2Nsb3Nlc3RQb2ludCA/IG9wdF9jbG9zZXN0UG9pbnQgOiBbTmFOLCBOYU5dO1xuICAgIHRoaXMuY2xvc2VzdFBvaW50WFkocG9pbnRbMF0sIHBvaW50WzFdLCBjbG9zZXN0UG9pbnQsIEluZmluaXR5KTtcbiAgICByZXR1cm4gY2xvc2VzdFBvaW50O1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgZ2VvbWV0cnkgaW5jbHVkZXMgdGhlIHNwZWNpZmllZCBjb29yZGluYXRlLiBJZiB0aGVcbiAgICogY29vcmRpbmF0ZSBpcyBvbiB0aGUgYm91bmRhcnkgb2YgdGhlIGdlb21ldHJ5LCByZXR1cm5zIGZhbHNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBDb250YWlucyBjb29yZGluYXRlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgR2VvbWV0cnkucHJvdG90eXBlLmludGVyc2VjdHNDb29yZGluYXRlID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUpIHtcbiAgICByZXR1cm4gdGhpcy5jb250YWluc1hZKGNvb3JkaW5hdGVbMF0sIGNvb3JkaW5hdGVbMV0pO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHByb3RlY3RlZFxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS5jb21wdXRlRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBleHRlbnQgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnQ9fSBvcHRfZXh0ZW50IEV4dGVudC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS5nZXRFeHRlbnQgPSBmdW5jdGlvbiAob3B0X2V4dGVudCkge1xuICAgIGlmICh0aGlzLmV4dGVudFJldmlzaW9uXyAhPSB0aGlzLmdldFJldmlzaW9uKCkpIHtcbiAgICAgIHZhciBleHRlbnQgPSB0aGlzLmNvbXB1dGVFeHRlbnQodGhpcy5leHRlbnRfKTtcblxuICAgICAgaWYgKGlzTmFOKGV4dGVudFswXSkgfHwgaXNOYU4oZXh0ZW50WzFdKSkge1xuICAgICAgICBjcmVhdGVPclVwZGF0ZUVtcHR5KGV4dGVudCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZXh0ZW50UmV2aXNpb25fID0gdGhpcy5nZXRSZXZpc2lvbigpO1xuICAgIH1cblxuICAgIHJldHVybiByZXR1cm5PclVwZGF0ZSh0aGlzLmV4dGVudF8sIG9wdF9leHRlbnQpO1xuICB9O1xuICAvKipcbiAgICogUm90YXRlIHRoZSBnZW9tZXRyeSBhcm91bmQgYSBnaXZlbiBjb29yZGluYXRlLiBUaGlzIG1vZGlmaWVzIHRoZSBnZW9tZXRyeVxuICAgKiBjb29yZGluYXRlcyBpbiBwbGFjZS5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhbmdsZSBSb3RhdGlvbiBhbmdsZSBpbiByYWRpYW5zLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYW5jaG9yIFRoZSByb3RhdGlvbiBjZW50ZXIuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUucm90YXRlID0gZnVuY3Rpb24gKGFuZ2xlLCBhbmNob3IpIHtcbiAgICBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogU2NhbGUgdGhlIGdlb21ldHJ5ICh3aXRoIGFuIG9wdGlvbmFsIG9yaWdpbikuICBUaGlzIG1vZGlmaWVzIHRoZSBnZW9tZXRyeVxuICAgKiBjb29yZGluYXRlcyBpbiBwbGFjZS5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzeCBUaGUgc2NhbGluZyBmYWN0b3IgaW4gdGhlIHgtZGlyZWN0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9zeSBUaGUgc2NhbGluZyBmYWN0b3IgaW4gdGhlIHktZGlyZWN0aW9uIChkZWZhdWx0cyB0byBzeCkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPX0gb3B0X2FuY2hvciBUaGUgc2NhbGUgb3JpZ2luIChkZWZhdWx0cyB0byB0aGUgY2VudGVyXG4gICAqICAgICBvZiB0aGUgZ2VvbWV0cnkgZXh0ZW50KS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uIChzeCwgb3B0X3N5LCBvcHRfYW5jaG9yKSB7XG4gICAgYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIENyZWF0ZSBhIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiB0aGlzIGdlb21ldHJ5LiAgRm9yIGxpbmVzdHJpbmdzLCB0aGlzIHVzZXNcbiAgICogdGhlIFtEb3VnbGFzIFBldWNrZXJdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1JhbWVyLURvdWdsYXMtUGV1Y2tlcl9hbGdvcml0aG0pXG4gICAqIGFsZ29yaXRobS4gIEZvciBwb2x5Z29ucywgYSBxdWFudGl6YXRpb24tYmFzZWRcbiAgICogc2ltcGxpZmljYXRpb24gaXMgdXNlZCB0byBwcmVzZXJ2ZSB0b3BvbG9neS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHRvbGVyYW5jZSBUaGUgdG9sZXJhbmNlIGRpc3RhbmNlIGZvciBzaW1wbGlmaWNhdGlvbi5cbiAgICogQHJldHVybiB7R2VvbWV0cnl9IEEgbmV3LCBzaW1wbGlmaWVkIHZlcnNpb24gb2YgdGhlIG9yaWdpbmFsIGdlb21ldHJ5LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgR2VvbWV0cnkucHJvdG90eXBlLnNpbXBsaWZ5ID0gZnVuY3Rpb24gKHRvbGVyYW5jZSkge1xuICAgIHJldHVybiB0aGlzLmdldFNpbXBsaWZpZWRHZW9tZXRyeSh0b2xlcmFuY2UgKiB0b2xlcmFuY2UpO1xuICB9O1xuICAvKipcbiAgICogQ3JlYXRlIGEgc2ltcGxpZmllZCB2ZXJzaW9uIG9mIHRoaXMgZ2VvbWV0cnkgdXNpbmcgdGhlIERvdWdsYXMgUGV1Y2tlclxuICAgKiBhbGdvcml0aG0uXG4gICAqIFNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9SYW1lci1Eb3VnbGFzLVBldWNrZXJfYWxnb3JpdGhtLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge0dlb21ldHJ5fSBTaW1wbGlmaWVkIGdlb21ldHJ5LlxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS5nZXRTaW1wbGlmaWVkR2VvbWV0cnkgPSBmdW5jdGlvbiAoc3F1YXJlZFRvbGVyYW5jZSkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB0eXBlIG9mIHRoaXMgZ2VvbWV0cnkuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeSB0eXBlLlxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogQXBwbHkgYSB0cmFuc2Zvcm0gZnVuY3Rpb24gdG8gdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBnZW9tZXRyeS5cbiAgICogVGhlIGdlb21ldHJ5IGlzIG1vZGlmaWVkIGluIHBsYWNlLlxuICAgKiBJZiB5b3UgZG8gbm90IHdhbnQgdGhlIGdlb21ldHJ5IG1vZGlmaWVkIGluIHBsYWNlLCBmaXJzdCBgY2xvbmUoKWAgaXQgYW5kXG4gICAqIHRoZW4gdXNlIHRoaXMgZnVuY3Rpb24gb24gdGhlIGNsb25lLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufSB0cmFuc2Zvcm1GbiBUcmFuc2Zvcm0gZnVuY3Rpb24uXG4gICAqIENhbGxlZCB3aXRoIGEgZmxhdCBhcnJheSBvZiBnZW9tZXRyeSBjb29yZGluYXRlcy5cbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuYXBwbHlUcmFuc2Zvcm0gPSBmdW5jdGlvbiAodHJhbnNmb3JtRm4pIHtcbiAgICBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogVGVzdCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBwYXNzZWQgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqL1xuXG5cbiAgR2VvbWV0cnkucHJvdG90eXBlLmludGVyc2VjdHNFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBUcmFuc2xhdGUgdGhlIGdlb21ldHJ5LiAgVGhpcyBtb2RpZmllcyB0aGUgZ2VvbWV0cnkgY29vcmRpbmF0ZXMgaW4gcGxhY2UuICBJZlxuICAgKiBpbnN0ZWFkIHlvdSB3YW50IGEgbmV3IGdlb21ldHJ5LCBmaXJzdCBgY2xvbmUoKWAgdGhpcyBnZW9tZXRyeS5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YVggRGVsdGEgWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhWSBEZWx0YSBZLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgR2VvbWV0cnkucHJvdG90eXBlLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uIChkZWx0YVgsIGRlbHRhWSkge1xuICAgIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBUcmFuc2Zvcm0gZWFjaCBjb29yZGluYXRlIG9mIHRoZSBnZW9tZXRyeSBmcm9tIG9uZSBjb29yZGluYXRlIHJlZmVyZW5jZVxuICAgKiBzeXN0ZW0gdG8gYW5vdGhlci4gVGhlIGdlb21ldHJ5IGlzIG1vZGlmaWVkIGluIHBsYWNlLlxuICAgKiBGb3IgZXhhbXBsZSwgYSBsaW5lIHdpbGwgYmUgdHJhbnNmb3JtZWQgdG8gYSBsaW5lIGFuZCBhIGNpcmNsZSB0byBhIGNpcmNsZS5cbiAgICogSWYgeW91IGRvIG5vdCB3YW50IHRoZSBnZW9tZXRyeSBtb2RpZmllZCBpbiBwbGFjZSwgZmlyc3QgYGNsb25lKClgIGl0IGFuZFxuICAgKiB0aGVuIHVzZSB0aGlzIGZ1bmN0aW9uIG9uIHRoZSBjbG9uZS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBzb3VyY2UgVGhlIGN1cnJlbnQgcHJvamVjdGlvbi4gIENhbiBiZSBhXG4gICAqICAgICBzdHJpbmcgaWRlbnRpZmllciBvciBhIHtAbGluayBtb2R1bGU6b2wvcHJvai9Qcm9qZWN0aW9uflByb2plY3Rpb259IG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBkZXN0aW5hdGlvbiBUaGUgZGVzaXJlZCBwcm9qZWN0aW9uLiAgQ2FuIGJlIGFcbiAgICogICAgIHN0cmluZyBpZGVudGlmaWVyIG9yIGEge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1Byb2plY3Rpb25+UHJvamVjdGlvbn0gb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtHZW9tZXRyeX0gVGhpcyBnZW9tZXRyeS4gIE5vdGUgdGhhdCBvcmlnaW5hbCBnZW9tZXRyeSBpc1xuICAgKiAgICAgbW9kaWZpZWQgaW4gcGxhY2UuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gKHNvdXJjZSwgZGVzdGluYXRpb24pIHtcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIHZhciBzb3VyY2VQcm9qID0gZ2V0UHJvamVjdGlvbihzb3VyY2UpO1xuICAgIHZhciB0cmFuc2Zvcm1GbiA9IHNvdXJjZVByb2ouZ2V0VW5pdHMoKSA9PSBVbml0cy5USUxFX1BJWEVMUyA/IGZ1bmN0aW9uIChpbkNvb3JkaW5hdGVzLCBvdXRDb29yZGluYXRlcywgc3RyaWRlKSB7XG4gICAgICB2YXIgcGl4ZWxFeHRlbnQgPSBzb3VyY2VQcm9qLmdldEV4dGVudCgpO1xuICAgICAgdmFyIHByb2plY3RlZEV4dGVudCA9IHNvdXJjZVByb2ouZ2V0V29ybGRFeHRlbnQoKTtcbiAgICAgIHZhciBzY2FsZSA9IGdldEhlaWdodChwcm9qZWN0ZWRFeHRlbnQpIC8gZ2V0SGVpZ2h0KHBpeGVsRXh0ZW50KTtcbiAgICAgIGNvbXBvc2VUcmFuc2Zvcm0odG1wVHJhbnNmb3JtLCBwcm9qZWN0ZWRFeHRlbnRbMF0sIHByb2plY3RlZEV4dGVudFszXSwgc2NhbGUsIC1zY2FsZSwgMCwgMCwgMCk7XG4gICAgICB0cmFuc2Zvcm0yRChpbkNvb3JkaW5hdGVzLCAwLCBpbkNvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlLCB0bXBUcmFuc2Zvcm0sIG91dENvb3JkaW5hdGVzKTtcbiAgICAgIHJldHVybiBnZXRUcmFuc2Zvcm0oc291cmNlUHJvaiwgZGVzdGluYXRpb24pKGluQ29vcmRpbmF0ZXMsIG91dENvb3JkaW5hdGVzLCBzdHJpZGUpO1xuICAgIH0gOiBnZXRUcmFuc2Zvcm0oc291cmNlUHJvaiwgZGVzdGluYXRpb24pO1xuICAgIHRoaXMuYXBwbHlUcmFuc2Zvcm0odHJhbnNmb3JtRm4pO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIHJldHVybiBHZW9tZXRyeTtcbn0oQmFzZU9iamVjdCk7XG5cbmV4cG9ydCBkZWZhdWx0IEdlb21ldHJ5OyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9TaW1wbGVHZW9tZXRyeVxuICovXG5cblxuaW1wb3J0IEdlb21ldHJ5IGZyb20gJy4vR2VvbWV0cnkuanMnO1xuaW1wb3J0IEdlb21ldHJ5TGF5b3V0IGZyb20gJy4vR2VvbWV0cnlMYXlvdXQuanMnO1xuaW1wb3J0IHsgYWJzdHJhY3QgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IGNyZWF0ZU9yVXBkYXRlRnJvbUZsYXRDb29yZGluYXRlcywgZ2V0Q2VudGVyIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IHJvdGF0ZSwgc2NhbGUsIHRyYW5zZm9ybTJELCB0cmFuc2xhdGUgfSBmcm9tICcuL2ZsYXQvdHJhbnNmb3JtLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWJzdHJhY3QgYmFzZSBjbGFzczsgb25seSB1c2VkIGZvciBjcmVhdGluZyBzdWJjbGFzc2VzOyBkbyBub3QgaW5zdGFudGlhdGVcbiAqIGluIGFwcHMsIGFzIGNhbm5vdCBiZSByZW5kZXJlZC5cbiAqXG4gKiBAYWJzdHJhY3RcbiAqIEBhcGlcbiAqL1xuXG52YXIgU2ltcGxlR2VvbWV0cnkgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoU2ltcGxlR2VvbWV0cnksIF9zdXBlcik7XG5cbiAgZnVuY3Rpb24gU2ltcGxlR2VvbWV0cnkoKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMubGF5b3V0ID0gR2VvbWV0cnlMYXlvdXQuWFk7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5zdHJpZGUgPSAyO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIF90aGlzLmZsYXRDb29yZGluYXRlcyA9IG51bGw7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuY29tcHV0ZUV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICByZXR1cm4gY3JlYXRlT3JVcGRhdGVGcm9tRmxhdENvb3JkaW5hdGVzKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHRoaXMuc3RyaWRlLCBleHRlbnQpO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEByZXR1cm4ge0FycmF5PCo+fSBDb29yZGluYXRlcy5cbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuZ2V0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGZpcnN0IGNvb3JkaW5hdGUgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IEZpcnN0IGNvb3JkaW5hdGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuZ2V0Rmlyc3RDb29yZGluYXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZSgwLCB0aGlzLnN0cmlkZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBGbGF0IGNvb3JkaW5hdGVzLlxuICAgKi9cblxuXG4gIFNpbXBsZUdlb21ldHJ5LnByb3RvdHlwZS5nZXRGbGF0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmxhdENvb3JkaW5hdGVzO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBsYXN0IGNvb3JkaW5hdGUgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IExhc3QgcG9pbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuZ2V0TGFzdENvb3JkaW5hdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCAtIHRoaXMuc3RyaWRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUge0BsaW5rIG1vZHVsZTpvbC9nZW9tL0dlb21ldHJ5TGF5b3V0IGxheW91dH0gb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHR9IExheW91dC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFNpbXBsZUdlb21ldHJ5LnByb3RvdHlwZS5nZXRMYXlvdXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubGF5b3V0O1xuICB9O1xuICAvKipcbiAgICogQ3JlYXRlIGEgc2ltcGxpZmllZCB2ZXJzaW9uIG9mIHRoaXMgZ2VvbWV0cnkgdXNpbmcgdGhlIERvdWdsYXMgUGV1Y2tlciBhbGdvcml0aG0uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzcXVhcmVkVG9sZXJhbmNlIFNxdWFyZWQgdG9sZXJhbmNlLlxuICAgKiBAcmV0dXJuIHtTaW1wbGVHZW9tZXRyeX0gU2ltcGxpZmllZCBnZW9tZXRyeS5cbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuZ2V0U2ltcGxpZmllZEdlb21ldHJ5ID0gZnVuY3Rpb24gKHNxdWFyZWRUb2xlcmFuY2UpIHtcbiAgICBpZiAodGhpcy5zaW1wbGlmaWVkR2VvbWV0cnlSZXZpc2lvbiAhPT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB0aGlzLnNpbXBsaWZpZWRHZW9tZXRyeU1heE1pblNxdWFyZWRUb2xlcmFuY2UgPSAwO1xuICAgICAgdGhpcy5zaW1wbGlmaWVkR2VvbWV0cnlSZXZpc2lvbiA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9IC8vIElmIHNxdWFyZWRUb2xlcmFuY2UgaXMgbmVnYXRpdmUgb3IgaWYgd2Uga25vdyB0aGF0IHNpbXBsaWZpY2F0aW9uIHdpbGwgbm90XG4gICAgLy8gaGF2ZSBhbnkgZWZmZWN0IHRoZW4ganVzdCByZXR1cm4gdGhpcy5cblxuXG4gICAgaWYgKHNxdWFyZWRUb2xlcmFuY2UgPCAwIHx8IHRoaXMuc2ltcGxpZmllZEdlb21ldHJ5TWF4TWluU3F1YXJlZFRvbGVyYW5jZSAhPT0gMCAmJiBzcXVhcmVkVG9sZXJhbmNlIDw9IHRoaXMuc2ltcGxpZmllZEdlb21ldHJ5TWF4TWluU3F1YXJlZFRvbGVyYW5jZSkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgdmFyIHNpbXBsaWZpZWRHZW9tZXRyeSA9IHRoaXMuZ2V0U2ltcGxpZmllZEdlb21ldHJ5SW50ZXJuYWwoc3F1YXJlZFRvbGVyYW5jZSk7XG4gICAgdmFyIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgPSBzaW1wbGlmaWVkR2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG5cbiAgICBpZiAoc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcy5sZW5ndGggPCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBzaW1wbGlmaWVkR2VvbWV0cnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFNpbXBsaWZpY2F0aW9uIGRpZCBub3QgYWN0dWFsbHkgcmVtb3ZlIGFueSBjb29yZGluYXRlcy4gIFdlIG5vdyBrbm93XG4gICAgICAvLyB0aGF0IGFueSBjYWxscyB0byBnZXRTaW1wbGlmaWVkR2VvbWV0cnkgd2l0aCBhIHNxdWFyZWRUb2xlcmFuY2UgbGVzc1xuICAgICAgLy8gdGhhbiBvciBlcXVhbCB0byB0aGUgY3VycmVudCBzcXVhcmVkVG9sZXJhbmNlIHdpbGwgYWxzbyBub3QgaGF2ZSBhbnlcbiAgICAgIC8vIGVmZmVjdC4gIFRoaXMgYWxsb3dzIHVzIHRvIHNob3J0IGNpcmN1aXQgc2ltcGxpZmljYXRpb24gKHNhdmluZyBDUFVcbiAgICAgIC8vIGN5Y2xlcykgYW5kIHByZXZlbnRzIHRoZSBjYWNoZSBvZiBzaW1wbGlmaWVkIGdlb21ldHJpZXMgZnJvbSBmaWxsaW5nXG4gICAgICAvLyB1cCB3aXRoIHVzZWxlc3MgaWRlbnRpY2FsIGNvcGllcyBvZiB0aGlzIGdlb21ldHJ5IChzYXZpbmcgbWVtb3J5KS5cbiAgICAgIHRoaXMuc2ltcGxpZmllZEdlb21ldHJ5TWF4TWluU3F1YXJlZFRvbGVyYW5jZSA9IHNxdWFyZWRUb2xlcmFuY2U7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICogQHJldHVybiB7U2ltcGxlR2VvbWV0cnl9IFNpbXBsaWZpZWQgZ2VvbWV0cnkuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuZ2V0U2ltcGxpZmllZEdlb21ldHJ5SW50ZXJuYWwgPSBmdW5jdGlvbiAoc3F1YXJlZFRvbGVyYW5jZSkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBTdHJpZGUuXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLmdldFN0cmlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zdHJpZGU7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdH0gbGF5b3V0IExheW91dC5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuc2V0RmxhdENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKGxheW91dCwgZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgdGhpcy5zdHJpZGUgPSBnZXRTdHJpZGVGb3JMYXlvdXQobGF5b3V0KTtcbiAgICB0aGlzLmxheW91dCA9IGxheW91dDtcbiAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IGZsYXRDb29yZGluYXRlcztcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0geyFBcnJheTwqPn0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9HZW9tZXRyeUxheW91dC5qc1wiKS5kZWZhdWx0PX0gb3B0X2xheW91dCBMYXlvdXQuXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLnNldENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKGNvb3JkaW5hdGVzLCBvcHRfbGF5b3V0KSB7XG4gICAgYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9HZW9tZXRyeUxheW91dC5qc1wiKS5kZWZhdWx0fHVuZGVmaW5lZH0gbGF5b3V0IExheW91dC5cbiAgICogQHBhcmFtIHtBcnJheTwqPn0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBuZXN0aW5nIE5lc3RpbmcuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuc2V0TGF5b3V0ID0gZnVuY3Rpb24gKGxheW91dCwgY29vcmRpbmF0ZXMsIG5lc3RpbmcpIHtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB2YXIgc3RyaWRlO1xuXG4gICAgaWYgKGxheW91dCkge1xuICAgICAgc3RyaWRlID0gZ2V0U3RyaWRlRm9yTGF5b3V0KGxheW91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbmVzdGluZzsgKytpKSB7XG4gICAgICAgIGlmIChjb29yZGluYXRlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLmxheW91dCA9IEdlb21ldHJ5TGF5b3V0LlhZO1xuICAgICAgICAgIHRoaXMuc3RyaWRlID0gMjtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29vcmRpbmF0ZXMgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7QXJyYXl9ICovXG4gICAgICAgICAgY29vcmRpbmF0ZXNbMF07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3RyaWRlID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgICAgbGF5b3V0ID0gZ2V0TGF5b3V0Rm9yU3RyaWRlKHN0cmlkZSk7XG4gICAgfVxuXG4gICAgdGhpcy5sYXlvdXQgPSBsYXlvdXQ7XG4gICAgdGhpcy5zdHJpZGUgPSBzdHJpZGU7XG4gIH07XG4gIC8qKlxuICAgKiBBcHBseSBhIHRyYW5zZm9ybSBmdW5jdGlvbiB0byB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBUaGUgZ2VvbWV0cnkgaXMgbW9kaWZpZWQgaW4gcGxhY2UuXG4gICAqIElmIHlvdSBkbyBub3Qgd2FudCB0aGUgZ2VvbWV0cnkgbW9kaWZpZWQgaW4gcGxhY2UsIGZpcnN0IGBjbG9uZSgpYCBpdCBhbmRcbiAgICogdGhlbiB1c2UgdGhpcyBmdW5jdGlvbiBvbiB0aGUgY2xvbmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gdHJhbnNmb3JtRm4gVHJhbnNmb3JtIGZ1bmN0aW9uLlxuICAgKiBDYWxsZWQgd2l0aCBhIGZsYXQgYXJyYXkgb2YgZ2VvbWV0cnkgY29vcmRpbmF0ZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuYXBwbHlUcmFuc2Zvcm0gPSBmdW5jdGlvbiAodHJhbnNmb3JtRm4pIHtcbiAgICBpZiAodGhpcy5mbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHRyYW5zZm9ybUZuKHRoaXMuZmxhdENvb3JkaW5hdGVzLCB0aGlzLmZsYXRDb29yZGluYXRlcywgdGhpcy5zdHJpZGUpO1xuICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUm90YXRlIHRoZSBnZW9tZXRyeSBhcm91bmQgYSBnaXZlbiBjb29yZGluYXRlLiBUaGlzIG1vZGlmaWVzIHRoZSBnZW9tZXRyeVxuICAgKiBjb29yZGluYXRlcyBpbiBwbGFjZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlIFJvdGF0aW9uIGFuZ2xlIGluIGNvdW50ZXItY2xvY2t3aXNlIHJhZGlhbnMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBhbmNob3IgVGhlIHJvdGF0aW9uIGNlbnRlci5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFNpbXBsZUdlb21ldHJ5LnByb3RvdHlwZS5yb3RhdGUgPSBmdW5jdGlvbiAoYW5nbGUsIGFuY2hvcikge1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSB0aGlzLmdldEZsYXRDb29yZGluYXRlcygpO1xuXG4gICAgaWYgKGZsYXRDb29yZGluYXRlcykge1xuICAgICAgdmFyIHN0cmlkZSA9IHRoaXMuZ2V0U3RyaWRlKCk7XG4gICAgICByb3RhdGUoZmxhdENvb3JkaW5hdGVzLCAwLCBmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCBzdHJpZGUsIGFuZ2xlLCBhbmNob3IsIGZsYXRDb29yZGluYXRlcyk7XG4gICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTY2FsZSB0aGUgZ2VvbWV0cnkgKHdpdGggYW4gb3B0aW9uYWwgb3JpZ2luKS4gIFRoaXMgbW9kaWZpZXMgdGhlIGdlb21ldHJ5XG4gICAqIGNvb3JkaW5hdGVzIGluIHBsYWNlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3ggVGhlIHNjYWxpbmcgZmFjdG9yIGluIHRoZSB4LWRpcmVjdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfc3kgVGhlIHNjYWxpbmcgZmFjdG9yIGluIHRoZSB5LWRpcmVjdGlvbiAoZGVmYXVsdHMgdG8gc3gpLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9hbmNob3IgVGhlIHNjYWxlIG9yaWdpbiAoZGVmYXVsdHMgdG8gdGhlIGNlbnRlclxuICAgKiAgICAgb2YgdGhlIGdlb21ldHJ5IGV4dGVudCkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAoc3gsIG9wdF9zeSwgb3B0X2FuY2hvcikge1xuICAgIHZhciBzeSA9IG9wdF9zeTtcblxuICAgIGlmIChzeSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzeSA9IHN4O1xuICAgIH1cblxuICAgIHZhciBhbmNob3IgPSBvcHRfYW5jaG9yO1xuXG4gICAgaWYgKCFhbmNob3IpIHtcbiAgICAgIGFuY2hvciA9IGdldENlbnRlcih0aGlzLmdldEV4dGVudCgpKTtcbiAgICB9XG5cbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcblxuICAgIGlmIChmbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHZhciBzdHJpZGUgPSB0aGlzLmdldFN0cmlkZSgpO1xuICAgICAgc2NhbGUoZmxhdENvb3JkaW5hdGVzLCAwLCBmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCBzdHJpZGUsIHN4LCBzeSwgYW5jaG9yLCBmbGF0Q29vcmRpbmF0ZXMpO1xuICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogVHJhbnNsYXRlIHRoZSBnZW9tZXRyeS4gIFRoaXMgbW9kaWZpZXMgdGhlIGdlb21ldHJ5IGNvb3JkaW5hdGVzIGluIHBsYWNlLiAgSWZcbiAgICogaW5zdGVhZCB5b3Ugd2FudCBhIG5ldyBnZW9tZXRyeSwgZmlyc3QgYGNsb25lKClgIHRoaXMgZ2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YVggRGVsdGEgWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhWSBEZWx0YSBZLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uIChkZWx0YVgsIGRlbHRhWSkge1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSB0aGlzLmdldEZsYXRDb29yZGluYXRlcygpO1xuXG4gICAgaWYgKGZsYXRDb29yZGluYXRlcykge1xuICAgICAgdmFyIHN0cmlkZSA9IHRoaXMuZ2V0U3RyaWRlKCk7XG4gICAgICB0cmFuc2xhdGUoZmxhdENvb3JkaW5hdGVzLCAwLCBmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCBzdHJpZGUsIGRlbHRhWCwgZGVsdGFZLCBmbGF0Q29vcmRpbmF0ZXMpO1xuICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBTaW1wbGVHZW9tZXRyeTtcbn0oR2VvbWV0cnkpO1xuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdH0gbGF5b3V0IExheW91dC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldExheW91dEZvclN0cmlkZShzdHJpZGUpIHtcbiAgdmFyIGxheW91dDtcblxuICBpZiAoc3RyaWRlID09IDIpIHtcbiAgICBsYXlvdXQgPSBHZW9tZXRyeUxheW91dC5YWTtcbiAgfSBlbHNlIGlmIChzdHJpZGUgPT0gMykge1xuICAgIGxheW91dCA9IEdlb21ldHJ5TGF5b3V0LlhZWjtcbiAgfSBlbHNlIGlmIChzdHJpZGUgPT0gNCkge1xuICAgIGxheW91dCA9IEdlb21ldHJ5TGF5b3V0LlhZWk07XG4gIH1cblxuICByZXR1cm4gKFxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9HZW9tZXRyeUxheW91dC5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIGxheW91dFxuICApO1xufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdH0gbGF5b3V0IExheW91dC5cbiAqIEByZXR1cm4ge251bWJlcn0gU3RyaWRlLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFN0cmlkZUZvckxheW91dChsYXlvdXQpIHtcbiAgdmFyIHN0cmlkZTtcblxuICBpZiAobGF5b3V0ID09IEdlb21ldHJ5TGF5b3V0LlhZKSB7XG4gICAgc3RyaWRlID0gMjtcbiAgfSBlbHNlIGlmIChsYXlvdXQgPT0gR2VvbWV0cnlMYXlvdXQuWFlaIHx8IGxheW91dCA9PSBHZW9tZXRyeUxheW91dC5YWU0pIHtcbiAgICBzdHJpZGUgPSAzO1xuICB9IGVsc2UgaWYgKGxheW91dCA9PSBHZW9tZXRyeUxheW91dC5YWVpNKSB7XG4gICAgc3RyaWRlID0gNDtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgc3RyaWRlXG4gICk7XG59XG4vKipcbiAqIEBwYXJhbSB7U2ltcGxlR2VvbWV0cnl9IHNpbXBsZUdlb21ldHJ5IFNpbXBsZSBnZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9kZXN0IERlc3RpbmF0aW9uLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gVHJhbnNmb3JtZWQgZmxhdCBjb29yZGluYXRlcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtR2VvbTJEKHNpbXBsZUdlb21ldHJ5LCB0cmFuc2Zvcm0sIG9wdF9kZXN0KSB7XG4gIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBzaW1wbGVHZW9tZXRyeS5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcblxuICBpZiAoIWZsYXRDb29yZGluYXRlcykge1xuICAgIHJldHVybiBudWxsO1xuICB9IGVsc2Uge1xuICAgIHZhciBzdHJpZGUgPSBzaW1wbGVHZW9tZXRyeS5nZXRTdHJpZGUoKTtcbiAgICByZXR1cm4gdHJhbnNmb3JtMkQoZmxhdENvb3JkaW5hdGVzLCAwLCBmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCBzdHJpZGUsIHRyYW5zZm9ybSwgb3B0X2Rlc3QpO1xuICB9XG59XG5leHBvcnQgZGVmYXVsdCBTaW1wbGVHZW9tZXRyeTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L2Nsb3Nlc3RcbiAqL1xuaW1wb3J0IHsgbGVycCwgc3F1YXJlZERpc3RhbmNlIGFzIHNxdWFyZWREeCB9IGZyb20gJy4uLy4uL21hdGguanMnO1xuLyoqXG4gKiBSZXR1cm5zIHRoZSBwb2ludCBvbiB0aGUgMkQgbGluZSBzZWdtZW50IGZsYXRDb29yZGluYXRlc1tvZmZzZXQxXSB0b1xuICogZmxhdENvb3JkaW5hdGVzW29mZnNldDJdIHRoYXQgaXMgY2xvc2VzdCB0byB0aGUgcG9pbnQgKHgsIHkpLiAgRXh0cmFcbiAqIGRpbWVuc2lvbnMgYXJlIGxpbmVhcmx5IGludGVycG9sYXRlZC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0MSBPZmZzZXQgMS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQyIE9mZnNldCAyLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gY2xvc2VzdFBvaW50IENsb3Nlc3QgcG9pbnQuXG4gKi9cblxuZnVuY3Rpb24gYXNzaWduQ2xvc2VzdChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldDEsIG9mZnNldDIsIHN0cmlkZSwgeCwgeSwgY2xvc2VzdFBvaW50KSB7XG4gIHZhciB4MSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQxXTtcbiAgdmFyIHkxID0gZmxhdENvb3JkaW5hdGVzW29mZnNldDEgKyAxXTtcbiAgdmFyIGR4ID0gZmxhdENvb3JkaW5hdGVzW29mZnNldDJdIC0geDE7XG4gIHZhciBkeSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQyICsgMV0gLSB5MTtcbiAgdmFyIG9mZnNldDtcblxuICBpZiAoZHggPT09IDAgJiYgZHkgPT09IDApIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQxO1xuICB9IGVsc2Uge1xuICAgIHZhciB0ID0gKCh4IC0geDEpICogZHggKyAoeSAtIHkxKSAqIGR5KSAvIChkeCAqIGR4ICsgZHkgKiBkeSk7XG5cbiAgICBpZiAodCA+IDEpIHtcbiAgICAgIG9mZnNldCA9IG9mZnNldDI7XG4gICAgfSBlbHNlIGlmICh0ID4gMCkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpZGU7ICsraSkge1xuICAgICAgICBjbG9zZXN0UG9pbnRbaV0gPSBsZXJwKGZsYXRDb29yZGluYXRlc1tvZmZzZXQxICsgaV0sIGZsYXRDb29yZGluYXRlc1tvZmZzZXQyICsgaV0sIHQpO1xuICAgICAgfVxuXG4gICAgICBjbG9zZXN0UG9pbnQubGVuZ3RoID0gc3RyaWRlO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBvZmZzZXQgPSBvZmZzZXQxO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaWRlOyArK2kpIHtcbiAgICBjbG9zZXN0UG9pbnRbaV0gPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgaV07XG4gIH1cblxuICBjbG9zZXN0UG9pbnQubGVuZ3RoID0gc3RyaWRlO1xufVxuLyoqXG4gKiBSZXR1cm4gdGhlIHNxdWFyZWQgb2YgdGhlIGxhcmdlc3QgZGlzdGFuY2UgYmV0d2VlbiBhbnkgcGFpciBvZiBjb25zZWN1dGl2ZVxuICogY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IG1heCBNYXggc3F1YXJlZCBkZWx0YS5cbiAqIEByZXR1cm4ge251bWJlcn0gTWF4IHNxdWFyZWQgZGVsdGEuXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gbWF4U3F1YXJlZERlbHRhKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgbWF4KSB7XG4gIHZhciB4MSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXRdO1xuICB2YXIgeTEgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG5cbiAgZm9yIChvZmZzZXQgKz0gc3RyaWRlOyBvZmZzZXQgPCBlbmQ7IG9mZnNldCArPSBzdHJpZGUpIHtcbiAgICB2YXIgeDIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgICB2YXIgeTIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gICAgdmFyIHNxdWFyZWREZWx0YSA9IHNxdWFyZWREeCh4MSwgeTEsIHgyLCB5Mik7XG5cbiAgICBpZiAoc3F1YXJlZERlbHRhID4gbWF4KSB7XG4gICAgICBtYXggPSBzcXVhcmVkRGVsdGE7XG4gICAgfVxuXG4gICAgeDEgPSB4MjtcbiAgICB5MSA9IHkyO1xuICB9XG5cbiAgcmV0dXJuIG1heDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBlbmRzIEVuZHMuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXggTWF4IHNxdWFyZWQgZGVsdGEuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE1heCBzcXVhcmVkIGRlbHRhLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhcnJheU1heFNxdWFyZWREZWx0YShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBtYXgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGVuZCA9IGVuZHNbaV07XG4gICAgbWF4ID0gbWF4U3F1YXJlZERlbHRhKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgbWF4KTtcbiAgICBvZmZzZXQgPSBlbmQ7XG4gIH1cblxuICByZXR1cm4gbWF4O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBFbmRzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IG1heCBNYXggc3F1YXJlZCBkZWx0YS5cbiAqIEByZXR1cm4ge251bWJlcn0gTWF4IHNxdWFyZWQgZGVsdGEuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpQXJyYXlNYXhTcXVhcmVkRGVsdGEoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUsIG1heCkge1xuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGVuZHMgPSBlbmRzc1tpXTtcbiAgICBtYXggPSBhcnJheU1heFNxdWFyZWREZWx0YShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBtYXgpO1xuICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHJldHVybiBtYXg7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4RGVsdGEgTWF4IGRlbHRhLlxuICogQHBhcmFtIHtib29sZWFufSBpc1JpbmcgSXMgcmluZy5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBjbG9zZXN0UG9pbnQgQ2xvc2VzdCBwb2ludC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5TcXVhcmVkRGlzdGFuY2UgTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X3RtcFBvaW50IFRlbXBvcmFyeSBwb2ludCBvYmplY3QuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYXNzaWduQ2xvc2VzdFBvaW50KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgbWF4RGVsdGEsIGlzUmluZywgeCwgeSwgY2xvc2VzdFBvaW50LCBtaW5TcXVhcmVkRGlzdGFuY2UsIG9wdF90bXBQb2ludCkge1xuICBpZiAob2Zmc2V0ID09IGVuZCkge1xuICAgIHJldHVybiBtaW5TcXVhcmVkRGlzdGFuY2U7XG4gIH1cblxuICB2YXIgaSwgc3F1YXJlZERpc3RhbmNlO1xuXG4gIGlmIChtYXhEZWx0YSA9PT0gMCkge1xuICAgIC8vIEFsbCBwb2ludHMgYXJlIGlkZW50aWNhbCwgc28ganVzdCB0ZXN0IHRoZSBmaXJzdCBwb2ludC5cbiAgICBzcXVhcmVkRGlzdGFuY2UgPSBzcXVhcmVkRHgoeCwgeSwgZmxhdENvb3JkaW5hdGVzW29mZnNldF0sIGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXSk7XG5cbiAgICBpZiAoc3F1YXJlZERpc3RhbmNlIDwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgc3RyaWRlOyArK2kpIHtcbiAgICAgICAgY2xvc2VzdFBvaW50W2ldID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIGldO1xuICAgICAgfVxuXG4gICAgICBjbG9zZXN0UG9pbnQubGVuZ3RoID0gc3RyaWRlO1xuICAgICAgcmV0dXJuIHNxdWFyZWREaXN0YW5jZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgICB9XG4gIH1cblxuICB2YXIgdG1wUG9pbnQgPSBvcHRfdG1wUG9pbnQgPyBvcHRfdG1wUG9pbnQgOiBbTmFOLCBOYU5dO1xuICB2YXIgaW5kZXggPSBvZmZzZXQgKyBzdHJpZGU7XG5cbiAgd2hpbGUgKGluZGV4IDwgZW5kKSB7XG4gICAgYXNzaWduQ2xvc2VzdChmbGF0Q29vcmRpbmF0ZXMsIGluZGV4IC0gc3RyaWRlLCBpbmRleCwgc3RyaWRlLCB4LCB5LCB0bXBQb2ludCk7XG4gICAgc3F1YXJlZERpc3RhbmNlID0gc3F1YXJlZER4KHgsIHksIHRtcFBvaW50WzBdLCB0bXBQb2ludFsxXSk7XG5cbiAgICBpZiAoc3F1YXJlZERpc3RhbmNlIDwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgICBtaW5TcXVhcmVkRGlzdGFuY2UgPSBzcXVhcmVkRGlzdGFuY2U7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBzdHJpZGU7ICsraSkge1xuICAgICAgICBjbG9zZXN0UG9pbnRbaV0gPSB0bXBQb2ludFtpXTtcbiAgICAgIH1cblxuICAgICAgY2xvc2VzdFBvaW50Lmxlbmd0aCA9IHN0cmlkZTtcbiAgICAgIGluZGV4ICs9IHN0cmlkZTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2tpcCBhaGVhZCBtdWx0aXBsZSBwb2ludHMsIGJlY2F1c2Ugd2Uga25vdyB0aGF0IGFsbCB0aGUgc2tpcHBlZFxuICAgICAgLy8gcG9pbnRzIGNhbm5vdCBiZSBhbnkgY2xvc2VyIHRoYW4gdGhlIGNsb3Nlc3QgcG9pbnQgd2UgaGF2ZSBmb3VuZCBzb1xuICAgICAgLy8gZmFyLiAgV2Uga25vdyB0aGlzIGJlY2F1c2Ugd2Uga25vdyBob3cgY2xvc2UgdGhlIGN1cnJlbnQgcG9pbnQgaXMsIGhvd1xuICAgICAgLy8gY2xvc2UgdGhlIGNsb3Nlc3QgcG9pbnQgd2UgaGF2ZSBmb3VuZCBzbyBmYXIgaXMsIGFuZCB0aGUgbWF4aW11bVxuICAgICAgLy8gZGlzdGFuY2UgYmV0d2VlbiBjb25zZWN1dGl2ZSBwb2ludHMuICBGb3IgZXhhbXBsZSwgaWYgd2UncmUgY3VycmVudGx5XG4gICAgICAvLyBhdCBkaXN0YW5jZSAxMCwgdGhlIGJlc3Qgd2UndmUgZm91bmQgc28gZmFyIGlzIDMsIGFuZCB0aGF0IHRoZSBtYXhpbXVtXG4gICAgICAvLyBkaXN0YW5jZSBiZXR3ZWVuIGNvbnNlY3V0aXZlIHBvaW50cyBpcyAyLCB0aGVuIHdlJ2xsIG5lZWQgdG8gc2tpcCBhdFxuICAgICAgLy8gbGVhc3QgKDEwIC0gMykgLyAyID09IDMgKHJvdW5kZWQgZG93bikgcG9pbnRzIHRvIGhhdmUgYW55IGNoYW5jZSBvZlxuICAgICAgLy8gZmluZGluZyBhIGNsb3NlciBwb2ludC4gIFdlIHVzZSBNYXRoLm1heCguLi4sIDEpIHRvIGVuc3VyZSB0aGF0IHdlXG4gICAgICAvLyBhbHdheXMgYWR2YW5jZSBhdCBsZWFzdCBvbmUgcG9pbnQsIHRvIGF2b2lkIGFuIGluZmluaXRlIGxvb3AuXG4gICAgICBpbmRleCArPSBzdHJpZGUgKiBNYXRoLm1heCgoTWF0aC5zcXJ0KHNxdWFyZWREaXN0YW5jZSkgLSBNYXRoLnNxcnQobWluU3F1YXJlZERpc3RhbmNlKSkgLyBtYXhEZWx0YSB8IDAsIDEpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc1JpbmcpIHtcbiAgICAvLyBDaGVjayB0aGUgY2xvc2luZyBzZWdtZW50LlxuICAgIGFzc2lnbkNsb3Nlc3QoZmxhdENvb3JkaW5hdGVzLCBlbmQgLSBzdHJpZGUsIG9mZnNldCwgc3RyaWRlLCB4LCB5LCB0bXBQb2ludCk7XG4gICAgc3F1YXJlZERpc3RhbmNlID0gc3F1YXJlZER4KHgsIHksIHRtcFBvaW50WzBdLCB0bXBQb2ludFsxXSk7XG5cbiAgICBpZiAoc3F1YXJlZERpc3RhbmNlIDwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgICBtaW5TcXVhcmVkRGlzdGFuY2UgPSBzcXVhcmVkRGlzdGFuY2U7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBzdHJpZGU7ICsraSkge1xuICAgICAgICBjbG9zZXN0UG9pbnRbaV0gPSB0bXBQb2ludFtpXTtcbiAgICAgIH1cblxuICAgICAgY2xvc2VzdFBvaW50Lmxlbmd0aCA9IHN0cmlkZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWluU3F1YXJlZERpc3RhbmNlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IG1heERlbHRhIE1heCBkZWx0YS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNSaW5nIElzIHJpbmcuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gY2xvc2VzdFBvaW50IENsb3Nlc3QgcG9pbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gbWluU3F1YXJlZERpc3RhbmNlIE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF90bXBQb2ludCBUZW1wb3JhcnkgcG9pbnQgb2JqZWN0LlxuICogQHJldHVybiB7bnVtYmVyfSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2lnbkNsb3Nlc3RBcnJheVBvaW50KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIG1heERlbHRhLCBpc1JpbmcsIHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlLCBvcHRfdG1wUG9pbnQpIHtcbiAgdmFyIHRtcFBvaW50ID0gb3B0X3RtcFBvaW50ID8gb3B0X3RtcFBvaW50IDogW05hTiwgTmFOXTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICBtaW5TcXVhcmVkRGlzdGFuY2UgPSBhc3NpZ25DbG9zZXN0UG9pbnQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBtYXhEZWx0YSwgaXNSaW5nLCB4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSwgdG1wUG9pbnQpO1xuICAgIG9mZnNldCA9IGVuZDtcbiAgfVxuXG4gIHJldHVybiBtaW5TcXVhcmVkRGlzdGFuY2U7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IGVuZHNzIEVuZHNzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4RGVsdGEgTWF4IGRlbHRhLlxuICogQHBhcmFtIHtib29sZWFufSBpc1JpbmcgSXMgcmluZy5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBjbG9zZXN0UG9pbnQgQ2xvc2VzdCBwb2ludC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5TcXVhcmVkRGlzdGFuY2UgTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X3RtcFBvaW50IFRlbXBvcmFyeSBwb2ludCBvYmplY3QuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYXNzaWduQ2xvc2VzdE11bHRpQXJyYXlQb2ludChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc3MsIHN0cmlkZSwgbWF4RGVsdGEsIGlzUmluZywgeCwgeSwgY2xvc2VzdFBvaW50LCBtaW5TcXVhcmVkRGlzdGFuY2UsIG9wdF90bXBQb2ludCkge1xuICB2YXIgdG1wUG9pbnQgPSBvcHRfdG1wUG9pbnQgPyBvcHRfdG1wUG9pbnQgOiBbTmFOLCBOYU5dO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHNzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kcyA9IGVuZHNzW2ldO1xuICAgIG1pblNxdWFyZWREaXN0YW5jZSA9IGFzc2lnbkNsb3Nlc3RBcnJheVBvaW50KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIG1heERlbHRhLCBpc1JpbmcsIHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlLCB0bXBQb2ludCk7XG4gICAgb2Zmc2V0ID0gZW5kc1tlbmRzLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L2RlZmxhdGVcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEByZXR1cm4ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmxhdGVDb29yZGluYXRlKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBjb29yZGluYXRlLCBzdHJpZGUpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gY29vcmRpbmF0ZS5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgZmxhdENvb3JkaW5hdGVzW29mZnNldCsrXSA9IGNvb3JkaW5hdGVbaV07XG4gIH1cblxuICByZXR1cm4gb2Zmc2V0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmxhdGVDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgY29vcmRpbmF0ZXMsIHN0cmlkZSkge1xuICBmb3IgKHZhciBpID0gMCwgaWkgPSBjb29yZGluYXRlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGNvb3JkaW5hdGUgPSBjb29yZGluYXRlc1tpXTtcblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3RyaWRlOyArK2opIHtcbiAgICAgIGZsYXRDb29yZGluYXRlc1tvZmZzZXQrK10gPSBjb29yZGluYXRlW2pdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvZmZzZXQ7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj59IGNvb3JkaW5hdGVzcyBDb29yZGluYXRlc3MuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9lbmRzIEVuZHMuXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBFbmRzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZsYXRlQ29vcmRpbmF0ZXNBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgY29vcmRpbmF0ZXNzLCBzdHJpZGUsIG9wdF9lbmRzKSB7XG4gIHZhciBlbmRzID0gb3B0X2VuZHMgPyBvcHRfZW5kcyA6IFtdO1xuICB2YXIgaSA9IDA7XG5cbiAgZm9yICh2YXIgaiA9IDAsIGpqID0gY29vcmRpbmF0ZXNzLmxlbmd0aDsgaiA8IGpqOyArK2opIHtcbiAgICB2YXIgZW5kID0gZGVmbGF0ZUNvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBjb29yZGluYXRlc3Nbal0sIHN0cmlkZSk7XG4gICAgZW5kc1tpKytdID0gZW5kO1xuICAgIG9mZnNldCA9IGVuZDtcbiAgfVxuXG4gIGVuZHMubGVuZ3RoID0gaTtcbiAgcmV0dXJuIGVuZHM7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj4+fSBjb29yZGluYXRlc3NzIENvb3JkaW5hdGVzc3MuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj49fSBvcHRfZW5kc3MgRW5kc3MuXG4gKiBAcmV0dXJuIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gRW5kc3MuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmxhdGVNdWx0aUNvb3JkaW5hdGVzQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGNvb3JkaW5hdGVzc3MsIHN0cmlkZSwgb3B0X2VuZHNzKSB7XG4gIHZhciBlbmRzcyA9IG9wdF9lbmRzcyA/IG9wdF9lbmRzcyA6IFtdO1xuICB2YXIgaSA9IDA7XG5cbiAgZm9yICh2YXIgaiA9IDAsIGpqID0gY29vcmRpbmF0ZXNzcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgdmFyIGVuZHMgPSBkZWZsYXRlQ29vcmRpbmF0ZXNBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgY29vcmRpbmF0ZXNzc1tqXSwgc3RyaWRlLCBlbmRzc1tpXSk7XG4gICAgZW5kc3NbaSsrXSA9IGVuZHM7XG4gICAgb2Zmc2V0ID0gZW5kc1tlbmRzLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgZW5kc3MubGVuZ3RoID0gaTtcbiAgcmV0dXJuIGVuZHNzO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL2ZsYXQvc2ltcGxpZnlcbiAqL1xuLy8gQmFzZWQgb24gc2ltcGxpZnktanMgaHR0cHM6Ly9naXRodWIuY29tL21vdXJuZXIvc2ltcGxpZnktanNcbi8vIENvcHlyaWdodCAoYykgMjAxMiwgVmxhZGltaXIgQWdhZm9ua2luXG4vLyBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuLy8gbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4vL1xuLy8gICAgMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuLy8gICAgICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbi8vXG4vLyAgICAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuLy8gICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuLy8gICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbi8vXG4vLyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuLy8gQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuLy8gSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0Vcbi8vIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkVcbi8vIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1Jcbi8vIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GXG4vLyBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1Ncbi8vIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOXG4vLyBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKVxuLy8gQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEVcbi8vIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuaW1wb3J0IHsgc3F1YXJlZERpc3RhbmNlLCBzcXVhcmVkU2VnbWVudERpc3RhbmNlIH0gZnJvbSAnLi4vLi4vbWF0aC5qcyc7XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaGlnaFF1YWxpdHkgSGlnaGVzdCBxdWFsaXR5LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X3NpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgU2ltcGxpZmllZCBmbGF0XG4gKiAgICAgY29vcmRpbmF0ZXMuXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBTaW1wbGlmaWVkIGxpbmUgc3RyaW5nLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzaW1wbGlmeUxpbmVTdHJpbmcoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBzcXVhcmVkVG9sZXJhbmNlLCBoaWdoUXVhbGl0eSwgb3B0X3NpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMpIHtcbiAgdmFyIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgPSBvcHRfc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcyAhPT0gdW5kZWZpbmVkID8gb3B0X3NpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgOiBbXTtcblxuICBpZiAoIWhpZ2hRdWFsaXR5KSB7XG4gICAgZW5kID0gcmFkaWFsRGlzdGFuY2UoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBzcXVhcmVkVG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCAwKTtcbiAgICBmbGF0Q29vcmRpbmF0ZXMgPSBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzO1xuICAgIG9mZnNldCA9IDA7XG4gICAgc3RyaWRlID0gMjtcbiAgfVxuXG4gIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMubGVuZ3RoID0gZG91Z2xhc1BldWNrZXIoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBzcXVhcmVkVG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCAwKTtcbiAgcmV0dXJuIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXM7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcyBTaW1wbGlmaWVkIGZsYXRcbiAqICAgICBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzaW1wbGlmaWVkT2Zmc2V0IFNpbXBsaWZpZWQgb2Zmc2V0LlxuICogQHJldHVybiB7bnVtYmVyfSBTaW1wbGlmaWVkIG9mZnNldC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZG91Z2xhc1BldWNrZXIoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBzcXVhcmVkVG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBzaW1wbGlmaWVkT2Zmc2V0KSB7XG4gIHZhciBuID0gKGVuZCAtIG9mZnNldCkgLyBzdHJpZGU7XG5cbiAgaWYgKG4gPCAzKSB7XG4gICAgZm9yICg7IG9mZnNldCA8IGVuZDsgb2Zmc2V0ICs9IHN0cmlkZSkge1xuICAgICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0gZmxhdENvb3JkaW5hdGVzW29mZnNldF07XG4gICAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHNpbXBsaWZpZWRPZmZzZXQ7XG4gIH1cbiAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuXG5cbiAgdmFyIG1hcmtlcnMgPSBuZXcgQXJyYXkobik7XG4gIG1hcmtlcnNbMF0gPSAxO1xuICBtYXJrZXJzW24gLSAxXSA9IDE7XG4gIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cblxuICB2YXIgc3RhY2sgPSBbb2Zmc2V0LCBlbmQgLSBzdHJpZGVdO1xuICB2YXIgaW5kZXggPSAwO1xuXG4gIHdoaWxlIChzdGFjay5sZW5ndGggPiAwKSB7XG4gICAgdmFyIGxhc3QgPSBzdGFjay5wb3AoKTtcbiAgICB2YXIgZmlyc3QgPSBzdGFjay5wb3AoKTtcbiAgICB2YXIgbWF4U3F1YXJlZERpc3RhbmNlID0gMDtcbiAgICB2YXIgeDEgPSBmbGF0Q29vcmRpbmF0ZXNbZmlyc3RdO1xuICAgIHZhciB5MSA9IGZsYXRDb29yZGluYXRlc1tmaXJzdCArIDFdO1xuICAgIHZhciB4MiA9IGZsYXRDb29yZGluYXRlc1tsYXN0XTtcbiAgICB2YXIgeTIgPSBmbGF0Q29vcmRpbmF0ZXNbbGFzdCArIDFdO1xuXG4gICAgZm9yICh2YXIgaSA9IGZpcnN0ICsgc3RyaWRlOyBpIDwgbGFzdDsgaSArPSBzdHJpZGUpIHtcbiAgICAgIHZhciB4ID0gZmxhdENvb3JkaW5hdGVzW2ldO1xuICAgICAgdmFyIHkgPSBmbGF0Q29vcmRpbmF0ZXNbaSArIDFdO1xuICAgICAgdmFyIHNxdWFyZWREaXN0YW5jZV8xID0gc3F1YXJlZFNlZ21lbnREaXN0YW5jZSh4LCB5LCB4MSwgeTEsIHgyLCB5Mik7XG5cbiAgICAgIGlmIChzcXVhcmVkRGlzdGFuY2VfMSA+IG1heFNxdWFyZWREaXN0YW5jZSkge1xuICAgICAgICBpbmRleCA9IGk7XG4gICAgICAgIG1heFNxdWFyZWREaXN0YW5jZSA9IHNxdWFyZWREaXN0YW5jZV8xO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtYXhTcXVhcmVkRGlzdGFuY2UgPiBzcXVhcmVkVG9sZXJhbmNlKSB7XG4gICAgICBtYXJrZXJzWyhpbmRleCAtIG9mZnNldCkgLyBzdHJpZGVdID0gMTtcblxuICAgICAgaWYgKGZpcnN0ICsgc3RyaWRlIDwgaW5kZXgpIHtcbiAgICAgICAgc3RhY2sucHVzaChmaXJzdCwgaW5kZXgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5kZXggKyBzdHJpZGUgPCBsYXN0KSB7XG4gICAgICAgIHN0YWNrLnB1c2goaW5kZXgsIGxhc3QpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgaWYgKG1hcmtlcnNbaV0pIHtcbiAgICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBpICogc3RyaWRlXTtcbiAgICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBpICogc3RyaWRlICsgMV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHNpbXBsaWZpZWRPZmZzZXQ7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZW5kcyBFbmRzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcyBTaW1wbGlmaWVkIGZsYXRcbiAqICAgICBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzaW1wbGlmaWVkT2Zmc2V0IFNpbXBsaWZpZWQgb2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBzaW1wbGlmaWVkRW5kcyBTaW1wbGlmaWVkIGVuZHMuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFNpbXBsaWZpZWQgb2Zmc2V0LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkb3VnbGFzUGV1Y2tlckFycmF5KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIHNxdWFyZWRUb2xlcmFuY2UsIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIHNpbXBsaWZpZWRPZmZzZXQsIHNpbXBsaWZpZWRFbmRzKSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmQgPSBlbmRzW2ldO1xuICAgIHNpbXBsaWZpZWRPZmZzZXQgPSBkb3VnbGFzUGV1Y2tlcihmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIHNxdWFyZWRUb2xlcmFuY2UsIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIHNpbXBsaWZpZWRPZmZzZXQpO1xuICAgIHNpbXBsaWZpZWRFbmRzLnB1c2goc2ltcGxpZmllZE9mZnNldCk7XG4gICAgb2Zmc2V0ID0gZW5kO1xuICB9XG5cbiAgcmV0dXJuIHNpbXBsaWZpZWRPZmZzZXQ7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IGVuZHNzIEVuZHNzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcyBTaW1wbGlmaWVkIGZsYXRcbiAqICAgICBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzaW1wbGlmaWVkT2Zmc2V0IFNpbXBsaWZpZWQgb2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gc2ltcGxpZmllZEVuZHNzIFNpbXBsaWZpZWQgZW5kc3MuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFNpbXBsaWZpZWQgb2Zmc2V0LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkb3VnbGFzUGV1Y2tlck11bHRpQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUsIHNxdWFyZWRUb2xlcmFuY2UsIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIHNpbXBsaWZpZWRPZmZzZXQsIHNpbXBsaWZpZWRFbmRzcykge1xuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGVuZHMgPSBlbmRzc1tpXTtcbiAgICB2YXIgc2ltcGxpZmllZEVuZHMgPSBbXTtcbiAgICBzaW1wbGlmaWVkT2Zmc2V0ID0gZG91Z2xhc1BldWNrZXJBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBzcXVhcmVkVG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBzaW1wbGlmaWVkT2Zmc2V0LCBzaW1wbGlmaWVkRW5kcyk7XG4gICAgc2ltcGxpZmllZEVuZHNzLnB1c2goc2ltcGxpZmllZEVuZHMpO1xuICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHJldHVybiBzaW1wbGlmaWVkT2Zmc2V0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgU2ltcGxpZmllZCBmbGF0XG4gKiAgICAgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gc2ltcGxpZmllZE9mZnNldCBTaW1wbGlmaWVkIG9mZnNldC5cbiAqIEByZXR1cm4ge251bWJlcn0gU2ltcGxpZmllZCBvZmZzZXQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJhZGlhbERpc3RhbmNlKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgc3F1YXJlZFRvbGVyYW5jZSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgc2ltcGxpZmllZE9mZnNldCkge1xuICBpZiAoZW5kIDw9IG9mZnNldCArIHN0cmlkZSkge1xuICAgIC8vIHplcm8gb3Igb25lIHBvaW50LCBubyBzaW1wbGlmaWNhdGlvbiBwb3NzaWJsZSwgc28gY29weSBhbmQgcmV0dXJuXG4gICAgZm9yICg7IG9mZnNldCA8IGVuZDsgb2Zmc2V0ICs9IHN0cmlkZSkge1xuICAgICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0gZmxhdENvb3JkaW5hdGVzW29mZnNldF07XG4gICAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHNpbXBsaWZpZWRPZmZzZXQ7XG4gIH1cblxuICB2YXIgeDEgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgdmFyIHkxID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdOyAvLyBjb3B5IGZpcnN0IHBvaW50XG5cbiAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0geDE7XG4gIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IHkxO1xuICB2YXIgeDIgPSB4MTtcbiAgdmFyIHkyID0geTE7XG5cbiAgZm9yIChvZmZzZXQgKz0gc3RyaWRlOyBvZmZzZXQgPCBlbmQ7IG9mZnNldCArPSBzdHJpZGUpIHtcbiAgICB4MiA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXRdO1xuICAgIHkyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuXG4gICAgaWYgKHNxdWFyZWREaXN0YW5jZSh4MSwgeTEsIHgyLCB5MikgPiBzcXVhcmVkVG9sZXJhbmNlKSB7XG4gICAgICAvLyBjb3B5IHBvaW50IGF0IG9mZnNldFxuICAgICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0geDI7XG4gICAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSB5MjtcbiAgICAgIHgxID0geDI7XG4gICAgICB5MSA9IHkyO1xuICAgIH1cbiAgfVxuXG4gIGlmICh4MiAhPSB4MSB8fCB5MiAhPSB5MSkge1xuICAgIC8vIGNvcHkgbGFzdCBwb2ludFxuICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IHgyO1xuICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IHkyO1xuICB9XG5cbiAgcmV0dXJuIHNpbXBsaWZpZWRPZmZzZXQ7XG59XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0b2xlcmFuY2UgVG9sZXJhbmNlLlxuICogQHJldHVybiB7bnVtYmVyfSBSb3VuZGVkIHZhbHVlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzbmFwKHZhbHVlLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIHRvbGVyYW5jZSAqIE1hdGgucm91bmQodmFsdWUgLyB0b2xlcmFuY2UpO1xufVxuLyoqXG4gKiBTaW1wbGlmaWVzIGEgbGluZSBzdHJpbmcgdXNpbmcgYW4gYWxnb3JpdGhtIGRlc2lnbmVkIGJ5IFRpbSBTY2hhdWIuXG4gKiBDb29yZGluYXRlcyBhcmUgc25hcHBlZCB0byB0aGUgbmVhcmVzdCB2YWx1ZSBpbiBhIHZpcnR1YWwgZ3JpZCBhbmRcbiAqIGNvbnNlY3V0aXZlIGR1cGxpY2F0ZSBjb29yZGluYXRlcyBhcmUgZGlzY2FyZGVkLiAgVGhpcyBlZmZlY3RpdmVseSBwcmVzZXJ2ZXNcbiAqIHRvcG9sb2d5IGFzIHRoZSBzaW1wbGlmaWNhdGlvbiBvZiBhbnkgc3Vic2VjdGlvbiBvZiBhIGxpbmUgc3RyaW5nIGlzXG4gKiBpbmRlcGVuZGVudCBvZiB0aGUgcmVzdCBvZiB0aGUgbGluZSBzdHJpbmcuICBUaGlzIG1lYW5zIHRoYXQsIGZvciBleGFtcGxlcyxcbiAqIHRoZSBjb21tb24gZWRnZSBiZXR3ZWVuIHR3byBwb2x5Z29ucyB3aWxsIGJlIHNpbXBsaWZpZWQgdG8gdGhlIHNhbWUgbGluZVxuICogc3RyaW5nIGluZGVwZW5kZW50bHkgaW4gYm90aCBwb2x5Z29ucy4gIFRoaXMgaW1wbGVtZW50YXRpb24gdXNlcyBhIHNpbmdsZVxuICogcGFzcyBvdmVyIHRoZSBjb29yZGluYXRlcyBhbmQgZWxpbWluYXRlcyBpbnRlcm1lZGlhdGUgY29sbGluZWFyIHBvaW50cy5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gdG9sZXJhbmNlIFRvbGVyYW5jZS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcyBTaW1wbGlmaWVkIGZsYXRcbiAqICAgICBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzaW1wbGlmaWVkT2Zmc2V0IFNpbXBsaWZpZWQgb2Zmc2V0LlxuICogQHJldHVybiB7bnVtYmVyfSBTaW1wbGlmaWVkIG9mZnNldC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcXVhbnRpemUoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCB0b2xlcmFuY2UsIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIHNpbXBsaWZpZWRPZmZzZXQpIHtcbiAgLy8gZG8gbm90aGluZyBpZiB0aGUgbGluZSBpcyBlbXB0eVxuICBpZiAob2Zmc2V0ID09IGVuZCkge1xuICAgIHJldHVybiBzaW1wbGlmaWVkT2Zmc2V0O1xuICB9IC8vIHNuYXAgdGhlIGZpcnN0IGNvb3JkaW5hdGUgKFAxKVxuXG5cbiAgdmFyIHgxID0gc25hcChmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XSwgdG9sZXJhbmNlKTtcbiAgdmFyIHkxID0gc25hcChmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV0sIHRvbGVyYW5jZSk7XG4gIG9mZnNldCArPSBzdHJpZGU7IC8vIGFkZCB0aGUgZmlyc3QgY29vcmRpbmF0ZSB0byB0aGUgb3V0cHV0XG5cbiAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0geDE7XG4gIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IHkxOyAvLyBmaW5kIHRoZSBuZXh0IGNvb3JkaW5hdGUgdGhhdCBkb2VzIG5vdCBzbmFwIHRvIHRoZSBzYW1lIHZhbHVlIGFzIHRoZSBmaXJzdFxuICAvLyBjb29yZGluYXRlIChQMilcblxuICB2YXIgeDIsIHkyO1xuXG4gIGRvIHtcbiAgICB4MiA9IHNuYXAoZmxhdENvb3JkaW5hdGVzW29mZnNldF0sIHRvbGVyYW5jZSk7XG4gICAgeTIgPSBzbmFwKGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXSwgdG9sZXJhbmNlKTtcbiAgICBvZmZzZXQgKz0gc3RyaWRlO1xuXG4gICAgaWYgKG9mZnNldCA9PSBlbmQpIHtcbiAgICAgIC8vIGFsbCBjb29yZGluYXRlcyBzbmFwIHRvIHRoZSBzYW1lIHZhbHVlLCB0aGUgbGluZSBjb2xsYXBzZXMgdG8gYSBwb2ludFxuICAgICAgLy8gcHVzaCB0aGUgbGFzdCBzbmFwcGVkIHZhbHVlIGFueXdheSB0byBlbnN1cmUgdGhhdCB0aGUgb3V0cHV0IGNvbnRhaW5zXG4gICAgICAvLyBhdCBsZWFzdCB0d28gcG9pbnRzXG4gICAgICAvLyBGSVhNRSBzaG91bGQgd2UgcmVhbGx5IHJldHVybiBhdCBsZWFzdCB0d28gcG9pbnRzIGFueXdheT9cbiAgICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IHgyO1xuICAgICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0geTI7XG4gICAgICByZXR1cm4gc2ltcGxpZmllZE9mZnNldDtcbiAgICB9XG4gIH0gd2hpbGUgKHgyID09IHgxICYmIHkyID09IHkxKTtcblxuICB3aGlsZSAob2Zmc2V0IDwgZW5kKSB7XG4gICAgLy8gc25hcCB0aGUgbmV4dCBjb29yZGluYXRlIChQMylcbiAgICB2YXIgeDMgPSBzbmFwKGZsYXRDb29yZGluYXRlc1tvZmZzZXRdLCB0b2xlcmFuY2UpO1xuICAgIHZhciB5MyA9IHNuYXAoZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdLCB0b2xlcmFuY2UpO1xuICAgIG9mZnNldCArPSBzdHJpZGU7IC8vIHNraXAgUDMgaWYgaXQgaXMgZXF1YWwgdG8gUDJcblxuICAgIGlmICh4MyA9PSB4MiAmJiB5MyA9PSB5Mikge1xuICAgICAgY29udGludWU7XG4gICAgfSAvLyBjYWxjdWxhdGUgdGhlIGRlbHRhIGJldHdlZW4gUDEgYW5kIFAyXG5cblxuICAgIHZhciBkeDEgPSB4MiAtIHgxO1xuICAgIHZhciBkeTEgPSB5MiAtIHkxOyAvLyBjYWxjdWxhdGUgdGhlIGRlbHRhIGJldHdlZW4gUDMgYW5kIFAxXG5cbiAgICB2YXIgZHgyID0geDMgLSB4MTtcbiAgICB2YXIgZHkyID0geTMgLSB5MTsgLy8gaWYgUDEsIFAyLCBhbmQgUDMgYXJlIGNvbGluZWFyIGFuZCBQMyBpcyBmdXJ0aGVyIGZyb20gUDEgdGhhbiBQMiBpcyBmcm9tXG4gICAgLy8gUDEgaW4gdGhlIHNhbWUgZGlyZWN0aW9uIHRoZW4gUDIgaXMgb24gdGhlIHN0cmFpZ2h0IGxpbmUgYmV0d2VlbiBQMSBhbmRcbiAgICAvLyBQM1xuXG4gICAgaWYgKGR4MSAqIGR5MiA9PSBkeTEgKiBkeDIgJiYgKGR4MSA8IDAgJiYgZHgyIDwgZHgxIHx8IGR4MSA9PSBkeDIgfHwgZHgxID4gMCAmJiBkeDIgPiBkeDEpICYmIChkeTEgPCAwICYmIGR5MiA8IGR5MSB8fCBkeTEgPT0gZHkyIHx8IGR5MSA+IDAgJiYgZHkyID4gZHkxKSkge1xuICAgICAgLy8gZGlzY2FyZCBQMiBhbmQgc2V0IFAyID0gUDNcbiAgICAgIHgyID0geDM7XG4gICAgICB5MiA9IHkzO1xuICAgICAgY29udGludWU7XG4gICAgfSAvLyBlaXRoZXIgUDEsIFAyLCBhbmQgUDMgYXJlIG5vdCBjb2xpbmVhciwgb3IgdGhleSBhcmUgY29saW5lYXIgYnV0IFAzIGlzXG4gICAgLy8gYmV0d2VlbiBQMyBhbmQgUDEgb3Igb24gdGhlIG9wcG9zaXRlIGhhbGYgb2YgdGhlIGxpbmUgdG8gUDIuICBhZGQgUDIsXG4gICAgLy8gYW5kIGNvbnRpbnVlIHdpdGggUDEgPSBQMiBhbmQgUDIgPSBQM1xuXG5cbiAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSB4MjtcbiAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSB5MjtcbiAgICB4MSA9IHgyO1xuICAgIHkxID0geTI7XG4gICAgeDIgPSB4MztcbiAgICB5MiA9IHkzO1xuICB9IC8vIGFkZCB0aGUgbGFzdCBwb2ludCAoUDIpXG5cblxuICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSB4MjtcbiAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0geTI7XG4gIHJldHVybiBzaW1wbGlmaWVkT2Zmc2V0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHRvbGVyYW5jZSBUb2xlcmFuY2UuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgU2ltcGxpZmllZCBmbGF0XG4gKiAgICAgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gc2ltcGxpZmllZE9mZnNldCBTaW1wbGlmaWVkIG9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gc2ltcGxpZmllZEVuZHMgU2ltcGxpZmllZCBlbmRzLlxuICogQHJldHVybiB7bnVtYmVyfSBTaW1wbGlmaWVkIG9mZnNldC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcXVhbnRpemVBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCB0b2xlcmFuY2UsIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIHNpbXBsaWZpZWRPZmZzZXQsIHNpbXBsaWZpZWRFbmRzKSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmQgPSBlbmRzW2ldO1xuICAgIHNpbXBsaWZpZWRPZmZzZXQgPSBxdWFudGl6ZShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIHRvbGVyYW5jZSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgc2ltcGxpZmllZE9mZnNldCk7XG4gICAgc2ltcGxpZmllZEVuZHMucHVzaChzaW1wbGlmaWVkT2Zmc2V0KTtcbiAgICBvZmZzZXQgPSBlbmQ7XG4gIH1cblxuICByZXR1cm4gc2ltcGxpZmllZE9mZnNldDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gZW5kc3MgRW5kc3MuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0b2xlcmFuY2UgVG9sZXJhbmNlLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzIFNpbXBsaWZpZWQgZmxhdFxuICogICAgIGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IHNpbXBsaWZpZWRPZmZzZXQgU2ltcGxpZmllZCBvZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBzaW1wbGlmaWVkRW5kc3MgU2ltcGxpZmllZCBlbmRzcy5cbiAqIEByZXR1cm4ge251bWJlcn0gU2ltcGxpZmllZCBvZmZzZXQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHF1YW50aXplTXVsdGlBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc3MsIHN0cmlkZSwgdG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBzaW1wbGlmaWVkT2Zmc2V0LCBzaW1wbGlmaWVkRW5kc3MpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kc3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmRzID0gZW5kc3NbaV07XG4gICAgdmFyIHNpbXBsaWZpZWRFbmRzID0gW107XG4gICAgc2ltcGxpZmllZE9mZnNldCA9IHF1YW50aXplQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgdG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBzaW1wbGlmaWVkT2Zmc2V0LCBzaW1wbGlmaWVkRW5kcyk7XG4gICAgc2ltcGxpZmllZEVuZHNzLnB1c2goc2ltcGxpZmllZEVuZHMpO1xuICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHJldHVybiBzaW1wbGlmaWVkT2Zmc2V0O1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL2ZsYXQvaW5mbGF0ZVxuICovXG5cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj19IG9wdF9jb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IENvb3JkaW5hdGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5mbGF0ZUNvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgb3B0X2Nvb3JkaW5hdGVzKSB7XG4gIHZhciBjb29yZGluYXRlcyA9IG9wdF9jb29yZGluYXRlcyAhPT0gdW5kZWZpbmVkID8gb3B0X2Nvb3JkaW5hdGVzIDogW107XG4gIHZhciBpID0gMDtcblxuICBmb3IgKHZhciBqID0gb2Zmc2V0OyBqIDwgZW5kOyBqICs9IHN0cmlkZSkge1xuICAgIGNvb3JkaW5hdGVzW2krK10gPSBmbGF0Q29vcmRpbmF0ZXMuc2xpY2UoaiwgaiArIHN0cmlkZSk7XG4gIH1cblxuICBjb29yZGluYXRlcy5sZW5ndGggPSBpO1xuICByZXR1cm4gY29vcmRpbmF0ZXM7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZW5kcyBFbmRzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+PX0gb3B0X2Nvb3JkaW5hdGVzcyBDb29yZGluYXRlc3MuXG4gKiBAcmV0dXJuIHtBcnJheTxBcnJheTxpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pn0gQ29vcmRpbmF0ZXNzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpbmZsYXRlQ29vcmRpbmF0ZXNBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBvcHRfY29vcmRpbmF0ZXNzKSB7XG4gIHZhciBjb29yZGluYXRlc3MgPSBvcHRfY29vcmRpbmF0ZXNzICE9PSB1bmRlZmluZWQgPyBvcHRfY29vcmRpbmF0ZXNzIDogW107XG4gIHZhciBpID0gMDtcblxuICBmb3IgKHZhciBqID0gMCwgamogPSBlbmRzLmxlbmd0aDsgaiA8IGpqOyArK2opIHtcbiAgICB2YXIgZW5kID0gZW5kc1tqXTtcbiAgICBjb29yZGluYXRlc3NbaSsrXSA9IGluZmxhdGVDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGNvb3JkaW5hdGVzc1tpXSk7XG4gICAgb2Zmc2V0ID0gZW5kO1xuICB9XG5cbiAgY29vcmRpbmF0ZXNzLmxlbmd0aCA9IGk7XG4gIHJldHVybiBjb29yZGluYXRlc3M7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IGVuZHNzIEVuZHNzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PEFycmF5PGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+Pj19IG9wdF9jb29yZGluYXRlc3NzXG4gKiAgICAgQ29vcmRpbmF0ZXNzcy5cbiAqIEByZXR1cm4ge0FycmF5PEFycmF5PEFycmF5PGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+Pn0gQ29vcmRpbmF0ZXNzcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW5mbGF0ZU11bHRpQ29vcmRpbmF0ZXNBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc3MsIHN0cmlkZSwgb3B0X2Nvb3JkaW5hdGVzc3MpIHtcbiAgdmFyIGNvb3JkaW5hdGVzc3MgPSBvcHRfY29vcmRpbmF0ZXNzcyAhPT0gdW5kZWZpbmVkID8gb3B0X2Nvb3JkaW5hdGVzc3MgOiBbXTtcbiAgdmFyIGkgPSAwO1xuXG4gIGZvciAodmFyIGogPSAwLCBqaiA9IGVuZHNzLmxlbmd0aDsgaiA8IGpqOyArK2opIHtcbiAgICB2YXIgZW5kcyA9IGVuZHNzW2pdO1xuICAgIGNvb3JkaW5hdGVzc3NbaSsrXSA9IGluZmxhdGVDb29yZGluYXRlc0FycmF5KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIGNvb3JkaW5hdGVzc3NbaV0pO1xuICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIGNvb3JkaW5hdGVzc3MubGVuZ3RoID0gaTtcbiAgcmV0dXJuIGNvb3JkaW5hdGVzc3M7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vZmxhdC9hcmVhXG4gKi9cblxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7bnVtYmVyfSBBcmVhLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGluZWFyUmluZyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUpIHtcbiAgdmFyIHR3aWNlQXJlYSA9IDA7XG4gIHZhciB4MSA9IGZsYXRDb29yZGluYXRlc1tlbmQgLSBzdHJpZGVdO1xuICB2YXIgeTEgPSBmbGF0Q29vcmRpbmF0ZXNbZW5kIC0gc3RyaWRlICsgMV07XG5cbiAgZm9yICg7IG9mZnNldCA8IGVuZDsgb2Zmc2V0ICs9IHN0cmlkZSkge1xuICAgIHZhciB4MiA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXRdO1xuICAgIHZhciB5MiA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXTtcbiAgICB0d2ljZUFyZWEgKz0geTEgKiB4MiAtIHgxICogeTI7XG4gICAgeDEgPSB4MjtcbiAgICB5MSA9IHkyO1xuICB9XG5cbiAgcmV0dXJuIHR3aWNlQXJlYSAvIDI7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZW5kcyBFbmRzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEFyZWEuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclJpbmdzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUpIHtcbiAgdmFyIGFyZWEgPSAwO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmQgPSBlbmRzW2ldO1xuICAgIGFyZWEgKz0gbGluZWFyUmluZyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUpO1xuICAgIG9mZnNldCA9IGVuZDtcbiAgfVxuXG4gIHJldHVybiBhcmVhO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBFbmRzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7bnVtYmVyfSBBcmVhLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5nc3MoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUpIHtcbiAgdmFyIGFyZWEgPSAwO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHNzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kcyA9IGVuZHNzW2ldO1xuICAgIGFyZWEgKz0gbGluZWFyUmluZ3MoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSk7XG4gICAgb2Zmc2V0ID0gZW5kc1tlbmRzLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgcmV0dXJuIGFyZWE7XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL0xpbmVhclJpbmdcbiAqL1xuXG5cbmltcG9ydCBHZW9tZXRyeUxheW91dCBmcm9tICcuL0dlb21ldHJ5TGF5b3V0LmpzJztcbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IFNpbXBsZUdlb21ldHJ5IGZyb20gJy4vU2ltcGxlR2VvbWV0cnkuanMnO1xuaW1wb3J0IHsgYXNzaWduQ2xvc2VzdFBvaW50LCBtYXhTcXVhcmVkRGVsdGEgfSBmcm9tICcuL2ZsYXQvY2xvc2VzdC5qcyc7XG5pbXBvcnQgeyBjbG9zZXN0U3F1YXJlZERpc3RhbmNlWFkgfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZGVmbGF0ZUNvb3JkaW5hdGVzIH0gZnJvbSAnLi9mbGF0L2RlZmxhdGUuanMnO1xuaW1wb3J0IHsgZG91Z2xhc1BldWNrZXIgfSBmcm9tICcuL2ZsYXQvc2ltcGxpZnkuanMnO1xuaW1wb3J0IHsgaW5mbGF0ZUNvb3JkaW5hdGVzIH0gZnJvbSAnLi9mbGF0L2luZmxhdGUuanMnO1xuaW1wb3J0IHsgbGluZWFyUmluZyBhcyBsaW5lYXJSaW5nQXJlYSB9IGZyb20gJy4vZmxhdC9hcmVhLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogTGluZWFyIHJpbmcgZ2VvbWV0cnkuIE9ubHkgdXNlZCBhcyBwYXJ0IG9mIHBvbHlnb247IGNhbm5vdCBiZSByZW5kZXJlZFxuICogb24gaXRzIG93bi5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIExpbmVhclJpbmcgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoTGluZWFyUmluZywgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPnxBcnJheTxudW1iZXI+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAgICogICAgIEZvciBpbnRlcm5hbCB1c2UsIGZsYXQgY29vcmRpbmF0ZXMgaW4gY29tYmluYXRpb24gd2l0aCBgb3B0X2xheW91dGAgYXJlIGFsc28gYWNjZXB0ZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9HZW9tZXRyeUxheW91dC5qc1wiKS5kZWZhdWx0PX0gb3B0X2xheW91dCBMYXlvdXQuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gTGluZWFyUmluZyhjb29yZGluYXRlcywgb3B0X2xheW91dCkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5tYXhEZWx0YV8gPSAtMTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5tYXhEZWx0YVJldmlzaW9uXyA9IC0xO1xuXG4gICAgaWYgKG9wdF9sYXlvdXQgIT09IHVuZGVmaW5lZCAmJiAhQXJyYXkuaXNBcnJheShjb29yZGluYXRlc1swXSkpIHtcbiAgICAgIF90aGlzLnNldEZsYXRDb29yZGluYXRlcyhvcHRfbGF5b3V0LFxuICAgICAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuICAgICAgY29vcmRpbmF0ZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBfdGhpcy5zZXRDb29yZGluYXRlcyhcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzLCBvcHRfbGF5b3V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIE1ha2UgYSBjb21wbGV0ZSBjb3B5IG9mIHRoZSBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7IUxpbmVhclJpbmd9IENsb25lLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTGluZWFyUmluZy5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBMaW5lYXJSaW5nKHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKCksIHRoaXMubGF5b3V0KTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjbG9zZXN0UG9pbnQgQ2xvc2VzdCBwb2ludC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblNxdWFyZWREaXN0YW5jZSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKi9cblxuXG4gIExpbmVhclJpbmcucHJvdG90eXBlLmNsb3Nlc3RQb2ludFhZID0gZnVuY3Rpb24gKHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgaWYgKG1pblNxdWFyZWREaXN0YW5jZSA8IGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWSh0aGlzLmdldEV4dGVudCgpLCB4LCB5KSkge1xuICAgICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tYXhEZWx0YVJldmlzaW9uXyAhPSB0aGlzLmdldFJldmlzaW9uKCkpIHtcbiAgICAgIHRoaXMubWF4RGVsdGFfID0gTWF0aC5zcXJ0KG1heFNxdWFyZWREZWx0YSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSwgMCkpO1xuICAgICAgdGhpcy5tYXhEZWx0YVJldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXNzaWduQ2xvc2VzdFBvaW50KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHRoaXMuc3RyaWRlLCB0aGlzLm1heERlbHRhXywgdHJ1ZSwgeCwgeSwgY2xvc2VzdFBvaW50LCBtaW5TcXVhcmVkRGlzdGFuY2UpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBhcmVhIG9mIHRoZSBsaW5lYXIgcmluZyBvbiBwcm9qZWN0ZWQgcGxhbmUuXG4gICAqIEByZXR1cm4ge251bWJlcn0gQXJlYSAob24gcHJvamVjdGVkIHBsYW5lKS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVhclJpbmcucHJvdG90eXBlLmdldEFyZWEgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGxpbmVhclJpbmdBcmVhKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHRoaXMuc3RyaWRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIGxpbmVhciByaW5nLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSBDb29yZGluYXRlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVhclJpbmcucHJvdG90eXBlLmdldENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBpbmZsYXRlQ29vcmRpbmF0ZXModGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgdGhpcy5zdHJpZGUpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge0xpbmVhclJpbmd9IFNpbXBsaWZpZWQgTGluZWFyUmluZy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIExpbmVhclJpbmcucHJvdG90eXBlLmdldFNpbXBsaWZpZWRHZW9tZXRyeUludGVybmFsID0gZnVuY3Rpb24gKHNxdWFyZWRUb2xlcmFuY2UpIHtcbiAgICB2YXIgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMubGVuZ3RoID0gZG91Z2xhc1BldWNrZXIodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgdGhpcy5zdHJpZGUsIHNxdWFyZWRUb2xlcmFuY2UsIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIDApO1xuICAgIHJldHVybiBuZXcgTGluZWFyUmluZyhzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBHZW9tZXRyeUxheW91dC5YWSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhpcyBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkgdHlwZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVhclJpbmcucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIEdlb21ldHJ5VHlwZS5MSU5FQVJfUklORztcbiAgfTtcbiAgLyoqXG4gICAqIFRlc3QgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgcGFzc2VkIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lYXJSaW5nLnByb3RvdHlwZS5pbnRlcnNlY3RzRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIGxpbmVhciByaW5nLlxuICAgKiBAcGFyYW0geyFBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHQ9fSBvcHRfbGF5b3V0IExheW91dC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVhclJpbmcucHJvdG90eXBlLnNldENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKGNvb3JkaW5hdGVzLCBvcHRfbGF5b3V0KSB7XG4gICAgdGhpcy5zZXRMYXlvdXQob3B0X2xheW91dCwgY29vcmRpbmF0ZXMsIDEpO1xuXG4gICAgaWYgKCF0aGlzLmZsYXRDb29yZGluYXRlcykge1xuICAgICAgdGhpcy5mbGF0Q29vcmRpbmF0ZXMgPSBbXTtcbiAgICB9XG5cbiAgICB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggPSBkZWZsYXRlQ29vcmRpbmF0ZXModGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIGNvb3JkaW5hdGVzLCB0aGlzLnN0cmlkZSk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG5cbiAgcmV0dXJuIExpbmVhclJpbmc7XG59KFNpbXBsZUdlb21ldHJ5KTtcblxuZXhwb3J0IGRlZmF1bHQgTGluZWFyUmluZzsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vUG9pbnRcbiAqL1xuXG5cbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IFNpbXBsZUdlb21ldHJ5IGZyb20gJy4vU2ltcGxlR2VvbWV0cnkuanMnO1xuaW1wb3J0IHsgY29udGFpbnNYWSwgY3JlYXRlT3JVcGRhdGVGcm9tQ29vcmRpbmF0ZSB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBkZWZsYXRlQ29vcmRpbmF0ZSB9IGZyb20gJy4vZmxhdC9kZWZsYXRlLmpzJztcbmltcG9ydCB7IHNxdWFyZWREaXN0YW5jZSBhcyBzcXVhcmVkRHggfSBmcm9tICcuLi9tYXRoLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogUG9pbnQgZ2VvbWV0cnkuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBQb2ludCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhQb2ludCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHQ9fSBvcHRfbGF5b3V0IExheW91dC5cbiAgICovXG5cblxuICBmdW5jdGlvbiBQb2ludChjb29yZGluYXRlcywgb3B0X2xheW91dCkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG5cbiAgICBfdGhpcy5zZXRDb29yZGluYXRlcyhjb29yZGluYXRlcywgb3B0X2xheW91dCk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIE1ha2UgYSBjb21wbGV0ZSBjb3B5IG9mIHRoZSBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7IVBvaW50fSBDbG9uZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvaW50LnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcG9pbnQgPSBuZXcgUG9pbnQodGhpcy5mbGF0Q29vcmRpbmF0ZXMuc2xpY2UoKSwgdGhpcy5sYXlvdXQpO1xuICAgIHBvaW50LmFwcGx5UHJvcGVydGllcyh0aGlzKTtcbiAgICByZXR1cm4gcG9pbnQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY2xvc2VzdFBvaW50IENsb3Nlc3QgcG9pbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtaW5TcXVhcmVkRGlzdGFuY2UgTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAgICovXG5cblxuICBQb2ludC5wcm90b3R5cGUuY2xvc2VzdFBvaW50WFkgPSBmdW5jdGlvbiAoeCwgeSwgY2xvc2VzdFBvaW50LCBtaW5TcXVhcmVkRGlzdGFuY2UpIHtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgdmFyIHNxdWFyZWREaXN0YW5jZSA9IHNxdWFyZWREeCh4LCB5LCBmbGF0Q29vcmRpbmF0ZXNbMF0sIGZsYXRDb29yZGluYXRlc1sxXSk7XG5cbiAgICBpZiAoc3F1YXJlZERpc3RhbmNlIDwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgICB2YXIgc3RyaWRlID0gdGhpcy5zdHJpZGU7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaWRlOyArK2kpIHtcbiAgICAgICAgY2xvc2VzdFBvaW50W2ldID0gZmxhdENvb3JkaW5hdGVzW2ldO1xuICAgICAgfVxuXG4gICAgICBjbG9zZXN0UG9pbnQubGVuZ3RoID0gc3RyaWRlO1xuICAgICAgcmV0dXJuIHNxdWFyZWREaXN0YW5jZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IENvb3JkaW5hdGVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9pbnQucHJvdG90eXBlLmdldENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhdGhpcy5mbGF0Q29vcmRpbmF0ZXMgPyBbXSA6IHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICovXG5cblxuICBQb2ludC5wcm90b3R5cGUuY29tcHV0ZUV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICByZXR1cm4gY3JlYXRlT3JVcGRhdGVGcm9tQ29vcmRpbmF0ZSh0aGlzLmZsYXRDb29yZGluYXRlcywgZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdHlwZSBvZiB0aGlzIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeSB0eXBlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9pbnQucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIEdlb21ldHJ5VHlwZS5QT0lOVDtcbiAgfTtcbiAgLyoqXG4gICAqIFRlc3QgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgcGFzc2VkIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQb2ludC5wcm90b3R5cGUuaW50ZXJzZWN0c0V4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICByZXR1cm4gY29udGFpbnNYWShleHRlbnQsIHRoaXMuZmxhdENvb3JkaW5hdGVzWzBdLCB0aGlzLmZsYXRDb29yZGluYXRlc1sxXSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0geyFBcnJheTwqPn0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9HZW9tZXRyeUxheW91dC5qc1wiKS5kZWZhdWx0PX0gb3B0X2xheW91dCBMYXlvdXQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQb2ludC5wcm90b3R5cGUuc2V0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB0aGlzLnNldExheW91dChvcHRfbGF5b3V0LCBjb29yZGluYXRlcywgMCk7XG5cbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIH1cblxuICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IGRlZmxhdGVDb29yZGluYXRlKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCBjb29yZGluYXRlcywgdGhpcy5zdHJpZGUpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuXG4gIHJldHVybiBQb2ludDtcbn0oU2ltcGxlR2VvbWV0cnkpO1xuXG5leHBvcnQgZGVmYXVsdCBQb2ludDsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L2NvbnRhaW5zXG4gKi9cbmltcG9ydCB7IGZvckVhY2hDb3JuZXIgfSBmcm9tICcuLi8uLi9leHRlbnQuanMnO1xuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMgZXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5nQ29udGFpbnNFeHRlbnQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBleHRlbnQpIHtcbiAgdmFyIG91dHNpZGUgPSBmb3JFYWNoQ29ybmVyKGV4dGVudCxcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IENvbnRhaW5zICh4LCB5KS5cbiAgICovXG4gIGZ1bmN0aW9uIChjb29yZGluYXRlKSB7XG4gICAgcmV0dXJuICFsaW5lYXJSaW5nQ29udGFpbnNYWShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGNvb3JkaW5hdGVbMF0sIGNvb3JkaW5hdGVbMV0pO1xuICB9KTtcbiAgcmV0dXJuICFvdXRzaWRlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gKiBAcmV0dXJuIHtib29sZWFufSBDb250YWlucyAoeCwgeSkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclJpbmdDb250YWluc1hZKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgeCwgeSkge1xuICAvLyBodHRwOi8vZ2VvbWFsZ29yaXRobXMuY29tL2EwMy1faW5jbHVzaW9uLmh0bWxcbiAgLy8gQ29weXJpZ2h0IDIwMDAgc29mdFN1cmZlciwgMjAxMiBEYW4gU3VuZGF5XG4gIC8vIFRoaXMgY29kZSBtYXkgYmUgZnJlZWx5IHVzZWQgYW5kIG1vZGlmaWVkIGZvciBhbnkgcHVycG9zZVxuICAvLyBwcm92aWRpbmcgdGhhdCB0aGlzIGNvcHlyaWdodCBub3RpY2UgaXMgaW5jbHVkZWQgd2l0aCBpdC5cbiAgLy8gU29mdFN1cmZlciBtYWtlcyBubyB3YXJyYW50eSBmb3IgdGhpcyBjb2RlLCBhbmQgY2Fubm90IGJlIGhlbGRcbiAgLy8gbGlhYmxlIGZvciBhbnkgcmVhbCBvciBpbWFnaW5lZCBkYW1hZ2UgcmVzdWx0aW5nIGZyb20gaXRzIHVzZS5cbiAgLy8gVXNlcnMgb2YgdGhpcyBjb2RlIG11c3QgdmVyaWZ5IGNvcnJlY3RuZXNzIGZvciB0aGVpciBhcHBsaWNhdGlvbi5cbiAgdmFyIHduID0gMDtcbiAgdmFyIHgxID0gZmxhdENvb3JkaW5hdGVzW2VuZCAtIHN0cmlkZV07XG4gIHZhciB5MSA9IGZsYXRDb29yZGluYXRlc1tlbmQgLSBzdHJpZGUgKyAxXTtcblxuICBmb3IgKDsgb2Zmc2V0IDwgZW5kOyBvZmZzZXQgKz0gc3RyaWRlKSB7XG4gICAgdmFyIHgyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldF07XG4gICAgdmFyIHkyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuXG4gICAgaWYgKHkxIDw9IHkpIHtcbiAgICAgIGlmICh5MiA+IHkgJiYgKHgyIC0geDEpICogKHkgLSB5MSkgLSAoeCAtIHgxKSAqICh5MiAtIHkxKSA+IDApIHtcbiAgICAgICAgd24rKztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHkyIDw9IHkgJiYgKHgyIC0geDEpICogKHkgLSB5MSkgLSAoeCAtIHgxKSAqICh5MiAtIHkxKSA8IDApIHtcbiAgICAgIHduLS07XG4gICAgfVxuXG4gICAgeDEgPSB4MjtcbiAgICB5MSA9IHkyO1xuICB9XG5cbiAgcmV0dXJuIHduICE9PSAwO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gKiBAcmV0dXJuIHtib29sZWFufSBDb250YWlucyAoeCwgeSkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclJpbmdzQ29udGFpbnNYWShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCB4LCB5KSB7XG4gIGlmIChlbmRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmICghbGluZWFyUmluZ0NvbnRhaW5zWFkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNbMF0sIHN0cmlkZSwgeCwgeSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMSwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICBpZiAobGluZWFyUmluZ0NvbnRhaW5zWFkoZmxhdENvb3JkaW5hdGVzLCBlbmRzW2kgLSAxXSwgZW5kc1tpXSwgc3RyaWRlLCB4LCB5KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBFbmRzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gKiBAcmV0dXJuIHtib29sZWFufSBDb250YWlucyAoeCwgeSkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclJpbmdzc0NvbnRhaW5zWFkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUsIHgsIHkpIHtcbiAgaWYgKGVuZHNzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHNzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kcyA9IGVuZHNzW2ldO1xuXG4gICAgaWYgKGxpbmVhclJpbmdzQ29udGFpbnNYWShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCB4LCB5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgb2Zmc2V0ID0gZW5kc1tlbmRzLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL2ZsYXQvaW50ZXJpb3Jwb2ludFxuICovXG5pbXBvcnQgeyBsaW5lYXJSaW5nc0NvbnRhaW5zWFkgfSBmcm9tICcuL2NvbnRhaW5zLmpzJztcbmltcG9ydCB7IG51bWJlclNhZmVDb21wYXJlRnVuY3Rpb24gfSBmcm9tICcuLi8uLi9hcnJheS5qcyc7XG4vKipcbiAqIENhbGN1bGF0ZXMgYSBwb2ludCB0aGF0IGlzIGxpa2VseSB0byBsaWUgaW4gdGhlIGludGVyaW9yIG9mIHRoZSBsaW5lYXIgcmluZ3MuXG4gKiBJbnNwaXJlZCBieSBKVFMncyBjb20udml2aWRzb2x1dGlvbnMuanRzLmdlb20uR2VvbWV0cnkjZ2V0SW50ZXJpb3JQb2ludC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZW5kcyBFbmRzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDZW50ZXJzIEZsYXQgY2VudGVycy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmbGF0Q2VudGVyc09mZnNldCBGbGF0IGNlbnRlciBvZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfZGVzdCBEZXN0aW5hdGlvbi5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IERlc3RpbmF0aW9uIHBvaW50IGFzIFhZTSBjb29yZGluYXRlLCB3aGVyZSBNIGlzIHRoZVxuICogbGVuZ3RoIG9mIHRoZSBob3Jpem9udGFsIGludGVyc2VjdGlvbiB0aGF0IHRoZSBwb2ludCBiZWxvbmdzIHRvLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbnRlcmlvclBvaW50T2ZBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBmbGF0Q2VudGVycywgZmxhdENlbnRlcnNPZmZzZXQsIG9wdF9kZXN0KSB7XG4gIHZhciBpLCBpaSwgeCwgeDEsIHgyLCB5MSwgeTI7XG4gIHZhciB5ID0gZmxhdENlbnRlcnNbZmxhdENlbnRlcnNPZmZzZXQgKyAxXTtcbiAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuXG4gIHZhciBpbnRlcnNlY3Rpb25zID0gW107IC8vIENhbGN1bGF0ZSBpbnRlcnNlY3Rpb25zIHdpdGggdGhlIGhvcml6b250YWwgbGluZVxuXG4gIGZvciAodmFyIHIgPSAwLCByciA9IGVuZHMubGVuZ3RoOyByIDwgcnI7ICsrcikge1xuICAgIHZhciBlbmQgPSBlbmRzW3JdO1xuICAgIHgxID0gZmxhdENvb3JkaW5hdGVzW2VuZCAtIHN0cmlkZV07XG4gICAgeTEgPSBmbGF0Q29vcmRpbmF0ZXNbZW5kIC0gc3RyaWRlICsgMV07XG5cbiAgICBmb3IgKGkgPSBvZmZzZXQ7IGkgPCBlbmQ7IGkgKz0gc3RyaWRlKSB7XG4gICAgICB4MiA9IGZsYXRDb29yZGluYXRlc1tpXTtcbiAgICAgIHkyID0gZmxhdENvb3JkaW5hdGVzW2kgKyAxXTtcblxuICAgICAgaWYgKHkgPD0geTEgJiYgeTIgPD0geSB8fCB5MSA8PSB5ICYmIHkgPD0geTIpIHtcbiAgICAgICAgeCA9ICh5IC0geTEpIC8gKHkyIC0geTEpICogKHgyIC0geDEpICsgeDE7XG4gICAgICAgIGludGVyc2VjdGlvbnMucHVzaCh4KTtcbiAgICAgIH1cblxuICAgICAgeDEgPSB4MjtcbiAgICAgIHkxID0geTI7XG4gICAgfVxuICB9IC8vIEZpbmQgdGhlIGxvbmdlc3Qgc2VnbWVudCBvZiB0aGUgaG9yaXpvbnRhbCBsaW5lIHRoYXQgaGFzIGl0cyBjZW50ZXIgcG9pbnRcbiAgLy8gaW5zaWRlIHRoZSBsaW5lYXIgcmluZy5cblxuXG4gIHZhciBwb2ludFggPSBOYU47XG4gIHZhciBtYXhTZWdtZW50TGVuZ3RoID0gLUluZmluaXR5O1xuICBpbnRlcnNlY3Rpb25zLnNvcnQobnVtYmVyU2FmZUNvbXBhcmVGdW5jdGlvbik7XG4gIHgxID0gaW50ZXJzZWN0aW9uc1swXTtcblxuICBmb3IgKGkgPSAxLCBpaSA9IGludGVyc2VjdGlvbnMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHgyID0gaW50ZXJzZWN0aW9uc1tpXTtcbiAgICB2YXIgc2VnbWVudExlbmd0aCA9IE1hdGguYWJzKHgyIC0geDEpO1xuXG4gICAgaWYgKHNlZ21lbnRMZW5ndGggPiBtYXhTZWdtZW50TGVuZ3RoKSB7XG4gICAgICB4ID0gKHgxICsgeDIpIC8gMjtcblxuICAgICAgaWYgKGxpbmVhclJpbmdzQ29udGFpbnNYWShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCB4LCB5KSkge1xuICAgICAgICBwb2ludFggPSB4O1xuICAgICAgICBtYXhTZWdtZW50TGVuZ3RoID0gc2VnbWVudExlbmd0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB4MSA9IHgyO1xuICB9XG5cbiAgaWYgKGlzTmFOKHBvaW50WCkpIHtcbiAgICAvLyBUaGVyZSBpcyBubyBob3Jpem9udGFsIGxpbmUgdGhhdCBoYXMgaXRzIGNlbnRlciBwb2ludCBpbnNpZGUgdGhlIGxpbmVhclxuICAgIC8vIHJpbmcuICBVc2UgdGhlIGNlbnRlciBvZiB0aGUgdGhlIGxpbmVhciByaW5nJ3MgZXh0ZW50LlxuICAgIHBvaW50WCA9IGZsYXRDZW50ZXJzW2ZsYXRDZW50ZXJzT2Zmc2V0XTtcbiAgfVxuXG4gIGlmIChvcHRfZGVzdCkge1xuICAgIG9wdF9kZXN0LnB1c2gocG9pbnRYLCB5LCBtYXhTZWdtZW50TGVuZ3RoKTtcbiAgICByZXR1cm4gb3B0X2Rlc3Q7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtwb2ludFgsIHksIG1heFNlZ21lbnRMZW5ndGhdO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IGVuZHNzIEVuZHNzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDZW50ZXJzIEZsYXQgY2VudGVycy5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEludGVyaW9yIHBvaW50cyBhcyBYWU0gY29vcmRpbmF0ZXMsIHdoZXJlIE0gaXMgdGhlXG4gKiBsZW5ndGggb2YgdGhlIGhvcml6b250YWwgaW50ZXJzZWN0aW9uIHRoYXQgdGhlIHBvaW50IGJlbG9uZ3MgdG8uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEludGVyaW9yUG9pbnRzT2ZNdWx0aUFycmF5KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzcywgc3RyaWRlLCBmbGF0Q2VudGVycykge1xuICB2YXIgaW50ZXJpb3JQb2ludHMgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGVuZHMgPSBlbmRzc1tpXTtcbiAgICBpbnRlcmlvclBvaW50cyA9IGdldEludGVyaW9yUG9pbnRPZkFycmF5KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIGZsYXRDZW50ZXJzLCAyICogaSwgaW50ZXJpb3JQb2ludHMpO1xuICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHJldHVybiBpbnRlcmlvclBvaW50cztcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L3NlZ21lbnRzXG4gKi9cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGNhbGxzIGBjYWxsYmFja2AgZm9yIGVhY2ggc2VnbWVudCBvZiB0aGUgZmxhdCBjb29yZGluYXRlc1xuICogYXJyYXkuIElmIHRoZSBjYWxsYmFjayByZXR1cm5zIGEgdHJ1dGh5IHZhbHVlIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRoYXRcbiAqIHZhbHVlIGltbWVkaWF0ZWx5LiBPdGhlcndpc2UgdGhlIGZ1bmN0aW9uIHJldHVybnMgYGZhbHNlYC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSwgaW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlKTogVH0gY2FsbGJhY2sgRnVuY3Rpb25cbiAqICAgICBjYWxsZWQgZm9yIGVhY2ggc2VnbWVudC5cbiAqIEByZXR1cm4ge1R8Ym9vbGVhbn0gVmFsdWUuXG4gKiBAdGVtcGxhdGUgVFxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9yRWFjaChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGNhbGxiYWNrKSB7XG4gIHZhciBwb2ludDEgPSBbZmxhdENvb3JkaW5hdGVzW29mZnNldF0sIGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXV07XG4gIHZhciBwb2ludDIgPSBbXTtcbiAgdmFyIHJldDtcblxuICBmb3IgKDsgb2Zmc2V0ICsgc3RyaWRlIDwgZW5kOyBvZmZzZXQgKz0gc3RyaWRlKSB7XG4gICAgcG9pbnQyWzBdID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIHN0cmlkZV07XG4gICAgcG9pbnQyWzFdID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIHN0cmlkZSArIDFdO1xuICAgIHJldCA9IGNhbGxiYWNrKHBvaW50MSwgcG9pbnQyKTtcblxuICAgIGlmIChyZXQpIHtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgcG9pbnQxWzBdID0gcG9pbnQyWzBdO1xuICAgIHBvaW50MVsxXSA9IHBvaW50MlsxXTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L2ludGVyc2VjdHNleHRlbnRcbiAqL1xuaW1wb3J0IHsgY29udGFpbnNFeHRlbnQsIGNyZWF0ZUVtcHR5LCBleHRlbmRGbGF0Q29vcmRpbmF0ZXMsIGludGVyc2VjdHMsIGludGVyc2VjdHNTZWdtZW50IH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGZvckVhY2ggYXMgZm9yRWFjaFNlZ21lbnQgfSBmcm9tICcuL3NlZ21lbnRzLmpzJztcbmltcG9ydCB7IGxpbmVhclJpbmdDb250YWluc0V4dGVudCwgbGluZWFyUmluZ0NvbnRhaW5zWFkgfSBmcm9tICcuL2NvbnRhaW5zLmpzJztcbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgZXh0ZW50IGludGVyc2VjdC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJzZWN0c0xpbmVTdHJpbmcoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBleHRlbnQpIHtcbiAgdmFyIGNvb3JkaW5hdGVzRXh0ZW50ID0gZXh0ZW5kRmxhdENvb3JkaW5hdGVzKGNyZWF0ZUVtcHR5KCksIGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSk7XG5cbiAgaWYgKCFpbnRlcnNlY3RzKGV4dGVudCwgY29vcmRpbmF0ZXNFeHRlbnQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGNvbnRhaW5zRXh0ZW50KGV4dGVudCwgY29vcmRpbmF0ZXNFeHRlbnQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAoY29vcmRpbmF0ZXNFeHRlbnRbMF0gPj0gZXh0ZW50WzBdICYmIGNvb3JkaW5hdGVzRXh0ZW50WzJdIDw9IGV4dGVudFsyXSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGNvb3JkaW5hdGVzRXh0ZW50WzFdID49IGV4dGVudFsxXSAmJiBjb29yZGluYXRlc0V4dGVudFszXSA8PSBleHRlbnRbM10pIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmb3JFYWNoU2VnbWVudChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gcG9pbnQxIFN0YXJ0IHBvaW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gcG9pbnQyIEVuZCBwb2ludC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBzZWdtZW50IGFuZCB0aGUgZXh0ZW50IGludGVyc2VjdCxcbiAgICogICAgIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKi9cbiAgZnVuY3Rpb24gKHBvaW50MSwgcG9pbnQyKSB7XG4gICAgcmV0dXJuIGludGVyc2VjdHNTZWdtZW50KGV4dGVudCwgcG9pbnQxLCBwb2ludDIpO1xuICB9KTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBlbmRzIEVuZHMuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgZXh0ZW50IGludGVyc2VjdC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJzZWN0c0xpbmVTdHJpbmdBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBleHRlbnQpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgaWYgKGludGVyc2VjdHNMaW5lU3RyaW5nKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzW2ldLCBzdHJpZGUsIGV4dGVudCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIG9mZnNldCA9IGVuZHNbaV07XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludGVyc2VjdHNMaW5lYXJSaW5nKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgZXh0ZW50KSB7XG4gIGlmIChpbnRlcnNlY3RzTGluZVN0cmluZyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGV4dGVudCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChsaW5lYXJSaW5nQ29udGFpbnNYWShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGV4dGVudFswXSwgZXh0ZW50WzFdKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGxpbmVhclJpbmdDb250YWluc1hZKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgZXh0ZW50WzBdLCBleHRlbnRbM10pKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAobGluZWFyUmluZ0NvbnRhaW5zWFkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBleHRlbnRbMl0sIGV4dGVudFsxXSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChsaW5lYXJSaW5nQ29udGFpbnNYWShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGV4dGVudFsyXSwgZXh0ZW50WzNdKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBleHRlbnQgaW50ZXJzZWN0LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnNlY3RzTGluZWFyUmluZ0FycmF5KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIGV4dGVudCkge1xuICBpZiAoIWludGVyc2VjdHNMaW5lYXJSaW5nKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzWzBdLCBzdHJpZGUsIGV4dGVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoZW5kcy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAxLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIGlmIChsaW5lYXJSaW5nQ29udGFpbnNFeHRlbnQoZmxhdENvb3JkaW5hdGVzLCBlbmRzW2kgLSAxXSwgZW5kc1tpXSwgc3RyaWRlLCBleHRlbnQpKSB7XG4gICAgICBpZiAoIWludGVyc2VjdHNMaW5lU3RyaW5nKGZsYXRDb29yZGluYXRlcywgZW5kc1tpIC0gMV0sIGVuZHNbaV0sIHN0cmlkZSwgZXh0ZW50KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IGVuZHNzIEVuZHNzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludGVyc2VjdHNMaW5lYXJSaW5nTXVsdGlBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc3MsIHN0cmlkZSwgZXh0ZW50KSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHNzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kcyA9IGVuZHNzW2ldO1xuXG4gICAgaWYgKGludGVyc2VjdHNMaW5lYXJSaW5nQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgZXh0ZW50KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgb2Zmc2V0ID0gZW5kc1tlbmRzLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL2ZsYXQvcmV2ZXJzZVxuICovXG5cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSkge1xuICB3aGlsZSAob2Zmc2V0IDwgZW5kIC0gc3RyaWRlKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpZGU7ICsraSkge1xuICAgICAgdmFyIHRtcCA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBpXTtcbiAgICAgIGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBpXSA9IGZsYXRDb29yZGluYXRlc1tlbmQgLSBzdHJpZGUgKyBpXTtcbiAgICAgIGZsYXRDb29yZGluYXRlc1tlbmQgLSBzdHJpZGUgKyBpXSA9IHRtcDtcbiAgICB9XG5cbiAgICBvZmZzZXQgKz0gc3RyaWRlO1xuICAgIGVuZCAtPSBzdHJpZGU7XG4gIH1cbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L29yaWVudFxuICovXG5pbXBvcnQgeyBjb29yZGluYXRlcyBhcyByZXZlcnNlQ29vcmRpbmF0ZXMgfSBmcm9tICcuL3JldmVyc2UuanMnO1xuLyoqXG4gKiBJcyB0aGUgbGluZWFyIHJpbmcgb3JpZW50ZWQgY2xvY2t3aXNlIGluIGEgY29vcmRpbmF0ZSBzeXN0ZW0gd2l0aCBhIGJvdHRvbS1sZWZ0XG4gKiBjb29yZGluYXRlIG9yaWdpbj8gRm9yIGEgY29vcmRpbmF0ZSBzeXN0ZW0gd2l0aCBhIHRvcC1sZWZ0IGNvb3JkaW5hdGUgb3JpZ2luLFxuICogdGhlIHJpbmcncyBvcmllbnRhdGlvbiBpcyBjbG9ja3dpc2Ugd2hlbiB0aGlzIGZ1bmN0aW9uIHJldHVybnMgZmFsc2UuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7Ym9vbGVhbn0gSXMgY2xvY2t3aXNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5nSXNDbG9ja3dpc2UoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKSB7XG4gIC8vIGh0dHA6Ly90aW55dXJsLmNvbS9jbG9ja3dpc2UtbWV0aG9kXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9PU0dlby9nZGFsL2Jsb2IvdHJ1bmsvZ2RhbC9vZ3Ivb2dybGluZWFycmluZy5jcHBcbiAgdmFyIGVkZ2UgPSAwO1xuICB2YXIgeDEgPSBmbGF0Q29vcmRpbmF0ZXNbZW5kIC0gc3RyaWRlXTtcbiAgdmFyIHkxID0gZmxhdENvb3JkaW5hdGVzW2VuZCAtIHN0cmlkZSArIDFdO1xuXG4gIGZvciAoOyBvZmZzZXQgPCBlbmQ7IG9mZnNldCArPSBzdHJpZGUpIHtcbiAgICB2YXIgeDIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgICB2YXIgeTIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gICAgZWRnZSArPSAoeDIgLSB4MSkgKiAoeTIgKyB5MSk7XG4gICAgeDEgPSB4MjtcbiAgICB5MSA9IHkyO1xuICB9XG5cbiAgcmV0dXJuIGVkZ2UgPT09IDAgPyB1bmRlZmluZWQgOiBlZGdlID4gMDtcbn1cbi8qKlxuICogRGV0ZXJtaW5lcyBpZiBsaW5lYXIgcmluZ3MgYXJlIG9yaWVudGVkLiAgQnkgZGVmYXVsdCwgbGVmdC1oYW5kIG9yaWVudGF0aW9uXG4gKiBpcyB0ZXN0ZWQgKGZpcnN0IHJpbmcgbXVzdCBiZSBjbG9ja3dpc2UsIHJlbWFpbmluZyByaW5ncyBjb3VudGVyLWNsb2Nrd2lzZSkuXG4gKiBUbyB0ZXN0IGZvciByaWdodC1oYW5kIG9yaWVudGF0aW9uLCB1c2UgdGhlIGBvcHRfcmlnaHRgIGFyZ3VtZW50LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZW5kcyBBcnJheSBvZiBlbmQgaW5kZXhlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JpZ2h0IFRlc3QgZm9yIHJpZ2h0LWhhbmQgb3JpZW50YXRpb25cbiAqICAgICAoY291bnRlci1jbG9ja3dpc2UgZXh0ZXJpb3IgcmluZyBhbmQgY2xvY2t3aXNlIGludGVyaW9yIHJpbmdzKS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFJpbmdzIGFyZSBjb3JyZWN0bHkgb3JpZW50ZWQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclJpbmdzQXJlT3JpZW50ZWQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgb3B0X3JpZ2h0KSB7XG4gIHZhciByaWdodCA9IG9wdF9yaWdodCAhPT0gdW5kZWZpbmVkID8gb3B0X3JpZ2h0IDogZmFsc2U7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGVuZCA9IGVuZHNbaV07XG4gICAgdmFyIGlzQ2xvY2t3aXNlID0gbGluZWFyUmluZ0lzQ2xvY2t3aXNlKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSk7XG5cbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgaWYgKHJpZ2h0ICYmIGlzQ2xvY2t3aXNlIHx8ICFyaWdodCAmJiAhaXNDbG9ja3dpc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocmlnaHQgJiYgIWlzQ2xvY2t3aXNlIHx8ICFyaWdodCAmJiBpc0Nsb2Nrd2lzZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgb2Zmc2V0ID0gZW5kO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIERldGVybWluZXMgaWYgbGluZWFyIHJpbmdzIGFyZSBvcmllbnRlZC4gIEJ5IGRlZmF1bHQsIGxlZnQtaGFuZCBvcmllbnRhdGlvblxuICogaXMgdGVzdGVkIChmaXJzdCByaW5nIG11c3QgYmUgY2xvY2t3aXNlLCByZW1haW5pbmcgcmluZ3MgY291bnRlci1jbG9ja3dpc2UpLlxuICogVG8gdGVzdCBmb3IgcmlnaHQtaGFuZCBvcmllbnRhdGlvbiwgdXNlIHRoZSBgb3B0X3JpZ2h0YCBhcmd1bWVudC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBBcnJheSBvZiBhcnJheSBvZiBlbmQgaW5kZXhlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JpZ2h0IFRlc3QgZm9yIHJpZ2h0LWhhbmQgb3JpZW50YXRpb25cbiAqICAgICAoY291bnRlci1jbG9ja3dpc2UgZXh0ZXJpb3IgcmluZyBhbmQgY2xvY2t3aXNlIGludGVyaW9yIHJpbmdzKS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFJpbmdzIGFyZSBjb3JyZWN0bHkgb3JpZW50ZWQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclJpbmdzc0FyZU9yaWVudGVkKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzcywgc3RyaWRlLCBvcHRfcmlnaHQpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kc3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmRzID0gZW5kc3NbaV07XG5cbiAgICBpZiAoIWxpbmVhclJpbmdzQXJlT3JpZW50ZWQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgb3B0X3JpZ2h0KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChlbmRzLmxlbmd0aCkge1xuICAgICAgb2Zmc2V0ID0gZW5kc1tlbmRzLmxlbmd0aCAtIDFdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBPcmllbnQgY29vcmRpbmF0ZXMgaW4gYSBmbGF0IGFycmF5IG9mIGxpbmVhciByaW5ncy4gIEJ5IGRlZmF1bHQsIHJpbmdzXG4gKiBhcmUgb3JpZW50ZWQgZm9sbG93aW5nIHRoZSBsZWZ0LWhhbmQgcnVsZSAoY2xvY2t3aXNlIGZvciBleHRlcmlvciBhbmRcbiAqIGNvdW50ZXItY2xvY2t3aXNlIGZvciBpbnRlcmlvciByaW5ncykuICBUbyBvcmllbnQgYWNjb3JkaW5nIHRvIHRoZVxuICogcmlnaHQtaGFuZCBydWxlLCB1c2UgdGhlIGBvcHRfcmlnaHRgIGFyZ3VtZW50LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZW5kcyBFbmRzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfcmlnaHQgRm9sbG93IHRoZSByaWdodC1oYW5kIHJ1bGUgZm9yIG9yaWVudGF0aW9uLlxuICogQHJldHVybiB7bnVtYmVyfSBFbmQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG9yaWVudExpbmVhclJpbmdzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIG9wdF9yaWdodCkge1xuICB2YXIgcmlnaHQgPSBvcHRfcmlnaHQgIT09IHVuZGVmaW5lZCA/IG9wdF9yaWdodCA6IGZhbHNlO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmQgPSBlbmRzW2ldO1xuICAgIHZhciBpc0Nsb2Nrd2lzZSA9IGxpbmVhclJpbmdJc0Nsb2Nrd2lzZShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUpO1xuICAgIHZhciByZXZlcnNlID0gaSA9PT0gMCA/IHJpZ2h0ICYmIGlzQ2xvY2t3aXNlIHx8ICFyaWdodCAmJiAhaXNDbG9ja3dpc2UgOiByaWdodCAmJiAhaXNDbG9ja3dpc2UgfHwgIXJpZ2h0ICYmIGlzQ2xvY2t3aXNlO1xuXG4gICAgaWYgKHJldmVyc2UpIHtcbiAgICAgIHJldmVyc2VDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUpO1xuICAgIH1cblxuICAgIG9mZnNldCA9IGVuZDtcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQ7XG59XG4vKipcbiAqIE9yaWVudCBjb29yZGluYXRlcyBpbiBhIGZsYXQgYXJyYXkgb2YgbGluZWFyIHJpbmdzLiAgQnkgZGVmYXVsdCwgcmluZ3NcbiAqIGFyZSBvcmllbnRlZCBmb2xsb3dpbmcgdGhlIGxlZnQtaGFuZCBydWxlIChjbG9ja3dpc2UgZm9yIGV4dGVyaW9yIGFuZFxuICogY291bnRlci1jbG9ja3dpc2UgZm9yIGludGVyaW9yIHJpbmdzKS4gIFRvIG9yaWVudCBhY2NvcmRpbmcgdG8gdGhlXG4gKiByaWdodC1oYW5kIHJ1bGUsIHVzZSB0aGUgYG9wdF9yaWdodGAgYXJndW1lbnQuXG4gKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gZW5kc3MgQXJyYXkgb2YgYXJyYXkgb2YgZW5kIGluZGV4ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yaWdodCBGb2xsb3cgdGhlIHJpZ2h0LWhhbmQgcnVsZSBmb3Igb3JpZW50YXRpb24uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEVuZC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gb3JpZW50TGluZWFyUmluZ3NBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc3MsIHN0cmlkZSwgb3B0X3JpZ2h0KSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHNzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICBvZmZzZXQgPSBvcmllbnRMaW5lYXJSaW5ncyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc3NbaV0sIHN0cmlkZSwgb3B0X3JpZ2h0KTtcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQ7XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL1BvbHlnb25cbiAqL1xuXG5cbmltcG9ydCBHZW9tZXRyeUxheW91dCBmcm9tICcuL0dlb21ldHJ5TGF5b3V0LmpzJztcbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IExpbmVhclJpbmcgZnJvbSAnLi9MaW5lYXJSaW5nLmpzJztcbmltcG9ydCBQb2ludCBmcm9tICcuL1BvaW50LmpzJztcbmltcG9ydCBTaW1wbGVHZW9tZXRyeSBmcm9tICcuL1NpbXBsZUdlb21ldHJ5LmpzJztcbmltcG9ydCB7IGFycmF5TWF4U3F1YXJlZERlbHRhLCBhc3NpZ25DbG9zZXN0QXJyYXlQb2ludCB9IGZyb20gJy4vZmxhdC9jbG9zZXN0LmpzJztcbmltcG9ydCB7IGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWSwgZ2V0Q2VudGVyIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGRlZmxhdGVDb29yZGluYXRlc0FycmF5IH0gZnJvbSAnLi9mbGF0L2RlZmxhdGUuanMnO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSAnLi4vYXJyYXkuanMnO1xuaW1wb3J0IHsgZ2V0SW50ZXJpb3JQb2ludE9mQXJyYXkgfSBmcm9tICcuL2ZsYXQvaW50ZXJpb3Jwb2ludC5qcyc7XG5pbXBvcnQgeyBpbmZsYXRlQ29vcmRpbmF0ZXNBcnJheSB9IGZyb20gJy4vZmxhdC9pbmZsYXRlLmpzJztcbmltcG9ydCB7IGludGVyc2VjdHNMaW5lYXJSaW5nQXJyYXkgfSBmcm9tICcuL2ZsYXQvaW50ZXJzZWN0c2V4dGVudC5qcyc7XG5pbXBvcnQgeyBsaW5lYXJSaW5nc0FyZU9yaWVudGVkLCBvcmllbnRMaW5lYXJSaW5ncyB9IGZyb20gJy4vZmxhdC9vcmllbnQuanMnO1xuaW1wb3J0IHsgbGluZWFyUmluZ3MgYXMgbGluZWFyUmluZ3NBcmVhIH0gZnJvbSAnLi9mbGF0L2FyZWEuanMnO1xuaW1wb3J0IHsgbGluZWFyUmluZ3NDb250YWluc1hZIH0gZnJvbSAnLi9mbGF0L2NvbnRhaW5zLmpzJztcbmltcG9ydCB7IG1vZHVsbyB9IGZyb20gJy4uL21hdGguanMnO1xuaW1wb3J0IHsgcXVhbnRpemVBcnJheSB9IGZyb20gJy4vZmxhdC9zaW1wbGlmeS5qcyc7XG5pbXBvcnQgeyBvZmZzZXQgYXMgc3BoZXJlT2Zmc2V0IH0gZnJvbSAnLi4vc3BoZXJlLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogUG9seWdvbiBnZW9tZXRyeS5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIFBvbHlnb24gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoUG9seWdvbiwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7IUFycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+fCFBcnJheTxudW1iZXI+fSBjb29yZGluYXRlc1xuICAgKiAgICAgQXJyYXkgb2YgbGluZWFyIHJpbmdzIHRoYXQgZGVmaW5lIHRoZSBwb2x5Z29uLiBUaGUgZmlyc3QgbGluZWFyIHJpbmcgb2YgdGhlXG4gICAqICAgICBhcnJheSBkZWZpbmVzIHRoZSBvdXRlci1ib3VuZGFyeSBvciBzdXJmYWNlIG9mIHRoZSBwb2x5Z29uLiBFYWNoIHN1YnNlcXVlbnRcbiAgICogICAgIGxpbmVhciByaW5nIGRlZmluZXMgYSBob2xlIGluIHRoZSBzdXJmYWNlIG9mIHRoZSBwb2x5Z29uLiBBIGxpbmVhciByaW5nIGlzXG4gICAqICAgICBhbiBhcnJheSBvZiB2ZXJ0aWNlcycgY29vcmRpbmF0ZXMgd2hlcmUgdGhlIGZpcnN0IGNvb3JkaW5hdGUgYW5kIHRoZSBsYXN0IGFyZVxuICAgKiAgICAgZXF1aXZhbGVudC4gKEZvciBpbnRlcm5hbCB1c2UsIGZsYXQgY29vcmRpbmF0ZXMgaW4gY29tYmluYXRpb24gd2l0aFxuICAgKiAgICAgYG9wdF9sYXlvdXRgIGFuZCBgb3B0X2VuZHNgIGFyZSBhbHNvIGFjY2VwdGVkLilcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHQ9fSBvcHRfbGF5b3V0IExheW91dC5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X2VuZHMgRW5kcyAoZm9yIGludGVybmFsIHVzZSB3aXRoIGZsYXQgY29vcmRpbmF0ZXMpLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFBvbHlnb24oY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQsIG9wdF9lbmRzKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5lbmRzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmZsYXRJbnRlcmlvclBvaW50UmV2aXNpb25fID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmxhdEludGVyaW9yUG9pbnRfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5tYXhEZWx0YV8gPSAtMTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5tYXhEZWx0YVJldmlzaW9uXyA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLm9yaWVudGVkUmV2aXNpb25fID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIF90aGlzLm9yaWVudGVkRmxhdENvb3JkaW5hdGVzXyA9IG51bGw7XG5cbiAgICBpZiAob3B0X2xheW91dCAhPT0gdW5kZWZpbmVkICYmIG9wdF9lbmRzKSB7XG4gICAgICBfdGhpcy5zZXRGbGF0Q29vcmRpbmF0ZXMob3B0X2xheW91dCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzKTtcblxuICAgICAgX3RoaXMuZW5kc18gPSBvcHRfZW5kcztcbiAgICB9IGVsc2Uge1xuICAgICAgX3RoaXMuc2V0Q29vcmRpbmF0ZXMoXG4gICAgICAvKiogQHR5cGUge0FycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+fSAqL1xuICAgICAgY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpO1xuICAgIH1cblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQXBwZW5kIHRoZSBwYXNzZWQgbGluZWFyIHJpbmcgdG8gdGhpcyBwb2x5Z29uLlxuICAgKiBAcGFyYW0ge0xpbmVhclJpbmd9IGxpbmVhclJpbmcgTGluZWFyIHJpbmcuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5hcHBlbmRMaW5lYXJSaW5nID0gZnVuY3Rpb24gKGxpbmVhclJpbmcpIHtcbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IGxpbmVhclJpbmcuZ2V0RmxhdENvb3JkaW5hdGVzKCkuc2xpY2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXh0ZW5kKHRoaXMuZmxhdENvb3JkaW5hdGVzLCBsaW5lYXJSaW5nLmdldEZsYXRDb29yZGluYXRlcygpKTtcbiAgICB9XG5cbiAgICB0aGlzLmVuZHNfLnB1c2godGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIE1ha2UgYSBjb21wbGV0ZSBjb3B5IG9mIHRoZSBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7IVBvbHlnb259IENsb25lLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHBvbHlnb24gPSBuZXcgUG9seWdvbih0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZSgpLCB0aGlzLmxheW91dCwgdGhpcy5lbmRzXy5zbGljZSgpKTtcbiAgICBwb2x5Z29uLmFwcGx5UHJvcGVydGllcyh0aGlzKTtcbiAgICByZXR1cm4gcG9seWdvbjtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjbG9zZXN0UG9pbnQgQ2xvc2VzdCBwb2ludC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblNxdWFyZWREaXN0YW5jZSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKi9cblxuXG4gIFBvbHlnb24ucHJvdG90eXBlLmNsb3Nlc3RQb2ludFhZID0gZnVuY3Rpb24gKHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgaWYgKG1pblNxdWFyZWREaXN0YW5jZSA8IGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWSh0aGlzLmdldEV4dGVudCgpLCB4LCB5KSkge1xuICAgICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tYXhEZWx0YVJldmlzaW9uXyAhPSB0aGlzLmdldFJldmlzaW9uKCkpIHtcbiAgICAgIHRoaXMubWF4RGVsdGFfID0gTWF0aC5zcXJ0KGFycmF5TWF4U3F1YXJlZERlbHRhKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgMCkpO1xuICAgICAgdGhpcy5tYXhEZWx0YVJldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXNzaWduQ2xvc2VzdEFycmF5UG9pbnQodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZW5kc18sIHRoaXMuc3RyaWRlLCB0aGlzLm1heERlbHRhXywgdHJ1ZSwgeCwgeSwgY2xvc2VzdFBvaW50LCBtaW5TcXVhcmVkRGlzdGFuY2UpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMgKHgsIHkpLlxuICAgKi9cblxuXG4gIFBvbHlnb24ucHJvdG90eXBlLmNvbnRhaW5zWFkgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIHJldHVybiBsaW5lYXJSaW5nc0NvbnRhaW5zWFkodGhpcy5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgeCwgeSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGFyZWEgb2YgdGhlIHBvbHlnb24gb24gcHJvamVjdGVkIHBsYW5lLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEFyZWEgKG9uIHByb2plY3RlZCBwbGFuZSkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5nZXRBcmVhID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBsaW5lYXJSaW5nc0FyZWEodGhpcy5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGNvb3JkaW5hdGUgYXJyYXkgZm9yIHRoaXMgZ2VvbWV0cnkuICBUaGlzIGFycmF5IGhhcyB0aGUgc3RydWN0dXJlXG4gICAqIG9mIGEgR2VvSlNPTiBjb29yZGluYXRlIGFycmF5IGZvciBwb2x5Z29ucy5cbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JpZ2h0IE9yaWVudCBjb29yZGluYXRlcyBhY2NvcmRpbmcgdG8gdGhlIHJpZ2h0LWhhbmRcbiAgICogICAgIHJ1bGUgKGNvdW50ZXItY2xvY2t3aXNlIGZvciBleHRlcmlvciBhbmQgY2xvY2t3aXNlIGZvciBpbnRlcmlvciByaW5ncykuXG4gICAqICAgICBJZiBgZmFsc2VgLCBjb29yZGluYXRlcyB3aWxsIGJlIG9yaWVudGVkIGFjY29yZGluZyB0byB0aGUgbGVmdC1oYW5kIHJ1bGVcbiAgICogICAgIChjbG9ja3dpc2UgZm9yIGV4dGVyaW9yIGFuZCBjb3VudGVyLWNsb2Nrd2lzZSBmb3IgaW50ZXJpb3IgcmluZ3MpLlxuICAgKiAgICAgQnkgZGVmYXVsdCwgY29vcmRpbmF0ZSBvcmllbnRhdGlvbiB3aWxsIGRlcGVuZCBvbiBob3cgdGhlIGdlb21ldHJ5IHdhc1xuICAgKiAgICAgY29uc3RydWN0ZWQuXG4gICAqIEByZXR1cm4ge0FycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+fSBDb29yZGluYXRlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvbHlnb24ucHJvdG90eXBlLmdldENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKG9wdF9yaWdodCkge1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXM7XG5cbiAgICBpZiAob3B0X3JpZ2h0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKS5zbGljZSgpO1xuICAgICAgb3JpZW50TGluZWFyUmluZ3MoZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgb3B0X3JpZ2h0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIGluZmxhdGVDb29yZGluYXRlc0FycmF5KGZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gRW5kcy5cbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5nZXRFbmRzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmVuZHNfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gSW50ZXJpb3IgcG9pbnQuXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuZ2V0RmxhdEludGVyaW9yUG9pbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuZmxhdEludGVyaW9yUG9pbnRSZXZpc2lvbl8gIT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB2YXIgZmxhdENlbnRlciA9IGdldENlbnRlcih0aGlzLmdldEV4dGVudCgpKTtcbiAgICAgIHRoaXMuZmxhdEludGVyaW9yUG9pbnRfID0gZ2V0SW50ZXJpb3JQb2ludE9mQXJyYXkodGhpcy5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgZmxhdENlbnRlciwgMCk7XG4gICAgICB0aGlzLmZsYXRJbnRlcmlvclBvaW50UmV2aXNpb25fID0gdGhpcy5nZXRSZXZpc2lvbigpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZsYXRJbnRlcmlvclBvaW50XztcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiBhbiBpbnRlcmlvciBwb2ludCBvZiB0aGUgcG9seWdvbi5cbiAgICogQHJldHVybiB7UG9pbnR9IEludGVyaW9yIHBvaW50IGFzIFhZTSBjb29yZGluYXRlLCB3aGVyZSBNIGlzIHRoZVxuICAgKiBsZW5ndGggb2YgdGhlIGhvcml6b250YWwgaW50ZXJzZWN0aW9uIHRoYXQgdGhlIHBvaW50IGJlbG9uZ3MgdG8uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5nZXRJbnRlcmlvclBvaW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBuZXcgUG9pbnQodGhpcy5nZXRGbGF0SW50ZXJpb3JQb2ludCgpLCBHZW9tZXRyeUxheW91dC5YWU0pO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBudW1iZXIgb2YgcmluZ3Mgb2YgdGhlIHBvbHlnb24sICB0aGlzIGluY2x1ZGVzIHRoZSBleHRlcmlvclxuICAgKiByaW5nIGFuZCBhbnkgaW50ZXJpb3IgcmluZ3MuXG4gICAqXG4gICAqIEByZXR1cm4ge251bWJlcn0gTnVtYmVyIG9mIHJpbmdzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuZ2V0TGluZWFyUmluZ0NvdW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmVuZHNfLmxlbmd0aDtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgTnRoIGxpbmVhciByaW5nIG9mIHRoZSBwb2x5Z29uIGdlb21ldHJ5LiBSZXR1cm4gYG51bGxgIGlmIHRoZVxuICAgKiBnaXZlbiBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuXG4gICAqIFRoZSBleHRlcmlvciBsaW5lYXIgcmluZyBpcyBhdmFpbGFibGUgYXQgaW5kZXggYDBgIGFuZCB0aGUgaW50ZXJpb3IgcmluZ3NcbiAgICogYXQgaW5kZXggYDFgIGFuZCBiZXlvbmQuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleC5cbiAgICogQHJldHVybiB7TGluZWFyUmluZ30gTGluZWFyIHJpbmcuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5nZXRMaW5lYXJSaW5nID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgaWYgKGluZGV4IDwgMCB8fCB0aGlzLmVuZHNfLmxlbmd0aCA8PSBpbmRleCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBMaW5lYXJSaW5nKHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKGluZGV4ID09PSAwID8gMCA6IHRoaXMuZW5kc19baW5kZXggLSAxXSwgdGhpcy5lbmRzX1tpbmRleF0pLCB0aGlzLmxheW91dCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGxpbmVhciByaW5ncyBvZiB0aGUgcG9seWdvbi5cbiAgICogQHJldHVybiB7QXJyYXk8TGluZWFyUmluZz59IExpbmVhciByaW5ncy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvbHlnb24ucHJvdG90eXBlLmdldExpbmVhclJpbmdzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBsYXlvdXQgPSB0aGlzLmxheW91dDtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgdmFyIGVuZHMgPSB0aGlzLmVuZHNfO1xuICAgIHZhciBsaW5lYXJSaW5ncyA9IFtdO1xuICAgIHZhciBvZmZzZXQgPSAwO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICAgIHZhciBsaW5lYXJSaW5nID0gbmV3IExpbmVhclJpbmcoZmxhdENvb3JkaW5hdGVzLnNsaWNlKG9mZnNldCwgZW5kKSwgbGF5b3V0KTtcbiAgICAgIGxpbmVhclJpbmdzLnB1c2gobGluZWFyUmluZyk7XG4gICAgICBvZmZzZXQgPSBlbmQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpbmVhclJpbmdzO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gT3JpZW50ZWQgZmxhdCBjb29yZGluYXRlcy5cbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5vcmllbnRlZFJldmlzaW9uXyAhPSB0aGlzLmdldFJldmlzaW9uKCkpIHtcbiAgICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSB0aGlzLmZsYXRDb29yZGluYXRlcztcblxuICAgICAgaWYgKGxpbmVhclJpbmdzQXJlT3JpZW50ZWQoZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSkpIHtcbiAgICAgICAgdGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc18gPSBmbGF0Q29vcmRpbmF0ZXM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9yaWVudGVkRmxhdENvb3JkaW5hdGVzXyA9IGZsYXRDb29yZGluYXRlcy5zbGljZSgpO1xuICAgICAgICB0aGlzLm9yaWVudGVkRmxhdENvb3JkaW5hdGVzXy5sZW5ndGggPSBvcmllbnRMaW5lYXJSaW5ncyh0aGlzLm9yaWVudGVkRmxhdENvb3JkaW5hdGVzXywgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm9yaWVudGVkUmV2aXNpb25fID0gdGhpcy5nZXRSZXZpc2lvbigpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm9yaWVudGVkRmxhdENvb3JkaW5hdGVzXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzcXVhcmVkVG9sZXJhbmNlIFNxdWFyZWQgdG9sZXJhbmNlLlxuICAgKiBAcmV0dXJuIHtQb2x5Z29ufSBTaW1wbGlmaWVkIFBvbHlnb24uXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5nZXRTaW1wbGlmaWVkR2VvbWV0cnlJbnRlcm5hbCA9IGZ1bmN0aW9uIChzcXVhcmVkVG9sZXJhbmNlKSB7XG4gICAgdmFyIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgPSBbXTtcbiAgICB2YXIgc2ltcGxpZmllZEVuZHMgPSBbXTtcbiAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IHF1YW50aXplQXJyYXkodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZW5kc18sIHRoaXMuc3RyaWRlLCBNYXRoLnNxcnQoc3F1YXJlZFRvbGVyYW5jZSksIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIDAsIHNpbXBsaWZpZWRFbmRzKTtcbiAgICByZXR1cm4gbmV3IFBvbHlnb24oc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgR2VvbWV0cnlMYXlvdXQuWFksIHNpbXBsaWZpZWRFbmRzKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdHlwZSBvZiB0aGlzIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeSB0eXBlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gR2VvbWV0cnlUeXBlLlBPTFlHT047XG4gIH07XG4gIC8qKlxuICAgKiBUZXN0IGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIHBhc3NlZCBleHRlbnQgaW50ZXJzZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBleHRlbnQgaW50ZXJzZWN0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuaW50ZXJzZWN0c0V4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICByZXR1cm4gaW50ZXJzZWN0c0xpbmVhclJpbmdBcnJheSh0aGlzLmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzKCksIDAsIHRoaXMuZW5kc18sIHRoaXMuc3RyaWRlLCBleHRlbnQpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBjb29yZGluYXRlcyBvZiB0aGUgcG9seWdvbi5cbiAgICogQHBhcmFtIHshQXJyYXk8QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuc2V0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB0aGlzLnNldExheW91dChvcHRfbGF5b3V0LCBjb29yZGluYXRlcywgMik7XG5cbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIH1cblxuICAgIHZhciBlbmRzID0gZGVmbGF0ZUNvb3JkaW5hdGVzQXJyYXkodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIGNvb3JkaW5hdGVzLCB0aGlzLnN0cmlkZSwgdGhpcy5lbmRzXyk7XG4gICAgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoID0gZW5kcy5sZW5ndGggPT09IDAgPyAwIDogZW5kc1tlbmRzLmxlbmd0aCAtIDFdO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuXG4gIHJldHVybiBQb2x5Z29uO1xufShTaW1wbGVHZW9tZXRyeSk7XG5cbmV4cG9ydCBkZWZhdWx0IFBvbHlnb247XG4vKipcbiAqIENyZWF0ZSBhbiBhcHByb3hpbWF0aW9uIG9mIGEgY2lyY2xlIG9uIHRoZSBzdXJmYWNlIG9mIGEgc3BoZXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNlbnRlciBDZW50ZXIgKGBbbG9uLCBsYXRdYCBpbiBkZWdyZWVzKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSByYWRpdXMgVGhlIGdyZWF0LWNpcmNsZSBkaXN0YW5jZSBmcm9tIHRoZSBjZW50ZXIgdG9cbiAqICAgICB0aGUgcG9seWdvbiB2ZXJ0aWNlcy5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X24gT3B0aW9uYWwgbnVtYmVyIG9mIHZlcnRpY2VzIGZvciB0aGUgcmVzdWx0aW5nXG4gKiAgICAgcG9seWdvbi4gRGVmYXVsdCBpcyBgMzJgLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfc3BoZXJlUmFkaXVzIE9wdGlvbmFsIHJhZGl1cyBmb3IgdGhlIHNwaGVyZSAoZGVmYXVsdHMgdG9cbiAqICAgICB0aGUgRWFydGgncyBtZWFuIHJhZGl1cyB1c2luZyB0aGUgV0dTODQgZWxsaXBzb2lkKS5cbiAqIEByZXR1cm4ge1BvbHlnb259IFRoZSBcImNpcmN1bGFyXCIgcG9seWdvbi5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2lyY3VsYXIoY2VudGVyLCByYWRpdXMsIG9wdF9uLCBvcHRfc3BoZXJlUmFkaXVzKSB7XG4gIHZhciBuID0gb3B0X24gPyBvcHRfbiA6IDMyO1xuICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG5cbiAgdmFyIGZsYXRDb29yZGluYXRlcyA9IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgZXh0ZW5kKGZsYXRDb29yZGluYXRlcywgc3BoZXJlT2Zmc2V0KGNlbnRlciwgcmFkaXVzLCAyICogTWF0aC5QSSAqIGkgLyBuLCBvcHRfc3BoZXJlUmFkaXVzKSk7XG4gIH1cblxuICBmbGF0Q29vcmRpbmF0ZXMucHVzaChmbGF0Q29vcmRpbmF0ZXNbMF0sIGZsYXRDb29yZGluYXRlc1sxXSk7XG4gIHJldHVybiBuZXcgUG9seWdvbihmbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZLCBbZmxhdENvb3JkaW5hdGVzLmxlbmd0aF0pO1xufVxuLyoqXG4gKiBDcmVhdGUgYSBwb2x5Z29uIGZyb20gYW4gZXh0ZW50LiBUaGUgbGF5b3V0IHVzZWQgaXMgYFhZYC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IFRoZSBleHRlbnQuXG4gKiBAcmV0dXJuIHtQb2x5Z29ufSBUaGUgcG9seWdvbi5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbUV4dGVudChleHRlbnQpIHtcbiAgdmFyIG1pblggPSBleHRlbnRbMF07XG4gIHZhciBtaW5ZID0gZXh0ZW50WzFdO1xuICB2YXIgbWF4WCA9IGV4dGVudFsyXTtcbiAgdmFyIG1heFkgPSBleHRlbnRbM107XG4gIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBbbWluWCwgbWluWSwgbWluWCwgbWF4WSwgbWF4WCwgbWF4WSwgbWF4WCwgbWluWSwgbWluWCwgbWluWV07XG4gIHJldHVybiBuZXcgUG9seWdvbihmbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZLCBbZmxhdENvb3JkaW5hdGVzLmxlbmd0aF0pO1xufVxuLyoqXG4gKiBDcmVhdGUgYSByZWd1bGFyIHBvbHlnb24gZnJvbSBhIGNpcmNsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9DaXJjbGUuanNcIikuZGVmYXVsdH0gY2lyY2xlIENpcmNsZSBnZW9tZXRyeS5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3NpZGVzIE51bWJlciBvZiBzaWRlcyBvZiB0aGUgcG9seWdvbi4gRGVmYXVsdCBpcyAzMi5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2FuZ2xlIFN0YXJ0IGFuZ2xlIGZvciB0aGUgZmlyc3QgdmVydGV4IG9mIHRoZSBwb2x5Z29uIGluXG4gKiAgICAgY291bnRlci1jbG9ja3dpc2UgcmFkaWFucy4gMCBtZWFucyBFYXN0LiBEZWZhdWx0IGlzIDAuXG4gKiBAcmV0dXJuIHtQb2x5Z29ufSBQb2x5Z29uIGdlb21ldHJ5LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tQ2lyY2xlKGNpcmNsZSwgb3B0X3NpZGVzLCBvcHRfYW5nbGUpIHtcbiAgdmFyIHNpZGVzID0gb3B0X3NpZGVzID8gb3B0X3NpZGVzIDogMzI7XG4gIHZhciBzdHJpZGUgPSBjaXJjbGUuZ2V0U3RyaWRlKCk7XG4gIHZhciBsYXlvdXQgPSBjaXJjbGUuZ2V0TGF5b3V0KCk7XG4gIHZhciBjZW50ZXIgPSBjaXJjbGUuZ2V0Q2VudGVyKCk7XG4gIHZhciBhcnJheUxlbmd0aCA9IHN0cmlkZSAqIChzaWRlcyArIDEpO1xuICB2YXIgZmxhdENvb3JkaW5hdGVzID0gbmV3IEFycmF5KGFycmF5TGVuZ3RoKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5TGVuZ3RoOyBpICs9IHN0cmlkZSkge1xuICAgIGZsYXRDb29yZGluYXRlc1tpXSA9IDA7XG4gICAgZmxhdENvb3JkaW5hdGVzW2kgKyAxXSA9IDA7XG5cbiAgICBmb3IgKHZhciBqID0gMjsgaiA8IHN0cmlkZTsgaisrKSB7XG4gICAgICBmbGF0Q29vcmRpbmF0ZXNbaSArIGpdID0gY2VudGVyW2pdO1xuICAgIH1cbiAgfVxuXG4gIHZhciBlbmRzID0gW2ZsYXRDb29yZGluYXRlcy5sZW5ndGhdO1xuICB2YXIgcG9seWdvbiA9IG5ldyBQb2x5Z29uKGZsYXRDb29yZGluYXRlcywgbGF5b3V0LCBlbmRzKTtcbiAgbWFrZVJlZ3VsYXIocG9seWdvbiwgY2VudGVyLCBjaXJjbGUuZ2V0UmFkaXVzKCksIG9wdF9hbmdsZSk7XG4gIHJldHVybiBwb2x5Z29uO1xufVxuLyoqXG4gKiBNb2RpZnkgdGhlIGNvb3JkaW5hdGVzIG9mIGEgcG9seWdvbiB0byBtYWtlIGl0IGEgcmVndWxhciBwb2x5Z29uLlxuICogQHBhcmFtIHtQb2x5Z29ufSBwb2x5Z29uIFBvbHlnb24gZ2VvbWV0cnkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY2VudGVyIENlbnRlciBvZiB0aGUgcmVndWxhciBwb2x5Z29uLlxuICogQHBhcmFtIHtudW1iZXJ9IHJhZGl1cyBSYWRpdXMgb2YgdGhlIHJlZ3VsYXIgcG9seWdvbi5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2FuZ2xlIFN0YXJ0IGFuZ2xlIGZvciB0aGUgZmlyc3QgdmVydGV4IG9mIHRoZSBwb2x5Z29uIGluXG4gKiAgICAgY291bnRlci1jbG9ja3dpc2UgcmFkaWFucy4gMCBtZWFucyBFYXN0LiBEZWZhdWx0IGlzIDAuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG1ha2VSZWd1bGFyKHBvbHlnb24sIGNlbnRlciwgcmFkaXVzLCBvcHRfYW5nbGUpIHtcbiAgdmFyIGZsYXRDb29yZGluYXRlcyA9IHBvbHlnb24uZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gIHZhciBzdHJpZGUgPSBwb2x5Z29uLmdldFN0cmlkZSgpO1xuICB2YXIgc2lkZXMgPSBmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoIC8gc3RyaWRlIC0gMTtcbiAgdmFyIHN0YXJ0QW5nbGUgPSBvcHRfYW5nbGUgPyBvcHRfYW5nbGUgOiAwO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDw9IHNpZGVzOyArK2kpIHtcbiAgICB2YXIgb2Zmc2V0ID0gaSAqIHN0cmlkZTtcbiAgICB2YXIgYW5nbGUgPSBzdGFydEFuZ2xlICsgbW9kdWxvKGksIHNpZGVzKSAqIDIgKiBNYXRoLlBJIC8gc2lkZXM7XG4gICAgZmxhdENvb3JkaW5hdGVzW29mZnNldF0gPSBjZW50ZXJbMF0gKyByYWRpdXMgKiBNYXRoLmNvcyhhbmdsZSk7XG4gICAgZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdID0gY2VudGVyWzFdICsgcmFkaXVzICogTWF0aC5zaW4oYW5nbGUpO1xuICB9XG5cbiAgcG9seWdvbi5jaGFuZ2VkKCk7XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9WaWV3XG4gKi9cblxuXG5pbXBvcnQgQmFzZU9iamVjdCBmcm9tICcuL09iamVjdC5qcyc7XG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4vZ2VvbS9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IFVuaXRzIGZyb20gJy4vcHJvai9Vbml0cy5qcyc7XG5pbXBvcnQgVmlld0hpbnQgZnJvbSAnLi9WaWV3SGludC5qcyc7XG5pbXBvcnQgVmlld1Byb3BlcnR5IGZyb20gJy4vVmlld1Byb3BlcnR5LmpzJztcbmltcG9ydCB7IERFRkFVTFRfVElMRV9TSVpFIH0gZnJvbSAnLi90aWxlZ3JpZC9jb21tb24uanMnO1xuaW1wb3J0IHsgTUVURVJTX1BFUl9VTklULCBjcmVhdGVQcm9qZWN0aW9uLCBmcm9tVXNlckNvb3JkaW5hdGUsIGZyb21Vc2VyRXh0ZW50LCBnZXRVc2VyUHJvamVjdGlvbiwgdG9Vc2VyQ29vcmRpbmF0ZSwgdG9Vc2VyRXh0ZW50IH0gZnJvbSAnLi9wcm9qLmpzJztcbmltcG9ydCB7IFZPSUQgfSBmcm9tICcuL2Z1bmN0aW9ucy5qcyc7XG5pbXBvcnQgeyBhZGQgYXMgYWRkQ29vcmRpbmF0ZSwgZXF1YWxzIGFzIGNvb3JkaW5hdGVzRXF1YWwsIHJvdGF0ZSBhcyByb3RhdGVDb29yZGluYXRlIH0gZnJvbSAnLi9jb29yZGluYXRlLmpzJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4vYXNzZXJ0cy5qcyc7XG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICcuL29iai5qcyc7XG5pbXBvcnQgeyBub25lIGFzIGNlbnRlck5vbmUsIGNyZWF0ZUV4dGVudCB9IGZyb20gJy4vY2VudGVyY29uc3RyYWludC5qcyc7XG5pbXBvcnQgeyBjbGFtcCwgbW9kdWxvIH0gZnJvbSAnLi9tYXRoLmpzJztcbmltcG9ydCB7IGNyZWF0ZU1pbk1heFJlc29sdXRpb24gfSBmcm9tICcuL3Jlc29sdXRpb25jb25zdHJhaW50LmpzJztcbmltcG9ydCB7IGNyZWF0ZVNuYXBUb04sIGNyZWF0ZVNuYXBUb1plcm8sIGRpc2FibGUsIG5vbmUgYXMgcm90YXRpb25Ob25lIH0gZnJvbSAnLi9yb3RhdGlvbmNvbnN0cmFpbnQuanMnO1xuaW1wb3J0IHsgY3JlYXRlU25hcFRvUG93ZXIsIGNyZWF0ZVNuYXBUb1Jlc29sdXRpb25zIH0gZnJvbSAnLi9yZXNvbHV0aW9uY29uc3RyYWludC5qcyc7XG5pbXBvcnQgeyBlYXNlT3V0IH0gZnJvbSAnLi9lYXNpbmcuanMnO1xuaW1wb3J0IHsgZXF1YWxzIH0gZnJvbSAnLi9jb29yZGluYXRlLmpzJztcbmltcG9ydCB7IGdldENlbnRlciwgZ2V0Rm9yVmlld0FuZFNpemUsIGdldEhlaWdodCwgZ2V0V2lkdGgsIGlzRW1wdHkgfSBmcm9tICcuL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBpbkFuZE91dCB9IGZyb20gJy4vZWFzaW5nLmpzJztcbmltcG9ydCB7IGxpbmVhckZpbmROZWFyZXN0IH0gZnJvbSAnLi9hcnJheS5qcyc7XG5pbXBvcnQgeyBmcm9tRXh0ZW50IGFzIHBvbHlnb25Gcm9tRXh0ZW50IH0gZnJvbSAnLi9nZW9tL1BvbHlnb24uanMnO1xuLyoqXG4gKiBBbiBhbmltYXRpb24gY29uZmlndXJhdGlvblxuICpcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEFuaW1hdGlvblxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gW3NvdXJjZUNlbnRlcl1cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFt0YXJnZXRDZW50ZXJdXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3NvdXJjZVJlc29sdXRpb25dXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RhcmdldFJlc29sdXRpb25dXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3NvdXJjZVJvdGF0aW9uXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt0YXJnZXRSb3RhdGlvbl1cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFthbmNob3JdXG4gKiBAcHJvcGVydHkge251bWJlcn0gc3RhcnRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkdXJhdGlvblxuICogQHByb3BlcnR5IHtib29sZWFufSBjb21wbGV0ZVxuICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXIpOm51bWJlcn0gZWFzaW5nXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKGJvb2xlYW4pOnZvaWR9IGNhbGxiYWNrXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBDb25zdHJhaW50c1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2NlbnRlcmNvbnN0cmFpbnQuanNcIikuVHlwZX0gY2VudGVyXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vcmVzb2x1dGlvbmNvbnN0cmFpbnQuanNcIikuVHlwZX0gcmVzb2x1dGlvblxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL3JvdGF0aW9uY29uc3RyYWludC5qc1wiKS5UeXBlfSByb3RhdGlvblxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gRml0T3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gW3NpemVdIFRoZSBzaXplIGluIHBpeGVscyBvZiB0aGUgYm94IHRvIGZpdFxuICogdGhlIGV4dGVudCBpbnRvLiBEZWZhdWx0IGlzIHRoZSBjdXJyZW50IHNpemUgb2YgdGhlIGZpcnN0IG1hcCBpbiB0aGUgRE9NIHRoYXRcbiAqIHVzZXMgdGhpcyB2aWV3LCBvciBgWzEwMCwgMTAwXWAgaWYgbm8gc3VjaCBtYXAgaXMgZm91bmQuXG4gKiBAcHJvcGVydHkgeyFBcnJheTxudW1iZXI+fSBbcGFkZGluZz1bMCwgMCwgMCwgMF1dIFBhZGRpbmcgKGluIHBpeGVscykgdG8gYmVcbiAqIGNsZWFyZWQgaW5zaWRlIHRoZSB2aWV3LiBWYWx1ZXMgaW4gdGhlIGFycmF5IGFyZSB0b3AsIHJpZ2h0LCBib3R0b20gYW5kIGxlZnRcbiAqIHBhZGRpbmcuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtuZWFyZXN0PWZhbHNlXSBJZiB0aGUgdmlldyBgY29uc3RyYWluUmVzb2x1dGlvbmAgb3B0aW9uIGlzIGB0cnVlYCxcbiAqIGdldCB0aGUgbmVhcmVzdCBleHRlbnQgaW5zdGVhZCBvZiB0aGUgY2xvc2VzdCB0aGF0IGFjdHVhbGx5IGZpdHMgdGhlIHZpZXcuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblJlc29sdXRpb249MF0gTWluaW11bSByZXNvbHV0aW9uIHRoYXQgd2Ugem9vbSB0by5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4Wm9vbV0gTWF4aW11bSB6b29tIGxldmVsIHRoYXQgd2Ugem9vbSB0by4gSWZcbiAqIGBtaW5SZXNvbHV0aW9uYCBpcyBnaXZlbiwgdGhpcyBwcm9wZXJ0eSBpcyBpZ25vcmVkLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbl0gVGhlIGR1cmF0aW9uIG9mIHRoZSBhbmltYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuICogQnkgZGVmYXVsdCwgdGhlcmUgaXMgbm8gYW5pbWF0aW9uIHRvIHRoZSB0YXJnZXQgZXh0ZW50LlxuICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXIpOm51bWJlcn0gW2Vhc2luZ10gVGhlIGVhc2luZyBmdW5jdGlvbiB1c2VkIGR1cmluZ1xuICogdGhlIGFuaW1hdGlvbiAoZGVmYXVsdHMgdG8ge0BsaW5rIG1vZHVsZTpvbC9lYXNpbmd+aW5BbmRPdXR9KS5cbiAqIFRoZSBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBmb3IgZWFjaCBmcmFtZSB3aXRoIGEgbnVtYmVyIHJlcHJlc2VudGluZyBhXG4gKiBmcmFjdGlvbiBvZiB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24uICBUaGUgZnVuY3Rpb24gc2hvdWxkIHJldHVybiBhIG51bWJlclxuICogYmV0d2VlbiAwIGFuZCAxIHJlcHJlc2VudGluZyB0aGUgcHJvZ3Jlc3MgdG93YXJkIHRoZSBkZXN0aW5hdGlvbiBzdGF0ZS5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oYm9vbGVhbik6dm9pZH0gW2NhbGxiYWNrXSBGdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgdmlldyBpcyBpblxuICogaXRzIGZpbmFsIHBvc2l0aW9uLiBUaGUgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgd2l0aCBgdHJ1ZWAgaWYgdGhlIGFuaW1hdGlvblxuICogc2VyaWVzIGNvbXBsZXRlZCBvbiBpdHMgb3duIG9yIGBmYWxzZWAgaWYgaXQgd2FzIGNhbmNlbGxlZC5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFZpZXdPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBbY2VudGVyXSBUaGUgaW5pdGlhbCBjZW50ZXIgZm9yXG4gKiB0aGUgdmlldy4gSWYgYSB1c2VyIHByb2plY3Rpb24gaXMgbm90IHNldCwgdGhlIGNvb3JkaW5hdGUgc3lzdGVtIGZvciB0aGUgY2VudGVyIGlzXG4gKiBzcGVjaWZpZWQgd2l0aCB0aGUgYHByb2plY3Rpb25gIG9wdGlvbi4gTGF5ZXIgc291cmNlcyB3aWxsIG5vdCBiZSBmZXRjaGVkIGlmIHRoaXNcbiAqIGlzIG5vdCBzZXQsIGJ1dCB0aGUgY2VudGVyIGNhbiBiZSBzZXQgbGF0ZXIgd2l0aCB7QGxpbmsgI3NldENlbnRlcn0uXG4gKiBAcHJvcGVydHkge2Jvb2xlYW58bnVtYmVyfSBbY29uc3RyYWluUm90YXRpb249dHJ1ZV0gUm90YXRpb24gY29uc3RyYWludC5cbiAqIGBmYWxzZWAgbWVhbnMgbm8gY29uc3RyYWludC4gYHRydWVgIG1lYW5zIG5vIGNvbnN0cmFpbnQsIGJ1dCBzbmFwIHRvIHplcm9cbiAqIG5lYXIgemVyby4gQSBudW1iZXIgY29uc3RyYWlucyB0aGUgcm90YXRpb24gdG8gdGhhdCBudW1iZXIgb2YgdmFsdWVzLiBGb3JcbiAqIGV4YW1wbGUsIGA0YCB3aWxsIGNvbnN0cmFpbiB0aGUgcm90YXRpb24gdG8gMCwgOTAsIDE4MCwgYW5kIDI3MCBkZWdyZWVzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZW5hYmxlUm90YXRpb249dHJ1ZV0gRW5hYmxlIHJvdGF0aW9uLlxuICogSWYgYGZhbHNlYCwgYSByb3RhdGlvbiBjb25zdHJhaW50IHRoYXQgYWx3YXlzIHNldHMgdGhlIHJvdGF0aW9uIHRvIHplcm8gaXNcbiAqIHVzZWQuIFRoZSBgY29uc3RyYWluUm90YXRpb25gIG9wdGlvbiBoYXMgbm8gZWZmZWN0IGlmIGBlbmFibGVSb3RhdGlvbmAgaXNcbiAqIGBmYWxzZWAuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF0gVGhlIGV4dGVudCB0aGF0IGNvbnN0cmFpbnMgdGhlXG4gKiB2aWV3LCBpbiBvdGhlciB3b3Jkcywgbm90aGluZyBvdXRzaWRlIG9mIHRoaXMgZXh0ZW50IGNhbiBiZSB2aXNpYmxlIG9uIHRoZSBtYXAuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtjb25zdHJhaW5Pbmx5Q2VudGVyPWZhbHNlXSBJZiB0cnVlLCB0aGUgZXh0ZW50XG4gKiBjb25zdHJhaW50IHdpbGwgb25seSBhcHBseSB0byB0aGUgdmlldyBjZW50ZXIgYW5kIG5vdCB0aGUgd2hvbGUgZXh0ZW50LlxuICogQHByb3BlcnR5IHtib29sZWFufSBbc21vb3RoRXh0ZW50Q29uc3RyYWludD10cnVlXSBJZiB0cnVlLCB0aGUgZXh0ZW50XG4gKiBjb25zdHJhaW50IHdpbGwgYmUgYXBwbGllZCBzbW9vdGhseSwgaS5lLiBhbGxvdyB0aGUgdmlldyB0byBnbyBzbGlnaHRseSBvdXRzaWRlXG4gKiBvZiB0aGUgZ2l2ZW4gYGV4dGVudGAuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFJlc29sdXRpb25dIFRoZSBtYXhpbXVtIHJlc29sdXRpb24gdXNlZCB0byBkZXRlcm1pbmVcbiAqIHRoZSByZXNvbHV0aW9uIGNvbnN0cmFpbnQuIEl0IGlzIHVzZWQgdG9nZXRoZXIgd2l0aCBgbWluUmVzb2x1dGlvbmAgKG9yXG4gKiBgbWF4Wm9vbWApIGFuZCBgem9vbUZhY3RvcmAuIElmIHVuc3BlY2lmaWVkIGl0IGlzIGNhbGN1bGF0ZWQgaW4gc3VjaCBhIHdheVxuICogdGhhdCB0aGUgcHJvamVjdGlvbidzIHZhbGlkaXR5IGV4dGVudCBmaXRzIGluIGEgMjU2eDI1NiBweCB0aWxlLiBJZiB0aGVcbiAqIHByb2plY3Rpb24gaXMgU3BoZXJpY2FsIE1lcmNhdG9yICh0aGUgZGVmYXVsdCkgdGhlbiBgbWF4UmVzb2x1dGlvbmAgZGVmYXVsdHNcbiAqIHRvIGA0MDA3NTAxNi42ODU1Nzg0OSAvIDI1NiA9IDE1NjU0My4wMzM5MjgwNDA5N2AuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblJlc29sdXRpb25dIFRoZSBtaW5pbXVtIHJlc29sdXRpb24gdXNlZCB0byBkZXRlcm1pbmVcbiAqIHRoZSByZXNvbHV0aW9uIGNvbnN0cmFpbnQuICBJdCBpcyB1c2VkIHRvZ2V0aGVyIHdpdGggYG1heFJlc29sdXRpb25gIChvclxuICogYG1pblpvb21gKSBhbmQgYHpvb21GYWN0b3JgLiAgSWYgdW5zcGVjaWZpZWQgaXQgaXMgY2FsY3VsYXRlZCBhc3N1bWluZyAyOVxuICogem9vbSBsZXZlbHMgKHdpdGggYSBmYWN0b3Igb2YgMikuIElmIHRoZSBwcm9qZWN0aW9uIGlzIFNwaGVyaWNhbCBNZXJjYXRvclxuICogKHRoZSBkZWZhdWx0KSB0aGVuIGBtaW5SZXNvbHV0aW9uYCBkZWZhdWx0cyB0b1xuICogYDQwMDc1MDE2LjY4NTU3ODQ5IC8gMjU2IC8gTWF0aC5wb3coMiwgMjgpID0gMC4wMDA1ODMxNjgyNDU1ODM5MjUzYC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4Wm9vbT0yOF0gVGhlIG1heGltdW0gem9vbSBsZXZlbCB1c2VkIHRvIGRldGVybWluZSB0aGVcbiAqIHJlc29sdXRpb24gY29uc3RyYWludC4gSXQgaXMgdXNlZCB0b2dldGhlciB3aXRoIGBtaW5ab29tYCAob3JcbiAqIGBtYXhSZXNvbHV0aW9uYCkgYW5kIGB6b29tRmFjdG9yYC4gIE5vdGUgdGhhdCBpZiBgbWluUmVzb2x1dGlvbmAgaXMgYWxzb1xuICogcHJvdmlkZWQsIGl0IGlzIGdpdmVuIHByZWNlZGVuY2Ugb3ZlciBgbWF4Wm9vbWAuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblpvb209MF0gVGhlIG1pbmltdW0gem9vbSBsZXZlbCB1c2VkIHRvIGRldGVybWluZSB0aGVcbiAqIHJlc29sdXRpb24gY29uc3RyYWludC4gSXQgaXMgdXNlZCB0b2dldGhlciB3aXRoIGBtYXhab29tYCAob3JcbiAqIGBtaW5SZXNvbHV0aW9uYCkgYW5kIGB6b29tRmFjdG9yYC4gIE5vdGUgdGhhdCBpZiBgbWF4UmVzb2x1dGlvbmAgaXMgYWxzb1xuICogcHJvdmlkZWQsIGl0IGlzIGdpdmVuIHByZWNlZGVuY2Ugb3ZlciBgbWluWm9vbWAuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFttdWx0aVdvcmxkPWZhbHNlXSBJZiBgZmFsc2VgIHRoZSB2aWV3IGlzIGNvbnN0cmFpbmVkIHNvXG4gKiBvbmx5IG9uZSB3b3JsZCBpcyB2aXNpYmxlLCBhbmQgeW91IGNhbm5vdCBwYW4gb2ZmIHRoZSBlZGdlLiAgSWYgYHRydWVgIHRoZSBtYXBcbiAqIG1heSBzaG93IG11bHRpcGxlIHdvcmxkcyBhdCBsb3cgem9vbSBsZXZlbHMuICBPbmx5IHVzZWQgaWYgdGhlIGBwcm9qZWN0aW9uYCBpc1xuICogZ2xvYmFsLiAgTm90ZSB0aGF0IGlmIGBleHRlbnRgIGlzIGFsc28gcHJvdmlkZWQgaXQgaXMgZ2l2ZW4gcHJlY2VkZW5jZS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2NvbnN0cmFpblJlc29sdXRpb249ZmFsc2VdIElmIHRydWUsIHRoZSB2aWV3IHdpbGwgYWx3YXlzXG4gKiBhbmltYXRlIHRvIHRoZSBjbG9zZXN0IHpvb20gbGV2ZWwgYWZ0ZXIgYW4gaW50ZXJhY3Rpb247IGZhbHNlIG1lYW5zXG4gKiBpbnRlcm1lZGlhcnkgem9vbSBsZXZlbHMgYXJlIGFsbG93ZWQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzbW9vdGhSZXNvbHV0aW9uQ29uc3RyYWludD10cnVlXSBJZiB0cnVlLCB0aGUgcmVzb2x1dGlvblxuICogbWluL21heCB2YWx1ZXMgd2lsbCBiZSBhcHBsaWVkIHNtb290aGx5LCBpLiBlLiBhbGxvdyB0aGUgdmlldyB0byBleGNlZWQgc2xpZ2h0bHlcbiAqIHRoZSBnaXZlbiByZXNvbHV0aW9uIG9yIHpvb20gYm91bmRzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbc2hvd0Z1bGxFeHRlbnQ9ZmFsc2VdIEFsbG93IHRoZSB2aWV3IHRvIGJlIHpvb21lZCBvdXQgdG9cbiAqIHNob3cgdGhlIGZ1bGwgY29uZmlndXJlZCBleHRlbnQuIEJ5IGRlZmF1bHQsIHdoZW4gYSB2aWV3IGlzIGNvbmZpZ3VyZWQgd2l0aCBhblxuICogZXh0ZW50LCB1c2VycyB3aWxsIG5vdCBiZSBhYmxlIHRvIHpvb20gb3V0IHNvIHRoZSB2aWV3cG9ydCBleGNlZWRzIHRoZSBleHRlbnQgaW5cbiAqIGVpdGhlciBkaW1lbnNpb24uIFRoaXMgbWVhbnMgdGhlIGZ1bGwgZXh0ZW50IG1heSBub3QgYmUgdmlzaWJsZSBpZiB0aGUgdmlld3BvcnRcbiAqIGlzIHRhbGxlciBvciB3aWRlciB0aGFuIHRoZSBhc3BlY3QgcmF0aW8gb2YgdGhlIGNvbmZpZ3VyZWQgZXh0ZW50LiBJZlxuICogc2hvd0Z1bGxFeHRlbnQgaXMgdHJ1ZSwgdGhlIHVzZXIgd2lsbCBiZSBhYmxlIHRvIHpvb20gb3V0IHNvIHRoYXQgdGhlIHZpZXdwb3J0XG4gKiBleGNlZWRzIHRoZSBoZWlnaHQgb3Igd2lkdGggb2YgdGhlIGNvbmZpZ3VyZWQgZXh0ZW50LCBidXQgbm90IGJvdGgsIGFsbG93aW5nIHRoZVxuICogZnVsbCBleHRlbnQgdG8gYmUgc2hvd24uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gW3Byb2plY3Rpb249J0VQU0c6Mzg1NyddIFRoZVxuICogcHJvamVjdGlvbi4gVGhlIGRlZmF1bHQgaXMgU3BoZXJpY2FsIE1lcmNhdG9yLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyZXNvbHV0aW9uXSBUaGUgaW5pdGlhbCByZXNvbHV0aW9uIGZvciB0aGUgdmlldy4gVGhlXG4gKiB1bml0cyBhcmUgYHByb2plY3Rpb25gIHVuaXRzIHBlciBwaXhlbCAoZS5nLiBtZXRlcnMgcGVyIHBpeGVsKS4gQW5cbiAqIGFsdGVybmF0aXZlIHRvIHNldHRpbmcgdGhpcyBpcyB0byBzZXQgYHpvb21gLiBMYXllciBzb3VyY2VzIHdpbGwgbm90IGJlXG4gKiBmZXRjaGVkIGlmIG5laXRoZXIgdGhpcyBub3IgYHpvb21gIGFyZSBkZWZpbmVkLCBidXQgdGhleSBjYW4gYmUgc2V0IGxhdGVyXG4gKiB3aXRoIHtAbGluayAjc2V0Wm9vbX0gb3Ige0BsaW5rICNzZXRSZXNvbHV0aW9ufS5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gW3Jlc29sdXRpb25zXSBSZXNvbHV0aW9ucyB0byBkZXRlcm1pbmUgdGhlXG4gKiByZXNvbHV0aW9uIGNvbnN0cmFpbnQuIElmIHNldCB0aGUgYG1heFJlc29sdXRpb25gLCBgbWluUmVzb2x1dGlvbmAsXG4gKiBgbWluWm9vbWAsIGBtYXhab29tYCwgYW5kIGB6b29tRmFjdG9yYCBvcHRpb25zIGFyZSBpZ25vcmVkLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyb3RhdGlvbj0wXSBUaGUgaW5pdGlhbCByb3RhdGlvbiBmb3IgdGhlIHZpZXcgaW4gcmFkaWFuc1xuICogKHBvc2l0aXZlIHJvdGF0aW9uIGNsb2Nrd2lzZSwgMCBtZWFucyBOb3J0aCkuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3pvb21dIE9ubHkgdXNlZCBpZiBgcmVzb2x1dGlvbmAgaXMgbm90IGRlZmluZWQuIFpvb21cbiAqIGxldmVsIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBpbml0aWFsIHJlc29sdXRpb24gZm9yIHRoZSB2aWV3LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6b29tRmFjdG9yPTJdIFRoZSB6b29tIGZhY3RvciB1c2VkIHRvIGNvbXB1dGUgdGhlXG4gKiBjb3JyZXNwb25kaW5nIHJlc29sdXRpb24uXG4gKiBAcHJvcGVydHkgeyFBcnJheTxudW1iZXI+fSBbcGFkZGluZz1bMCwgMCwgMCwgMF1dIFBhZGRpbmcgKGluIGNzcyBwaXhlbHMpLlxuICogSWYgdGhlIG1hcCB2aWV3cG9ydCBpcyBwYXJ0aWFsbHkgY292ZXJlZCB3aXRoIG90aGVyIGNvbnRlbnQgKG92ZXJsYXlzKSBhbG9uZ1xuICogaXRzIGVkZ2VzLCB0aGlzIHNldHRpbmcgYWxsb3dzIHRvIHNoaWZ0IHRoZSBjZW50ZXIgb2YgdGhlIHZpZXdwb3J0IGF3YXkgZnJvbVxuICogdGhhdCBjb250ZW50LiBUaGUgb3JkZXIgb2YgdGhlIHZhbHVlcyBpcyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBBbmltYXRpb25PcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBbY2VudGVyXSBUaGUgY2VudGVyIG9mIHRoZSB2aWV3IGF0IHRoZSBlbmQgb2ZcbiAqIHRoZSBhbmltYXRpb24uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3pvb21dIFRoZSB6b29tIGxldmVsIG9mIHRoZSB2aWV3IGF0IHRoZSBlbmQgb2YgdGhlXG4gKiBhbmltYXRpb24uIFRoaXMgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGByZXNvbHV0aW9uYC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmVzb2x1dGlvbl0gVGhlIHJlc29sdXRpb24gb2YgdGhlIHZpZXcgYXQgdGhlIGVuZFxuICogb2YgdGhlIGFuaW1hdGlvbi4gIElmIGB6b29tYCBpcyBhbHNvIHByb3ZpZGVkLCB0aGlzIG9wdGlvbiB3aWxsIGJlIGlnbm9yZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3JvdGF0aW9uXSBUaGUgcm90YXRpb24gb2YgdGhlIHZpZXcgYXQgdGhlIGVuZCBvZlxuICogdGhlIGFuaW1hdGlvbi5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFthbmNob3JdIE9wdGlvbmFsIGFuY2hvciB0byByZW1haW4gZml4ZWRcbiAqIGR1cmluZyBhIHJvdGF0aW9uIG9yIHJlc29sdXRpb24gYW5pbWF0aW9uLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj0xMDAwXSBUaGUgZHVyYXRpb24gb2YgdGhlIGFuaW1hdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6bnVtYmVyfSBbZWFzaW5nXSBUaGUgZWFzaW5nIGZ1bmN0aW9uIHVzZWRcbiAqIGR1cmluZyB0aGUgYW5pbWF0aW9uIChkZWZhdWx0cyB0byB7QGxpbmsgbW9kdWxlOm9sL2Vhc2luZ35pbkFuZE91dH0pLlxuICogVGhlIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGZvciBlYWNoIGZyYW1lIHdpdGggYSBudW1iZXIgcmVwcmVzZW50aW5nIGFcbiAqIGZyYWN0aW9uIG9mIHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbi4gIFRoZSBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIGEgbnVtYmVyXG4gKiBiZXR3ZWVuIDAgYW5kIDEgcmVwcmVzZW50aW5nIHRoZSBwcm9ncmVzcyB0b3dhcmQgdGhlIGRlc3RpbmF0aW9uIHN0YXRlLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gU3RhdGVcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNlbnRlclxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uXG4gKiBAcHJvcGVydHkge251bWJlcn0gcmVzb2x1dGlvblxuICogQHByb3BlcnR5IHtudW1iZXJ9IHJvdGF0aW9uXG4gKiBAcHJvcGVydHkge251bWJlcn0gem9vbVxuICovXG5cbi8qKlxuICogRGVmYXVsdCBtaW4gem9vbSBsZXZlbCBmb3IgdGhlIG1hcCB2aWV3LlxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG52YXIgREVGQVVMVF9NSU5fWk9PTSA9IDA7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEEgVmlldyBvYmplY3QgcmVwcmVzZW50cyBhIHNpbXBsZSAyRCB2aWV3IG9mIHRoZSBtYXAuXG4gKlxuICogVGhpcyBpcyB0aGUgb2JqZWN0IHRvIGFjdCB1cG9uIHRvIGNoYW5nZSB0aGUgY2VudGVyLCByZXNvbHV0aW9uLFxuICogYW5kIHJvdGF0aW9uIG9mIHRoZSBtYXAuXG4gKlxuICogQSBWaWV3IGhhcyBhIGBwcm9qZWN0aW9uYC4gVGhlIHByb2plY3Rpb24gZGV0ZXJtaW5lcyB0aGVcbiAqIGNvb3JkaW5hdGUgc3lzdGVtIG9mIHRoZSBjZW50ZXIsIGFuZCBpdHMgdW5pdHMgZGV0ZXJtaW5lIHRoZSB1bml0cyBvZiB0aGVcbiAqIHJlc29sdXRpb24gKHByb2plY3Rpb24gdW5pdHMgcGVyIHBpeGVsKS4gVGhlIGRlZmF1bHQgcHJvamVjdGlvbiBpc1xuICogU3BoZXJpY2FsIE1lcmNhdG9yIChFUFNHOjM4NTcpLlxuICpcbiAqICMjIyBUaGUgdmlldyBzdGF0ZXNcbiAqXG4gKiBBIFZpZXcgaXMgZGV0ZXJtaW5lZCBieSB0aHJlZSBzdGF0ZXM6IGBjZW50ZXJgLCBgcmVzb2x1dGlvbmAsXG4gKiBhbmQgYHJvdGF0aW9uYC4gRWFjaCBzdGF0ZSBoYXMgYSBjb3JyZXNwb25kaW5nIGdldHRlciBhbmQgc2V0dGVyLCBlLmcuXG4gKiBgZ2V0Q2VudGVyYCBhbmQgYHNldENlbnRlcmAgZm9yIHRoZSBgY2VudGVyYCBzdGF0ZS5cbiAqXG4gKiBUaGUgYHpvb21gIHN0YXRlIGlzIGFjdHVhbGx5IG5vdCBzYXZlZCBvbiB0aGUgdmlldzogYWxsIGNvbXB1dGF0aW9uc1xuICogaW50ZXJuYWxseSB1c2UgdGhlIGByZXNvbHV0aW9uYCBzdGF0ZS4gU3RpbGwsIHRoZSBgc2V0Wm9vbWAgYW5kIGBnZXRab29tYFxuICogbWV0aG9kcyBhcmUgYXZhaWxhYmxlLCBhcyB3ZWxsIGFzIGBnZXRSZXNvbHV0aW9uRm9yWm9vbWAgYW5kXG4gKiBgZ2V0Wm9vbUZvclJlc29sdXRpb25gIHRvIHN3aXRjaCBmcm9tIG9uZSBzeXN0ZW0gdG8gdGhlIG90aGVyLlxuICpcbiAqICMjIyBUaGUgY29uc3RyYWludHNcbiAqXG4gKiBgc2V0Q2VudGVyYCwgYHNldFJlc29sdXRpb25gIGFuZCBgc2V0Um90YXRpb25gIGNhbiBiZSB1c2VkIHRvIGNoYW5nZSB0aGVcbiAqIHN0YXRlcyBvZiB0aGUgdmlldywgYnV0IGFueSBjb25zdHJhaW50IGRlZmluZWQgaW4gdGhlIGNvbnN0cnVjdG9yIHdpbGxcbiAqIGJlIGFwcGxpZWQgYWxvbmcgdGhlIHdheS5cbiAqXG4gKiBBIFZpZXcgb2JqZWN0IGNhbiBoYXZlIGEgKnJlc29sdXRpb24gY29uc3RyYWludCosIGEgKnJvdGF0aW9uIGNvbnN0cmFpbnQqXG4gKiBhbmQgYSAqY2VudGVyIGNvbnN0cmFpbnQqLlxuICpcbiAqIFRoZSAqcmVzb2x1dGlvbiBjb25zdHJhaW50KiB0eXBpY2FsbHkgcmVzdHJpY3RzIG1pbi9tYXggdmFsdWVzIGFuZFxuICogc25hcHMgdG8gc3BlY2lmaWMgcmVzb2x1dGlvbnMuIEl0IGlzIGRldGVybWluZWQgYnkgdGhlIGZvbGxvd2luZ1xuICogb3B0aW9uczogYHJlc29sdXRpb25zYCwgYG1heFJlc29sdXRpb25gLCBgbWF4Wm9vbWAgYW5kIGB6b29tRmFjdG9yYC5cbiAqIElmIGByZXNvbHV0aW9uc2AgaXMgc2V0LCB0aGUgb3RoZXIgdGhyZWUgb3B0aW9ucyBhcmUgaWdub3JlZC4gU2VlXG4gKiBkb2N1bWVudGF0aW9uIGZvciBlYWNoIG9wdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4gQnkgZGVmYXVsdCwgdGhlIHZpZXdcbiAqIG9ubHkgaGFzIGEgbWluL21heCByZXN0cmljdGlvbiBhbmQgYWxsb3cgaW50ZXJtZWRpYXJ5IHpvb20gbGV2ZWxzIHdoZW5cbiAqIHBpbmNoLXpvb21pbmcgZm9yIGV4YW1wbGUuXG4gKlxuICogVGhlICpyb3RhdGlvbiBjb25zdHJhaW50KiBzbmFwcyB0byBzcGVjaWZpYyBhbmdsZXMuIEl0IGlzIGRldGVybWluZWRcbiAqIGJ5IHRoZSBmb2xsb3dpbmcgb3B0aW9uczogYGVuYWJsZVJvdGF0aW9uYCBhbmQgYGNvbnN0cmFpblJvdGF0aW9uYC5cbiAqIEJ5IGRlZmF1bHQgcm90YXRpb24gaXMgYWxsb3dlZCBhbmQgaXRzIHZhbHVlIGlzIHNuYXBwZWQgdG8gemVybyB3aGVuIGFwcHJvYWNoaW5nIHRoZVxuICogaG9yaXpvbnRhbC5cbiAqXG4gKiBUaGUgKmNlbnRlciBjb25zdHJhaW50KiBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBgZXh0ZW50YCBvcHRpb24uIEJ5XG4gKiBkZWZhdWx0IHRoZSB2aWV3IGNlbnRlciBpcyBub3QgY29uc3RyYWluZWQgYXQgYWxsLlxuICpcbiAqICMjIyBDaGFuZ2luZyB0aGUgdmlldyBzdGF0ZVxuICpcbiAqIEl0IGlzIGltcG9ydGFudCB0byBub3RlIHRoYXQgYHNldFpvb21gLCBgc2V0UmVzb2x1dGlvbmAsIGBzZXRDZW50ZXJgIGFuZFxuICogYHNldFJvdGF0aW9uYCBhcmUgc3ViamVjdCB0byB0aGUgYWJvdmUgbWVudGlvbmVkIGNvbnN0cmFpbnRzLiBBcyBzdWNoLCBpdFxuICogbWF5IHNvbWV0aW1lcyBub3QgYmUgcG9zc2libGUgdG8ga25vdyBpbiBhZHZhbmNlIHRoZSByZXN1bHRpbmcgc3RhdGUgb2YgdGhlXG4gKiBWaWV3LiBGb3IgZXhhbXBsZSwgY2FsbGluZyBgc2V0UmVzb2x1dGlvbigxMClgIGRvZXMgbm90IGd1YXJhbnRlZSB0aGF0XG4gKiBgZ2V0UmVzb2x1dGlvbigpYCB3aWxsIHJldHVybiBgMTBgLlxuICpcbiAqIEEgY29uc2VxdWVuY2Ugb2YgdGhpcyBpcyB0aGF0LCB3aGVuIGFwcGx5aW5nIGEgZGVsdGEgb24gdGhlIHZpZXcgc3RhdGUsIG9uZVxuICogc2hvdWxkIHVzZSBgYWRqdXN0Q2VudGVyYCwgYGFkanVzdFJvdGF0aW9uYCwgYGFkanVzdFpvb21gIGFuZCBgYWRqdXN0UmVzb2x1dGlvbmBcbiAqIHJhdGhlciB0aGFuIHRoZSBjb3JyZXNwb25kaW5nIHNldHRlcnMuIFRoaXMgd2lsbCBsZXQgdmlldyBkbyBpdHMgaW50ZXJuYWxcbiAqIGNvbXB1dGF0aW9ucy4gQmVzaWRlcywgdGhlIGBhZGp1c3QqYCBtZXRob2RzIGFsc28gdGFrZSBhbiBgb3B0X2FuY2hvcmBcbiAqIGFyZ3VtZW50IHdoaWNoIGFsbG93cyBzcGVjaWZ5aW5nIGFuIG9yaWdpbiBmb3IgdGhlIHRyYW5zZm9ybWF0aW9uLlxuICpcbiAqICMjIyBJbnRlcmFjdGluZyB3aXRoIHRoZSB2aWV3XG4gKlxuICogVmlldyBjb25zdHJhaW50cyBhcmUgdXN1YWxseSBvbmx5IGFwcGxpZWQgd2hlbiB0aGUgdmlldyBpcyAqYXQgcmVzdCosIG1lYW5pbmcgdGhhdFxuICogbm8gaW50ZXJhY3Rpb24gb3IgYW5pbWF0aW9uIGlzIG9uZ29pbmcuIEFzIHN1Y2gsIGlmIHRoZSB1c2VyIHB1dHMgdGhlIHZpZXcgaW4gYVxuICogc3RhdGUgdGhhdCBpcyBub3QgZXF1aXZhbGVudCB0byBhIGNvbnN0cmFpbmVkIG9uZSAoZS5nLiByb3RhdGluZyB0aGUgdmlldyB3aGVuXG4gKiB0aGUgc25hcCBhbmdsZSBpcyAwKSwgYW4gYW5pbWF0aW9uIHdpbGwgYmUgdHJpZ2dlcmVkIGF0IHRoZSBpbnRlcmFjdGlvbiBlbmQgdG9cbiAqIHB1dCBiYWNrIHRoZSB2aWV3IHRvIGEgc3RhYmxlIHN0YXRlO1xuICpcbiAqIEBhcGlcbiAqL1xuXG52YXIgVmlldyA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhWaWV3LCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtWaWV3T3B0aW9ucz19IG9wdF9vcHRpb25zIFZpZXcgb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBWaWV3KG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gYXNzaWduKHt9LCBvcHRfb3B0aW9ucyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIF90aGlzLmhpbnRzXyA9IFswLCAwXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxBcnJheTxBbmltYXRpb24+Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmFuaW1hdGlvbnNfID0gW107XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnVwZGF0ZUFuaW1hdGlvbktleV87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnByb2plY3Rpb25fID0gY3JlYXRlUHJvamVjdGlvbihvcHRpb25zLnByb2plY3Rpb24sICdFUFNHOjM4NTcnKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnZpZXdwb3J0U2l6ZV8gPSBbMTAwLCAxMDBdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnRhcmdldENlbnRlcl8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy50YXJnZXRSZXNvbHV0aW9uXztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGFyZ2V0Um90YXRpb25fO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLmNhbmNlbEFuY2hvcl8gPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAob3B0aW9ucy5jZW50ZXIpIHtcbiAgICAgIG9wdGlvbnMuY2VudGVyID0gZnJvbVVzZXJDb29yZGluYXRlKG9wdGlvbnMuY2VudGVyLCBfdGhpcy5wcm9qZWN0aW9uXyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuZXh0ZW50KSB7XG4gICAgICBvcHRpb25zLmV4dGVudCA9IGZyb21Vc2VyRXh0ZW50KG9wdGlvbnMuZXh0ZW50LCBfdGhpcy5wcm9qZWN0aW9uXyk7XG4gICAgfVxuXG4gICAgX3RoaXMuYXBwbHlPcHRpb25zXyhvcHRpb25zKTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogU2V0IHVwIHRoZSB2aWV3IHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7Vmlld09wdGlvbnN9IG9wdGlvbnMgVmlldyBvcHRpb25zLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmFwcGx5T3B0aW9uc18gPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCAqPn1cbiAgICAgKi9cbiAgICB2YXIgcHJvcGVydGllcyA9IHt9O1xuICAgIHZhciByZXNvbHV0aW9uQ29uc3RyYWludEluZm8gPSBjcmVhdGVSZXNvbHV0aW9uQ29uc3RyYWludChvcHRpb25zKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLm1heFJlc29sdXRpb25fID0gcmVzb2x1dGlvbkNvbnN0cmFpbnRJbmZvLm1heFJlc29sdXRpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5taW5SZXNvbHV0aW9uXyA9IHJlc29sdXRpb25Db25zdHJhaW50SW5mby5taW5SZXNvbHV0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMuem9vbUZhY3Rvcl8gPSByZXNvbHV0aW9uQ29uc3RyYWludEluZm8uem9vbUZhY3RvcjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHRoaXMucmVzb2x1dGlvbnNfID0gb3B0aW9ucy5yZXNvbHV0aW9ucztcbiAgICAvKipcbiAgICAgKiBQYWRkaW5nIChpbiBjc3MgcGl4ZWxzKS5cbiAgICAgKiBJZiB0aGUgbWFwIHZpZXdwb3J0IGlzIHBhcnRpYWxseSBjb3ZlcmVkIHdpdGggb3RoZXIgY29udGVudCAob3ZlcmxheXMpIGFsb25nXG4gICAgICogaXRzIGVkZ2VzLCB0aGlzIHNldHRpbmcgYWxsb3dzIHRvIHNoaWZ0IHRoZSBjZW50ZXIgb2YgdGhlIHZpZXdwb3J0IGF3YXkgZnJvbSB0aGF0XG4gICAgICogY29udGVudC4gVGhlIG9yZGVyIG9mIHRoZSB2YWx1ZXMgaW4gdGhlIGFycmF5IGlzIHRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdC5cbiAgICAgKiBUaGUgZGVmYXVsdCBpcyBubyBwYWRkaW5nLCB3aGljaCBpcyBlcXVpdmFsZW50IHRvIGBbMCwgMCwgMCwgMF1gLlxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fHVuZGVmaW5lZH1cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgICB0aGlzLnBhZGRpbmcgPSBvcHRpb25zLnBhZGRpbmc7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5taW5ab29tXyA9IHJlc29sdXRpb25Db25zdHJhaW50SW5mby5taW5ab29tO1xuICAgIHZhciBjZW50ZXJDb25zdHJhaW50ID0gY3JlYXRlQ2VudGVyQ29uc3RyYWludChvcHRpb25zKTtcbiAgICB2YXIgcmVzb2x1dGlvbkNvbnN0cmFpbnQgPSByZXNvbHV0aW9uQ29uc3RyYWludEluZm8uY29uc3RyYWludDtcbiAgICB2YXIgcm90YXRpb25Db25zdHJhaW50ID0gY3JlYXRlUm90YXRpb25Db25zdHJhaW50KG9wdGlvbnMpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0NvbnN0cmFpbnRzfVxuICAgICAqL1xuXG4gICAgdGhpcy5jb25zdHJhaW50c18gPSB7XG4gICAgICBjZW50ZXI6IGNlbnRlckNvbnN0cmFpbnQsXG4gICAgICByZXNvbHV0aW9uOiByZXNvbHV0aW9uQ29uc3RyYWludCxcbiAgICAgIHJvdGF0aW9uOiByb3RhdGlvbkNvbnN0cmFpbnRcbiAgICB9O1xuICAgIHRoaXMuc2V0Um90YXRpb24ob3B0aW9ucy5yb3RhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yb3RhdGlvbiA6IDApO1xuICAgIHRoaXMuc2V0Q2VudGVySW50ZXJuYWwob3B0aW9ucy5jZW50ZXIgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2VudGVyIDogbnVsbCk7XG5cbiAgICBpZiAob3B0aW9ucy5yZXNvbHV0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuc2V0UmVzb2x1dGlvbihvcHRpb25zLnJlc29sdXRpb24pO1xuICAgIH0gZWxzZSBpZiAob3B0aW9ucy56b29tICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuc2V0Wm9vbShvcHRpb25zLnpvb20pO1xuICAgIH1cblxuICAgIHRoaXMuc2V0UHJvcGVydGllcyhwcm9wZXJ0aWVzKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtWaWV3T3B0aW9uc31cbiAgICAgKi9cblxuICAgIHRoaXMub3B0aW9uc18gPSBvcHRpb25zO1xuICB9O1xuICAvKipcbiAgICogR2V0IGFuIHVwZGF0ZWQgdmVyc2lvbiBvZiB0aGUgdmlldyBvcHRpb25zIHVzZWQgdG8gY29uc3RydWN0IHRoZSB2aWV3LiAgVGhlXG4gICAqIGN1cnJlbnQgcmVzb2x1dGlvbiAob3Igem9vbSksIGNlbnRlciwgYW5kIHJvdGF0aW9uIGFyZSBhcHBsaWVkIHRvIGFueSBzdG9yZWRcbiAgICogb3B0aW9ucy4gIFRoZSBwcm92aWRlZCBvcHRpb25zIGNhbiBiZSB1c2VkIHRvIGFwcGx5IG5ldyBtaW4vbWF4IHpvb20gb3JcbiAgICogcmVzb2x1dGlvbiBsaW1pdHMuXG4gICAqIEBwYXJhbSB7Vmlld09wdGlvbnN9IG5ld09wdGlvbnMgTmV3IG9wdGlvbnMgdG8gYmUgYXBwbGllZC5cbiAgICogQHJldHVybiB7Vmlld09wdGlvbnN9IE5ldyBvcHRpb25zIHVwZGF0ZWQgd2l0aCB0aGUgY3VycmVudCB2aWV3IHN0YXRlLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFVwZGF0ZWRPcHRpb25zXyA9IGZ1bmN0aW9uIChuZXdPcHRpb25zKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhc3NpZ24oe30sIHRoaXMub3B0aW9uc18pOyAvLyBwcmVzZXJ2ZSByZXNvbHV0aW9uIChvciB6b29tKVxuXG4gICAgaWYgKG9wdGlvbnMucmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBvcHRpb25zLnJlc29sdXRpb24gPSB0aGlzLmdldFJlc29sdXRpb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucy56b29tID0gdGhpcy5nZXRab29tKCk7XG4gICAgfSAvLyBwcmVzZXJ2ZSBjZW50ZXJcblxuXG4gICAgb3B0aW9ucy5jZW50ZXIgPSB0aGlzLmdldENlbnRlckludGVybmFsKCk7IC8vIHByZXNlcnZlIHJvdGF0aW9uXG5cbiAgICBvcHRpb25zLnJvdGF0aW9uID0gdGhpcy5nZXRSb3RhdGlvbigpO1xuICAgIHJldHVybiBhc3NpZ24oe30sIG9wdGlvbnMsIG5ld09wdGlvbnMpO1xuICB9O1xuICAvKipcbiAgICogQW5pbWF0ZSB0aGUgdmlldy4gIFRoZSB2aWV3J3MgY2VudGVyLCB6b29tIChvciByZXNvbHV0aW9uKSwgYW5kIHJvdGF0aW9uXG4gICAqIGNhbiBiZSBhbmltYXRlZCBmb3Igc21vb3RoIHRyYW5zaXRpb25zIGJldHdlZW4gdmlldyBzdGF0ZXMuICBGb3IgZXhhbXBsZSxcbiAgICogdG8gYW5pbWF0ZSB0aGUgdmlldyB0byBhIG5ldyB6b29tIGxldmVsOlxuICAgKlxuICAgKiAgICAgdmlldy5hbmltYXRlKHt6b29tOiB2aWV3LmdldFpvb20oKSArIDF9KTtcbiAgICpcbiAgICogQnkgZGVmYXVsdCwgdGhlIGFuaW1hdGlvbiBsYXN0cyBvbmUgc2Vjb25kIGFuZCB1c2VzIGluLWFuZC1vdXQgZWFzaW5nLiAgWW91XG4gICAqIGNhbiBjdXN0b21pemUgdGhpcyBiZWhhdmlvciBieSBpbmNsdWRpbmcgYGR1cmF0aW9uYCAoaW4gbWlsbGlzZWNvbmRzKSBhbmRcbiAgICogYGVhc2luZ2Agb3B0aW9ucyAoc2VlIHtAbGluayBtb2R1bGU6b2wvZWFzaW5nfSkuXG4gICAqXG4gICAqIFRvIGNoYWluIHRvZ2V0aGVyIG11bHRpcGxlIGFuaW1hdGlvbnMsIGNhbGwgdGhlIG1ldGhvZCB3aXRoIG11bHRpcGxlXG4gICAqIGFuaW1hdGlvbiBvYmplY3RzLiAgRm9yIGV4YW1wbGUsIHRvIGZpcnN0IHpvb20gYW5kIHRoZW4gcGFuOlxuICAgKlxuICAgKiAgICAgdmlldy5hbmltYXRlKHt6b29tOiAxMH0sIHtjZW50ZXI6IFswLCAwXX0pO1xuICAgKlxuICAgKiBJZiB5b3UgcHJvdmlkZSBhIGZ1bmN0aW9uIGFzIHRoZSBsYXN0IGFyZ3VtZW50IHRvIHRoZSBhbmltYXRlIG1ldGhvZCwgaXRcbiAgICogd2lsbCBnZXQgY2FsbGVkIGF0IHRoZSBlbmQgb2YgYW4gYW5pbWF0aW9uIHNlcmllcy4gIFRoZSBjYWxsYmFjayB3aWxsIGJlXG4gICAqIGNhbGxlZCB3aXRoIGB0cnVlYCBpZiB0aGUgYW5pbWF0aW9uIHNlcmllcyBjb21wbGV0ZWQgb24gaXRzIG93biBvciBgZmFsc2VgXG4gICAqIGlmIGl0IHdhcyBjYW5jZWxsZWQuXG4gICAqXG4gICAqIEFuaW1hdGlvbnMgYXJlIGNhbmNlbGxlZCBieSB1c2VyIGludGVyYWN0aW9ucyAoZS5nLiBkcmFnZ2luZyB0aGUgbWFwKSBvciBieVxuICAgKiBjYWxsaW5nIGB2aWV3LnNldENlbnRlcigpYCwgYHZpZXcuc2V0UmVzb2x1dGlvbigpYCwgb3IgYHZpZXcuc2V0Um90YXRpb24oKWBcbiAgICogKG9yIGFub3RoZXIgbWV0aG9kIHRoYXQgY2FsbHMgb25lIG9mIHRoZXNlKS5cbiAgICpcbiAgICogQHBhcmFtIHsuLi4oQW5pbWF0aW9uT3B0aW9uc3xmdW5jdGlvbihib29sZWFuKTogdm9pZCl9IHZhcl9hcmdzIEFuaW1hdGlvblxuICAgKiAgICAgb3B0aW9ucy4gIE11bHRpcGxlIGFuaW1hdGlvbnMgY2FuIGJlIHJ1biBpbiBzZXJpZXMgYnkgcGFzc2luZyBtdWx0aXBsZVxuICAgKiAgICAgb3B0aW9ucyBvYmplY3RzLiAgVG8gcnVuIG11bHRpcGxlIGFuaW1hdGlvbnMgaW4gcGFyYWxsZWwsIGNhbGwgdGhlIG1ldGhvZFxuICAgKiAgICAgbXVsdGlwbGUgdGltZXMuICBBbiBvcHRpb25hbCBjYWxsYmFjayBjYW4gYmUgcHJvdmlkZWQgYXMgYSBmaW5hbFxuICAgKiAgICAgYXJndW1lbnQuICBUaGUgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgd2l0aCBhIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyXG4gICAqICAgICB0aGUgYW5pbWF0aW9uIGNvbXBsZXRlZCB3aXRob3V0IGJlaW5nIGNhbmNlbGxlZC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmFuaW1hdGUgPSBmdW5jdGlvbiAodmFyX2FyZ3MpIHtcbiAgICBpZiAodGhpcy5pc0RlZigpICYmICF0aGlzLmdldEFuaW1hdGluZygpKSB7XG4gICAgICB0aGlzLnJlc29sdmVDb25zdHJhaW50cygwKTtcbiAgICB9XG5cbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHNbaV07XG5cbiAgICAgIGlmIChvcHRpb25zLmNlbnRlcikge1xuICAgICAgICBvcHRpb25zID0gYXNzaWduKHt9LCBvcHRpb25zKTtcbiAgICAgICAgb3B0aW9ucy5jZW50ZXIgPSBmcm9tVXNlckNvb3JkaW5hdGUob3B0aW9ucy5jZW50ZXIsIHRoaXMuZ2V0UHJvamVjdGlvbigpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnMuYW5jaG9yKSB7XG4gICAgICAgIG9wdGlvbnMgPSBhc3NpZ24oe30sIG9wdGlvbnMpO1xuICAgICAgICBvcHRpb25zLmFuY2hvciA9IGZyb21Vc2VyQ29vcmRpbmF0ZShvcHRpb25zLmFuY2hvciwgdGhpcy5nZXRQcm9qZWN0aW9uKCkpO1xuICAgICAgfVxuXG4gICAgICBhcmdzW2ldID0gb3B0aW9ucztcbiAgICB9XG5cbiAgICB0aGlzLmFuaW1hdGVJbnRlcm5hbC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Li4uKEFuaW1hdGlvbk9wdGlvbnN8ZnVuY3Rpb24oYm9vbGVhbik6IHZvaWQpfSB2YXJfYXJncyBBbmltYXRpb24gb3B0aW9ucy5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hbmltYXRlSW50ZXJuYWwgPSBmdW5jdGlvbiAodmFyX2FyZ3MpIHtcbiAgICB2YXIgYW5pbWF0aW9uQ291bnQgPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBjYWxsYmFjaztcblxuICAgIGlmIChhbmltYXRpb25Db3VudCA+IDEgJiYgdHlwZW9mIGFyZ3VtZW50c1thbmltYXRpb25Db3VudCAtIDFdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjYWxsYmFjayA9IGFyZ3VtZW50c1thbmltYXRpb25Db3VudCAtIDFdO1xuICAgICAgLS1hbmltYXRpb25Db3VudDtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuaXNEZWYoKSkge1xuICAgICAgLy8gaWYgdmlldyBwcm9wZXJ0aWVzIGFyZSBub3QgeWV0IHNldCwgc2hvcnRjdXQgdG8gdGhlIGZpbmFsIHN0YXRlXG4gICAgICB2YXIgc3RhdGUgPSBhcmd1bWVudHNbYW5pbWF0aW9uQ291bnQgLSAxXTtcblxuICAgICAgaWYgKHN0YXRlLmNlbnRlcikge1xuICAgICAgICB0aGlzLnNldENlbnRlckludGVybmFsKHN0YXRlLmNlbnRlcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdGF0ZS56b29tICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5zZXRab29tKHN0YXRlLnpvb20pO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3RhdGUucm90YXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLnNldFJvdGF0aW9uKHN0YXRlLnJvdGF0aW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIGFuaW1hdGlvbkNhbGxiYWNrKGNhbGxiYWNrLCB0cnVlKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBzdGFydCA9IERhdGUubm93KCk7XG4gICAgdmFyIGNlbnRlciA9IHRoaXMudGFyZ2V0Q2VudGVyXy5zbGljZSgpO1xuICAgIHZhciByZXNvbHV0aW9uID0gdGhpcy50YXJnZXRSZXNvbHV0aW9uXztcbiAgICB2YXIgcm90YXRpb24gPSB0aGlzLnRhcmdldFJvdGF0aW9uXztcbiAgICB2YXIgc2VyaWVzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFuaW1hdGlvbkNvdW50OyArK2kpIHtcbiAgICAgIHZhciBvcHRpb25zID1cbiAgICAgIC8qKiBAdHlwZSB7QW5pbWF0aW9uT3B0aW9uc30gKi9cbiAgICAgIGFyZ3VtZW50c1tpXTtcbiAgICAgIHZhciBhbmltYXRpb24gPSB7XG4gICAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgICAgY29tcGxldGU6IGZhbHNlLFxuICAgICAgICBhbmNob3I6IG9wdGlvbnMuYW5jaG9yLFxuICAgICAgICBkdXJhdGlvbjogb3B0aW9ucy5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kdXJhdGlvbiA6IDEwMDAsXG4gICAgICAgIGVhc2luZzogb3B0aW9ucy5lYXNpbmcgfHwgaW5BbmRPdXQsXG4gICAgICAgIGNhbGxiYWNrOiBjYWxsYmFja1xuICAgICAgfTtcblxuICAgICAgaWYgKG9wdGlvbnMuY2VudGVyKSB7XG4gICAgICAgIGFuaW1hdGlvbi5zb3VyY2VDZW50ZXIgPSBjZW50ZXI7XG4gICAgICAgIGFuaW1hdGlvbi50YXJnZXRDZW50ZXIgPSBvcHRpb25zLmNlbnRlci5zbGljZSgpO1xuICAgICAgICBjZW50ZXIgPSBhbmltYXRpb24udGFyZ2V0Q2VudGVyO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy56b29tICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYW5pbWF0aW9uLnNvdXJjZVJlc29sdXRpb24gPSByZXNvbHV0aW9uO1xuICAgICAgICBhbmltYXRpb24udGFyZ2V0UmVzb2x1dGlvbiA9IHRoaXMuZ2V0UmVzb2x1dGlvbkZvclpvb20ob3B0aW9ucy56b29tKTtcbiAgICAgICAgcmVzb2x1dGlvbiA9IGFuaW1hdGlvbi50YXJnZXRSZXNvbHV0aW9uO1xuICAgICAgfSBlbHNlIGlmIChvcHRpb25zLnJlc29sdXRpb24pIHtcbiAgICAgICAgYW5pbWF0aW9uLnNvdXJjZVJlc29sdXRpb24gPSByZXNvbHV0aW9uO1xuICAgICAgICBhbmltYXRpb24udGFyZ2V0UmVzb2x1dGlvbiA9IG9wdGlvbnMucmVzb2x1dGlvbjtcbiAgICAgICAgcmVzb2x1dGlvbiA9IGFuaW1hdGlvbi50YXJnZXRSZXNvbHV0aW9uO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5yb3RhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGFuaW1hdGlvbi5zb3VyY2VSb3RhdGlvbiA9IHJvdGF0aW9uO1xuICAgICAgICB2YXIgZGVsdGEgPSBtb2R1bG8ob3B0aW9ucy5yb3RhdGlvbiAtIHJvdGF0aW9uICsgTWF0aC5QSSwgMiAqIE1hdGguUEkpIC0gTWF0aC5QSTtcbiAgICAgICAgYW5pbWF0aW9uLnRhcmdldFJvdGF0aW9uID0gcm90YXRpb24gKyBkZWx0YTtcbiAgICAgICAgcm90YXRpb24gPSBhbmltYXRpb24udGFyZ2V0Um90YXRpb247XG4gICAgICB9IC8vIGNoZWNrIGlmIGFuaW1hdGlvbiBpcyBhIG5vLW9wXG5cblxuICAgICAgaWYgKGlzTm9vcEFuaW1hdGlvbihhbmltYXRpb24pKSB7XG4gICAgICAgIGFuaW1hdGlvbi5jb21wbGV0ZSA9IHRydWU7IC8vIHdlIHN0aWxsIHB1c2ggaXQgb250byB0aGUgc2VyaWVzIGZvciBjYWxsYmFjayBoYW5kbGluZ1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhcnQgKz0gYW5pbWF0aW9uLmR1cmF0aW9uO1xuICAgICAgfVxuXG4gICAgICBzZXJpZXMucHVzaChhbmltYXRpb24pO1xuICAgIH1cblxuICAgIHRoaXMuYW5pbWF0aW9uc18ucHVzaChzZXJpZXMpO1xuICAgIHRoaXMuc2V0SGludChWaWV3SGludC5BTklNQVRJTkcsIDEpO1xuICAgIHRoaXMudXBkYXRlQW5pbWF0aW9uc18oKTtcbiAgfTtcbiAgLyoqXG4gICAqIERldGVybWluZSBpZiB0aGUgdmlldyBpcyBiZWluZyBhbmltYXRlZC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHZpZXcgaXMgYmVpbmcgYW5pbWF0ZWQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRBbmltYXRpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGludHNfW1ZpZXdIaW50LkFOSU1BVElOR10gPiAwO1xuICB9O1xuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIHRoZSB1c2VyIGlzIGludGVyYWN0aW5nIHdpdGggdGhlIHZpZXcsIHN1Y2ggYXMgcGFubmluZyBvciB6b29taW5nLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaGUgdmlldyBpcyBiZWluZyBpbnRlcmFjdGVkIHdpdGguXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRJbnRlcmFjdGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5oaW50c19bVmlld0hpbnQuSU5URVJBQ1RJTkddID4gMDtcbiAgfTtcbiAgLyoqXG4gICAqIENhbmNlbCBhbnkgb25nb2luZyBhbmltYXRpb25zLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuY2FuY2VsQW5pbWF0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNldEhpbnQoVmlld0hpbnQuQU5JTUFUSU5HLCAtdGhpcy5oaW50c19bVmlld0hpbnQuQU5JTUFUSU5HXSk7XG4gICAgdmFyIGFuY2hvcjtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRoaXMuYW5pbWF0aW9uc18ubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdmFyIHNlcmllcyA9IHRoaXMuYW5pbWF0aW9uc19baV07XG5cbiAgICAgIGlmIChzZXJpZXNbMF0uY2FsbGJhY2spIHtcbiAgICAgICAgYW5pbWF0aW9uQ2FsbGJhY2soc2VyaWVzWzBdLmNhbGxiYWNrLCBmYWxzZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghYW5jaG9yKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwLCBqaiA9IHNlcmllcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgICAgICAgdmFyIGFuaW1hdGlvbiA9IHNlcmllc1tqXTtcblxuICAgICAgICAgIGlmICghYW5pbWF0aW9uLmNvbXBsZXRlKSB7XG4gICAgICAgICAgICBhbmNob3IgPSBhbmltYXRpb24uYW5jaG9yO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5hbmltYXRpb25zXy5sZW5ndGggPSAwO1xuICAgIHRoaXMuY2FuY2VsQW5jaG9yXyA9IGFuY2hvcjtcbiAgfTtcbiAgLyoqXG4gICAqIFVwZGF0ZSBhbGwgYW5pbWF0aW9ucy5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS51cGRhdGVBbmltYXRpb25zXyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy51cGRhdGVBbmltYXRpb25LZXlfICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMudXBkYXRlQW5pbWF0aW9uS2V5Xyk7XG4gICAgICB0aGlzLnVwZGF0ZUFuaW1hdGlvbktleV8gPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmdldEFuaW1hdGluZygpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIG5vdyA9IERhdGUubm93KCk7XG4gICAgdmFyIG1vcmUgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSB0aGlzLmFuaW1hdGlvbnNfLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB2YXIgc2VyaWVzID0gdGhpcy5hbmltYXRpb25zX1tpXTtcbiAgICAgIHZhciBzZXJpZXNDb21wbGV0ZSA9IHRydWU7XG5cbiAgICAgIGZvciAodmFyIGogPSAwLCBqaiA9IHNlcmllcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgICAgIHZhciBhbmltYXRpb24gPSBzZXJpZXNbal07XG5cbiAgICAgICAgaWYgKGFuaW1hdGlvbi5jb21wbGV0ZSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGVsYXBzZWQgPSBub3cgLSBhbmltYXRpb24uc3RhcnQ7XG4gICAgICAgIHZhciBmcmFjdGlvbiA9IGFuaW1hdGlvbi5kdXJhdGlvbiA+IDAgPyBlbGFwc2VkIC8gYW5pbWF0aW9uLmR1cmF0aW9uIDogMTtcblxuICAgICAgICBpZiAoZnJhY3Rpb24gPj0gMSkge1xuICAgICAgICAgIGFuaW1hdGlvbi5jb21wbGV0ZSA9IHRydWU7XG4gICAgICAgICAgZnJhY3Rpb24gPSAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNlcmllc0NvbXBsZXRlID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvZ3Jlc3MgPSBhbmltYXRpb24uZWFzaW5nKGZyYWN0aW9uKTtcblxuICAgICAgICBpZiAoYW5pbWF0aW9uLnNvdXJjZUNlbnRlcikge1xuICAgICAgICAgIHZhciB4MCA9IGFuaW1hdGlvbi5zb3VyY2VDZW50ZXJbMF07XG4gICAgICAgICAgdmFyIHkwID0gYW5pbWF0aW9uLnNvdXJjZUNlbnRlclsxXTtcbiAgICAgICAgICB2YXIgeDEgPSBhbmltYXRpb24udGFyZ2V0Q2VudGVyWzBdO1xuICAgICAgICAgIHZhciB5MSA9IGFuaW1hdGlvbi50YXJnZXRDZW50ZXJbMV07XG4gICAgICAgICAgdmFyIHggPSB4MCArIHByb2dyZXNzICogKHgxIC0geDApO1xuICAgICAgICAgIHZhciB5ID0geTAgKyBwcm9ncmVzcyAqICh5MSAtIHkwKTtcbiAgICAgICAgICB0aGlzLnRhcmdldENlbnRlcl8gPSBbeCwgeV07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYW5pbWF0aW9uLnNvdXJjZVJlc29sdXRpb24gJiYgYW5pbWF0aW9uLnRhcmdldFJlc29sdXRpb24pIHtcbiAgICAgICAgICB2YXIgcmVzb2x1dGlvbiA9IHByb2dyZXNzID09PSAxID8gYW5pbWF0aW9uLnRhcmdldFJlc29sdXRpb24gOiBhbmltYXRpb24uc291cmNlUmVzb2x1dGlvbiArIHByb2dyZXNzICogKGFuaW1hdGlvbi50YXJnZXRSZXNvbHV0aW9uIC0gYW5pbWF0aW9uLnNvdXJjZVJlc29sdXRpb24pO1xuXG4gICAgICAgICAgaWYgKGFuaW1hdGlvbi5hbmNob3IpIHtcbiAgICAgICAgICAgIHZhciBzaXplID0gdGhpcy5nZXRWaWV3cG9ydFNpemVfKHRoaXMuZ2V0Um90YXRpb24oKSk7XG4gICAgICAgICAgICB2YXIgY29uc3RyYWluZWRSZXNvbHV0aW9uID0gdGhpcy5jb25zdHJhaW50c18ucmVzb2x1dGlvbihyZXNvbHV0aW9uLCAwLCBzaXplLCB0cnVlKTtcbiAgICAgICAgICAgIHRoaXMudGFyZ2V0Q2VudGVyXyA9IHRoaXMuY2FsY3VsYXRlQ2VudGVyWm9vbShjb25zdHJhaW5lZFJlc29sdXRpb24sIGFuaW1hdGlvbi5hbmNob3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMudGFyZ2V0UmVzb2x1dGlvbl8gPSByZXNvbHV0aW9uO1xuICAgICAgICAgIHRoaXMuYXBwbHlUYXJnZXRTdGF0ZV8odHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYW5pbWF0aW9uLnNvdXJjZVJvdGF0aW9uICE9PSB1bmRlZmluZWQgJiYgYW5pbWF0aW9uLnRhcmdldFJvdGF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB2YXIgcm90YXRpb24gPSBwcm9ncmVzcyA9PT0gMSA/IG1vZHVsbyhhbmltYXRpb24udGFyZ2V0Um90YXRpb24gKyBNYXRoLlBJLCAyICogTWF0aC5QSSkgLSBNYXRoLlBJIDogYW5pbWF0aW9uLnNvdXJjZVJvdGF0aW9uICsgcHJvZ3Jlc3MgKiAoYW5pbWF0aW9uLnRhcmdldFJvdGF0aW9uIC0gYW5pbWF0aW9uLnNvdXJjZVJvdGF0aW9uKTtcblxuICAgICAgICAgIGlmIChhbmltYXRpb24uYW5jaG9yKSB7XG4gICAgICAgICAgICB2YXIgY29uc3RyYWluZWRSb3RhdGlvbiA9IHRoaXMuY29uc3RyYWludHNfLnJvdGF0aW9uKHJvdGF0aW9uLCB0cnVlKTtcbiAgICAgICAgICAgIHRoaXMudGFyZ2V0Q2VudGVyXyA9IHRoaXMuY2FsY3VsYXRlQ2VudGVyUm90YXRlKGNvbnN0cmFpbmVkUm90YXRpb24sIGFuaW1hdGlvbi5hbmNob3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMudGFyZ2V0Um90YXRpb25fID0gcm90YXRpb247XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmFwcGx5VGFyZ2V0U3RhdGVfKHRydWUpO1xuICAgICAgICBtb3JlID0gdHJ1ZTtcblxuICAgICAgICBpZiAoIWFuaW1hdGlvbi5jb21wbGV0ZSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChzZXJpZXNDb21wbGV0ZSkge1xuICAgICAgICB0aGlzLmFuaW1hdGlvbnNfW2ldID0gbnVsbDtcbiAgICAgICAgdGhpcy5zZXRIaW50KFZpZXdIaW50LkFOSU1BVElORywgLTEpO1xuICAgICAgICB2YXIgY2FsbGJhY2sgPSBzZXJpZXNbMF0uY2FsbGJhY2s7XG5cbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgYW5pbWF0aW9uQ2FsbGJhY2soY2FsbGJhY2ssIHRydWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSAvLyBwcnVuZSBjb21wbGV0ZWQgc2VyaWVzXG5cblxuICAgIHRoaXMuYW5pbWF0aW9uc18gPSB0aGlzLmFuaW1hdGlvbnNfLmZpbHRlcihCb29sZWFuKTtcblxuICAgIGlmIChtb3JlICYmIHRoaXMudXBkYXRlQW5pbWF0aW9uS2V5XyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnVwZGF0ZUFuaW1hdGlvbktleV8gPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy51cGRhdGVBbmltYXRpb25zXy5iaW5kKHRoaXMpKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gcm90YXRpb24gVGFyZ2V0IHJvdGF0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBhbmNob3IgUm90YXRpb24gYW5jaG9yLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IENlbnRlciBmb3Igcm90YXRpb24gYW5kIGFuY2hvci5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5jYWxjdWxhdGVDZW50ZXJSb3RhdGUgPSBmdW5jdGlvbiAocm90YXRpb24sIGFuY2hvcikge1xuICAgIHZhciBjZW50ZXI7XG4gICAgdmFyIGN1cnJlbnRDZW50ZXIgPSB0aGlzLmdldENlbnRlckludGVybmFsKCk7XG5cbiAgICBpZiAoY3VycmVudENlbnRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjZW50ZXIgPSBbY3VycmVudENlbnRlclswXSAtIGFuY2hvclswXSwgY3VycmVudENlbnRlclsxXSAtIGFuY2hvclsxXV07XG4gICAgICByb3RhdGVDb29yZGluYXRlKGNlbnRlciwgcm90YXRpb24gLSB0aGlzLmdldFJvdGF0aW9uKCkpO1xuICAgICAgYWRkQ29vcmRpbmF0ZShjZW50ZXIsIGFuY2hvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNlbnRlcjtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFRhcmdldCByZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBhbmNob3IgWm9vbSBhbmNob3IuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH0gQ2VudGVyIGZvciByZXNvbHV0aW9uIGFuZCBhbmNob3IuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuY2FsY3VsYXRlQ2VudGVyWm9vbSA9IGZ1bmN0aW9uIChyZXNvbHV0aW9uLCBhbmNob3IpIHtcbiAgICB2YXIgY2VudGVyO1xuICAgIHZhciBjdXJyZW50Q2VudGVyID0gdGhpcy5nZXRDZW50ZXJJbnRlcm5hbCgpO1xuICAgIHZhciBjdXJyZW50UmVzb2x1dGlvbiA9IHRoaXMuZ2V0UmVzb2x1dGlvbigpO1xuXG4gICAgaWYgKGN1cnJlbnRDZW50ZXIgIT09IHVuZGVmaW5lZCAmJiBjdXJyZW50UmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YXIgeCA9IGFuY2hvclswXSAtIHJlc29sdXRpb24gKiAoYW5jaG9yWzBdIC0gY3VycmVudENlbnRlclswXSkgLyBjdXJyZW50UmVzb2x1dGlvbjtcbiAgICAgIHZhciB5ID0gYW5jaG9yWzFdIC0gcmVzb2x1dGlvbiAqIChhbmNob3JbMV0gLSBjdXJyZW50Q2VudGVyWzFdKSAvIGN1cnJlbnRSZXNvbHV0aW9uO1xuICAgICAgY2VudGVyID0gW3gsIHldO1xuICAgIH1cblxuICAgIHJldHVybiBjZW50ZXI7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZpZXdwb3J0IHNpemUuXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3JvdGF0aW9uIFRha2UgaW50byBhY2NvdW50IHRoZSByb3RhdGlvbiBvZiB0aGUgdmlld3BvcnQgd2hlbiBnaXZpbmcgdGhlIHNpemVcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemV9IFZpZXdwb3J0IHNpemUgb3IgYFsxMDAsIDEwMF1gIHdoZW4gbm8gdmlld3BvcnQgaXMgZm91bmQuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0Vmlld3BvcnRTaXplXyA9IGZ1bmN0aW9uIChvcHRfcm90YXRpb24pIHtcbiAgICB2YXIgc2l6ZSA9IHRoaXMudmlld3BvcnRTaXplXztcblxuICAgIGlmIChvcHRfcm90YXRpb24pIHtcbiAgICAgIHZhciB3ID0gc2l6ZVswXTtcbiAgICAgIHZhciBoID0gc2l6ZVsxXTtcbiAgICAgIHJldHVybiBbTWF0aC5hYnModyAqIE1hdGguY29zKG9wdF9yb3RhdGlvbikpICsgTWF0aC5hYnMoaCAqIE1hdGguc2luKG9wdF9yb3RhdGlvbikpLCBNYXRoLmFicyh3ICogTWF0aC5zaW4ob3B0X3JvdGF0aW9uKSkgKyBNYXRoLmFicyhoICogTWF0aC5jb3Mob3B0X3JvdGF0aW9uKSldO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc2l6ZTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTdG9yZXMgdGhlIHZpZXdwb3J0IHNpemUgb24gdGhlIHZpZXcuIFRoZSB2aWV3cG9ydCBzaXplIGlzIG5vdCByZWFkIGV2ZXJ5IHRpbWUgZnJvbSB0aGUgRE9NXG4gICAqIHRvIGF2b2lkIHBlcmZvcm1hbmNlIGhpdCBhbmQgbGF5b3V0IHJlZmxvdy5cbiAgICogVGhpcyBzaG91bGQgYmUgZG9uZSBvbiBtYXAgc2l6ZSBjaGFuZ2UuXG4gICAqIE5vdGU6IHRoZSBjb25zdHJhaW50cyBhcmUgbm90IHJlc29sdmVkIGR1cmluZyBhbiBhbmltYXRpb24gdG8gYXZvaWQgc3RvcHBpbmcgaXRcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZT19IG9wdF9zaXplIFZpZXdwb3J0IHNpemU7IGlmIHVuZGVmaW5lZCwgWzEwMCwgMTAwXSBpcyBhc3N1bWVkXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuc2V0Vmlld3BvcnRTaXplID0gZnVuY3Rpb24gKG9wdF9zaXplKSB7XG4gICAgdGhpcy52aWV3cG9ydFNpemVfID0gQXJyYXkuaXNBcnJheShvcHRfc2l6ZSkgPyBvcHRfc2l6ZS5zbGljZSgpIDogWzEwMCwgMTAwXTtcblxuICAgIGlmICghdGhpcy5nZXRBbmltYXRpbmcoKSkge1xuICAgICAgdGhpcy5yZXNvbHZlQ29uc3RyYWludHMoMCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB2aWV3IGNlbnRlci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkfSBUaGUgY2VudGVyIG9mIHRoZSB2aWV3LlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0Q2VudGVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBjZW50ZXIgPSB0aGlzLmdldENlbnRlckludGVybmFsKCk7XG5cbiAgICBpZiAoIWNlbnRlcikge1xuICAgICAgcmV0dXJuIGNlbnRlcjtcbiAgICB9XG5cbiAgICByZXR1cm4gdG9Vc2VyQ29vcmRpbmF0ZShjZW50ZXIsIHRoaXMuZ2V0UHJvamVjdGlvbigpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdmlldyBjZW50ZXIgd2l0aG91dCB0cmFuc2Zvcm1pbmcgdG8gdXNlciBwcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IFRoZSBjZW50ZXIgb2YgdGhlIHZpZXcuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0Q2VudGVySW50ZXJuYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkfSAqL1xuICAgICAgdGhpcy5nZXQoVmlld1Byb3BlcnR5LkNFTlRFUilcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Q29uc3RyYWludHN9IENvbnN0cmFpbnRzLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldENvbnN0cmFpbnRzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnN0cmFpbnRzXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFJlc29sdXRpb24gY29uc3RyYWludCBpcyBzZXRcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRDb25zdHJhaW5SZXNvbHV0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnNfLmNvbnN0cmFpblJlc29sdXRpb247XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfaGludHMgRGVzdGluYXRpb24gYXJyYXkuXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEhpbnQuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0SGludHMgPSBmdW5jdGlvbiAob3B0X2hpbnRzKSB7XG4gICAgaWYgKG9wdF9oaW50cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBvcHRfaGludHNbMF0gPSB0aGlzLmhpbnRzX1swXTtcbiAgICAgIG9wdF9oaW50c1sxXSA9IHRoaXMuaGludHNfWzFdO1xuICAgICAgcmV0dXJuIG9wdF9oaW50cztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuaGludHNfLnNsaWNlKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBleHRlbnQgZm9yIHRoZSBjdXJyZW50IHZpZXcgc3RhdGUgYW5kIHRoZSBwYXNzZWQgc2l6ZS5cbiAgICogVGhlIHNpemUgaXMgdGhlIHBpeGVsIGRpbWVuc2lvbnMgb2YgdGhlIGJveCBpbnRvIHdoaWNoIHRoZSBjYWxjdWxhdGVkIGV4dGVudFxuICAgKiBzaG91bGQgZml0LiBJbiBtb3N0IGNhc2VzIHlvdSB3YW50IHRvIGdldCB0aGUgZXh0ZW50IG9mIHRoZSBlbnRpcmUgbWFwLFxuICAgKiB0aGF0IGlzIGBtYXAuZ2V0U2l6ZSgpYC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZT19IG9wdF9zaXplIEJveCBwaXhlbCBzaXplLiBJZiBub3QgcHJvdmlkZWQsIHRoZSBzaXplXG4gICAqIG9mIHRoZSBtYXAgdGhhdCB1c2VzIHRoaXMgdmlldyB3aWxsIGJlIHVzZWQuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuY2FsY3VsYXRlRXh0ZW50ID0gZnVuY3Rpb24gKG9wdF9zaXplKSB7XG4gICAgdmFyIGV4dGVudCA9IHRoaXMuY2FsY3VsYXRlRXh0ZW50SW50ZXJuYWwob3B0X3NpemUpO1xuICAgIHJldHVybiB0b1VzZXJFeHRlbnQoZXh0ZW50LCB0aGlzLmdldFByb2plY3Rpb24oKSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplPX0gb3B0X3NpemUgQm94IHBpeGVsIHNpemUuIElmIG5vdCBwcm92aWRlZCxcbiAgICogdGhlIG1hcCdzIGxhc3Qga25vd24gdmlld3BvcnQgc2l6ZSB3aWxsIGJlIHVzZWQuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmNhbGN1bGF0ZUV4dGVudEludGVybmFsID0gZnVuY3Rpb24gKG9wdF9zaXplKSB7XG4gICAgdmFyIHNpemUgPSBvcHRfc2l6ZSB8fCB0aGlzLmdldFZpZXdwb3J0U2l6ZV8oKTtcbiAgICB2YXIgY2VudGVyID1cbiAgICAvKiogQHR5cGUgeyFpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gKi9cbiAgICB0aGlzLmdldENlbnRlckludGVybmFsKCk7XG4gICAgYXNzZXJ0KGNlbnRlciwgMSk7IC8vIFRoZSB2aWV3IGNlbnRlciBpcyBub3QgZGVmaW5lZFxuXG4gICAgdmFyIHJlc29sdXRpb24gPVxuICAgIC8qKiBAdHlwZSB7IW51bWJlcn0gKi9cbiAgICB0aGlzLmdldFJlc29sdXRpb24oKTtcbiAgICBhc3NlcnQocmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkLCAyKTsgLy8gVGhlIHZpZXcgcmVzb2x1dGlvbiBpcyBub3QgZGVmaW5lZFxuXG4gICAgdmFyIHJvdGF0aW9uID1cbiAgICAvKiogQHR5cGUgeyFudW1iZXJ9ICovXG4gICAgdGhpcy5nZXRSb3RhdGlvbigpO1xuICAgIGFzc2VydChyb3RhdGlvbiAhPT0gdW5kZWZpbmVkLCAzKTsgLy8gVGhlIHZpZXcgcm90YXRpb24gaXMgbm90IGRlZmluZWRcblxuICAgIHJldHVybiBnZXRGb3JWaWV3QW5kU2l6ZShjZW50ZXIsIHJlc29sdXRpb24sIHJvdGF0aW9uLCBzaXplKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbWF4aW11bSByZXNvbHV0aW9uIG9mIHRoZSB2aWV3LlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBtYXhpbXVtIHJlc29sdXRpb24gb2YgdGhlIHZpZXcuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRNYXhSZXNvbHV0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm1heFJlc29sdXRpb25fO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtaW5pbXVtIHJlc29sdXRpb24gb2YgdGhlIHZpZXcuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIG1pbmltdW0gcmVzb2x1dGlvbiBvZiB0aGUgdmlldy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldE1pblJlc29sdXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubWluUmVzb2x1dGlvbl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1heGltdW0gem9vbSBsZXZlbCBmb3IgdGhlIHZpZXcuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIG1heGltdW0gem9vbSBsZXZlbC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldE1heFpvb20gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgdGhpcy5nZXRab29tRm9yUmVzb2x1dGlvbih0aGlzLm1pblJlc29sdXRpb25fKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgYSBuZXcgbWF4aW11bSB6b29tIGxldmVsIGZvciB0aGUgdmlldy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHpvb20gVGhlIG1heGltdW0gem9vbSBsZXZlbC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLnNldE1heFpvb20gPSBmdW5jdGlvbiAoem9vbSkge1xuICAgIHRoaXMuYXBwbHlPcHRpb25zXyh0aGlzLmdldFVwZGF0ZWRPcHRpb25zXyh7XG4gICAgICBtYXhab29tOiB6b29tXG4gICAgfSkpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtaW5pbXVtIHpvb20gbGV2ZWwgZm9yIHRoZSB2aWV3LlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBtaW5pbXVtIHpvb20gbGV2ZWwuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRNaW5ab29tID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgIHRoaXMuZ2V0Wm9vbUZvclJlc29sdXRpb24odGhpcy5tYXhSZXNvbHV0aW9uXylcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogU2V0IGEgbmV3IG1pbmltdW0gem9vbSBsZXZlbCBmb3IgdGhlIHZpZXcuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6b29tIFRoZSBtaW5pbXVtIHpvb20gbGV2ZWwuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5zZXRNaW5ab29tID0gZnVuY3Rpb24gKHpvb20pIHtcbiAgICB0aGlzLmFwcGx5T3B0aW9uc18odGhpcy5nZXRVcGRhdGVkT3B0aW9uc18oe1xuICAgICAgbWluWm9vbTogem9vbVxuICAgIH0pKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB3aGV0aGVyIHRoZSB2aWV3IHNob3VkIGFsbG93IGludGVybWVkaWFyeSB6b29tIGxldmVscy5cbiAgICogQHBhcmFtIHtib29sZWFufSBlbmFibGVkIFdoZXRoZXIgdGhlIHJlc29sdXRpb24gaXMgY29uc3RyYWluZWQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5zZXRDb25zdHJhaW5SZXNvbHV0aW9uID0gZnVuY3Rpb24gKGVuYWJsZWQpIHtcbiAgICB0aGlzLmFwcGx5T3B0aW9uc18odGhpcy5nZXRVcGRhdGVkT3B0aW9uc18oe1xuICAgICAgY29uc3RyYWluUmVzb2x1dGlvbjogZW5hYmxlZFxuICAgIH0pKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdmlldyBwcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBUaGUgcHJvamVjdGlvbiBvZiB0aGUgdmlldy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFByb2plY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucHJvamVjdGlvbl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHZpZXcgcmVzb2x1dGlvbi5cbiAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gVGhlIHJlc29sdXRpb24gb2YgdGhlIHZpZXcuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRSZXNvbHV0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge251bWJlcnx1bmRlZmluZWR9ICovXG4gICAgICB0aGlzLmdldChWaWV3UHJvcGVydHkuUkVTT0xVVElPTilcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSByZXNvbHV0aW9ucyBmb3IgdGhlIHZpZXcuIFRoaXMgcmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzb2x1dGlvbnNcbiAgICogcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgVmlldywgb3IgdW5kZWZpbmVkIGlmIG5vbmUgd2VyZSBnaXZlbi5cbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPnx1bmRlZmluZWR9IFRoZSByZXNvbHV0aW9ucyBvZiB0aGUgdmlldy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFJlc29sdXRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlc29sdXRpb25zXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgcmVzb2x1dGlvbiBmb3IgYSBwcm92aWRlZCBleHRlbnQgKGluIG1hcCB1bml0cykgYW5kIHNpemUgKGluIHBpeGVscykuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplPX0gb3B0X3NpemUgQm94IHBpeGVsIHNpemUuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIHJlc29sdXRpb24gYXQgd2hpY2ggdGhlIHByb3ZpZGVkIGV4dGVudCB3aWxsIHJlbmRlciBhdFxuICAgKiAgICAgdGhlIGdpdmVuIHNpemUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRSZXNvbHV0aW9uRm9yRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCwgb3B0X3NpemUpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRSZXNvbHV0aW9uRm9yRXh0ZW50SW50ZXJuYWwoZnJvbVVzZXJFeHRlbnQoZXh0ZW50LCB0aGlzLmdldFByb2plY3Rpb24oKSksIG9wdF9zaXplKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgcmVzb2x1dGlvbiBmb3IgYSBwcm92aWRlZCBleHRlbnQgKGluIG1hcCB1bml0cykgYW5kIHNpemUgKGluIHBpeGVscykuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplPX0gb3B0X3NpemUgQm94IHBpeGVsIHNpemUuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIHJlc29sdXRpb24gYXQgd2hpY2ggdGhlIHByb3ZpZGVkIGV4dGVudCB3aWxsIHJlbmRlciBhdFxuICAgKiAgICAgdGhlIGdpdmVuIHNpemUuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0UmVzb2x1dGlvbkZvckV4dGVudEludGVybmFsID0gZnVuY3Rpb24gKGV4dGVudCwgb3B0X3NpemUpIHtcbiAgICB2YXIgc2l6ZSA9IG9wdF9zaXplIHx8IHRoaXMuZ2V0Vmlld3BvcnRTaXplXygpO1xuICAgIHZhciB4UmVzb2x1dGlvbiA9IGdldFdpZHRoKGV4dGVudCkgLyBzaXplWzBdO1xuICAgIHZhciB5UmVzb2x1dGlvbiA9IGdldEhlaWdodChleHRlbnQpIC8gc2l6ZVsxXTtcbiAgICByZXR1cm4gTWF0aC5tYXgoeFJlc29sdXRpb24sIHlSZXNvbHV0aW9uKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMSBmb3IgYVxuICAgKiByZXNvbHV0aW9uLiBFeHBvbmVudGlhbCBzY2FsaW5nIGlzIGFzc3VtZWQuXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3Bvd2VyIFBvd2VyLlxuICAgKiBAcmV0dXJuIHtmdW5jdGlvbihudW1iZXIpOiBudW1iZXJ9IFJlc29sdXRpb24gZm9yIHZhbHVlIGZ1bmN0aW9uLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFJlc29sdXRpb25Gb3JWYWx1ZUZ1bmN0aW9uID0gZnVuY3Rpb24gKG9wdF9wb3dlcikge1xuICAgIHZhciBwb3dlciA9IG9wdF9wb3dlciB8fCAyO1xuICAgIHZhciBtYXhSZXNvbHV0aW9uID0gdGhpcy5nZXRDb25zdHJhaW5lZFJlc29sdXRpb24odGhpcy5tYXhSZXNvbHV0aW9uXyk7XG4gICAgdmFyIG1pblJlc29sdXRpb24gPSB0aGlzLm1pblJlc29sdXRpb25fO1xuICAgIHZhciBtYXggPSBNYXRoLmxvZyhtYXhSZXNvbHV0aW9uIC8gbWluUmVzb2x1dGlvbikgLyBNYXRoLmxvZyhwb3dlcik7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKlxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlLlxuICAgICAgICogQHJldHVybiB7bnVtYmVyfSBSZXNvbHV0aW9uLlxuICAgICAgICovXG4gICAgICBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIHJlc29sdXRpb24gPSBtYXhSZXNvbHV0aW9uIC8gTWF0aC5wb3cocG93ZXIsIHZhbHVlICogbWF4KTtcbiAgICAgICAgcmV0dXJuIHJlc29sdXRpb247XG4gICAgICB9XG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdmlldyByb3RhdGlvbi5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgcm90YXRpb24gb2YgdGhlIHZpZXcgaW4gcmFkaWFucy5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFJvdGF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgIHRoaXMuZ2V0KFZpZXdQcm9wZXJ0eS5ST1RBVElPTilcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgcmVzb2x1dGlvbiBmb3IgYSB2YWx1ZSBiZXR3ZWVuXG4gICAqIDAgYW5kIDEuIEV4cG9uZW50aWFsIHNjYWxpbmcgaXMgYXNzdW1lZC5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfcG93ZXIgUG93ZXIuXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9uKG51bWJlcik6IG51bWJlcn0gVmFsdWUgZm9yIHJlc29sdXRpb24gZnVuY3Rpb24uXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0VmFsdWVGb3JSZXNvbHV0aW9uRnVuY3Rpb24gPSBmdW5jdGlvbiAob3B0X3Bvd2VyKSB7XG4gICAgdmFyIGxvZ1Bvd2VyID0gTWF0aC5sb2cob3B0X3Bvd2VyIHx8IDIpO1xuICAgIHZhciBtYXhSZXNvbHV0aW9uID0gdGhpcy5nZXRDb25zdHJhaW5lZFJlc29sdXRpb24odGhpcy5tYXhSZXNvbHV0aW9uXyk7XG4gICAgdmFyIG1pblJlc29sdXRpb24gPSB0aGlzLm1pblJlc29sdXRpb25fO1xuICAgIHZhciBtYXggPSBNYXRoLmxvZyhtYXhSZXNvbHV0aW9uIC8gbWluUmVzb2x1dGlvbikgLyBsb2dQb3dlcjtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqXG4gICAgICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgICAgICogQHJldHVybiB7bnVtYmVyfSBWYWx1ZS5cbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gKHJlc29sdXRpb24pIHtcbiAgICAgICAgdmFyIHZhbHVlID0gTWF0aC5sb2cobWF4UmVzb2x1dGlvbiAvIHJlc29sdXRpb24pIC8gbG9nUG93ZXIgLyBtYXg7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICApO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgdmlld3BvcnQgbWludXMgcGFkZGluZy5cbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfcm90YXRpb24gVGFrZSBpbnRvIGFjY291bnQgdGhlIHJvdGF0aW9uIG9mIHRoZSB2aWV3cG9ydCB3aGVuIGdpdmluZyB0aGUgc2l6ZVxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gVmlld3BvcnQgc2l6ZSByZWR1Y2VkIGJ5IHRoZSBwYWRkaW5nLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFZpZXdwb3J0U2l6ZU1pbnVzUGFkZGluZ18gPSBmdW5jdGlvbiAob3B0X3JvdGF0aW9uKSB7XG4gICAgdmFyIHNpemUgPSB0aGlzLmdldFZpZXdwb3J0U2l6ZV8ob3B0X3JvdGF0aW9uKTtcbiAgICB2YXIgcGFkZGluZyA9IHRoaXMucGFkZGluZztcblxuICAgIGlmIChwYWRkaW5nKSB7XG4gICAgICBzaXplID0gW3NpemVbMF0gLSBwYWRkaW5nWzFdIC0gcGFkZGluZ1szXSwgc2l6ZVsxXSAtIHBhZGRpbmdbMF0gLSBwYWRkaW5nWzJdXTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2l6ZTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge1N0YXRlfSBWaWV3IHN0YXRlLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBwcm9qZWN0aW9uID0gdGhpcy5nZXRQcm9qZWN0aW9uKCk7XG4gICAgdmFyIHJlc29sdXRpb24gPVxuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuZ2V0UmVzb2x1dGlvbigpO1xuICAgIHZhciByb3RhdGlvbiA9IHRoaXMuZ2V0Um90YXRpb24oKTtcbiAgICB2YXIgY2VudGVyID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSAqL1xuICAgIHRoaXMuZ2V0Q2VudGVySW50ZXJuYWwoKTtcbiAgICB2YXIgcGFkZGluZyA9IHRoaXMucGFkZGluZztcblxuICAgIGlmIChwYWRkaW5nKSB7XG4gICAgICB2YXIgcmVkdWNlZFNpemUgPSB0aGlzLmdldFZpZXdwb3J0U2l6ZU1pbnVzUGFkZGluZ18oKTtcbiAgICAgIGNlbnRlciA9IGNhbGN1bGF0ZUNlbnRlck9uKGNlbnRlciwgdGhpcy5nZXRWaWV3cG9ydFNpemVfKCksIFtyZWR1Y2VkU2l6ZVswXSAvIDIgKyBwYWRkaW5nWzNdLCByZWR1Y2VkU2l6ZVsxXSAvIDIgKyBwYWRkaW5nWzBdXSwgcmVzb2x1dGlvbiwgcm90YXRpb24pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBjZW50ZXI6IGNlbnRlci5zbGljZSgwKSxcbiAgICAgIHByb2plY3Rpb246IHByb2plY3Rpb24gIT09IHVuZGVmaW5lZCA/IHByb2plY3Rpb24gOiBudWxsLFxuICAgICAgcmVzb2x1dGlvbjogcmVzb2x1dGlvbixcbiAgICAgIHJvdGF0aW9uOiByb3RhdGlvbixcbiAgICAgIHpvb206IHRoaXMuZ2V0Wm9vbSgpXG4gICAgfTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgY3VycmVudCB6b29tIGxldmVsLiBUaGlzIG1ldGhvZCBtYXkgcmV0dXJuIG5vbi1pbnRlZ2VyIHpvb20gbGV2ZWxzXG4gICAqIGlmIHRoZSB2aWV3IGRvZXMgbm90IGNvbnN0cmFpbiB0aGUgcmVzb2x1dGlvbiwgb3IgaWYgYW4gaW50ZXJhY3Rpb24gb3JcbiAgICogYW5pbWF0aW9uIGlzIHVuZGVyd2F5LlxuICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBab29tLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0Wm9vbSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgem9vbTtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHRoaXMuZ2V0UmVzb2x1dGlvbigpO1xuXG4gICAgaWYgKHJlc29sdXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgem9vbSA9IHRoaXMuZ2V0Wm9vbUZvclJlc29sdXRpb24ocmVzb2x1dGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHpvb207XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHpvb20gbGV2ZWwgZm9yIGEgcmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gVGhlIHJlc29sdXRpb24uXG4gICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFRoZSB6b29tIGxldmVsIGZvciB0aGUgcHJvdmlkZWQgcmVzb2x1dGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFpvb21Gb3JSZXNvbHV0aW9uID0gZnVuY3Rpb24gKHJlc29sdXRpb24pIHtcbiAgICB2YXIgb2Zmc2V0ID0gdGhpcy5taW5ab29tXyB8fCAwO1xuICAgIHZhciBtYXgsIHpvb21GYWN0b3I7XG5cbiAgICBpZiAodGhpcy5yZXNvbHV0aW9uc18pIHtcbiAgICAgIHZhciBuZWFyZXN0ID0gbGluZWFyRmluZE5lYXJlc3QodGhpcy5yZXNvbHV0aW9uc18sIHJlc29sdXRpb24sIDEpO1xuICAgICAgb2Zmc2V0ID0gbmVhcmVzdDtcbiAgICAgIG1heCA9IHRoaXMucmVzb2x1dGlvbnNfW25lYXJlc3RdO1xuXG4gICAgICBpZiAobmVhcmVzdCA9PSB0aGlzLnJlc29sdXRpb25zXy5sZW5ndGggLSAxKSB7XG4gICAgICAgIHpvb21GYWN0b3IgPSAyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgem9vbUZhY3RvciA9IG1heCAvIHRoaXMucmVzb2x1dGlvbnNfW25lYXJlc3QgKyAxXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbWF4ID0gdGhpcy5tYXhSZXNvbHV0aW9uXztcbiAgICAgIHpvb21GYWN0b3IgPSB0aGlzLnpvb21GYWN0b3JfO1xuICAgIH1cblxuICAgIHJldHVybiBvZmZzZXQgKyBNYXRoLmxvZyhtYXggLyByZXNvbHV0aW9uKSAvIE1hdGgubG9nKHpvb21GYWN0b3IpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSByZXNvbHV0aW9uIGZvciBhIHpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6b29tIFpvb20gbGV2ZWwuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIHZpZXcgcmVzb2x1dGlvbiBmb3IgdGhlIHByb3ZpZGVkIHpvb20gbGV2ZWwuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRSZXNvbHV0aW9uRm9yWm9vbSA9IGZ1bmN0aW9uICh6b29tKSB7XG4gICAgaWYgKHRoaXMucmVzb2x1dGlvbnNfKSB7XG4gICAgICBpZiAodGhpcy5yZXNvbHV0aW9uc18ubGVuZ3RoIDw9IDEpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG5cbiAgICAgIHZhciBiYXNlTGV2ZWwgPSBjbGFtcChNYXRoLmZsb29yKHpvb20pLCAwLCB0aGlzLnJlc29sdXRpb25zXy5sZW5ndGggLSAyKTtcbiAgICAgIHZhciB6b29tRmFjdG9yID0gdGhpcy5yZXNvbHV0aW9uc19bYmFzZUxldmVsXSAvIHRoaXMucmVzb2x1dGlvbnNfW2Jhc2VMZXZlbCArIDFdO1xuICAgICAgcmV0dXJuIHRoaXMucmVzb2x1dGlvbnNfW2Jhc2VMZXZlbF0gLyBNYXRoLnBvdyh6b29tRmFjdG9yLCBjbGFtcCh6b29tIC0gYmFzZUxldmVsLCAwLCAxKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLm1heFJlc29sdXRpb25fIC8gTWF0aC5wb3codGhpcy56b29tRmFjdG9yXywgem9vbSAtIHRoaXMubWluWm9vbV8pO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEZpdCB0aGUgZ2l2ZW4gZ2VvbWV0cnkgb3IgZXh0ZW50IGJhc2VkIG9uIHRoZSBnaXZlbiBtYXAgc2l6ZSBhbmQgYm9yZGVyLlxuICAgKiBUaGUgc2l6ZSBpcyBwaXhlbCBkaW1lbnNpb25zIG9mIHRoZSBib3ggdG8gZml0IHRoZSBleHRlbnQgaW50by5cbiAgICogSW4gbW9zdCBjYXNlcyB5b3Ugd2lsbCB3YW50IHRvIHVzZSB0aGUgbWFwIHNpemUsIHRoYXQgaXMgYG1hcC5nZXRTaXplKClgLlxuICAgKiBUYWtlcyBjYXJlIG9mIHRoZSBtYXAgYW5nbGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBnZW9tZXRyeU9yRXh0ZW50IFRoZSBnZW9tZXRyeSBvclxuICAgKiAgICAgZXh0ZW50IHRvIGZpdCB0aGUgdmlldyB0by5cbiAgICogQHBhcmFtIHtGaXRPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmZpdCA9IGZ1bmN0aW9uIChnZW9tZXRyeU9yRXh0ZW50LCBvcHRfb3B0aW9ucykge1xuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgdmFyIGdlb21ldHJ5O1xuICAgIGFzc2VydChBcnJheS5pc0FycmF5KGdlb21ldHJ5T3JFeHRlbnQpIHx8IHR5cGVvZlxuICAgIC8qKiBAdHlwZSB7P30gKi9cbiAgICBnZW9tZXRyeU9yRXh0ZW50LmdldFNpbXBsaWZpZWRHZW9tZXRyeSA9PT0gJ2Z1bmN0aW9uJywgMjQpOyAvLyBJbnZhbGlkIGV4dGVudCBvciBnZW9tZXRyeSBwcm92aWRlZCBhcyBgZ2VvbWV0cnlgXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShnZW9tZXRyeU9yRXh0ZW50KSkge1xuICAgICAgYXNzZXJ0KCFpc0VtcHR5KGdlb21ldHJ5T3JFeHRlbnQpLCAyNSk7IC8vIENhbm5vdCBmaXQgZW1wdHkgZXh0ZW50IHByb3ZpZGVkIGFzIGBnZW9tZXRyeWBcblxuICAgICAgdmFyIGV4dGVudCA9IGZyb21Vc2VyRXh0ZW50KGdlb21ldHJ5T3JFeHRlbnQsIHRoaXMuZ2V0UHJvamVjdGlvbigpKTtcbiAgICAgIGdlb21ldHJ5ID0gcG9seWdvbkZyb21FeHRlbnQoZXh0ZW50KTtcbiAgICB9IGVsc2UgaWYgKGdlb21ldHJ5T3JFeHRlbnQuZ2V0VHlwZSgpID09PSBHZW9tZXRyeVR5cGUuQ0lSQ0xFKSB7XG4gICAgICB2YXIgZXh0ZW50ID0gZnJvbVVzZXJFeHRlbnQoZ2VvbWV0cnlPckV4dGVudC5nZXRFeHRlbnQoKSwgdGhpcy5nZXRQcm9qZWN0aW9uKCkpO1xuICAgICAgZ2VvbWV0cnkgPSBwb2x5Z29uRnJvbUV4dGVudChleHRlbnQpO1xuICAgICAgZ2VvbWV0cnkucm90YXRlKHRoaXMuZ2V0Um90YXRpb24oKSwgZ2V0Q2VudGVyKGV4dGVudCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdXNlclByb2plY3Rpb24gPSBnZXRVc2VyUHJvamVjdGlvbigpO1xuXG4gICAgICBpZiAodXNlclByb2plY3Rpb24pIHtcbiAgICAgICAgZ2VvbWV0cnkgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeU9yRXh0ZW50LmNsb25lKCkudHJhbnNmb3JtKHVzZXJQcm9qZWN0aW9uLCB0aGlzLmdldFByb2plY3Rpb24oKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBnZW9tZXRyeSA9IGdlb21ldHJ5T3JFeHRlbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5maXRJbnRlcm5hbChnZW9tZXRyeSwgb3B0X29wdGlvbnMpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgVGhlIGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge0ZpdE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmZpdEludGVybmFsID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBvcHRfb3B0aW9ucykge1xuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgfHwge307XG4gICAgdmFyIHNpemUgPSBvcHRpb25zLnNpemU7XG5cbiAgICBpZiAoIXNpemUpIHtcbiAgICAgIHNpemUgPSB0aGlzLmdldFZpZXdwb3J0U2l6ZU1pbnVzUGFkZGluZ18oKTtcbiAgICB9XG5cbiAgICB2YXIgcGFkZGluZyA9IG9wdGlvbnMucGFkZGluZyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5wYWRkaW5nIDogWzAsIDAsIDAsIDBdO1xuICAgIHZhciBuZWFyZXN0ID0gb3B0aW9ucy5uZWFyZXN0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm5lYXJlc3QgOiBmYWxzZTtcbiAgICB2YXIgbWluUmVzb2x1dGlvbjtcblxuICAgIGlmIChvcHRpb25zLm1pblJlc29sdXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgbWluUmVzb2x1dGlvbiA9IG9wdGlvbnMubWluUmVzb2x1dGlvbjtcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMubWF4Wm9vbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBtaW5SZXNvbHV0aW9uID0gdGhpcy5nZXRSZXNvbHV0aW9uRm9yWm9vbShvcHRpb25zLm1heFpvb20pO1xuICAgIH0gZWxzZSB7XG4gICAgICBtaW5SZXNvbHV0aW9uID0gMDtcbiAgICB9XG5cbiAgICB2YXIgY29vcmRzID0gZ2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7IC8vIGNhbGN1bGF0ZSByb3RhdGVkIGV4dGVudFxuXG4gICAgdmFyIHJvdGF0aW9uID0gdGhpcy5nZXRSb3RhdGlvbigpO1xuICAgIHZhciBjb3NBbmdsZSA9IE1hdGguY29zKC1yb3RhdGlvbik7XG4gICAgdmFyIHNpbkFuZ2xlID0gTWF0aC5zaW4oLXJvdGF0aW9uKTtcbiAgICB2YXIgbWluUm90WCA9ICtJbmZpbml0eTtcbiAgICB2YXIgbWluUm90WSA9ICtJbmZpbml0eTtcbiAgICB2YXIgbWF4Um90WCA9IC1JbmZpbml0eTtcbiAgICB2YXIgbWF4Um90WSA9IC1JbmZpbml0eTtcbiAgICB2YXIgc3RyaWRlID0gZ2VvbWV0cnkuZ2V0U3RyaWRlKCk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBjb29yZHMubGVuZ3RoOyBpIDwgaWk7IGkgKz0gc3RyaWRlKSB7XG4gICAgICB2YXIgcm90WCA9IGNvb3Jkc1tpXSAqIGNvc0FuZ2xlIC0gY29vcmRzW2kgKyAxXSAqIHNpbkFuZ2xlO1xuICAgICAgdmFyIHJvdFkgPSBjb29yZHNbaV0gKiBzaW5BbmdsZSArIGNvb3Jkc1tpICsgMV0gKiBjb3NBbmdsZTtcbiAgICAgIG1pblJvdFggPSBNYXRoLm1pbihtaW5Sb3RYLCByb3RYKTtcbiAgICAgIG1pblJvdFkgPSBNYXRoLm1pbihtaW5Sb3RZLCByb3RZKTtcbiAgICAgIG1heFJvdFggPSBNYXRoLm1heChtYXhSb3RYLCByb3RYKTtcbiAgICAgIG1heFJvdFkgPSBNYXRoLm1heChtYXhSb3RZLCByb3RZKTtcbiAgICB9IC8vIGNhbGN1bGF0ZSByZXNvbHV0aW9uXG5cblxuICAgIHZhciByZXNvbHV0aW9uID0gdGhpcy5nZXRSZXNvbHV0aW9uRm9yRXh0ZW50SW50ZXJuYWwoW21pblJvdFgsIG1pblJvdFksIG1heFJvdFgsIG1heFJvdFldLCBbc2l6ZVswXSAtIHBhZGRpbmdbMV0gLSBwYWRkaW5nWzNdLCBzaXplWzFdIC0gcGFkZGluZ1swXSAtIHBhZGRpbmdbMl1dKTtcbiAgICByZXNvbHV0aW9uID0gaXNOYU4ocmVzb2x1dGlvbikgPyBtaW5SZXNvbHV0aW9uIDogTWF0aC5tYXgocmVzb2x1dGlvbiwgbWluUmVzb2x1dGlvbik7XG4gICAgcmVzb2x1dGlvbiA9IHRoaXMuZ2V0Q29uc3RyYWluZWRSZXNvbHV0aW9uKHJlc29sdXRpb24sIG5lYXJlc3QgPyAwIDogMSk7IC8vIGNhbGN1bGF0ZSBjZW50ZXJcblxuICAgIHNpbkFuZ2xlID0gLXNpbkFuZ2xlOyAvLyBnbyBiYWNrIHRvIG9yaWdpbmFsIHJvdGF0aW9uXG5cbiAgICB2YXIgY2VudGVyUm90WCA9IChtaW5Sb3RYICsgbWF4Um90WCkgLyAyO1xuICAgIHZhciBjZW50ZXJSb3RZID0gKG1pblJvdFkgKyBtYXhSb3RZKSAvIDI7XG4gICAgY2VudGVyUm90WCArPSAocGFkZGluZ1sxXSAtIHBhZGRpbmdbM10pIC8gMiAqIHJlc29sdXRpb247XG4gICAgY2VudGVyUm90WSArPSAocGFkZGluZ1swXSAtIHBhZGRpbmdbMl0pIC8gMiAqIHJlc29sdXRpb247XG4gICAgdmFyIGNlbnRlclggPSBjZW50ZXJSb3RYICogY29zQW5nbGUgLSBjZW50ZXJSb3RZICogc2luQW5nbGU7XG4gICAgdmFyIGNlbnRlclkgPSBjZW50ZXJSb3RZICogY29zQW5nbGUgKyBjZW50ZXJSb3RYICogc2luQW5nbGU7XG4gICAgdmFyIGNlbnRlciA9IHRoaXMuZ2V0Q29uc3RyYWluZWRDZW50ZXIoW2NlbnRlclgsIGNlbnRlclldLCByZXNvbHV0aW9uKTtcbiAgICB2YXIgY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrID8gb3B0aW9ucy5jYWxsYmFjayA6IFZPSUQ7XG5cbiAgICBpZiAob3B0aW9ucy5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmFuaW1hdGVJbnRlcm5hbCh7XG4gICAgICAgIHJlc29sdXRpb246IHJlc29sdXRpb24sXG4gICAgICAgIGNlbnRlcjogY2VudGVyLFxuICAgICAgICBkdXJhdGlvbjogb3B0aW9ucy5kdXJhdGlvbixcbiAgICAgICAgZWFzaW5nOiBvcHRpb25zLmVhc2luZ1xuICAgICAgfSwgY2FsbGJhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRhcmdldFJlc29sdXRpb25fID0gcmVzb2x1dGlvbjtcbiAgICAgIHRoaXMudGFyZ2V0Q2VudGVyXyA9IGNlbnRlcjtcbiAgICAgIHRoaXMuYXBwbHlUYXJnZXRTdGF0ZV8oZmFsc2UsIHRydWUpO1xuICAgICAgYW5pbWF0aW9uQ2FsbGJhY2soY2FsbGJhY2ssIHRydWUpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIENlbnRlciBvbiBjb29yZGluYXRlIGFuZCB2aWV3IHBvc2l0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemV9IHNpemUgQm94IHBpeGVsIHNpemUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH0gcG9zaXRpb24gUG9zaXRpb24gb24gdGhlIHZpZXcgdG8gY2VudGVyIG9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuY2VudGVyT24gPSBmdW5jdGlvbiAoY29vcmRpbmF0ZSwgc2l6ZSwgcG9zaXRpb24pIHtcbiAgICB0aGlzLmNlbnRlck9uSW50ZXJuYWwoZnJvbVVzZXJDb29yZGluYXRlKGNvb3JkaW5hdGUsIHRoaXMuZ2V0UHJvamVjdGlvbigpKSwgc2l6ZSwgcG9zaXRpb24pO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIEJveCBwaXhlbCBzaXplLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBvc2l0aW9uIFBvc2l0aW9uIG9uIHRoZSB2aWV3IHRvIGNlbnRlciBvbi5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5jZW50ZXJPbkludGVybmFsID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUsIHNpemUsIHBvc2l0aW9uKSB7XG4gICAgdGhpcy5zZXRDZW50ZXJJbnRlcm5hbChjYWxjdWxhdGVDZW50ZXJPbihjb29yZGluYXRlLCBzaXplLCBwb3NpdGlvbiwgdGhpcy5nZXRSZXNvbHV0aW9uKCksIHRoaXMuZ2V0Um90YXRpb24oKSkpO1xuICB9O1xuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgc2hpZnQgYmV0d2VlbiBtYXAgYW5kIHZpZXdwb3J0IGNlbnRlci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY2VudGVyIENlbnRlci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIFNpemUuXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj58dW5kZWZpbmVkfSBDZW50ZXIgc2hpZnQuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuY2FsY3VsYXRlQ2VudGVyU2hpZnQgPSBmdW5jdGlvbiAoY2VudGVyLCByZXNvbHV0aW9uLCByb3RhdGlvbiwgc2l6ZSkge1xuICAgIHZhciBjZW50ZXJTaGlmdDtcbiAgICB2YXIgcGFkZGluZyA9IHRoaXMucGFkZGluZztcblxuICAgIGlmIChwYWRkaW5nICYmIGNlbnRlcikge1xuICAgICAgdmFyIHJlZHVjZWRTaXplID0gdGhpcy5nZXRWaWV3cG9ydFNpemVNaW51c1BhZGRpbmdfKC1yb3RhdGlvbik7XG4gICAgICB2YXIgc2hpZnRlZENlbnRlciA9IGNhbGN1bGF0ZUNlbnRlck9uKGNlbnRlciwgc2l6ZSwgW3JlZHVjZWRTaXplWzBdIC8gMiArIHBhZGRpbmdbM10sIHJlZHVjZWRTaXplWzFdIC8gMiArIHBhZGRpbmdbMF1dLCByZXNvbHV0aW9uLCByb3RhdGlvbik7XG4gICAgICBjZW50ZXJTaGlmdCA9IFtjZW50ZXJbMF0gLSBzaGlmdGVkQ2VudGVyWzBdLCBjZW50ZXJbMV0gLSBzaGlmdGVkQ2VudGVyWzFdXTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2VudGVyU2hpZnQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJcyBkZWZpbmVkLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmlzRGVmID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhIXRoaXMuZ2V0Q2VudGVySW50ZXJuYWwoKSAmJiB0aGlzLmdldFJlc29sdXRpb24oKSAhPT0gdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogQWRkcyByZWxhdGl2ZSBjb29yZGluYXRlcyB0byB0aGUgY2VudGVyIG9mIHRoZSB2aWV3LiBBbnkgZXh0ZW50IGNvbnN0cmFpbnQgd2lsbCBhcHBseS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gZGVsdGFDb29yZGluYXRlcyBSZWxhdGl2ZSB2YWx1ZSB0byBhZGQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hZGp1c3RDZW50ZXIgPSBmdW5jdGlvbiAoZGVsdGFDb29yZGluYXRlcykge1xuICAgIHZhciBjZW50ZXIgPSB0b1VzZXJDb29yZGluYXRlKHRoaXMudGFyZ2V0Q2VudGVyXywgdGhpcy5nZXRQcm9qZWN0aW9uKCkpO1xuICAgIHRoaXMuc2V0Q2VudGVyKFtjZW50ZXJbMF0gKyBkZWx0YUNvb3JkaW5hdGVzWzBdLCBjZW50ZXJbMV0gKyBkZWx0YUNvb3JkaW5hdGVzWzFdXSk7XG4gIH07XG4gIC8qKlxuICAgKiBBZGRzIHJlbGF0aXZlIGNvb3JkaW5hdGVzIHRvIHRoZSBjZW50ZXIgb2YgdGhlIHZpZXcuIEFueSBleHRlbnQgY29uc3RyYWludCB3aWxsIGFwcGx5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBkZWx0YUNvb3JkaW5hdGVzIFJlbGF0aXZlIHZhbHVlIHRvIGFkZC5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hZGp1c3RDZW50ZXJJbnRlcm5hbCA9IGZ1bmN0aW9uIChkZWx0YUNvb3JkaW5hdGVzKSB7XG4gICAgdmFyIGNlbnRlciA9IHRoaXMudGFyZ2V0Q2VudGVyXztcbiAgICB0aGlzLnNldENlbnRlckludGVybmFsKFtjZW50ZXJbMF0gKyBkZWx0YUNvb3JkaW5hdGVzWzBdLCBjZW50ZXJbMV0gKyBkZWx0YUNvb3JkaW5hdGVzWzFdXSk7XG4gIH07XG4gIC8qKlxuICAgKiBNdWx0aXBseSB0aGUgdmlldyByZXNvbHV0aW9uIGJ5IGEgcmF0aW8sIG9wdGlvbmFsbHkgdXNpbmcgYW4gYW5jaG9yLiBBbnkgcmVzb2x1dGlvblxuICAgKiBjb25zdHJhaW50IHdpbGwgYXBwbHkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByYXRpbyBUaGUgcmF0aW8gdG8gYXBwbHkgb24gdGhlIHZpZXcgcmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9hbmNob3IgVGhlIG9yaWdpbiBvZiB0aGUgdHJhbnNmb3JtYXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hZGp1c3RSZXNvbHV0aW9uID0gZnVuY3Rpb24gKHJhdGlvLCBvcHRfYW5jaG9yKSB7XG4gICAgdmFyIGFuY2hvciA9IG9wdF9hbmNob3IgJiYgZnJvbVVzZXJDb29yZGluYXRlKG9wdF9hbmNob3IsIHRoaXMuZ2V0UHJvamVjdGlvbigpKTtcbiAgICB0aGlzLmFkanVzdFJlc29sdXRpb25JbnRlcm5hbChyYXRpbywgYW5jaG9yKTtcbiAgfTtcbiAgLyoqXG4gICAqIE11bHRpcGx5IHRoZSB2aWV3IHJlc29sdXRpb24gYnkgYSByYXRpbywgb3B0aW9uYWxseSB1c2luZyBhbiBhbmNob3IuIEFueSByZXNvbHV0aW9uXG4gICAqIGNvbnN0cmFpbnQgd2lsbCBhcHBseS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJhdGlvIFRoZSByYXRpbyB0byBhcHBseSBvbiB0aGUgdmlldyByZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPX0gb3B0X2FuY2hvciBUaGUgb3JpZ2luIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbi5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hZGp1c3RSZXNvbHV0aW9uSW50ZXJuYWwgPSBmdW5jdGlvbiAocmF0aW8sIG9wdF9hbmNob3IpIHtcbiAgICB2YXIgaXNNb3ZpbmcgPSB0aGlzLmdldEFuaW1hdGluZygpIHx8IHRoaXMuZ2V0SW50ZXJhY3RpbmcoKTtcbiAgICB2YXIgc2l6ZSA9IHRoaXMuZ2V0Vmlld3BvcnRTaXplXyh0aGlzLmdldFJvdGF0aW9uKCkpO1xuICAgIHZhciBuZXdSZXNvbHV0aW9uID0gdGhpcy5jb25zdHJhaW50c18ucmVzb2x1dGlvbih0aGlzLnRhcmdldFJlc29sdXRpb25fICogcmF0aW8sIDAsIHNpemUsIGlzTW92aW5nKTtcblxuICAgIGlmIChvcHRfYW5jaG9yKSB7XG4gICAgICB0aGlzLnRhcmdldENlbnRlcl8gPSB0aGlzLmNhbGN1bGF0ZUNlbnRlclpvb20obmV3UmVzb2x1dGlvbiwgb3B0X2FuY2hvcik7XG4gICAgfVxuXG4gICAgdGhpcy50YXJnZXRSZXNvbHV0aW9uXyAqPSByYXRpbztcbiAgICB0aGlzLmFwcGx5VGFyZ2V0U3RhdGVfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBBZGRzIGEgdmFsdWUgdG8gdGhlIHZpZXcgem9vbSBsZXZlbCwgb3B0aW9uYWxseSB1c2luZyBhbiBhbmNob3IuIEFueSByZXNvbHV0aW9uXG4gICAqIGNvbnN0cmFpbnQgd2lsbCBhcHBseS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhIFJlbGF0aXZlIHZhbHVlIHRvIGFkZCB0byB0aGUgem9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9hbmNob3IgVGhlIG9yaWdpbiBvZiB0aGUgdHJhbnNmb3JtYXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hZGp1c3Rab29tID0gZnVuY3Rpb24gKGRlbHRhLCBvcHRfYW5jaG9yKSB7XG4gICAgdGhpcy5hZGp1c3RSZXNvbHV0aW9uKE1hdGgucG93KHRoaXMuem9vbUZhY3Rvcl8sIC1kZWx0YSksIG9wdF9hbmNob3IpO1xuICB9O1xuICAvKipcbiAgICogQWRkcyBhIHZhbHVlIHRvIHRoZSB2aWV3IHJvdGF0aW9uLCBvcHRpb25hbGx5IHVzaW5nIGFuIGFuY2hvci4gQW55IHJvdGF0aW9uXG4gICAqIGNvbnN0cmFpbnQgd2lsbCBhcHBseS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhIFJlbGF0aXZlIHZhbHVlIHRvIGFkZCB0byB0aGUgem9vbSByb3RhdGlvbiwgaW4gcmFkaWFucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9hbmNob3IgVGhlIHJvdGF0aW9uIGNlbnRlci5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmFkanVzdFJvdGF0aW9uID0gZnVuY3Rpb24gKGRlbHRhLCBvcHRfYW5jaG9yKSB7XG4gICAgaWYgKG9wdF9hbmNob3IpIHtcbiAgICAgIG9wdF9hbmNob3IgPSBmcm9tVXNlckNvb3JkaW5hdGUob3B0X2FuY2hvciwgdGhpcy5nZXRQcm9qZWN0aW9uKCkpO1xuICAgIH1cblxuICAgIHRoaXMuYWRqdXN0Um90YXRpb25JbnRlcm5hbChkZWx0YSwgb3B0X2FuY2hvcik7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gZGVsdGEgUmVsYXRpdmUgdmFsdWUgdG8gYWRkIHRvIHRoZSB6b29tIHJvdGF0aW9uLCBpbiByYWRpYW5zLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPX0gb3B0X2FuY2hvciBUaGUgcm90YXRpb24gY2VudGVyLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmFkanVzdFJvdGF0aW9uSW50ZXJuYWwgPSBmdW5jdGlvbiAoZGVsdGEsIG9wdF9hbmNob3IpIHtcbiAgICB2YXIgaXNNb3ZpbmcgPSB0aGlzLmdldEFuaW1hdGluZygpIHx8IHRoaXMuZ2V0SW50ZXJhY3RpbmcoKTtcbiAgICB2YXIgbmV3Um90YXRpb24gPSB0aGlzLmNvbnN0cmFpbnRzXy5yb3RhdGlvbih0aGlzLnRhcmdldFJvdGF0aW9uXyArIGRlbHRhLCBpc01vdmluZyk7XG5cbiAgICBpZiAob3B0X2FuY2hvcikge1xuICAgICAgdGhpcy50YXJnZXRDZW50ZXJfID0gdGhpcy5jYWxjdWxhdGVDZW50ZXJSb3RhdGUobmV3Um90YXRpb24sIG9wdF9hbmNob3IpO1xuICAgIH1cblxuICAgIHRoaXMudGFyZ2V0Um90YXRpb25fICs9IGRlbHRhO1xuICAgIHRoaXMuYXBwbHlUYXJnZXRTdGF0ZV8oKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY2VudGVyIG9mIHRoZSBjdXJyZW50IHZpZXcuIEFueSBleHRlbnQgY29uc3RyYWludCB3aWxsIGFwcGx5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH0gY2VudGVyIFRoZSBjZW50ZXIgb2YgdGhlIHZpZXcuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5zZXRDZW50ZXIgPSBmdW5jdGlvbiAoY2VudGVyKSB7XG4gICAgdGhpcy5zZXRDZW50ZXJJbnRlcm5hbChmcm9tVXNlckNvb3JkaW5hdGUoY2VudGVyLCB0aGlzLmdldFByb2plY3Rpb24oKSkpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBjZW50ZXIgdXNpbmcgdGhlIHZpZXcgcHJvamVjdGlvbiAobm90IHRoZSB1c2VyIHByb2plY3Rpb24pLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH0gY2VudGVyIFRoZSBjZW50ZXIgb2YgdGhlIHZpZXcuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuc2V0Q2VudGVySW50ZXJuYWwgPSBmdW5jdGlvbiAoY2VudGVyKSB7XG4gICAgdGhpcy50YXJnZXRDZW50ZXJfID0gY2VudGVyO1xuICAgIHRoaXMuYXBwbHlUYXJnZXRTdGF0ZV8oKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9WaWV3SGludC5qc1wiKS5kZWZhdWx0fSBoaW50IEhpbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YSBEZWx0YS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBOZXcgdmFsdWUuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuc2V0SGludCA9IGZ1bmN0aW9uIChoaW50LCBkZWx0YSkge1xuICAgIHRoaXMuaGludHNfW2hpbnRdICs9IGRlbHRhO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIHJldHVybiB0aGlzLmhpbnRzX1toaW50XTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgcmVzb2x1dGlvbiBmb3IgdGhpcyB2aWV3LiBBbnkgcmVzb2x1dGlvbiBjb25zdHJhaW50IHdpbGwgYXBwbHkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfHVuZGVmaW5lZH0gcmVzb2x1dGlvbiBUaGUgcmVzb2x1dGlvbiBvZiB0aGUgdmlldy5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLnNldFJlc29sdXRpb24gPSBmdW5jdGlvbiAocmVzb2x1dGlvbikge1xuICAgIHRoaXMudGFyZ2V0UmVzb2x1dGlvbl8gPSByZXNvbHV0aW9uO1xuICAgIHRoaXMuYXBwbHlUYXJnZXRTdGF0ZV8oKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgcm90YXRpb24gZm9yIHRoaXMgdmlldy4gQW55IHJvdGF0aW9uIGNvbnN0cmFpbnQgd2lsbCBhcHBseS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFRoZSByb3RhdGlvbiBvZiB0aGUgdmlldyBpbiByYWRpYW5zLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuc2V0Um90YXRpb24gPSBmdW5jdGlvbiAocm90YXRpb24pIHtcbiAgICB0aGlzLnRhcmdldFJvdGF0aW9uXyA9IHJvdGF0aW9uO1xuICAgIHRoaXMuYXBwbHlUYXJnZXRTdGF0ZV8oKTtcbiAgfTtcbiAgLyoqXG4gICAqIFpvb20gdG8gYSBzcGVjaWZpYyB6b29tIGxldmVsLiBBbnkgcmVzb2x1dGlvbiBjb25zdHJhaW4gd2lsbCBhcHBseS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHpvb20gWm9vbSBsZXZlbC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLnNldFpvb20gPSBmdW5jdGlvbiAoem9vbSkge1xuICAgIHRoaXMuc2V0UmVzb2x1dGlvbih0aGlzLmdldFJlc29sdXRpb25Gb3Jab29tKHpvb20pKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlY29tcHV0ZSByb3RhdGlvbi9yZXNvbHV0aW9uL2NlbnRlciBiYXNlZCBvbiB0YXJnZXQgdmFsdWVzLlxuICAgKiBOb3RlOiB3ZSBoYXZlIHRvIGNvbXB1dGUgcm90YXRpb24gZmlyc3QsIHRoZW4gcmVzb2x1dGlvbiBhbmQgY2VudGVyIGNvbnNpZGVyaW5nIHRoYXRcbiAgICogcGFyYW1ldGVycyBjYW4gaW5mbHVlbmNlIG9uZSBhbm90aGVyIGluIGNhc2UgYSB2aWV3IGV4dGVudCBjb25zdHJhaW50IGlzIHByZXNlbnQuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9kb05vdENhbmNlbEFuaW1zIERvIG5vdCBjYW5jZWwgYW5pbWF0aW9ucy5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2ZvcmNlTW92aW5nIEFwcGx5IGNvbnN0cmFpbnRzIGFzIGlmIHRoZSB2aWV3IGlzIG1vdmluZy5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hcHBseVRhcmdldFN0YXRlXyA9IGZ1bmN0aW9uIChvcHRfZG9Ob3RDYW5jZWxBbmltcywgb3B0X2ZvcmNlTW92aW5nKSB7XG4gICAgdmFyIGlzTW92aW5nID0gdGhpcy5nZXRBbmltYXRpbmcoKSB8fCB0aGlzLmdldEludGVyYWN0aW5nKCkgfHwgb3B0X2ZvcmNlTW92aW5nOyAvLyBjb21wdXRlIHJvdGF0aW9uXG5cbiAgICB2YXIgbmV3Um90YXRpb24gPSB0aGlzLmNvbnN0cmFpbnRzXy5yb3RhdGlvbih0aGlzLnRhcmdldFJvdGF0aW9uXywgaXNNb3ZpbmcpO1xuICAgIHZhciBzaXplID0gdGhpcy5nZXRWaWV3cG9ydFNpemVfKG5ld1JvdGF0aW9uKTtcbiAgICB2YXIgbmV3UmVzb2x1dGlvbiA9IHRoaXMuY29uc3RyYWludHNfLnJlc29sdXRpb24odGhpcy50YXJnZXRSZXNvbHV0aW9uXywgMCwgc2l6ZSwgaXNNb3ZpbmcpO1xuICAgIHZhciBuZXdDZW50ZXIgPSB0aGlzLmNvbnN0cmFpbnRzXy5jZW50ZXIodGhpcy50YXJnZXRDZW50ZXJfLCBuZXdSZXNvbHV0aW9uLCBzaXplLCBpc01vdmluZywgdGhpcy5jYWxjdWxhdGVDZW50ZXJTaGlmdCh0aGlzLnRhcmdldENlbnRlcl8sIG5ld1Jlc29sdXRpb24sIG5ld1JvdGF0aW9uLCBzaXplKSk7XG5cbiAgICBpZiAodGhpcy5nZXQoVmlld1Byb3BlcnR5LlJPVEFUSU9OKSAhPT0gbmV3Um90YXRpb24pIHtcbiAgICAgIHRoaXMuc2V0KFZpZXdQcm9wZXJ0eS5ST1RBVElPTiwgbmV3Um90YXRpb24pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmdldChWaWV3UHJvcGVydHkuUkVTT0xVVElPTikgIT09IG5ld1Jlc29sdXRpb24pIHtcbiAgICAgIHRoaXMuc2V0KFZpZXdQcm9wZXJ0eS5SRVNPTFVUSU9OLCBuZXdSZXNvbHV0aW9uKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuZ2V0KFZpZXdQcm9wZXJ0eS5DRU5URVIpIHx8ICFlcXVhbHModGhpcy5nZXQoVmlld1Byb3BlcnR5LkNFTlRFUiksIG5ld0NlbnRlcikpIHtcbiAgICAgIHRoaXMuc2V0KFZpZXdQcm9wZXJ0eS5DRU5URVIsIG5ld0NlbnRlcik7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZ2V0QW5pbWF0aW5nKCkgJiYgIW9wdF9kb05vdENhbmNlbEFuaW1zKSB7XG4gICAgICB0aGlzLmNhbmNlbEFuaW1hdGlvbnMoKTtcbiAgICB9XG5cbiAgICB0aGlzLmNhbmNlbEFuY2hvcl8gPSB1bmRlZmluZWQ7XG4gIH07XG4gIC8qKlxuICAgKiBJZiBhbnkgY29uc3RyYWludHMgbmVlZCB0byBiZSBhcHBsaWVkLCBhbiBhbmltYXRpb24gd2lsbCBiZSB0cmlnZ2VyZWQuXG4gICAqIFRoaXMgaXMgdHlwaWNhbGx5IGRvbmUgb24gaW50ZXJhY3Rpb24gZW5kLlxuICAgKiBOb3RlOiBjYWxsaW5nIHRoaXMgd2l0aCBhIGR1cmF0aW9uIG9mIDAgd2lsbCBhcHBseSB0aGUgY29uc3RyYWluZWQgdmFsdWVzIHN0cmFpZ2h0IGF3YXksXG4gICAqIHdpdGhvdXQgYW5pbWF0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9kdXJhdGlvbiBUaGUgYW5pbWF0aW9uIGR1cmF0aW9uIGluIG1zLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9yZXNvbHV0aW9uRGlyZWN0aW9uIFdoaWNoIGRpcmVjdGlvbiB0byB6b29tLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPX0gb3B0X2FuY2hvciBUaGUgb3JpZ2luIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbi5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5yZXNvbHZlQ29uc3RyYWludHMgPSBmdW5jdGlvbiAob3B0X2R1cmF0aW9uLCBvcHRfcmVzb2x1dGlvbkRpcmVjdGlvbiwgb3B0X2FuY2hvcikge1xuICAgIHZhciBkdXJhdGlvbiA9IG9wdF9kdXJhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0X2R1cmF0aW9uIDogMjAwO1xuICAgIHZhciBkaXJlY3Rpb24gPSBvcHRfcmVzb2x1dGlvbkRpcmVjdGlvbiB8fCAwO1xuICAgIHZhciBuZXdSb3RhdGlvbiA9IHRoaXMuY29uc3RyYWludHNfLnJvdGF0aW9uKHRoaXMudGFyZ2V0Um90YXRpb25fKTtcbiAgICB2YXIgc2l6ZSA9IHRoaXMuZ2V0Vmlld3BvcnRTaXplXyhuZXdSb3RhdGlvbik7XG4gICAgdmFyIG5ld1Jlc29sdXRpb24gPSB0aGlzLmNvbnN0cmFpbnRzXy5yZXNvbHV0aW9uKHRoaXMudGFyZ2V0UmVzb2x1dGlvbl8sIGRpcmVjdGlvbiwgc2l6ZSk7XG4gICAgdmFyIG5ld0NlbnRlciA9IHRoaXMuY29uc3RyYWludHNfLmNlbnRlcih0aGlzLnRhcmdldENlbnRlcl8sIG5ld1Jlc29sdXRpb24sIHNpemUsIGZhbHNlLCB0aGlzLmNhbGN1bGF0ZUNlbnRlclNoaWZ0KHRoaXMudGFyZ2V0Q2VudGVyXywgbmV3UmVzb2x1dGlvbiwgbmV3Um90YXRpb24sIHNpemUpKTtcblxuICAgIGlmIChkdXJhdGlvbiA9PT0gMCAmJiAhdGhpcy5jYW5jZWxBbmNob3JfKSB7XG4gICAgICB0aGlzLnRhcmdldFJlc29sdXRpb25fID0gbmV3UmVzb2x1dGlvbjtcbiAgICAgIHRoaXMudGFyZ2V0Um90YXRpb25fID0gbmV3Um90YXRpb247XG4gICAgICB0aGlzLnRhcmdldENlbnRlcl8gPSBuZXdDZW50ZXI7XG4gICAgICB0aGlzLmFwcGx5VGFyZ2V0U3RhdGVfKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGFuY2hvciA9IG9wdF9hbmNob3IgfHwgKGR1cmF0aW9uID09PSAwID8gdGhpcy5jYW5jZWxBbmNob3JfIDogdW5kZWZpbmVkKTtcbiAgICB0aGlzLmNhbmNlbEFuY2hvcl8gPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAodGhpcy5nZXRSZXNvbHV0aW9uKCkgIT09IG5ld1Jlc29sdXRpb24gfHwgdGhpcy5nZXRSb3RhdGlvbigpICE9PSBuZXdSb3RhdGlvbiB8fCAhdGhpcy5nZXRDZW50ZXJJbnRlcm5hbCgpIHx8ICFlcXVhbHModGhpcy5nZXRDZW50ZXJJbnRlcm5hbCgpLCBuZXdDZW50ZXIpKSB7XG4gICAgICBpZiAodGhpcy5nZXRBbmltYXRpbmcoKSkge1xuICAgICAgICB0aGlzLmNhbmNlbEFuaW1hdGlvbnMoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hbmltYXRlSW50ZXJuYWwoe1xuICAgICAgICByb3RhdGlvbjogbmV3Um90YXRpb24sXG4gICAgICAgIGNlbnRlcjogbmV3Q2VudGVyLFxuICAgICAgICByZXNvbHV0aW9uOiBuZXdSZXNvbHV0aW9uLFxuICAgICAgICBkdXJhdGlvbjogZHVyYXRpb24sXG4gICAgICAgIGVhc2luZzogZWFzZU91dCxcbiAgICAgICAgYW5jaG9yOiBhbmNob3JcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIE5vdGlmeSB0aGUgVmlldyB0aGF0IGFuIGludGVyYWN0aW9uIGhhcyBzdGFydGVkLlxuICAgKiBUaGUgdmlldyBzdGF0ZSB3aWxsIGJlIHJlc29sdmVkIHRvIGEgc3RhYmxlIG9uZSBpZiBuZWVkZWRcbiAgICogKGRlcGVuZGluZyBvbiBpdHMgY29uc3RyYWludHMpLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuYmVnaW5JbnRlcmFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlc29sdmVDb25zdHJhaW50cygwKTtcbiAgICB0aGlzLnNldEhpbnQoVmlld0hpbnQuSU5URVJBQ1RJTkcsIDEpO1xuICB9O1xuICAvKipcbiAgICogTm90aWZ5IHRoZSBWaWV3IHRoYXQgYW4gaW50ZXJhY3Rpb24gaGFzIGVuZGVkLiBUaGUgdmlldyBzdGF0ZSB3aWxsIGJlIHJlc29sdmVkXG4gICAqIHRvIGEgc3RhYmxlIG9uZSBpZiBuZWVkZWQgKGRlcGVuZGluZyBvbiBpdHMgY29uc3RyYWludHMpLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9kdXJhdGlvbiBBbmltYXRpb24gZHVyYXRpb24gaW4gbXMuXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3Jlc29sdXRpb25EaXJlY3Rpb24gV2hpY2ggZGlyZWN0aW9uIHRvIHpvb20uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU9fSBvcHRfYW5jaG9yIFRoZSBvcmlnaW4gb2YgdGhlIHRyYW5zZm9ybWF0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZW5kSW50ZXJhY3Rpb24gPSBmdW5jdGlvbiAob3B0X2R1cmF0aW9uLCBvcHRfcmVzb2x1dGlvbkRpcmVjdGlvbiwgb3B0X2FuY2hvcikge1xuICAgIHZhciBhbmNob3IgPSBvcHRfYW5jaG9yICYmIGZyb21Vc2VyQ29vcmRpbmF0ZShvcHRfYW5jaG9yLCB0aGlzLmdldFByb2plY3Rpb24oKSk7XG4gICAgdGhpcy5lbmRJbnRlcmFjdGlvbkludGVybmFsKG9wdF9kdXJhdGlvbiwgb3B0X3Jlc29sdXRpb25EaXJlY3Rpb24sIGFuY2hvcik7XG4gIH07XG4gIC8qKlxuICAgKiBOb3RpZnkgdGhlIFZpZXcgdGhhdCBhbiBpbnRlcmFjdGlvbiBoYXMgZW5kZWQuIFRoZSB2aWV3IHN0YXRlIHdpbGwgYmUgcmVzb2x2ZWRcbiAgICogdG8gYSBzdGFibGUgb25lIGlmIG5lZWRlZCAoZGVwZW5kaW5nIG9uIGl0cyBjb25zdHJhaW50cykuXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2R1cmF0aW9uIEFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtcy5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfcmVzb2x1dGlvbkRpcmVjdGlvbiBXaGljaCBkaXJlY3Rpb24gdG8gem9vbS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9hbmNob3IgVGhlIG9yaWdpbiBvZiB0aGUgdHJhbnNmb3JtYXRpb24uXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZW5kSW50ZXJhY3Rpb25JbnRlcm5hbCA9IGZ1bmN0aW9uIChvcHRfZHVyYXRpb24sIG9wdF9yZXNvbHV0aW9uRGlyZWN0aW9uLCBvcHRfYW5jaG9yKSB7XG4gICAgdGhpcy5zZXRIaW50KFZpZXdIaW50LklOVEVSQUNUSU5HLCAtMSk7XG4gICAgdGhpcy5yZXNvbHZlQ29uc3RyYWludHMob3B0X2R1cmF0aW9uLCBvcHRfcmVzb2x1dGlvbkRpcmVjdGlvbiwgb3B0X2FuY2hvcik7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgYSB2YWxpZCBwb3NpdGlvbiBmb3IgdGhlIHZpZXcgY2VudGVyIGFjY29yZGluZyB0byB0aGUgY3VycmVudCBjb25zdHJhaW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IHRhcmdldENlbnRlciBUYXJnZXQgY2VudGVyIHBvc2l0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF90YXJnZXRSZXNvbHV0aW9uIFRhcmdldCByZXNvbHV0aW9uLiBJZiBub3Qgc3VwcGxpZWQsIHRoZSBjdXJyZW50IG9uZSB3aWxsIGJlIHVzZWQuXG4gICAqIFRoaXMgaXMgdXNlZnVsIHRvIGd1ZXNzIGEgdmFsaWQgY2VudGVyIHBvc2l0aW9uIGF0IGEgZGlmZmVyZW50IHpvb20gbGV2ZWwuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH0gVmFsaWQgY2VudGVyIHBvc2l0aW9uLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldENvbnN0cmFpbmVkQ2VudGVyID0gZnVuY3Rpb24gKHRhcmdldENlbnRlciwgb3B0X3RhcmdldFJlc29sdXRpb24pIHtcbiAgICB2YXIgc2l6ZSA9IHRoaXMuZ2V0Vmlld3BvcnRTaXplXyh0aGlzLmdldFJvdGF0aW9uKCkpO1xuICAgIHJldHVybiB0aGlzLmNvbnN0cmFpbnRzXy5jZW50ZXIodGFyZ2V0Q2VudGVyLCBvcHRfdGFyZ2V0UmVzb2x1dGlvbiB8fCB0aGlzLmdldFJlc29sdXRpb24oKSwgc2l6ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgYSB2YWxpZCB6b29tIGxldmVsIGFjY29yZGluZyB0byB0aGUgY3VycmVudCB2aWV3IGNvbnN0cmFpbnRzLlxuICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHRhcmdldFpvb20gVGFyZ2V0IHpvb20uXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gW29wdF9kaXJlY3Rpb249MF0gSW5kaWNhdGUgd2hpY2ggcmVzb2x1dGlvbiBzaG91bGQgYmUgdXNlZFxuICAgKiBieSBhIHJlbmRlcmVyIGlmIHRoZSB2aWV3IHJlc29sdXRpb24gZG9lcyBub3QgbWF0Y2ggYW55IHJlc29sdXRpb24gb2YgdGhlIHRpbGUgc291cmNlLlxuICAgKiBJZiAwLCB0aGUgbmVhcmVzdCByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC4gSWYgMSwgdGhlIG5lYXJlc3QgbG93ZXIgcmVzb2x1dGlvblxuICAgKiB3aWxsIGJlIHVzZWQuIElmIC0xLCB0aGUgbmVhcmVzdCBoaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuXG4gICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFZhbGlkIHpvb20gbGV2ZWwuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0Q29uc3RyYWluZWRab29tID0gZnVuY3Rpb24gKHRhcmdldFpvb20sIG9wdF9kaXJlY3Rpb24pIHtcbiAgICB2YXIgdGFyZ2V0UmVzID0gdGhpcy5nZXRSZXNvbHV0aW9uRm9yWm9vbSh0YXJnZXRab29tKTtcbiAgICByZXR1cm4gdGhpcy5nZXRab29tRm9yUmVzb2x1dGlvbih0aGlzLmdldENvbnN0cmFpbmVkUmVzb2x1dGlvbih0YXJnZXRSZXMsIG9wdF9kaXJlY3Rpb24pKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhIHZhbGlkIHJlc29sdXRpb24gYWNjb3JkaW5nIHRvIHRoZSBjdXJyZW50IHZpZXcgY29uc3RyYWludHMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfHVuZGVmaW5lZH0gdGFyZ2V0UmVzb2x1dGlvbiBUYXJnZXQgcmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBbb3B0X2RpcmVjdGlvbj0wXSBJbmRpY2F0ZSB3aGljaCByZXNvbHV0aW9uIHNob3VsZCBiZSB1c2VkXG4gICAqIGJ5IGEgcmVuZGVyZXIgaWYgdGhlIHZpZXcgcmVzb2x1dGlvbiBkb2VzIG5vdCBtYXRjaCBhbnkgcmVzb2x1dGlvbiBvZiB0aGUgdGlsZSBzb3VyY2UuXG4gICAqIElmIDAsIHRoZSBuZWFyZXN0IHJlc29sdXRpb24gd2lsbCBiZSB1c2VkLiBJZiAxLCB0aGUgbmVhcmVzdCBsb3dlciByZXNvbHV0aW9uXG4gICAqIHdpbGwgYmUgdXNlZC4gSWYgLTEsIHRoZSBuZWFyZXN0IGhpZ2hlciByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC5cbiAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gVmFsaWQgcmVzb2x1dGlvbi5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRDb25zdHJhaW5lZFJlc29sdXRpb24gPSBmdW5jdGlvbiAodGFyZ2V0UmVzb2x1dGlvbiwgb3B0X2RpcmVjdGlvbikge1xuICAgIHZhciBkaXJlY3Rpb24gPSBvcHRfZGlyZWN0aW9uIHx8IDA7XG4gICAgdmFyIHNpemUgPSB0aGlzLmdldFZpZXdwb3J0U2l6ZV8odGhpcy5nZXRSb3RhdGlvbigpKTtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJhaW50c18ucmVzb2x1dGlvbih0YXJnZXRSZXNvbHV0aW9uLCBkaXJlY3Rpb24sIHNpemUpO1xuICB9O1xuXG4gIHJldHVybiBWaWV3O1xufShCYXNlT2JqZWN0KTtcbi8qKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGJhY2suXG4gKiBAcGFyYW0geyp9IHJldHVyblZhbHVlIFJldHVybiB2YWx1ZS5cbiAqL1xuXG5cbmZ1bmN0aW9uIGFuaW1hdGlvbkNhbGxiYWNrKGNhbGxiYWNrLCByZXR1cm5WYWx1ZSkge1xuICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBjYWxsYmFjayhyZXR1cm5WYWx1ZSk7XG4gIH0sIDApO1xufVxuLyoqXG4gKiBAcGFyYW0ge1ZpZXdPcHRpb25zfSBvcHRpb25zIFZpZXcgb3B0aW9ucy5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY2VudGVyY29uc3RyYWludC5qc1wiKS5UeXBlfSBUaGUgY29uc3RyYWludC5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDZW50ZXJDb25zdHJhaW50KG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMuZXh0ZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgc21vb3RoID0gb3B0aW9ucy5zbW9vdGhFeHRlbnRDb25zdHJhaW50ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnNtb290aEV4dGVudENvbnN0cmFpbnQgOiB0cnVlO1xuICAgIHJldHVybiBjcmVhdGVFeHRlbnQob3B0aW9ucy5leHRlbnQsIG9wdGlvbnMuY29uc3RyYWluT25seUNlbnRlciwgc21vb3RoKTtcbiAgfVxuXG4gIHZhciBwcm9qZWN0aW9uID0gY3JlYXRlUHJvamVjdGlvbihvcHRpb25zLnByb2plY3Rpb24sICdFUFNHOjM4NTcnKTtcblxuICBpZiAob3B0aW9ucy5tdWx0aVdvcmxkICE9PSB0cnVlICYmIHByb2plY3Rpb24uaXNHbG9iYWwoKSkge1xuICAgIHZhciBleHRlbnQgPSBwcm9qZWN0aW9uLmdldEV4dGVudCgpLnNsaWNlKCk7XG4gICAgZXh0ZW50WzBdID0gLUluZmluaXR5O1xuICAgIGV4dGVudFsyXSA9IEluZmluaXR5O1xuICAgIHJldHVybiBjcmVhdGVFeHRlbnQoZXh0ZW50LCBmYWxzZSwgZmFsc2UpO1xuICB9XG5cbiAgcmV0dXJuIGNlbnRlck5vbmU7XG59XG4vKipcbiAqIEBwYXJhbSB7Vmlld09wdGlvbnN9IG9wdGlvbnMgVmlldyBvcHRpb25zLlxuICogQHJldHVybiB7e2NvbnN0cmFpbnQ6IGltcG9ydChcIi4vcmVzb2x1dGlvbmNvbnN0cmFpbnQuanNcIikuVHlwZSwgbWF4UmVzb2x1dGlvbjogbnVtYmVyLFxuICogICAgIG1pblJlc29sdXRpb246IG51bWJlciwgbWluWm9vbTogbnVtYmVyLCB6b29tRmFjdG9yOiBudW1iZXJ9fSBUaGUgY29uc3RyYWludC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVzb2x1dGlvbkNvbnN0cmFpbnQob3B0aW9ucykge1xuICB2YXIgcmVzb2x1dGlvbkNvbnN0cmFpbnQ7XG4gIHZhciBtYXhSZXNvbHV0aW9uO1xuICB2YXIgbWluUmVzb2x1dGlvbjsgLy8gVE9ETzogbW92ZSB0aGVzZSB0byBiZSBvbCBjb25zdGFudHNcbiAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9vcGVubGF5ZXJzL29wZW5sYXllcnMvaXNzdWVzLzIwNzZcblxuICB2YXIgZGVmYXVsdE1heFpvb20gPSAyODtcbiAgdmFyIGRlZmF1bHRab29tRmFjdG9yID0gMjtcbiAgdmFyIG1pblpvb20gPSBvcHRpb25zLm1pblpvb20gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubWluWm9vbSA6IERFRkFVTFRfTUlOX1pPT007XG4gIHZhciBtYXhab29tID0gb3B0aW9ucy5tYXhab29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1heFpvb20gOiBkZWZhdWx0TWF4Wm9vbTtcbiAgdmFyIHpvb21GYWN0b3IgPSBvcHRpb25zLnpvb21GYWN0b3IgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuem9vbUZhY3RvciA6IGRlZmF1bHRab29tRmFjdG9yO1xuICB2YXIgbXVsdGlXb3JsZCA9IG9wdGlvbnMubXVsdGlXb3JsZCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5tdWx0aVdvcmxkIDogZmFsc2U7XG4gIHZhciBzbW9vdGggPSBvcHRpb25zLnNtb290aFJlc29sdXRpb25Db25zdHJhaW50ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnNtb290aFJlc29sdXRpb25Db25zdHJhaW50IDogdHJ1ZTtcbiAgdmFyIHNob3dGdWxsRXh0ZW50ID0gb3B0aW9ucy5zaG93RnVsbEV4dGVudCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zaG93RnVsbEV4dGVudCA6IGZhbHNlO1xuICB2YXIgcHJvamVjdGlvbiA9IGNyZWF0ZVByb2plY3Rpb24ob3B0aW9ucy5wcm9qZWN0aW9uLCAnRVBTRzozODU3Jyk7XG4gIHZhciBwcm9qRXh0ZW50ID0gcHJvamVjdGlvbi5nZXRFeHRlbnQoKTtcbiAgdmFyIGNvbnN0cmFpbk9ubHlDZW50ZXIgPSBvcHRpb25zLmNvbnN0cmFpbk9ubHlDZW50ZXI7XG4gIHZhciBleHRlbnQgPSBvcHRpb25zLmV4dGVudDtcblxuICBpZiAoIW11bHRpV29ybGQgJiYgIWV4dGVudCAmJiBwcm9qZWN0aW9uLmlzR2xvYmFsKCkpIHtcbiAgICBjb25zdHJhaW5Pbmx5Q2VudGVyID0gZmFsc2U7XG4gICAgZXh0ZW50ID0gcHJvakV4dGVudDtcbiAgfVxuXG4gIGlmIChvcHRpb25zLnJlc29sdXRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgcmVzb2x1dGlvbnMgPSBvcHRpb25zLnJlc29sdXRpb25zO1xuICAgIG1heFJlc29sdXRpb24gPSByZXNvbHV0aW9uc1ttaW5ab29tXTtcbiAgICBtaW5SZXNvbHV0aW9uID0gcmVzb2x1dGlvbnNbbWF4Wm9vbV0gIT09IHVuZGVmaW5lZCA/IHJlc29sdXRpb25zW21heFpvb21dIDogcmVzb2x1dGlvbnNbcmVzb2x1dGlvbnMubGVuZ3RoIC0gMV07XG5cbiAgICBpZiAob3B0aW9ucy5jb25zdHJhaW5SZXNvbHV0aW9uKSB7XG4gICAgICByZXNvbHV0aW9uQ29uc3RyYWludCA9IGNyZWF0ZVNuYXBUb1Jlc29sdXRpb25zKHJlc29sdXRpb25zLCBzbW9vdGgsICFjb25zdHJhaW5Pbmx5Q2VudGVyICYmIGV4dGVudCwgc2hvd0Z1bGxFeHRlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNvbHV0aW9uQ29uc3RyYWludCA9IGNyZWF0ZU1pbk1heFJlc29sdXRpb24obWF4UmVzb2x1dGlvbiwgbWluUmVzb2x1dGlvbiwgc21vb3RoLCAhY29uc3RyYWluT25seUNlbnRlciAmJiBleHRlbnQsIHNob3dGdWxsRXh0ZW50KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gY2FsY3VsYXRlIHRoZSBkZWZhdWx0IG1pbiBhbmQgbWF4IHJlc29sdXRpb25cbiAgICB2YXIgc2l6ZSA9ICFwcm9qRXh0ZW50ID8gLy8gdXNlIGFuIGV4dGVudCB0aGF0IGNhbiBmaXQgdGhlIHdob2xlIHdvcmxkIGlmIG5lZWQgYmVcbiAgICAzNjAgKiBNRVRFUlNfUEVSX1VOSVRbVW5pdHMuREVHUkVFU10gLyBwcm9qZWN0aW9uLmdldE1ldGVyc1BlclVuaXQoKSA6IE1hdGgubWF4KGdldFdpZHRoKHByb2pFeHRlbnQpLCBnZXRIZWlnaHQocHJvakV4dGVudCkpO1xuICAgIHZhciBkZWZhdWx0TWF4UmVzb2x1dGlvbiA9IHNpemUgLyBERUZBVUxUX1RJTEVfU0laRSAvIE1hdGgucG93KGRlZmF1bHRab29tRmFjdG9yLCBERUZBVUxUX01JTl9aT09NKTtcbiAgICB2YXIgZGVmYXVsdE1pblJlc29sdXRpb24gPSBkZWZhdWx0TWF4UmVzb2x1dGlvbiAvIE1hdGgucG93KGRlZmF1bHRab29tRmFjdG9yLCBkZWZhdWx0TWF4Wm9vbSAtIERFRkFVTFRfTUlOX1pPT00pOyAvLyB1c2VyIHByb3ZpZGVkIG1heFJlc29sdXRpb24gdGFrZXMgcHJlY2VkZW5jZVxuXG4gICAgbWF4UmVzb2x1dGlvbiA9IG9wdGlvbnMubWF4UmVzb2x1dGlvbjtcblxuICAgIGlmIChtYXhSZXNvbHV0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1pblpvb20gPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYXhSZXNvbHV0aW9uID0gZGVmYXVsdE1heFJlc29sdXRpb24gLyBNYXRoLnBvdyh6b29tRmFjdG9yLCBtaW5ab29tKTtcbiAgICB9IC8vIHVzZXIgcHJvdmlkZWQgbWluUmVzb2x1dGlvbiB0YWtlcyBwcmVjZWRlbmNlXG5cblxuICAgIG1pblJlc29sdXRpb24gPSBvcHRpb25zLm1pblJlc29sdXRpb247XG5cbiAgICBpZiAobWluUmVzb2x1dGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAob3B0aW9ucy5tYXhab29tICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMubWF4UmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbWluUmVzb2x1dGlvbiA9IG1heFJlc29sdXRpb24gLyBNYXRoLnBvdyh6b29tRmFjdG9yLCBtYXhab29tKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtaW5SZXNvbHV0aW9uID0gZGVmYXVsdE1heFJlc29sdXRpb24gLyBNYXRoLnBvdyh6b29tRmFjdG9yLCBtYXhab29tKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWluUmVzb2x1dGlvbiA9IGRlZmF1bHRNaW5SZXNvbHV0aW9uO1xuICAgICAgfVxuICAgIH0gLy8gZ2l2ZW4gZGlzY3JldGUgem9vbSBsZXZlbHMsIG1pblJlc29sdXRpb24gbWF5IGJlIGRpZmZlcmVudCB0aGFuIHByb3ZpZGVkXG5cblxuICAgIG1heFpvb20gPSBtaW5ab29tICsgTWF0aC5mbG9vcihNYXRoLmxvZyhtYXhSZXNvbHV0aW9uIC8gbWluUmVzb2x1dGlvbikgLyBNYXRoLmxvZyh6b29tRmFjdG9yKSk7XG4gICAgbWluUmVzb2x1dGlvbiA9IG1heFJlc29sdXRpb24gLyBNYXRoLnBvdyh6b29tRmFjdG9yLCBtYXhab29tIC0gbWluWm9vbSk7XG5cbiAgICBpZiAob3B0aW9ucy5jb25zdHJhaW5SZXNvbHV0aW9uKSB7XG4gICAgICByZXNvbHV0aW9uQ29uc3RyYWludCA9IGNyZWF0ZVNuYXBUb1Bvd2VyKHpvb21GYWN0b3IsIG1heFJlc29sdXRpb24sIG1pblJlc29sdXRpb24sIHNtb290aCwgIWNvbnN0cmFpbk9ubHlDZW50ZXIgJiYgZXh0ZW50LCBzaG93RnVsbEV4dGVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc29sdXRpb25Db25zdHJhaW50ID0gY3JlYXRlTWluTWF4UmVzb2x1dGlvbihtYXhSZXNvbHV0aW9uLCBtaW5SZXNvbHV0aW9uLCBzbW9vdGgsICFjb25zdHJhaW5Pbmx5Q2VudGVyICYmIGV4dGVudCwgc2hvd0Z1bGxFeHRlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY29uc3RyYWludDogcmVzb2x1dGlvbkNvbnN0cmFpbnQsXG4gICAgbWF4UmVzb2x1dGlvbjogbWF4UmVzb2x1dGlvbixcbiAgICBtaW5SZXNvbHV0aW9uOiBtaW5SZXNvbHV0aW9uLFxuICAgIG1pblpvb206IG1pblpvb20sXG4gICAgem9vbUZhY3Rvcjogem9vbUZhY3RvclxuICB9O1xufVxuLyoqXG4gKiBAcGFyYW0ge1ZpZXdPcHRpb25zfSBvcHRpb25zIFZpZXcgb3B0aW9ucy5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vcm90YXRpb25jb25zdHJhaW50LmpzXCIpLlR5cGV9IFJvdGF0aW9uIGNvbnN0cmFpbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVJvdGF0aW9uQ29uc3RyYWludChvcHRpb25zKSB7XG4gIHZhciBlbmFibGVSb3RhdGlvbiA9IG9wdGlvbnMuZW5hYmxlUm90YXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZW5hYmxlUm90YXRpb24gOiB0cnVlO1xuXG4gIGlmIChlbmFibGVSb3RhdGlvbikge1xuICAgIHZhciBjb25zdHJhaW5Sb3RhdGlvbiA9IG9wdGlvbnMuY29uc3RyYWluUm90YXRpb247XG5cbiAgICBpZiAoY29uc3RyYWluUm90YXRpb24gPT09IHVuZGVmaW5lZCB8fCBjb25zdHJhaW5Sb3RhdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgcmV0dXJuIGNyZWF0ZVNuYXBUb1plcm8oKTtcbiAgICB9IGVsc2UgaWYgKGNvbnN0cmFpblJvdGF0aW9uID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIHJvdGF0aW9uTm9uZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBjb25zdHJhaW5Sb3RhdGlvbiA9PT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiBjcmVhdGVTbmFwVG9OKGNvbnN0cmFpblJvdGF0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJvdGF0aW9uTm9uZTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRpc2FibGU7XG4gIH1cbn1cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGFuIGFuaW1hdGlvbiBpbnZvbHZlcyBubyB2aWV3IGNoYW5nZS5cbiAqIEBwYXJhbSB7QW5pbWF0aW9ufSBhbmltYXRpb24gVGhlIGFuaW1hdGlvbi5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBhbmltYXRpb24gaW52b2x2ZXMgbm8gdmlldyBjaGFuZ2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTm9vcEFuaW1hdGlvbihhbmltYXRpb24pIHtcbiAgaWYgKGFuaW1hdGlvbi5zb3VyY2VDZW50ZXIgJiYgYW5pbWF0aW9uLnRhcmdldENlbnRlcikge1xuICAgIGlmICghY29vcmRpbmF0ZXNFcXVhbChhbmltYXRpb24uc291cmNlQ2VudGVyLCBhbmltYXRpb24udGFyZ2V0Q2VudGVyKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChhbmltYXRpb24uc291cmNlUmVzb2x1dGlvbiAhPT0gYW5pbWF0aW9uLnRhcmdldFJlc29sdXRpb24pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoYW5pbWF0aW9uLnNvdXJjZVJvdGF0aW9uICE9PSBhbmltYXRpb24udGFyZ2V0Um90YXRpb24pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBCb3ggcGl4ZWwgc2l6ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH0gcG9zaXRpb24gUG9zaXRpb24gb24gdGhlIHZpZXcgdG8gY2VudGVyIG9uLlxuICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSByb3RhdGlvbiBSb3RhdGlvbi5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBTaGlmdGVkIGNlbnRlci5cbiAqL1xuXG5mdW5jdGlvbiBjYWxjdWxhdGVDZW50ZXJPbihjb29yZGluYXRlLCBzaXplLCBwb3NpdGlvbiwgcmVzb2x1dGlvbiwgcm90YXRpb24pIHtcbiAgLy8gY2FsY3VsYXRlIHJvdGF0ZWQgcG9zaXRpb25cbiAgdmFyIGNvc0FuZ2xlID0gTWF0aC5jb3MoLXJvdGF0aW9uKTtcbiAgdmFyIHNpbkFuZ2xlID0gTWF0aC5zaW4oLXJvdGF0aW9uKTtcbiAgdmFyIHJvdFggPSBjb29yZGluYXRlWzBdICogY29zQW5nbGUgLSBjb29yZGluYXRlWzFdICogc2luQW5nbGU7XG4gIHZhciByb3RZID0gY29vcmRpbmF0ZVsxXSAqIGNvc0FuZ2xlICsgY29vcmRpbmF0ZVswXSAqIHNpbkFuZ2xlO1xuICByb3RYICs9IChzaXplWzBdIC8gMiAtIHBvc2l0aW9uWzBdKSAqIHJlc29sdXRpb247XG4gIHJvdFkgKz0gKHBvc2l0aW9uWzFdIC0gc2l6ZVsxXSAvIDIpICogcmVzb2x1dGlvbjsgLy8gZ28gYmFjayB0byBvcmlnaW5hbCBhbmdsZVxuXG4gIHNpbkFuZ2xlID0gLXNpbkFuZ2xlOyAvLyBnbyBiYWNrIHRvIG9yaWdpbmFsIHJvdGF0aW9uXG5cbiAgdmFyIGNlbnRlclggPSByb3RYICogY29zQW5nbGUgLSByb3RZICogc2luQW5nbGU7XG4gIHZhciBjZW50ZXJZID0gcm90WSAqIGNvc0FuZ2xlICsgcm90WCAqIHNpbkFuZ2xlO1xuICByZXR1cm4gW2NlbnRlclgsIGNlbnRlclldO1xufVxuXG5leHBvcnQgZGVmYXVsdCBWaWV3OyIsIi8qKlxuICogQG1vZHVsZSBvbC9zaXplXG4gKi9cblxuLyoqXG4gKiBBbiBhcnJheSBvZiBudW1iZXJzIHJlcHJlc2VudGluZyBhIHNpemU6IGBbd2lkdGgsIGhlaWdodF1gLlxuICogQHR5cGVkZWYge0FycmF5PG51bWJlcj59IFNpemVcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIFJldHVybnMgYSBidWZmZXJlZCBzaXplLlxuICogQHBhcmFtIHtTaXplfSBzaXplIFNpemUuXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtIFRoZSBhbW91bnQgYnkgd2hpY2ggdG8gYnVmZmVyLlxuICogQHBhcmFtIHtTaXplPX0gb3B0X3NpemUgT3B0aW9uYWwgcmV1c2FibGUgc2l6ZSBhcnJheS5cbiAqIEByZXR1cm4ge1NpemV9IFRoZSBidWZmZXJlZCBzaXplLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVmZmVyKHNpemUsIG51bSwgb3B0X3NpemUpIHtcbiAgaWYgKG9wdF9zaXplID09PSB1bmRlZmluZWQpIHtcbiAgICBvcHRfc2l6ZSA9IFswLCAwXTtcbiAgfVxuXG4gIG9wdF9zaXplWzBdID0gc2l6ZVswXSArIDIgKiBudW07XG4gIG9wdF9zaXplWzFdID0gc2l6ZVsxXSArIDIgKiBudW07XG4gIHJldHVybiBvcHRfc2l6ZTtcbn1cbi8qKlxuICogRGV0ZXJtaW5lcyBpZiBhIHNpemUgaGFzIGEgcG9zaXRpdmUgYXJlYS5cbiAqIEBwYXJhbSB7U2l6ZX0gc2l6ZSBUaGUgc2l6ZSB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHNpemUgaGFzIGEgcG9zaXRpdmUgYXJlYS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaGFzQXJlYShzaXplKSB7XG4gIHJldHVybiBzaXplWzBdID4gMCAmJiBzaXplWzFdID4gMDtcbn1cbi8qKlxuICogUmV0dXJucyBhIHNpemUgc2NhbGVkIGJ5IGEgcmF0aW8uIFRoZSByZXN1bHQgd2lsbCBiZSBhbiBhcnJheSBvZiBpbnRlZ2Vycy5cbiAqIEBwYXJhbSB7U2l6ZX0gc2l6ZSBTaXplLlxuICogQHBhcmFtIHtudW1iZXJ9IHJhdGlvIFJhdGlvLlxuICogQHBhcmFtIHtTaXplPX0gb3B0X3NpemUgT3B0aW9uYWwgcmV1c2FibGUgc2l6ZSBhcnJheS5cbiAqIEByZXR1cm4ge1NpemV9IFRoZSBzY2FsZWQgc2l6ZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2NhbGUoc2l6ZSwgcmF0aW8sIG9wdF9zaXplKSB7XG4gIGlmIChvcHRfc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgb3B0X3NpemUgPSBbMCwgMF07XG4gIH1cblxuICBvcHRfc2l6ZVswXSA9IHNpemVbMF0gKiByYXRpbyArIDAuNSB8IDA7XG4gIG9wdF9zaXplWzFdID0gc2l6ZVsxXSAqIHJhdGlvICsgMC41IHwgMDtcbiAgcmV0dXJuIG9wdF9zaXplO1xufVxuLyoqXG4gKiBSZXR1cm5zIGFuIGBTaXplYCBhcnJheSBmb3IgdGhlIHBhc3NlZCBpbiBudW1iZXIgKG1lYW5pbmc6IHNxdWFyZSkgb3JcbiAqIGBTaXplYCBhcnJheS5cbiAqIChtZWFuaW5nOiBub24tc3F1YXJlKSxcbiAqIEBwYXJhbSB7bnVtYmVyfFNpemV9IHNpemUgV2lkdGggYW5kIGhlaWdodC5cbiAqIEBwYXJhbSB7U2l6ZT19IG9wdF9zaXplIE9wdGlvbmFsIHJldXNhYmxlIHNpemUgYXJyYXkuXG4gKiBAcmV0dXJuIHtTaXplfSBTaXplLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0b1NpemUoc2l6ZSwgb3B0X3NpemUpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoc2l6ZSkpIHtcbiAgICByZXR1cm4gc2l6ZTtcbiAgfSBlbHNlIHtcbiAgICBpZiAob3B0X3NpemUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0X3NpemUgPSBbc2l6ZSwgc2l6ZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdF9zaXplWzBdID0gc2l6ZTtcbiAgICAgIG9wdF9zaXplWzFdID0gc2l6ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3B0X3NpemU7XG4gIH1cbn0iLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL1BsdWdnYWJsZU1hcFxuICovXG5cblxuaW1wb3J0IEJhc2VPYmplY3QsIHsgZ2V0Q2hhbmdlRXZlbnRUeXBlIH0gZnJvbSAnLi9PYmplY3QuanMnO1xuaW1wb3J0IENvbGxlY3Rpb24gZnJvbSAnLi9Db2xsZWN0aW9uLmpzJztcbmltcG9ydCBDb2xsZWN0aW9uRXZlbnRUeXBlIGZyb20gJy4vQ29sbGVjdGlvbkV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4vZXZlbnRzL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgTGF5ZXJHcm91cCBmcm9tICcuL2xheWVyL0dyb3VwLmpzJztcbmltcG9ydCBNYXBCcm93c2VyRXZlbnQgZnJvbSAnLi9NYXBCcm93c2VyRXZlbnQuanMnO1xuaW1wb3J0IE1hcEJyb3dzZXJFdmVudEhhbmRsZXIgZnJvbSAnLi9NYXBCcm93c2VyRXZlbnRIYW5kbGVyLmpzJztcbmltcG9ydCBNYXBCcm93c2VyRXZlbnRUeXBlIGZyb20gJy4vTWFwQnJvd3NlckV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgTWFwRXZlbnQgZnJvbSAnLi9NYXBFdmVudC5qcyc7XG5pbXBvcnQgTWFwRXZlbnRUeXBlIGZyb20gJy4vTWFwRXZlbnRUeXBlLmpzJztcbmltcG9ydCBNYXBQcm9wZXJ0eSBmcm9tICcuL01hcFByb3BlcnR5LmpzJztcbmltcG9ydCBPYmplY3RFdmVudFR5cGUgZnJvbSAnLi9PYmplY3RFdmVudFR5cGUuanMnO1xuaW1wb3J0IFBvaW50ZXJFdmVudFR5cGUgZnJvbSAnLi9wb2ludGVyL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgUmVuZGVyRXZlbnRUeXBlIGZyb20gJy4vcmVuZGVyL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgVGlsZVF1ZXVlLCB7IGdldFRpbGVQcmlvcml0eSB9IGZyb20gJy4vVGlsZVF1ZXVlLmpzJztcbmltcG9ydCBWaWV3IGZyb20gJy4vVmlldy5qcyc7XG5pbXBvcnQgVmlld0hpbnQgZnJvbSAnLi9WaWV3SGludC5qcyc7XG5pbXBvcnQgeyBERVZJQ0VfUElYRUxfUkFUSU8sIElNQUdFX0RFQ09ERSwgUEFTU0lWRV9FVkVOVF9MSVNURU5FUlMgfSBmcm9tICcuL2hhcy5qcyc7XG5pbXBvcnQgeyBUUlVFIH0gZnJvbSAnLi9mdW5jdGlvbnMuanMnO1xuaW1wb3J0IHsgYXBwbHkgYXMgYXBwbHlUcmFuc2Zvcm0sIGNyZWF0ZSBhcyBjcmVhdGVUcmFuc2Zvcm0gfSBmcm9tICcuL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuL2Fzc2VydHMuanMnO1xuaW1wb3J0IHsgY2xvbmUsIGNyZWF0ZU9yVXBkYXRlRW1wdHksIGVxdWFscywgZ2V0Rm9yVmlld0FuZFNpemUsIGlzRW1wdHkgfSBmcm9tICcuL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBmcm9tVXNlckNvb3JkaW5hdGUsIHRvVXNlckNvb3JkaW5hdGUgfSBmcm9tICcuL3Byb2ouanMnO1xuaW1wb3J0IHsgaGFzQXJlYSB9IGZyb20gJy4vc2l6ZS5qcyc7XG5pbXBvcnQgeyBsaXN0ZW4sIHVubGlzdGVuQnlLZXkgfSBmcm9tICcuL2V2ZW50cy5qcyc7XG5pbXBvcnQgeyByZW1vdmVOb2RlIH0gZnJvbSAnLi9kb20uanMnO1xuLyoqXG4gKiBTdGF0ZSBvZiB0aGUgY3VycmVudCBmcmFtZS4gT25seSBgcGl4ZWxSYXRpb2AsIGB0aW1lYCBhbmQgYHZpZXdTdGF0ZWAgc2hvdWxkXG4gKiBiZSB1c2VkIGluIGFwcGxpY2F0aW9ucy5cbiAqIEB0eXBlZGVmIHtPYmplY3R9IEZyYW1lU3RhdGVcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBwaXhlbFJhdGlvIFRoZSBwaXhlbCByYXRpbyBvZiB0aGUgZnJhbWUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gdGltZSBUaGUgdGltZSB3aGVuIHJlbmRlcmluZyBvZiB0aGUgZnJhbWUgd2FzIHJlcXVlc3RlZC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9WaWV3LmpzXCIpLlN0YXRlfSB2aWV3U3RhdGUgVGhlIHN0YXRlIG9mIHRoZSBjdXJyZW50IHZpZXcuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGFuaW1hdGVcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfSBjb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCJyYnVzaFwiKS5kZWZhdWx0fSBkZWNsdXR0ZXJUcmVlXG4gKiBAcHJvcGVydHkge251bGx8aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpbmRleFxuICogQHByb3BlcnR5IHtBcnJheTxpbXBvcnQoXCIuL2xheWVyL0xheWVyLmpzXCIpLlN0YXRlPn0gbGF5ZXJTdGF0ZXNBcnJheVxuICogQHByb3BlcnR5IHtudW1iZXJ9IGxheWVySW5kZXhcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfSBwaXhlbFRvQ29vcmRpbmF0ZVRyYW5zZm9ybVxuICogQHByb3BlcnR5IHtBcnJheTxQb3N0UmVuZGVyRnVuY3Rpb24+fSBwb3N0UmVuZGVyRnVuY3Rpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplXG4gKiBAcHJvcGVydHkge1RpbGVRdWV1ZX0gdGlsZVF1ZXVlXG4gKiBAcHJvcGVydHkgeyFPYmplY3Q8c3RyaW5nLCBPYmplY3Q8c3RyaW5nLCBib29sZWFuPj59IHVzZWRUaWxlc1xuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSB2aWV3SGludHNcbiAqIEBwcm9wZXJ0eSB7IU9iamVjdDxzdHJpbmcsIE9iamVjdDxzdHJpbmcsIGJvb2xlYW4+Pn0gd2FudGVkVGlsZXNcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihQbHVnZ2FibGVNYXAsID9GcmFtZVN0YXRlKTogYW55fSBQb3N0UmVuZGVyRnVuY3Rpb25cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEF0UGl4ZWxPcHRpb25zXG4gKiBAcHJvcGVydHkge3VuZGVmaW5lZHxmdW5jdGlvbihpbXBvcnQoXCIuL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHQpOiBib29sZWFufSBbbGF5ZXJGaWx0ZXJdIExheWVyIGZpbHRlclxuICogZnVuY3Rpb24uIFRoZSBmaWx0ZXIgZnVuY3Rpb24gd2lsbCByZWNlaXZlIG9uZSBhcmd1bWVudCwgdGhlXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0xheWVyIGxheWVyLWNhbmRpZGF0ZX0gYW5kIGl0IHNob3VsZCByZXR1cm4gYSBib29sZWFuIHZhbHVlLlxuICogT25seSBsYXllcnMgd2hpY2ggYXJlIHZpc2libGUgYW5kIGZvciB3aGljaCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgYHRydWVgXG4gKiB3aWxsIGJlIHRlc3RlZCBmb3IgZmVhdHVyZXMuIEJ5IGRlZmF1bHQsIGFsbCB2aXNpYmxlIGxheWVycyB3aWxsIGJlIHRlc3RlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbaGl0VG9sZXJhbmNlPTBdIEhpdC1kZXRlY3Rpb24gdG9sZXJhbmNlIGluIGNzcyBwaXhlbHMuIFBpeGVsc1xuICogaW5zaWRlIHRoZSByYWRpdXMgYXJvdW5kIHRoZSBnaXZlbiBwb3NpdGlvbiB3aWxsIGJlIGNoZWNrZWQgZm9yIGZlYXR1cmVzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbY2hlY2tXcmFwcGVkPXRydWVdIENoZWNrLVdyYXBwZWQgV2lsbCBjaGVjayBmb3IgZm9yIHdyYXBwZWQgZ2VvbWV0cmllcyBpbnNpZGUgdGhlIHJhbmdlIG9mXG4gKiAgICsvLSAxIHdvcmxkIHdpZHRoLiBXb3JrcyBvbmx5IGlmIGEgcHJvamVjdGlvbiBpcyB1c2VkIHRoYXQgY2FuIGJlIHdyYXBwZWQuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNYXBPcHRpb25zSW50ZXJuYWxcbiAqIEBwcm9wZXJ0eSB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuL2NvbnRyb2wvQ29udHJvbC5qc1wiKS5kZWZhdWx0Pn0gW2NvbnRyb2xzXVxuICogQHByb3BlcnR5IHtDb2xsZWN0aW9uPGltcG9ydChcIi4vaW50ZXJhY3Rpb24vSW50ZXJhY3Rpb24uanNcIikuZGVmYXVsdD59IFtpbnRlcmFjdGlvbnNdXG4gKiBAcHJvcGVydHkge0hUTUxFbGVtZW50fERvY3VtZW50fSBrZXlib2FyZEV2ZW50VGFyZ2V0XG4gKiBAcHJvcGVydHkge0NvbGxlY3Rpb248aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHQ+fSBvdmVybGF5c1xuICogQHByb3BlcnR5IHtPYmplY3Q8c3RyaW5nLCAqPn0gdmFsdWVzXG4gKi9cblxuLyoqXG4gKiBPYmplY3QgbGl0ZXJhbCB3aXRoIGNvbmZpZyBvcHRpb25zIGZvciB0aGUgbWFwLlxuICogQHR5cGVkZWYge09iamVjdH0gTWFwT3B0aW9uc1xuICogQHByb3BlcnR5IHtDb2xsZWN0aW9uPGltcG9ydChcIi4vY29udHJvbC9Db250cm9sLmpzXCIpLmRlZmF1bHQ+fEFycmF5PGltcG9ydChcIi4vY29udHJvbC9Db250cm9sLmpzXCIpLmRlZmF1bHQ+fSBbY29udHJvbHNdXG4gKiBDb250cm9scyBpbml0aWFsbHkgYWRkZWQgdG8gdGhlIG1hcC4gSWYgbm90IHNwZWNpZmllZCxcbiAqIHtAbGluayBtb2R1bGU6b2wvY29udHJvbH5kZWZhdWx0c30gaXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcGl4ZWxSYXRpbz13aW5kb3cuZGV2aWNlUGl4ZWxSYXRpb10gVGhlIHJhdGlvIGJldHdlZW5cbiAqIHBoeXNpY2FsIHBpeGVscyBhbmQgZGV2aWNlLWluZGVwZW5kZW50IHBpeGVscyAoZGlwcykgb24gdGhlIGRldmljZS5cbiAqIEBwcm9wZXJ0eSB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuL2ludGVyYWN0aW9uL0ludGVyYWN0aW9uLmpzXCIpLmRlZmF1bHQ+fEFycmF5PGltcG9ydChcIi4vaW50ZXJhY3Rpb24vSW50ZXJhY3Rpb24uanNcIikuZGVmYXVsdD59IFtpbnRlcmFjdGlvbnNdXG4gKiBJbnRlcmFjdGlvbnMgdGhhdCBhcmUgaW5pdGlhbGx5IGFkZGVkIHRvIHRoZSBtYXAuIElmIG5vdCBzcGVjaWZpZWQsXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9ufmRlZmF1bHRzfSBpcyB1c2VkLlxuICogQHByb3BlcnR5IHtIVE1MRWxlbWVudHxEb2N1bWVudHxzdHJpbmd9IFtrZXlib2FyZEV2ZW50VGFyZ2V0XSBUaGUgZWxlbWVudCB0b1xuICogbGlzdGVuIHRvIGtleWJvYXJkIGV2ZW50cyBvbi4gVGhpcyBkZXRlcm1pbmVzIHdoZW4gdGhlIGBLZXlib2FyZFBhbmAgYW5kXG4gKiBgS2V5Ym9hcmRab29tYCBpbnRlcmFjdGlvbnMgdHJpZ2dlci4gRm9yIGV4YW1wbGUsIGlmIHRoaXMgb3B0aW9uIGlzIHNldCB0b1xuICogYGRvY3VtZW50YCB0aGUga2V5Ym9hcmQgaW50ZXJhY3Rpb25zIHdpbGwgYWx3YXlzIHRyaWdnZXIuIElmIHRoaXMgb3B0aW9uIGlzXG4gKiBub3Qgc3BlY2lmaWVkLCB0aGUgZWxlbWVudCB0aGUgbGlicmFyeSBsaXN0ZW5zIHRvIGtleWJvYXJkIGV2ZW50cyBvbiBpcyB0aGVcbiAqIG1hcCB0YXJnZXQgKGkuZS4gdGhlIHVzZXItcHJvdmlkZWQgZGl2IGZvciB0aGUgbWFwKS4gSWYgdGhpcyBpcyBub3RcbiAqIGBkb2N1bWVudGAsIHRoZSB0YXJnZXQgZWxlbWVudCBuZWVkcyB0byBiZSBmb2N1c2VkIGZvciBrZXkgZXZlbnRzIHRvIGJlXG4gKiBlbWl0dGVkLCByZXF1aXJpbmcgdGhhdCB0aGUgdGFyZ2V0IGVsZW1lbnQgaGFzIGEgYHRhYmluZGV4YCBhdHRyaWJ1dGUuXG4gKiBAcHJvcGVydHkge0FycmF5PGltcG9ydChcIi4vbGF5ZXIvQmFzZS5qc1wiKS5kZWZhdWx0PnxDb2xsZWN0aW9uPGltcG9ydChcIi4vbGF5ZXIvQmFzZS5qc1wiKS5kZWZhdWx0PnxMYXllckdyb3VwfSBbbGF5ZXJzXVxuICogTGF5ZXJzLiBJZiB0aGlzIGlzIG5vdCBkZWZpbmVkLCBhIG1hcCB3aXRoIG5vIGxheWVycyB3aWxsIGJlIHJlbmRlcmVkLiBOb3RlXG4gKiB0aGF0IGxheWVycyBhcmUgcmVuZGVyZWQgaW4gdGhlIG9yZGVyIHN1cHBsaWVkLCBzbyBpZiB5b3Ugd2FudCwgZm9yIGV4YW1wbGUsXG4gKiBhIHZlY3RvciBsYXllciB0byBhcHBlYXIgb24gdG9wIG9mIGEgdGlsZSBsYXllciwgaXQgbXVzdCBjb21lIGFmdGVyIHRoZSB0aWxlXG4gKiBsYXllci5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4VGlsZXNMb2FkaW5nPTE2XSBNYXhpbXVtIG51bWJlciB0aWxlcyB0byBsb2FkXG4gKiBzaW11bHRhbmVvdXNseS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbW92ZVRvbGVyYW5jZT0xXSBUaGUgbWluaW11bSBkaXN0YW5jZSBpbiBwaXhlbHMgdGhlXG4gKiBjdXJzb3IgbXVzdCBtb3ZlIHRvIGJlIGRldGVjdGVkIGFzIGEgbWFwIG1vdmUgZXZlbnQgaW5zdGVhZCBvZiBhIGNsaWNrLlxuICogSW5jcmVhc2luZyB0aGlzIHZhbHVlIGNhbiBtYWtlIGl0IGVhc2llciB0byBjbGljayBvbiB0aGUgbWFwLlxuICogQHByb3BlcnR5IHtDb2xsZWN0aW9uPGltcG9ydChcIi4vT3ZlcmxheS5qc1wiKS5kZWZhdWx0PnxBcnJheTxpbXBvcnQoXCIuL092ZXJsYXkuanNcIikuZGVmYXVsdD59IFtvdmVybGF5c11cbiAqIE92ZXJsYXlzIGluaXRpYWxseSBhZGRlZCB0byB0aGUgbWFwLiBCeSBkZWZhdWx0LCBubyBvdmVybGF5cyBhcmUgYWRkZWQuXG4gKiBAcHJvcGVydHkge0hUTUxFbGVtZW50fHN0cmluZ30gW3RhcmdldF0gVGhlIGNvbnRhaW5lciBmb3IgdGhlIG1hcCwgZWl0aGVyIHRoZVxuICogZWxlbWVudCBpdHNlbGYgb3IgdGhlIGBpZGAgb2YgdGhlIGVsZW1lbnQuIElmIG5vdCBzcGVjaWZpZWQgYXQgY29uc3RydWN0aW9uXG4gKiB0aW1lLCB7QGxpbmsgbW9kdWxlOm9sL01hcH5NYXAjc2V0VGFyZ2V0fSBtdXN0IGJlIGNhbGxlZCBmb3IgdGhlIG1hcCB0byBiZVxuICogcmVuZGVyZWQuIElmIHBhc3NlZCBieSBlbGVtZW50LCB0aGUgY29udGFpbmVyIGNhbiBiZSBpbiBhIHNlY29uZGFyeSBkb2N1bWVudC5cbiAqIEBwcm9wZXJ0eSB7Vmlld30gW3ZpZXddIFRoZSBtYXAncyB2aWV3LiAgTm8gbGF5ZXIgc291cmNlcyB3aWxsIGJlXG4gKiBmZXRjaGVkIHVubGVzcyB0aGlzIGlzIHNwZWNpZmllZCBhdCBjb25zdHJ1Y3Rpb24gdGltZSBvciB0aHJvdWdoXG4gKiB7QGxpbmsgbW9kdWxlOm9sL01hcH5NYXAjc2V0Vmlld30uXG4gKi9cblxuLyoqXG4gKiBAZmlyZXMgaW1wb3J0KFwiLi9NYXBCcm93c2VyRXZlbnQuanNcIikuTWFwQnJvd3NlckV2ZW50XG4gKiBAZmlyZXMgaW1wb3J0KFwiLi9NYXBFdmVudC5qc1wiKS5NYXBFdmVudFxuICogQGZpcmVzIGltcG9ydChcIi4vcmVuZGVyL0V2ZW50LmpzXCIpLmRlZmF1bHQjcHJlY29tcG9zZVxuICogQGZpcmVzIGltcG9ydChcIi4vcmVuZGVyL0V2ZW50LmpzXCIpLmRlZmF1bHQjcG9zdGNvbXBvc2VcbiAqIEBmaXJlcyBpbXBvcnQoXCIuL3JlbmRlci9FdmVudC5qc1wiKS5kZWZhdWx0I3JlbmRlcmNvbXBsZXRlXG4gKiBAYXBpXG4gKi9cblxudmFyIFBsdWdnYWJsZU1hcCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhQbHVnZ2FibGVNYXAsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge01hcE9wdGlvbnN9IG9wdGlvbnMgTWFwIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gUGx1Z2dhYmxlTWFwKG9wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnNJbnRlcm5hbCA9IGNyZWF0ZU9wdGlvbnNJbnRlcm5hbChvcHRpb25zKTtcbiAgICAvKiogQHByaXZhdGUgKi9cblxuICAgIF90aGlzLmJvdW5kSGFuZGxlQnJvd3NlckV2ZW50XyA9IF90aGlzLmhhbmRsZUJyb3dzZXJFdmVudC5iaW5kKF90aGlzKTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5tYXhUaWxlc0xvYWRpbmdfID0gb3B0aW9ucy5tYXhUaWxlc0xvYWRpbmcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubWF4VGlsZXNMb2FkaW5nIDogMTY7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMucGl4ZWxSYXRpb18gPSBvcHRpb25zLnBpeGVsUmF0aW8gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucGl4ZWxSYXRpbyA6IERFVklDRV9QSVhFTF9SQVRJTztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHsqfVxuICAgICAqL1xuXG4gICAgX3RoaXMucG9zdFJlbmRlclRpbWVvdXRIYW5kbGVfO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5hbmltYXRpb25EZWxheUtleV87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmFuaW1hdGlvbkRlbGF5XyA9XG4gICAgLyoqIEB0aGlzIHtQbHVnZ2FibGVNYXB9ICovXG4gICAgZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5hbmltYXRpb25EZWxheUtleV8gPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnJlbmRlckZyYW1lXyhEYXRlLm5vdygpKTtcbiAgICB9LmJpbmQoX3RoaXMpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm1fID0gY3JlYXRlVHJhbnNmb3JtKCk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfVxuICAgICAqL1xuXG4gICAgX3RoaXMucGl4ZWxUb0Nvb3JkaW5hdGVUcmFuc2Zvcm1fID0gY3JlYXRlVHJhbnNmb3JtKCk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZnJhbWVJbmRleF8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9GcmFtZVN0YXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZnJhbWVTdGF0ZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIFRoZSBleHRlbnQgYXQgdGhlIHByZXZpb3VzICdtb3ZlZW5kJyBldmVudC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5wcmV2aW91c0V4dGVudF8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuL2V2ZW50cy5qc1wiKS5FdmVudHNLZXl9XG4gICAgICovXG5cbiAgICBfdGhpcy52aWV3UHJvcGVydHlMaXN0ZW5lcktleV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuL2V2ZW50cy5qc1wiKS5FdmVudHNLZXl9XG4gICAgICovXG5cbiAgICBfdGhpcy52aWV3Q2hhbmdlTGlzdGVuZXJLZXlfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/QXJyYXk8aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxheWVyR3JvdXBQcm9wZXJ0eUxpc3RlbmVyS2V5c18gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFIVE1MRWxlbWVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLnZpZXdwb3J0XyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIF90aGlzLnZpZXdwb3J0Xy5jbGFzc05hbWUgPSAnb2wtdmlld3BvcnQnICsgKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyA/ICcgb2wtdG91Y2gnIDogJycpO1xuICAgIF90aGlzLnZpZXdwb3J0Xy5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgX3RoaXMudmlld3BvcnRfLnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XG4gICAgX3RoaXMudmlld3BvcnRfLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgIF90aGlzLnZpZXdwb3J0Xy5zdHlsZS5oZWlnaHQgPSAnMTAwJSc7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IUhUTUxFbGVtZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMub3ZlcmxheUNvbnRhaW5lcl8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBfdGhpcy5vdmVybGF5Q29udGFpbmVyXy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgX3RoaXMub3ZlcmxheUNvbnRhaW5lcl8uc3R5bGUuekluZGV4ID0gJzAnO1xuICAgIF90aGlzLm92ZXJsYXlDb250YWluZXJfLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgIF90aGlzLm92ZXJsYXlDb250YWluZXJfLnN0eWxlLmhlaWdodCA9ICcxMDAlJztcbiAgICBfdGhpcy5vdmVybGF5Q29udGFpbmVyXy5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnO1xuICAgIF90aGlzLm92ZXJsYXlDb250YWluZXJfLmNsYXNzTmFtZSA9ICdvbC1vdmVybGF5Y29udGFpbmVyJztcblxuICAgIF90aGlzLnZpZXdwb3J0Xy5hcHBlbmRDaGlsZChfdGhpcy5vdmVybGF5Q29udGFpbmVyXyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IUhUTUxFbGVtZW50fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5vdmVybGF5Q29udGFpbmVyU3RvcEV2ZW50XyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIF90aGlzLm92ZXJsYXlDb250YWluZXJTdG9wRXZlbnRfLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICBfdGhpcy5vdmVybGF5Q29udGFpbmVyU3RvcEV2ZW50Xy5zdHlsZS56SW5kZXggPSAnMCc7XG4gICAgX3RoaXMub3ZlcmxheUNvbnRhaW5lclN0b3BFdmVudF8uc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gICAgX3RoaXMub3ZlcmxheUNvbnRhaW5lclN0b3BFdmVudF8uc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIF90aGlzLm92ZXJsYXlDb250YWluZXJTdG9wRXZlbnRfLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG4gICAgX3RoaXMub3ZlcmxheUNvbnRhaW5lclN0b3BFdmVudF8uY2xhc3NOYW1lID0gJ29sLW92ZXJsYXljb250YWluZXItc3RvcGV2ZW50JztcblxuICAgIF90aGlzLnZpZXdwb3J0Xy5hcHBlbmRDaGlsZChfdGhpcy5vdmVybGF5Q29udGFpbmVyU3RvcEV2ZW50Xyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7TWFwQnJvd3NlckV2ZW50SGFuZGxlcn1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMubWFwQnJvd3NlckV2ZW50SGFuZGxlcl8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLm1vdmVUb2xlcmFuY2VfID0gb3B0aW9ucy5tb3ZlVG9sZXJhbmNlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0hUTUxFbGVtZW50fERvY3VtZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMua2V5Ym9hcmRFdmVudFRhcmdldF8gPSBvcHRpb25zSW50ZXJuYWwua2V5Ym9hcmRFdmVudFRhcmdldDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/QXJyYXk8aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmtleUhhbmRsZXJLZXlzXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0NvbGxlY3Rpb248aW1wb3J0KFwiLi9jb250cm9sL0NvbnRyb2wuanNcIikuZGVmYXVsdD59XG4gICAgICogQHByb3RlY3RlZFxuICAgICAqL1xuXG4gICAgX3RoaXMuY29udHJvbHMgPSBvcHRpb25zSW50ZXJuYWwuY29udHJvbHMgfHwgbmV3IENvbGxlY3Rpb24oKTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuL2ludGVyYWN0aW9uL0ludGVyYWN0aW9uLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKi9cblxuICAgIF90aGlzLmludGVyYWN0aW9ucyA9IG9wdGlvbnNJbnRlcm5hbC5pbnRlcmFjdGlvbnMgfHwgbmV3IENvbGxlY3Rpb24oKTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuL092ZXJsYXkuanNcIikuZGVmYXVsdD59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLm92ZXJsYXlzXyA9IG9wdGlvbnNJbnRlcm5hbC5vdmVybGF5cztcbiAgICAvKipcbiAgICAgKiBBIGxvb2t1cCBvZiBvdmVybGF5cyBieSBpZC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuL092ZXJsYXkuanNcIikuZGVmYXVsdD59XG4gICAgICovXG5cbiAgICBfdGhpcy5vdmVybGF5SWRJbmRleF8gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9yZW5kZXJlci9NYXAuanNcIikuZGVmYXVsdH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZXJfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7dW5kZWZpbmVkfGZ1bmN0aW9uKEV2ZW50KTogdm9pZH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMuaGFuZGxlUmVzaXplXztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshQXJyYXk8UG9zdFJlbmRlckZ1bmN0aW9uPn1cbiAgICAgKi9cblxuICAgIF90aGlzLnBvc3RSZW5kZXJGdW5jdGlvbnNfID0gW107XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7VGlsZVF1ZXVlfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGlsZVF1ZXVlXyA9IG5ldyBUaWxlUXVldWUoX3RoaXMuZ2V0VGlsZVByaW9yaXR5LmJpbmQoX3RoaXMpLCBfdGhpcy5oYW5kbGVUaWxlQ2hhbmdlXy5iaW5kKF90aGlzKSk7XG5cbiAgICBfdGhpcy5hZGRFdmVudExpc3RlbmVyKGdldENoYW5nZUV2ZW50VHlwZShNYXBQcm9wZXJ0eS5MQVlFUkdST1VQKSwgX3RoaXMuaGFuZGxlTGF5ZXJHcm91cENoYW5nZWRfKTtcblxuICAgIF90aGlzLmFkZEV2ZW50TGlzdGVuZXIoZ2V0Q2hhbmdlRXZlbnRUeXBlKE1hcFByb3BlcnR5LlZJRVcpLCBfdGhpcy5oYW5kbGVWaWV3Q2hhbmdlZF8pO1xuXG4gICAgX3RoaXMuYWRkRXZlbnRMaXN0ZW5lcihnZXRDaGFuZ2VFdmVudFR5cGUoTWFwUHJvcGVydHkuU0laRSksIF90aGlzLmhhbmRsZVNpemVDaGFuZ2VkXyk7XG5cbiAgICBfdGhpcy5hZGRFdmVudExpc3RlbmVyKGdldENoYW5nZUV2ZW50VHlwZShNYXBQcm9wZXJ0eS5UQVJHRVQpLCBfdGhpcy5oYW5kbGVUYXJnZXRDaGFuZ2VkXyk7IC8vIHNldFByb3BlcnRpZXMgd2lsbCB0cmlnZ2VyIHRoZSByZW5kZXJpbmcgb2YgdGhlIG1hcCBpZiB0aGUgbWFwXG4gICAgLy8gaXMgXCJkZWZpbmVkXCIgYWxyZWFkeS5cblxuXG4gICAgX3RoaXMuc2V0UHJvcGVydGllcyhvcHRpb25zSW50ZXJuYWwudmFsdWVzKTtcblxuICAgIF90aGlzLmNvbnRyb2xzLmZvckVhY2goXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbnRyb2wvQ29udHJvbC5qc1wiKS5kZWZhdWx0fSBjb250cm9sIENvbnRyb2wuXG4gICAgICogQHRoaXMge1BsdWdnYWJsZU1hcH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoY29udHJvbCkge1xuICAgICAgY29udHJvbC5zZXRNYXAodGhpcyk7XG4gICAgfS5iaW5kKF90aGlzKSk7XG5cbiAgICBfdGhpcy5jb250cm9scy5hZGRFdmVudExpc3RlbmVyKENvbGxlY3Rpb25FdmVudFR5cGUuQURELFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9Db2xsZWN0aW9uLmpzXCIpLkNvbGxlY3Rpb25FdmVudH0gZXZlbnQgQ29sbGVjdGlvbkV2ZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgZXZlbnQuZWxlbWVudC5zZXRNYXAodGhpcyk7XG4gICAgfS5iaW5kKF90aGlzKSk7XG5cbiAgICBfdGhpcy5jb250cm9scy5hZGRFdmVudExpc3RlbmVyKENvbGxlY3Rpb25FdmVudFR5cGUuUkVNT1ZFLFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9Db2xsZWN0aW9uLmpzXCIpLkNvbGxlY3Rpb25FdmVudH0gZXZlbnQgQ29sbGVjdGlvbkV2ZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgZXZlbnQuZWxlbWVudC5zZXRNYXAobnVsbCk7XG4gICAgfS5iaW5kKF90aGlzKSk7XG5cbiAgICBfdGhpcy5pbnRlcmFjdGlvbnMuZm9yRWFjaChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vaW50ZXJhY3Rpb24vSW50ZXJhY3Rpb24uanNcIikuZGVmYXVsdH0gaW50ZXJhY3Rpb24gSW50ZXJhY3Rpb24uXG4gICAgICogQHRoaXMge1BsdWdnYWJsZU1hcH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoaW50ZXJhY3Rpb24pIHtcbiAgICAgIGludGVyYWN0aW9uLnNldE1hcCh0aGlzKTtcbiAgICB9LmJpbmQoX3RoaXMpKTtcblxuICAgIF90aGlzLmludGVyYWN0aW9ucy5hZGRFdmVudExpc3RlbmVyKENvbGxlY3Rpb25FdmVudFR5cGUuQURELFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9Db2xsZWN0aW9uLmpzXCIpLkNvbGxlY3Rpb25FdmVudH0gZXZlbnQgQ29sbGVjdGlvbkV2ZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgZXZlbnQuZWxlbWVudC5zZXRNYXAodGhpcyk7XG4gICAgfS5iaW5kKF90aGlzKSk7XG5cbiAgICBfdGhpcy5pbnRlcmFjdGlvbnMuYWRkRXZlbnRMaXN0ZW5lcihDb2xsZWN0aW9uRXZlbnRUeXBlLlJFTU9WRSxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uRXZlbnR9IGV2ZW50IENvbGxlY3Rpb25FdmVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LmVsZW1lbnQuc2V0TWFwKG51bGwpO1xuICAgIH0uYmluZChfdGhpcykpO1xuXG4gICAgX3RoaXMub3ZlcmxheXNfLmZvckVhY2goX3RoaXMuYWRkT3ZlcmxheUludGVybmFsXy5iaW5kKF90aGlzKSk7XG5cbiAgICBfdGhpcy5vdmVybGF5c18uYWRkRXZlbnRMaXN0ZW5lcihDb2xsZWN0aW9uRXZlbnRUeXBlLkFERCxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uRXZlbnR9IGV2ZW50IENvbGxlY3Rpb25FdmVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIHRoaXMuYWRkT3ZlcmxheUludGVybmFsXyhcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBldmVudC5lbGVtZW50KTtcbiAgICB9LmJpbmQoX3RoaXMpKTtcblxuICAgIF90aGlzLm92ZXJsYXlzXy5hZGRFdmVudExpc3RlbmVyKENvbGxlY3Rpb25FdmVudFR5cGUuUkVNT1ZFLFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9Db2xsZWN0aW9uLmpzXCIpLkNvbGxlY3Rpb25FdmVudH0gZXZlbnQgQ29sbGVjdGlvbkV2ZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgdmFyIG92ZXJsYXkgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL092ZXJsYXkuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGV2ZW50LmVsZW1lbnQ7XG4gICAgICB2YXIgaWQgPSBvdmVybGF5LmdldElkKCk7XG5cbiAgICAgIGlmIChpZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLm92ZXJsYXlJZEluZGV4X1tpZC50b1N0cmluZygpXTtcbiAgICAgIH1cblxuICAgICAgZXZlbnQuZWxlbWVudC5zZXRNYXAobnVsbCk7XG4gICAgfS5iaW5kKF90aGlzKSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3JlbmRlcmVyL01hcC5qc1wiKS5kZWZhdWx0fSBUaGUgbWFwIHJlbmRlcmVyXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5jcmVhdGVSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VzZSBhIG1hcCB0eXBlIHRoYXQgaGFzIGEgY3JlYXRlUmVuZGVyZXIgbWV0aG9kJyk7XG4gIH07XG4gIC8qKlxuICAgKiBBZGQgdGhlIGdpdmVuIGNvbnRyb2wgdG8gdGhlIG1hcC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbnRyb2wvQ29udHJvbC5qc1wiKS5kZWZhdWx0fSBjb250cm9sIENvbnRyb2wuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmFkZENvbnRyb2wgPSBmdW5jdGlvbiAoY29udHJvbCkge1xuICAgIHRoaXMuZ2V0Q29udHJvbHMoKS5wdXNoKGNvbnRyb2wpO1xuICB9O1xuICAvKipcbiAgICogQWRkIHRoZSBnaXZlbiBpbnRlcmFjdGlvbiB0byB0aGUgbWFwLiBJZiB5b3Ugd2FudCB0byBhZGQgYW4gaW50ZXJhY3Rpb25cbiAgICogYXQgYW5vdGhlciBwb2ludCBvZiB0aGUgY29sbGVjdGlvbiB1c2UgYGdldEludGVyYWN0aW9uKClgIGFuZCB0aGUgbWV0aG9kc1xuICAgKiBhdmFpbGFibGUgb24ge0BsaW5rIG1vZHVsZTpvbC9Db2xsZWN0aW9ufkNvbGxlY3Rpb259LiBUaGlzIGNhbiBiZSB1c2VkIHRvXG4gICAqIHN0b3AgdGhlIGV2ZW50IHByb3BhZ2F0aW9uIGZyb20gdGhlIGhhbmRsZUV2ZW50IGZ1bmN0aW9uLiBUaGUgaW50ZXJhY3Rpb25zXG4gICAqIGdldCB0byBoYW5kbGUgdGhlIGV2ZW50cyBpbiB0aGUgcmV2ZXJzZSBvcmRlciBvZiB0aGlzIGNvbGxlY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9pbnRlcmFjdGlvbi9JbnRlcmFjdGlvbi5qc1wiKS5kZWZhdWx0fSBpbnRlcmFjdGlvbiBJbnRlcmFjdGlvbiB0byBhZGQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmFkZEludGVyYWN0aW9uID0gZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XG4gICAgdGhpcy5nZXRJbnRlcmFjdGlvbnMoKS5wdXNoKGludGVyYWN0aW9uKTtcbiAgfTtcbiAgLyoqXG4gICAqIEFkZHMgdGhlIGdpdmVuIGxheWVyIHRvIHRoZSB0b3Agb2YgdGhpcyBtYXAuIElmIHlvdSB3YW50IHRvIGFkZCBhIGxheWVyXG4gICAqIGVsc2V3aGVyZSBpbiB0aGUgc3RhY2ssIHVzZSBgZ2V0TGF5ZXJzKClgIGFuZCB0aGUgbWV0aG9kcyBhdmFpbGFibGUgb25cbiAgICoge0BsaW5rIG1vZHVsZTpvbC9Db2xsZWN0aW9ufkNvbGxlY3Rpb259LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbGF5ZXIvQmFzZS5qc1wiKS5kZWZhdWx0fSBsYXllciBMYXllci5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuYWRkTGF5ZXIgPSBmdW5jdGlvbiAobGF5ZXIpIHtcbiAgICB2YXIgbGF5ZXJzID0gdGhpcy5nZXRMYXllckdyb3VwKCkuZ2V0TGF5ZXJzKCk7XG4gICAgbGF5ZXJzLnB1c2gobGF5ZXIpO1xuICB9O1xuICAvKipcbiAgICogQWRkIHRoZSBnaXZlbiBvdmVybGF5IHRvIHRoZSBtYXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHR9IG92ZXJsYXkgT3ZlcmxheS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuYWRkT3ZlcmxheSA9IGZ1bmN0aW9uIChvdmVybGF5KSB7XG4gICAgdGhpcy5nZXRPdmVybGF5cygpLnB1c2gob3ZlcmxheSk7XG4gIH07XG4gIC8qKlxuICAgKiBUaGlzIGRlYWxzIHdpdGggbWFwJ3Mgb3ZlcmxheSBjb2xsZWN0aW9uIGNoYW5nZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHR9IG92ZXJsYXkgT3ZlcmxheS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmFkZE92ZXJsYXlJbnRlcm5hbF8gPSBmdW5jdGlvbiAob3ZlcmxheSkge1xuICAgIHZhciBpZCA9IG92ZXJsYXkuZ2V0SWQoKTtcblxuICAgIGlmIChpZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLm92ZXJsYXlJZEluZGV4X1tpZC50b1N0cmluZygpXSA9IG92ZXJsYXk7XG4gICAgfVxuXG4gICAgb3ZlcmxheS5zZXRNYXAodGhpcyk7XG4gIH07XG4gIC8qKlxuICAgKlxuICAgKiBDbGVhbiB1cC5cbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNldFRhcmdldChudWxsKTtcblxuICAgIF9zdXBlci5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsLmNhbGwodGhpcyk7XG4gIH07XG4gIC8qKlxuICAgKiBEZXRlY3QgZmVhdHVyZXMgdGhhdCBpbnRlcnNlY3QgYSBwaXhlbCBvbiB0aGUgdmlld3BvcnQsIGFuZCBleGVjdXRlIGFcbiAgICogY2FsbGJhY2sgd2l0aCBlYWNoIGludGVyc2VjdGluZyBmZWF0dXJlLiBMYXllcnMgaW5jbHVkZWQgaW4gdGhlIGRldGVjdGlvbiBjYW5cbiAgICogYmUgY29uZmlndXJlZCB0aHJvdWdoIHRoZSBgbGF5ZXJGaWx0ZXJgIG9wdGlvbiBpbiBgb3B0X29wdGlvbnNgLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZSwgaW1wb3J0KFwiLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0LCBpbXBvcnQoXCIuL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdCk6IFR9IGNhbGxiYWNrIEZlYXR1cmUgY2FsbGJhY2suIFRoZSBjYWxsYmFjayB3aWxsIGJlXG4gICAqICAgICBjYWxsZWQgd2l0aCB0d28gYXJndW1lbnRzLiBUaGUgZmlyc3QgYXJndW1lbnQgaXMgb25lXG4gICAqICAgICB7QGxpbmsgbW9kdWxlOm9sL0ZlYXR1cmUgZmVhdHVyZX0gb3JcbiAgICogICAgIHtAbGluayBtb2R1bGU6b2wvcmVuZGVyL0ZlYXR1cmUgcmVuZGVyIGZlYXR1cmV9IGF0IHRoZSBwaXhlbCwgdGhlIHNlY29uZCBpc1xuICAgKiAgICAgdGhlIHtAbGluayBtb2R1bGU6b2wvbGF5ZXIvTGF5ZXIgbGF5ZXJ9IG9mIHRoZSBmZWF0dXJlIGFuZCB3aWxsIGJlIG51bGwgZm9yXG4gICAqICAgICB1bm1hbmFnZWQgbGF5ZXJzLiBUbyBzdG9wIGRldGVjdGlvbiwgY2FsbGJhY2sgZnVuY3Rpb25zIGNhbiByZXR1cm4gYVxuICAgKiAgICAgdHJ1dGh5IHZhbHVlLlxuICAgKiBAcGFyYW0ge0F0UGl4ZWxPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9uYWwgb3B0aW9ucy5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IENhbGxiYWNrIHJlc3VsdCwgaS5lLiB0aGUgcmV0dXJuIHZhbHVlIG9mIGxhc3RcbiAgICogY2FsbGJhY2sgZXhlY3V0aW9uLCBvciB0aGUgZmlyc3QgdHJ1dGh5IGNhbGxiYWNrIHJldHVybiB2YWx1ZS5cbiAgICogQHRlbXBsYXRlIFMsVFxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5mb3JFYWNoRmVhdHVyZUF0UGl4ZWwgPSBmdW5jdGlvbiAocGl4ZWwsIGNhbGxiYWNrLCBvcHRfb3B0aW9ucykge1xuICAgIGlmICghdGhpcy5mcmFtZVN0YXRlXykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBjb29yZGluYXRlID0gdGhpcy5nZXRDb29yZGluYXRlRnJvbVBpeGVsSW50ZXJuYWwocGl4ZWwpO1xuICAgIG9wdF9vcHRpb25zID0gb3B0X29wdGlvbnMgIT09IHVuZGVmaW5lZCA/IG9wdF9vcHRpb25zIDoge307XG4gICAgdmFyIGhpdFRvbGVyYW5jZSA9IG9wdF9vcHRpb25zLmhpdFRvbGVyYW5jZSAhPT0gdW5kZWZpbmVkID8gb3B0X29wdGlvbnMuaGl0VG9sZXJhbmNlIDogMDtcbiAgICB2YXIgbGF5ZXJGaWx0ZXIgPSBvcHRfb3B0aW9ucy5sYXllckZpbHRlciAhPT0gdW5kZWZpbmVkID8gb3B0X29wdGlvbnMubGF5ZXJGaWx0ZXIgOiBUUlVFO1xuICAgIHZhciBjaGVja1dyYXBwZWQgPSBvcHRfb3B0aW9ucy5jaGVja1dyYXBwZWQgIT09IGZhbHNlO1xuICAgIHJldHVybiB0aGlzLnJlbmRlcmVyXy5mb3JFYWNoRmVhdHVyZUF0Q29vcmRpbmF0ZShjb29yZGluYXRlLCB0aGlzLmZyYW1lU3RhdGVfLCBoaXRUb2xlcmFuY2UsIGNoZWNrV3JhcHBlZCwgY2FsbGJhY2ssIG51bGwsIGxheWVyRmlsdGVyLCBudWxsKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhbGwgZmVhdHVyZXMgdGhhdCBpbnRlcnNlY3QgYSBwaXhlbCBvbiB0aGUgdmlld3BvcnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwuXG4gICAqIEBwYXJhbSB7QXRQaXhlbE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25hbCBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2U+fSBUaGUgZGV0ZWN0ZWQgZmVhdHVyZXMgb3JcbiAgICogYW4gZW1wdHkgYXJyYXkgaWYgbm9uZSB3ZXJlIGZvdW5kLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRGZWF0dXJlc0F0UGl4ZWwgPSBmdW5jdGlvbiAocGl4ZWwsIG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIGZlYXR1cmVzID0gW107XG4gICAgdGhpcy5mb3JFYWNoRmVhdHVyZUF0UGl4ZWwocGl4ZWwsIGZ1bmN0aW9uIChmZWF0dXJlKSB7XG4gICAgICBmZWF0dXJlcy5wdXNoKGZlYXR1cmUpO1xuICAgIH0sIG9wdF9vcHRpb25zKTtcbiAgICByZXR1cm4gZmVhdHVyZXM7XG4gIH07XG4gIC8qKlxuICAgKiBEZXRlY3QgbGF5ZXJzIHRoYXQgaGF2ZSBhIGNvbG9yIHZhbHVlIGF0IGEgcGl4ZWwgb24gdGhlIHZpZXdwb3J0LCBhbmRcbiAgICogZXhlY3V0ZSBhIGNhbGxiYWNrIHdpdGggZWFjaCBtYXRjaGluZyBsYXllci4gTGF5ZXJzIGluY2x1ZGVkIGluIHRoZVxuICAgKiBkZXRlY3Rpb24gY2FuIGJlIGNvbmZpZ3VyZWQgdGhyb3VnaCBgb3B0X2xheWVyRmlsdGVyYC5cbiAgICpcbiAgICogTm90ZTogdGhpcyBtYXkgZ2l2ZSBmYWxzZSBwb3NpdGl2ZXMgdW5sZXNzIHRoZSBtYXAgbGF5ZXJzIGhhdmUgaGFkIGRpZmZlcmVudCBgY2xhc3NOYW1lYFxuICAgKiBwcm9wZXJ0aWVzIGFzc2lnbmVkIHRvIHRoZW0uXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczogUywgaW1wb3J0KFwiLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0LCAoVWludDhDbGFtcGVkQXJyYXl8VWludDhBcnJheSkpOiBUfSBjYWxsYmFja1xuICAgKiAgICAgTGF5ZXIgY2FsbGJhY2suIFRoaXMgY2FsbGJhY2sgd2lsbCByZWNlaXZlIHR3byBhcmd1bWVudHM6IGZpcnN0IGlzIHRoZVxuICAgKiAgICAge0BsaW5rIG1vZHVsZTpvbC9sYXllci9MYXllciBsYXllcn0sIHNlY29uZCBhcmd1bWVudCBpcyBhbiBhcnJheSByZXByZXNlbnRpbmdcbiAgICogICAgIFtSLCBHLCBCLCBBXSBwaXhlbCB2YWx1ZXMgKDAgLSAyNTUpIGFuZCB3aWxsIGJlIGBudWxsYCBmb3IgbGF5ZXIgdHlwZXNcbiAgICogICAgIHRoYXQgZG8gbm90IGN1cnJlbnRseSBzdXBwb3J0IHRoaXMgYXJndW1lbnQuIFRvIHN0b3AgZGV0ZWN0aW9uLCBjYWxsYmFja1xuICAgKiAgICAgZnVuY3Rpb25zIGNhbiByZXR1cm4gYSB0cnV0aHkgdmFsdWUuXG4gICAqIEBwYXJhbSB7QXRQaXhlbE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQsIGkuZS4gdGhlIHJldHVybiB2YWx1ZSBvZiBsYXN0XG4gICAqIGNhbGxiYWNrIGV4ZWN1dGlvbiwgb3IgdGhlIGZpcnN0IHRydXRoeSBjYWxsYmFjayByZXR1cm4gdmFsdWUuXG4gICAqIEB0ZW1wbGF0ZSBTLFRcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZm9yRWFjaExheWVyQXRQaXhlbCA9IGZ1bmN0aW9uIChwaXhlbCwgY2FsbGJhY2ssIG9wdF9vcHRpb25zKSB7XG4gICAgaWYgKCF0aGlzLmZyYW1lU3RhdGVfKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyB8fCB7fTtcbiAgICB2YXIgaGl0VG9sZXJhbmNlID0gb3B0aW9ucy5oaXRUb2xlcmFuY2UgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuaGl0VG9sZXJhbmNlIDogMDtcbiAgICB2YXIgbGF5ZXJGaWx0ZXIgPSBvcHRpb25zLmxheWVyRmlsdGVyIHx8IFRSVUU7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXJfLmZvckVhY2hMYXllckF0UGl4ZWwocGl4ZWwsIHRoaXMuZnJhbWVTdGF0ZV8sIGhpdFRvbGVyYW5jZSwgY2FsbGJhY2ssIGxheWVyRmlsdGVyKTtcbiAgfTtcbiAgLyoqXG4gICAqIERldGVjdCBpZiBmZWF0dXJlcyBpbnRlcnNlY3QgYSBwaXhlbCBvbiB0aGUgdmlld3BvcnQuIExheWVycyBpbmNsdWRlZCBpbiB0aGVcbiAgICogZGV0ZWN0aW9uIGNhbiBiZSBjb25maWd1cmVkIHRocm91Z2ggYG9wdF9sYXllckZpbHRlcmAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwuXG4gICAqIEBwYXJhbSB7QXRQaXhlbE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25hbCBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJcyB0aGVyZSBhIGZlYXR1cmUgYXQgdGhlIGdpdmVuIHBpeGVsP1xuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5oYXNGZWF0dXJlQXRQaXhlbCA9IGZ1bmN0aW9uIChwaXhlbCwgb3B0X29wdGlvbnMpIHtcbiAgICBpZiAoIXRoaXMuZnJhbWVTdGF0ZV8pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbEludGVybmFsKHBpeGVsKTtcbiAgICBvcHRfb3B0aW9ucyA9IG9wdF9vcHRpb25zICE9PSB1bmRlZmluZWQgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIHZhciBsYXllckZpbHRlciA9IG9wdF9vcHRpb25zLmxheWVyRmlsdGVyICE9PSB1bmRlZmluZWQgPyBvcHRfb3B0aW9ucy5sYXllckZpbHRlciA6IFRSVUU7XG4gICAgdmFyIGhpdFRvbGVyYW5jZSA9IG9wdF9vcHRpb25zLmhpdFRvbGVyYW5jZSAhPT0gdW5kZWZpbmVkID8gb3B0X29wdGlvbnMuaGl0VG9sZXJhbmNlIDogMDtcbiAgICB2YXIgY2hlY2tXcmFwcGVkID0gb3B0X29wdGlvbnMuY2hlY2tXcmFwcGVkICE9PSBmYWxzZTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlcl8uaGFzRmVhdHVyZUF0Q29vcmRpbmF0ZShjb29yZGluYXRlLCB0aGlzLmZyYW1lU3RhdGVfLCBoaXRUb2xlcmFuY2UsIGNoZWNrV3JhcHBlZCwgbGF5ZXJGaWx0ZXIsIG51bGwpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29vcmRpbmF0ZSBpbiB1c2VyIHByb2plY3Rpb24gZm9yIGEgYnJvd3NlciBldmVudC5cbiAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBldmVudCBFdmVudC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IENvb3JkaW5hdGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldEV2ZW50Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiB0aGlzLmdldENvb3JkaW5hdGVGcm9tUGl4ZWwodGhpcy5nZXRFdmVudFBpeGVsKGV2ZW50KSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb29yZGluYXRlIGluIHZpZXcgcHJvamVjdGlvbiBmb3IgYSBicm93c2VyIGV2ZW50LlxuICAgKiBAcGFyYW0ge01vdXNlRXZlbnR9IGV2ZW50IEV2ZW50LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQ29vcmRpbmF0ZS5cbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldEV2ZW50Q29vcmRpbmF0ZUludGVybmFsID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbEludGVybmFsKHRoaXMuZ2V0RXZlbnRQaXhlbChldmVudCkpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyB0aGUgbWFwIHBpeGVsIHBvc2l0aW9uIGZvciBhIGJyb3dzZXIgZXZlbnQgcmVsYXRpdmUgdG8gdGhlIHZpZXdwb3J0LlxuICAgKiBAcGFyYW0ge1VJRXZlbnR9IGV2ZW50IEV2ZW50LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3BpeGVsLmpzXCIpLlBpeGVsfSBQaXhlbC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0RXZlbnRQaXhlbCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHZhciB2aWV3cG9ydFBvc2l0aW9uID0gdGhpcy52aWV3cG9ydF8uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdmFyIGV2ZW50UG9zaXRpb24gPSAvL0ZJWE1FIEFyZSB3ZSByZWFsbHkgY2FsbGluZyB0aGlzIHdpdGggYSBUb3VjaEV2ZW50IGFueXdoZXJlP1xuICAgICdjaGFuZ2VkVG91Y2hlcycgaW4gZXZlbnQgP1xuICAgIC8qKiBAdHlwZSB7VG91Y2hFdmVudH0gKi9cbiAgICBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSA6XG4gICAgLyoqIEB0eXBlIHtNb3VzZUV2ZW50fSAqL1xuICAgIGV2ZW50O1xuICAgIHJldHVybiBbZXZlbnRQb3NpdGlvbi5jbGllbnRYIC0gdmlld3BvcnRQb3NpdGlvbi5sZWZ0LCBldmVudFBvc2l0aW9uLmNsaWVudFkgLSB2aWV3cG9ydFBvc2l0aW9uLnRvcF07XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHRhcmdldCBpbiB3aGljaCB0aGlzIG1hcCBpcyByZW5kZXJlZC5cbiAgICogTm90ZSB0aGF0IHRoaXMgcmV0dXJucyB3aGF0IGlzIGVudGVyZWQgYXMgYW4gb3B0aW9uIG9yIGluIHNldFRhcmdldDpcbiAgICogaWYgdGhhdCB3YXMgYW4gZWxlbWVudCwgaXQgcmV0dXJucyBhbiBlbGVtZW50OyBpZiBhIHN0cmluZywgaXQgcmV0dXJucyB0aGF0LlxuICAgKiBAcmV0dXJuIHtIVE1MRWxlbWVudHxzdHJpbmd8dW5kZWZpbmVkfSBUaGUgRWxlbWVudCBvciBpZCBvZiB0aGUgRWxlbWVudCB0aGF0IHRoZVxuICAgKiAgICAgbWFwIGlzIHJlbmRlcmVkIGluLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRUYXJnZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7SFRNTEVsZW1lbnR8c3RyaW5nfHVuZGVmaW5lZH0gKi9cbiAgICAgIHRoaXMuZ2V0KE1hcFByb3BlcnR5LlRBUkdFVClcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBET00gZWxlbWVudCBpbnRvIHdoaWNoIHRoaXMgbWFwIGlzIHJlbmRlcmVkLiBJbiBjb250cmFzdCB0b1xuICAgKiBgZ2V0VGFyZ2V0YCB0aGlzIG1ldGhvZCBhbHdheXMgcmV0dXJuIGFuIGBFbGVtZW50YCwgb3IgYG51bGxgIGlmIHRoZVxuICAgKiBtYXAgaGFzIG5vIHRhcmdldC5cbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9IFRoZSBlbGVtZW50IHRoYXQgdGhlIG1hcCBpcyByZW5kZXJlZCBpbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0VGFyZ2V0RWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdGFyZ2V0ID0gdGhpcy5nZXRUYXJnZXQoKTtcblxuICAgIGlmICh0YXJnZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB0YXJnZXQgPT09ICdzdHJpbmcnID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0KSA6IHRhcmdldDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBjb29yZGluYXRlIGZvciBhIGdpdmVuIHBpeGVsLiAgVGhpcyByZXR1cm5zIGEgY29vcmRpbmF0ZSBpbiB0aGVcbiAgICogdXNlciBwcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsIHBvc2l0aW9uIGluIHRoZSBtYXAgdmlld3BvcnQuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBUaGUgY29vcmRpbmF0ZSBmb3IgdGhlIHBpeGVsIHBvc2l0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRDb29yZGluYXRlRnJvbVBpeGVsID0gZnVuY3Rpb24gKHBpeGVsKSB7XG4gICAgcmV0dXJuIHRvVXNlckNvb3JkaW5hdGUodGhpcy5nZXRDb29yZGluYXRlRnJvbVBpeGVsSW50ZXJuYWwocGl4ZWwpLCB0aGlzLmdldFZpZXcoKS5nZXRQcm9qZWN0aW9uKCkpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBjb29yZGluYXRlIGZvciBhIGdpdmVuIHBpeGVsLiAgVGhpcyByZXR1cm5zIGEgY29vcmRpbmF0ZSBpbiB0aGVcbiAgICogbWFwIHZpZXcgcHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3BpeGVsLmpzXCIpLlBpeGVsfSBwaXhlbCBQaXhlbCBwb3NpdGlvbiBpbiB0aGUgbWFwIHZpZXdwb3J0LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gVGhlIGNvb3JkaW5hdGUgZm9yIHRoZSBwaXhlbCBwb3NpdGlvbi5cbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldENvb3JkaW5hdGVGcm9tUGl4ZWxJbnRlcm5hbCA9IGZ1bmN0aW9uIChwaXhlbCkge1xuICAgIHZhciBmcmFtZVN0YXRlID0gdGhpcy5mcmFtZVN0YXRlXztcblxuICAgIGlmICghZnJhbWVTdGF0ZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBhcHBseVRyYW5zZm9ybShmcmFtZVN0YXRlLnBpeGVsVG9Db29yZGluYXRlVHJhbnNmb3JtLCBwaXhlbC5zbGljZSgpKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1hcCBjb250cm9scy4gTW9kaWZ5aW5nIHRoaXMgY29sbGVjdGlvbiBjaGFuZ2VzIHRoZSBjb250cm9sc1xuICAgKiBhc3NvY2lhdGVkIHdpdGggdGhlIG1hcC5cbiAgICogQHJldHVybiB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuL2NvbnRyb2wvQ29udHJvbC5qc1wiKS5kZWZhdWx0Pn0gQ29udHJvbHMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldENvbnRyb2xzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRyb2xzO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtYXAgb3ZlcmxheXMuIE1vZGlmeWluZyB0aGlzIGNvbGxlY3Rpb24gY2hhbmdlcyB0aGUgb3ZlcmxheXNcbiAgICogYXNzb2NpYXRlZCB3aXRoIHRoZSBtYXAuXG4gICAqIEByZXR1cm4ge0NvbGxlY3Rpb248aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHQ+fSBPdmVybGF5cy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0T3ZlcmxheXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMub3ZlcmxheXNfO1xuICB9O1xuICAvKipcbiAgICogR2V0IGFuIG92ZXJsYXkgYnkgaXRzIGlkZW50aWZpZXIgKHRoZSB2YWx1ZSByZXR1cm5lZCBieSBvdmVybGF5LmdldElkKCkpLlxuICAgKiBOb3RlIHRoYXQgdGhlIGluZGV4IHRyZWF0cyBzdHJpbmcgYW5kIG51bWVyaWMgaWRlbnRpZmllcnMgYXMgdGhlIHNhbWUuIFNvXG4gICAqIGBtYXAuZ2V0T3ZlcmxheUJ5SWQoMilgIHdpbGwgcmV0dXJuIGFuIG92ZXJsYXkgd2l0aCBpZCBgJzInYCBvciBgMmAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgT3ZlcmxheSBpZGVudGlmaWVyLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL092ZXJsYXkuanNcIikuZGVmYXVsdH0gT3ZlcmxheS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0T3ZlcmxheUJ5SWQgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICB2YXIgb3ZlcmxheSA9IHRoaXMub3ZlcmxheUlkSW5kZXhfW2lkLnRvU3RyaW5nKCldO1xuICAgIHJldHVybiBvdmVybGF5ICE9PSB1bmRlZmluZWQgPyBvdmVybGF5IDogbnVsbDtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbWFwIGludGVyYWN0aW9ucy4gTW9kaWZ5aW5nIHRoaXMgY29sbGVjdGlvbiBjaGFuZ2VzIHRoZSBpbnRlcmFjdGlvbnNcbiAgICogYXNzb2NpYXRlZCB3aXRoIHRoZSBtYXAuXG4gICAqXG4gICAqIEludGVyYWN0aW9ucyBhcmUgdXNlZCBmb3IgZS5nLiBwYW4sIHpvb20gYW5kIHJvdGF0ZS5cbiAgICogQHJldHVybiB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuL2ludGVyYWN0aW9uL0ludGVyYWN0aW9uLmpzXCIpLmRlZmF1bHQ+fSBJbnRlcmFjdGlvbnMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldEludGVyYWN0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnRlcmFjdGlvbnM7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGxheWVyZ3JvdXAgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbWFwLlxuICAgKiBAcmV0dXJuIHtMYXllckdyb3VwfSBBIGxheWVyIGdyb3VwIGNvbnRhaW5pbmcgdGhlIGxheWVycyBpbiB0aGlzIG1hcC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0TGF5ZXJHcm91cCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtMYXllckdyb3VwfSAqL1xuICAgICAgdGhpcy5nZXQoTWFwUHJvcGVydHkuTEFZRVJHUk9VUClcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBjb2xsZWN0aW9uIG9mIGxheWVycyBhc3NvY2lhdGVkIHdpdGggdGhpcyBtYXAuXG4gICAqIEByZXR1cm4geyFDb2xsZWN0aW9uPGltcG9ydChcIi4vbGF5ZXIvQmFzZS5qc1wiKS5kZWZhdWx0Pn0gTGF5ZXJzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRMYXllcnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGxheWVycyA9IHRoaXMuZ2V0TGF5ZXJHcm91cCgpLmdldExheWVycygpO1xuICAgIHJldHVybiBsYXllcnM7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBMYXllcnMgaGF2ZSBzb3VyY2VzIHRoYXQgYXJlIHN0aWxsIGxvYWRpbmcuXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRMb2FkaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBsYXllclN0YXRlc0FycmF5ID0gdGhpcy5nZXRMYXllckdyb3VwKCkuZ2V0TGF5ZXJTdGF0ZXNBcnJheSgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbGF5ZXJTdGF0ZXNBcnJheS5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgbGF5ZXIgPSBsYXllclN0YXRlc0FycmF5W2ldLmxheWVyO1xuICAgICAgdmFyIHNvdXJjZSA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGxheWVyLmdldFNvdXJjZSgpO1xuXG4gICAgICBpZiAoc291cmNlICYmIHNvdXJjZS5sb2FkaW5nKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgcGl4ZWwgZm9yIGEgY29vcmRpbmF0ZS4gIFRoaXMgdGFrZXMgYSBjb29yZGluYXRlIGluIHRoZSB1c2VyXG4gICAqIHByb2plY3Rpb24gYW5kIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcGl4ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQSBtYXAgY29vcmRpbmF0ZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH0gQSBwaXhlbCBwb3NpdGlvbiBpbiB0aGUgbWFwIHZpZXdwb3J0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRQaXhlbEZyb21Db29yZGluYXRlID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUpIHtcbiAgICB2YXIgdmlld0Nvb3JkaW5hdGUgPSBmcm9tVXNlckNvb3JkaW5hdGUoY29vcmRpbmF0ZSwgdGhpcy5nZXRWaWV3KCkuZ2V0UHJvamVjdGlvbigpKTtcbiAgICByZXR1cm4gdGhpcy5nZXRQaXhlbEZyb21Db29yZGluYXRlSW50ZXJuYWwodmlld0Nvb3JkaW5hdGUpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBwaXhlbCBmb3IgYSBjb29yZGluYXRlLiAgVGhpcyB0YWtlcyBhIGNvb3JkaW5hdGUgaW4gdGhlIG1hcCB2aWV3XG4gICAqIHByb2plY3Rpb24gYW5kIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcGl4ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQSBtYXAgY29vcmRpbmF0ZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH0gQSBwaXhlbCBwb3NpdGlvbiBpbiB0aGUgbWFwIHZpZXdwb3J0LlxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0UGl4ZWxGcm9tQ29vcmRpbmF0ZUludGVybmFsID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUpIHtcbiAgICB2YXIgZnJhbWVTdGF0ZSA9IHRoaXMuZnJhbWVTdGF0ZV87XG5cbiAgICBpZiAoIWZyYW1lU3RhdGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYXBwbHlUcmFuc2Zvcm0oZnJhbWVTdGF0ZS5jb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybSwgY29vcmRpbmF0ZS5zbGljZSgwLCAyKSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtYXAgcmVuZGVyZXIuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vcmVuZGVyZXIvTWFwLmpzXCIpLmRlZmF1bHR9IFJlbmRlcmVyXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlcl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHNpemUgb2YgdGhpcyBtYXAuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfHVuZGVmaW5lZH0gVGhlIHNpemUgaW4gcGl4ZWxzIG9mIHRoZSBtYXAgaW4gdGhlIERPTS5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZXx1bmRlZmluZWR9ICovXG4gICAgICB0aGlzLmdldChNYXBQcm9wZXJ0eS5TSVpFKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHZpZXcgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbWFwLiBBIHZpZXcgbWFuYWdlcyBwcm9wZXJ0aWVzIHN1Y2ggYXNcbiAgICogY2VudGVyIGFuZCByZXNvbHV0aW9uLlxuICAgKiBAcmV0dXJuIHtWaWV3fSBUaGUgdmlldyB0aGF0IGNvbnRyb2xzIHRoaXMgbWFwLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRWaWV3ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge1ZpZXd9ICovXG4gICAgICB0aGlzLmdldChNYXBQcm9wZXJ0eS5WSUVXKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGVsZW1lbnQgdGhhdCBzZXJ2ZXMgYXMgdGhlIG1hcCB2aWV3cG9ydC5cbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9IFZpZXdwb3J0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRWaWV3cG9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy52aWV3cG9ydF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGVsZW1lbnQgdGhhdCBzZXJ2ZXMgYXMgdGhlIGNvbnRhaW5lciBmb3Igb3ZlcmxheXMuICBFbGVtZW50cyBhZGRlZCB0b1xuICAgKiB0aGlzIGNvbnRhaW5lciB3aWxsIGxldCBtb3VzZWRvd24gYW5kIHRvdWNoc3RhcnQgZXZlbnRzIHRocm91Z2ggdG8gdGhlIG1hcCxcbiAgICogc28gY2xpY2tzIGFuZCBnZXN0dXJlcyBvbiBhbiBvdmVybGF5IHdpbGwgdHJpZ2dlciB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH5NYXBCcm93c2VyRXZlbnR9XG4gICAqIGV2ZW50cy5cbiAgICogQHJldHVybiB7IUhUTUxFbGVtZW50fSBUaGUgbWFwJ3Mgb3ZlcmxheSBjb250YWluZXIuXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRPdmVybGF5Q29udGFpbmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm92ZXJsYXlDb250YWluZXJfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBlbGVtZW50IHRoYXQgc2VydmVzIGFzIGEgY29udGFpbmVyIGZvciBvdmVybGF5cyB0aGF0IGRvbid0IGFsbG93XG4gICAqIGV2ZW50IHByb3BhZ2F0aW9uLiBFbGVtZW50cyBhZGRlZCB0byB0aGlzIGNvbnRhaW5lciB3b24ndCBsZXQgbW91c2Vkb3duIGFuZFxuICAgKiB0b3VjaHN0YXJ0IGV2ZW50cyB0aHJvdWdoIHRvIHRoZSBtYXAsIHNvIGNsaWNrcyBhbmQgZ2VzdHVyZXMgb24gYW4gb3ZlcmxheVxuICAgKiBkb24ndCB0cmlnZ2VyIGFueSB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH5NYXBCcm93c2VyRXZlbnR9LlxuICAgKiBAcmV0dXJuIHshSFRNTEVsZW1lbnR9IFRoZSBtYXAncyBvdmVybGF5IGNvbnRhaW5lciB0aGF0IHN0b3BzIGV2ZW50cy5cbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldE92ZXJsYXlDb250YWluZXJTdG9wRXZlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMub3ZlcmxheUNvbnRhaW5lclN0b3BFdmVudF87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHshRG9jdW1lbnR9IFRoZSBkb2N1bWVudCB3aGVyZSB0aGUgbWFwIGlzIGRpc3BsYXllZC5cbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldE93bmVyRG9jdW1lbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VGFyZ2V0RWxlbWVudCgpID8gdGhpcy5nZXRUYXJnZXRFbGVtZW50KCkub3duZXJEb2N1bWVudCA6IGRvY3VtZW50O1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1RpbGUuanNcIikuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGlsZVNvdXJjZUtleSBUaWxlIHNvdXJjZSBrZXkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHRpbGVDZW50ZXIgVGlsZSBjZW50ZXIuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0aWxlUmVzb2x1dGlvbiBUaWxlIHJlc29sdXRpb24uXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGlsZSBwcmlvcml0eS5cbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldFRpbGVQcmlvcml0eSA9IGZ1bmN0aW9uICh0aWxlLCB0aWxlU291cmNlS2V5LCB0aWxlQ2VudGVyLCB0aWxlUmVzb2x1dGlvbikge1xuICAgIHJldHVybiBnZXRUaWxlUHJpb3JpdHkodGhpcy5mcmFtZVN0YXRlXywgdGlsZSwgdGlsZVNvdXJjZUtleSwgdGlsZUNlbnRlciwgdGlsZVJlc29sdXRpb24pO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtVSUV2ZW50fSBicm93c2VyRXZlbnQgQnJvd3NlciBldmVudC5cbiAgICogQHBhcmFtIHtzdHJpbmc9fSBvcHRfdHlwZSBUeXBlLlxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuaGFuZGxlQnJvd3NlckV2ZW50ID0gZnVuY3Rpb24gKGJyb3dzZXJFdmVudCwgb3B0X3R5cGUpIHtcbiAgICB2YXIgdHlwZSA9IG9wdF90eXBlIHx8IGJyb3dzZXJFdmVudC50eXBlO1xuICAgIHZhciBtYXBCcm93c2VyRXZlbnQgPSBuZXcgTWFwQnJvd3NlckV2ZW50KHR5cGUsIHRoaXMsIGJyb3dzZXJFdmVudCk7XG4gICAgdGhpcy5oYW5kbGVNYXBCcm93c2VyRXZlbnQobWFwQnJvd3NlckV2ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7TWFwQnJvd3NlckV2ZW50fSBtYXBCcm93c2VyRXZlbnQgVGhlIGV2ZW50IHRvIGhhbmRsZS5cbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmhhbmRsZU1hcEJyb3dzZXJFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuZnJhbWVTdGF0ZV8pIHtcbiAgICAgIC8vIFdpdGggbm8gdmlldyBkZWZpbmVkLCB3ZSBjYW5ub3QgdHJhbnNsYXRlIHBpeGVscyBpbnRvIGdlb2dyYXBoaWNhbFxuICAgICAgLy8gY29vcmRpbmF0ZXMgc28gaW50ZXJhY3Rpb25zIGNhbm5vdCBiZSB1c2VkLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBvcmlnaW5hbEV2ZW50ID1cbiAgICAvKiogQHR5cGUge1BvaW50ZXJFdmVudH0gKi9cbiAgICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgICB2YXIgZXZlbnRUeXBlID0gb3JpZ2luYWxFdmVudC50eXBlO1xuXG4gICAgaWYgKGV2ZW50VHlwZSA9PT0gUG9pbnRlckV2ZW50VHlwZS5QT0lOVEVSRE9XTiB8fCBldmVudFR5cGUgPT09IEV2ZW50VHlwZS5XSEVFTCB8fCBldmVudFR5cGUgPT09IEV2ZW50VHlwZS5LRVlET1dOKSB7XG4gICAgICB2YXIgZG9jID0gdGhpcy5nZXRPd25lckRvY3VtZW50KCk7XG4gICAgICB2YXIgcm9vdE5vZGUgPSB0aGlzLnZpZXdwb3J0Xy5nZXRSb290Tm9kZSA/IHRoaXMudmlld3BvcnRfLmdldFJvb3ROb2RlKCkgOiBkb2M7XG4gICAgICB2YXIgdGFyZ2V0ID0gJ2hvc3QnIGluIHJvb3ROb2RlIC8vIFNoYWRvd1Jvb3RcbiAgICAgID9cbiAgICAgIC8qKiBAdHlwZSB7U2hhZG93Um9vdH0gKi9cbiAgICAgIHJvb3ROb2RlLmVsZW1lbnRGcm9tUG9pbnQob3JpZ2luYWxFdmVudC5jbGllbnRYLCBvcmlnaW5hbEV2ZW50LmNsaWVudFkpIDpcbiAgICAgIC8qKiBAdHlwZSB7Tm9kZX0gKi9cbiAgICAgIG9yaWdpbmFsRXZlbnQudGFyZ2V0O1xuXG4gICAgICBpZiAoIC8vIEFib3J0IGlmIHRoZSB0YXJnZXQgaXMgYSBjaGlsZCBvZiB0aGUgY29udGFpbmVyIGZvciBlbGVtZW50cyB3aG9zZSBldmVudHMgYXJlIG5vdCBtZWFudFxuICAgICAgLy8gdG8gYmUgaGFuZGxlZCBieSBtYXAgaW50ZXJhY3Rpb25zLlxuICAgICAgdGhpcy5vdmVybGF5Q29udGFpbmVyU3RvcEV2ZW50Xy5jb250YWlucyh0YXJnZXQpIHx8IC8vIEFib3J0IGlmIHRoZSBldmVudCB0YXJnZXQgaXMgYSBjaGlsZCBvZiB0aGUgY29udGFpbmVyIHRoYXQgaXMgbm8gbG9uZ2VyIGluIHRoZSBwYWdlLlxuICAgICAgLy8gSXQncyBwb3NzaWJsZSBmb3IgdGhlIHRhcmdldCB0byBubyBsb25nZXIgYmUgaW4gdGhlIHBhZ2UgaWYgaXQgaGFzIGJlZW4gcmVtb3ZlZCBpbiBhblxuICAgICAgLy8gZXZlbnQgbGlzdGVuZXIsIHRoaXMgbWlnaHQgaGFwcGVuIGluIGEgQ29udHJvbCB0aGF0IHJlY3JlYXRlcyBpdCdzIGNvbnRlbnQgYmFzZWQgb25cbiAgICAgIC8vIHVzZXIgaW50ZXJhY3Rpb24gZWl0aGVyIG1hbnVhbGx5IG9yIHZpYSBhIHJlbmRlciBpbiBzb21ldGhpbmcgbGlrZSBodHRwczovL3JlYWN0anMub3JnL1xuICAgICAgIShyb290Tm9kZSA9PT0gZG9jID8gZG9jLmRvY3VtZW50RWxlbWVudCA6IHJvb3ROb2RlKS5jb250YWlucyh0YXJnZXQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBtYXBCcm93c2VyRXZlbnQuZnJhbWVTdGF0ZSA9IHRoaXMuZnJhbWVTdGF0ZV87XG5cbiAgICBpZiAodGhpcy5kaXNwYXRjaEV2ZW50KG1hcEJyb3dzZXJFdmVudCkgIT09IGZhbHNlKSB7XG4gICAgICB2YXIgaW50ZXJhY3Rpb25zQXJyYXkgPSB0aGlzLmdldEludGVyYWN0aW9ucygpLmdldEFycmF5KCkuc2xpY2UoKTtcblxuICAgICAgZm9yICh2YXIgaSA9IGludGVyYWN0aW9uc0FycmF5Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHZhciBpbnRlcmFjdGlvbiA9IGludGVyYWN0aW9uc0FycmF5W2ldO1xuXG4gICAgICAgIGlmIChpbnRlcmFjdGlvbi5nZXRNYXAoKSAhPT0gdGhpcyB8fCAhaW50ZXJhY3Rpb24uZ2V0QWN0aXZlKCkgfHwgIXRoaXMuZ2V0VGFyZ2V0RWxlbWVudCgpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY29udCA9IGludGVyYWN0aW9uLmhhbmRsZUV2ZW50KG1hcEJyb3dzZXJFdmVudCk7XG5cbiAgICAgICAgaWYgKCFjb250IHx8IG1hcEJyb3dzZXJFdmVudC5wcm9wYWdhdGlvblN0b3BwZWQpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmhhbmRsZVBvc3RSZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGZyYW1lU3RhdGUgPSB0aGlzLmZyYW1lU3RhdGVfOyAvLyBNYW5hZ2UgdGhlIHRpbGUgcXVldWVcbiAgICAvLyBJbWFnZSBsb2FkcyBhcmUgZXhwZW5zaXZlIGFuZCBhIGxpbWl0ZWQgcmVzb3VyY2UsIHNvIHRyeSB0byB1c2UgdGhlbVxuICAgIC8vIGVmZmljaWVudGx5OlxuICAgIC8vICogV2hlbiB0aGUgdmlldyBpcyBzdGF0aWMgd2UgYWxsb3cgYSBsYXJnZSBudW1iZXIgb2YgcGFyYWxsZWwgdGlsZSBsb2Fkc1xuICAgIC8vICAgdG8gY29tcGxldGUgdGhlIGZyYW1lIGFzIHF1aWNrbHkgYXMgcG9zc2libGUuXG4gICAgLy8gKiBXaGVuIGFuaW1hdGluZyBvciBpbnRlcmFjdGluZywgaW1hZ2UgbG9hZHMgY2FuIGNhdXNlIGphbmtzLCBzbyB3ZSByZWR1Y2VcbiAgICAvLyAgIHRoZSBtYXhpbXVtIG51bWJlciBvZiBsb2FkcyBwZXIgZnJhbWUgYW5kIGxpbWl0IHRoZSBudW1iZXIgb2YgcGFyYWxsZWxcbiAgICAvLyAgIHRpbGUgbG9hZHMgdG8gcmVtYWluIHJlYWN0aXZlIHRvIHZpZXcgY2hhbmdlcyBhbmQgdG8gcmVkdWNlIHRoZSBjaGFuY2Ugb2ZcbiAgICAvLyAgIGxvYWRpbmcgdGlsZXMgdGhhdCB3aWxsIHF1aWNrbHkgZGlzYXBwZWFyIGZyb20gdmlldy5cblxuICAgIHZhciB0aWxlUXVldWUgPSB0aGlzLnRpbGVRdWV1ZV87XG5cbiAgICBpZiAoIXRpbGVRdWV1ZS5pc0VtcHR5KCkpIHtcbiAgICAgIHZhciBtYXhUb3RhbExvYWRpbmcgPSB0aGlzLm1heFRpbGVzTG9hZGluZ187XG4gICAgICB2YXIgbWF4TmV3TG9hZHMgPSBtYXhUb3RhbExvYWRpbmc7XG5cbiAgICAgIGlmIChmcmFtZVN0YXRlKSB7XG4gICAgICAgIHZhciBoaW50cyA9IGZyYW1lU3RhdGUudmlld0hpbnRzO1xuXG4gICAgICAgIGlmIChoaW50c1tWaWV3SGludC5BTklNQVRJTkddIHx8IGhpbnRzW1ZpZXdIaW50LklOVEVSQUNUSU5HXSkge1xuICAgICAgICAgIHZhciBsb3dPbkZyYW1lQnVkZ2V0ID0gIUlNQUdFX0RFQ09ERSAmJiBEYXRlLm5vdygpIC0gZnJhbWVTdGF0ZS50aW1lID4gODtcbiAgICAgICAgICBtYXhUb3RhbExvYWRpbmcgPSBsb3dPbkZyYW1lQnVkZ2V0ID8gMCA6IDg7XG4gICAgICAgICAgbWF4TmV3TG9hZHMgPSBsb3dPbkZyYW1lQnVkZ2V0ID8gMCA6IDI7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRpbGVRdWV1ZS5nZXRUaWxlc0xvYWRpbmcoKSA8IG1heFRvdGFsTG9hZGluZykge1xuICAgICAgICB0aWxlUXVldWUucmVwcmlvcml0aXplKCk7IC8vIEZJWE1FIG9ubHkgY2FsbCBpZiB2aWV3IGhhcyBjaGFuZ2VkXG5cbiAgICAgICAgdGlsZVF1ZXVlLmxvYWRNb3JlVGlsZXMobWF4VG90YWxMb2FkaW5nLCBtYXhOZXdMb2Fkcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGZyYW1lU3RhdGUgJiYgdGhpcy5oYXNMaXN0ZW5lcihSZW5kZXJFdmVudFR5cGUuUkVOREVSQ09NUExFVEUpICYmICFmcmFtZVN0YXRlLmFuaW1hdGUgJiYgIXRoaXMudGlsZVF1ZXVlXy5nZXRUaWxlc0xvYWRpbmcoKSAmJiAhdGhpcy5nZXRMb2FkaW5nKCkpIHtcbiAgICAgIHRoaXMucmVuZGVyZXJfLmRpc3BhdGNoUmVuZGVyRXZlbnQoUmVuZGVyRXZlbnRUeXBlLlJFTkRFUkNPTVBMRVRFLCBmcmFtZVN0YXRlKTtcbiAgICB9XG5cbiAgICB2YXIgcG9zdFJlbmRlckZ1bmN0aW9ucyA9IHRoaXMucG9zdFJlbmRlckZ1bmN0aW9uc187XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBwb3N0UmVuZGVyRnVuY3Rpb25zLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHBvc3RSZW5kZXJGdW5jdGlvbnNbaV0odGhpcywgZnJhbWVTdGF0ZSk7XG4gICAgfVxuXG4gICAgcG9zdFJlbmRlckZ1bmN0aW9ucy5sZW5ndGggPSAwO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmhhbmRsZVNpemVDaGFuZ2VkXyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5nZXRWaWV3KCkgJiYgIXRoaXMuZ2V0VmlldygpLmdldEFuaW1hdGluZygpKSB7XG4gICAgICB0aGlzLmdldFZpZXcoKS5yZXNvbHZlQ29uc3RyYWludHMoMCk7XG4gICAgfVxuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5oYW5kbGVUYXJnZXRDaGFuZ2VkXyA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyB0YXJnZXQgbWF5IGJlIHVuZGVmaW5lZCwgbnVsbCwgYSBzdHJpbmcgb3IgYW4gRWxlbWVudC5cbiAgICAvLyBJZiBpdCdzIGEgc3RyaW5nIHdlIGNvbnZlcnQgaXQgdG8gYW4gRWxlbWVudCBiZWZvcmUgcHJvY2VlZGluZy5cbiAgICAvLyBJZiBpdCdzIG5vdCBub3cgYW4gRWxlbWVudCB3ZSByZW1vdmUgdGhlIHZpZXdwb3J0IGZyb20gdGhlIERPTS5cbiAgICAvLyBJZiBpdCdzIGFuIEVsZW1lbnQgd2UgYXBwZW5kIHRoZSB2aWV3cG9ydCBlbGVtZW50IHRvIGl0LlxuICAgIHZhciB0YXJnZXRFbGVtZW50O1xuXG4gICAgaWYgKHRoaXMuZ2V0VGFyZ2V0KCkpIHtcbiAgICAgIHRhcmdldEVsZW1lbnQgPSB0aGlzLmdldFRhcmdldEVsZW1lbnQoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tYXBCcm93c2VyRXZlbnRIYW5kbGVyXykge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5rZXlIYW5kbGVyS2V5c18ubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICB1bmxpc3RlbkJ5S2V5KHRoaXMua2V5SGFuZGxlcktleXNfW2ldKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5rZXlIYW5kbGVyS2V5c18gPSBudWxsO1xuICAgICAgdGhpcy52aWV3cG9ydF8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuQ09OVEVYVE1FTlUsIHRoaXMuYm91bmRIYW5kbGVCcm93c2VyRXZlbnRfKTtcbiAgICAgIHRoaXMudmlld3BvcnRfLnJlbW92ZUV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLldIRUVMLCB0aGlzLmJvdW5kSGFuZGxlQnJvd3NlckV2ZW50Xyk7XG5cbiAgICAgIGlmICh0aGlzLmhhbmRsZVJlc2l6ZV8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5SRVNJWkUsIHRoaXMuaGFuZGxlUmVzaXplXywgZmFsc2UpO1xuICAgICAgICB0aGlzLmhhbmRsZVJlc2l6ZV8gPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHRoaXMubWFwQnJvd3NlckV2ZW50SGFuZGxlcl8uZGlzcG9zZSgpO1xuICAgICAgdGhpcy5tYXBCcm93c2VyRXZlbnRIYW5kbGVyXyA9IG51bGw7XG4gICAgICByZW1vdmVOb2RlKHRoaXMudmlld3BvcnRfKTtcbiAgICB9XG5cbiAgICBpZiAoIXRhcmdldEVsZW1lbnQpIHtcbiAgICAgIGlmICh0aGlzLnJlbmRlcmVyXykge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wb3N0UmVuZGVyVGltZW91dEhhbmRsZV8pO1xuICAgICAgICB0aGlzLnBvc3RSZW5kZXJUaW1lb3V0SGFuZGxlXyA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5wb3N0UmVuZGVyRnVuY3Rpb25zXy5sZW5ndGggPSAwO1xuICAgICAgICB0aGlzLnJlbmRlcmVyXy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucmVuZGVyZXJfID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuYW5pbWF0aW9uRGVsYXlLZXlfKSB7XG4gICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuYW5pbWF0aW9uRGVsYXlLZXlfKTtcbiAgICAgICAgdGhpcy5hbmltYXRpb25EZWxheUtleV8gPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRhcmdldEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy52aWV3cG9ydF8pO1xuXG4gICAgICBpZiAoIXRoaXMucmVuZGVyZXJfKSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXJfID0gdGhpcy5jcmVhdGVSZW5kZXJlcigpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm1hcEJyb3dzZXJFdmVudEhhbmRsZXJfID0gbmV3IE1hcEJyb3dzZXJFdmVudEhhbmRsZXIodGhpcywgdGhpcy5tb3ZlVG9sZXJhbmNlXyk7XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiBNYXBCcm93c2VyRXZlbnRUeXBlKSB7XG4gICAgICAgIHRoaXMubWFwQnJvd3NlckV2ZW50SGFuZGxlcl8uYWRkRXZlbnRMaXN0ZW5lcihNYXBCcm93c2VyRXZlbnRUeXBlW2tleV0sIHRoaXMuaGFuZGxlTWFwQnJvd3NlckV2ZW50LmJpbmQodGhpcykpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnZpZXdwb3J0Xy5hZGRFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5DT05URVhUTUVOVSwgdGhpcy5ib3VuZEhhbmRsZUJyb3dzZXJFdmVudF8sIGZhbHNlKTtcbiAgICAgIHRoaXMudmlld3BvcnRfLmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLldIRUVMLCB0aGlzLmJvdW5kSGFuZGxlQnJvd3NlckV2ZW50XywgUEFTU0lWRV9FVkVOVF9MSVNURU5FUlMgPyB7XG4gICAgICAgIHBhc3NpdmU6IGZhbHNlXG4gICAgICB9IDogZmFsc2UpO1xuICAgICAgdmFyIGtleWJvYXJkRXZlbnRUYXJnZXQgPSAhdGhpcy5rZXlib2FyZEV2ZW50VGFyZ2V0XyA/IHRhcmdldEVsZW1lbnQgOiB0aGlzLmtleWJvYXJkRXZlbnRUYXJnZXRfO1xuICAgICAgdGhpcy5rZXlIYW5kbGVyS2V5c18gPSBbbGlzdGVuKGtleWJvYXJkRXZlbnRUYXJnZXQsIEV2ZW50VHlwZS5LRVlET1dOLCB0aGlzLmhhbmRsZUJyb3dzZXJFdmVudCwgdGhpcyksIGxpc3RlbihrZXlib2FyZEV2ZW50VGFyZ2V0LCBFdmVudFR5cGUuS0VZUFJFU1MsIHRoaXMuaGFuZGxlQnJvd3NlckV2ZW50LCB0aGlzKV07XG5cbiAgICAgIGlmICghdGhpcy5oYW5kbGVSZXNpemVfKSB7XG4gICAgICAgIHRoaXMuaGFuZGxlUmVzaXplXyA9IHRoaXMudXBkYXRlU2l6ZS5iaW5kKHRoaXMpO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuUkVTSVpFLCB0aGlzLmhhbmRsZVJlc2l6ZV8sIGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnVwZGF0ZVNpemUoKTsgLy8gdXBkYXRlU2l6ZSBjYWxscyBzZXRTaXplLCBzbyBubyBuZWVkIHRvIGNhbGwgdGhpcy5yZW5kZXJcbiAgICAvLyBvdXJzZWx2ZXMgaGVyZS5cbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5oYW5kbGVUaWxlQ2hhbmdlXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmhhbmRsZVZpZXdQcm9wZXJ0eUNoYW5nZWRfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuaGFuZGxlVmlld0NoYW5nZWRfID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnZpZXdQcm9wZXJ0eUxpc3RlbmVyS2V5Xykge1xuICAgICAgdW5saXN0ZW5CeUtleSh0aGlzLnZpZXdQcm9wZXJ0eUxpc3RlbmVyS2V5Xyk7XG4gICAgICB0aGlzLnZpZXdQcm9wZXJ0eUxpc3RlbmVyS2V5XyA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudmlld0NoYW5nZUxpc3RlbmVyS2V5Xykge1xuICAgICAgdW5saXN0ZW5CeUtleSh0aGlzLnZpZXdDaGFuZ2VMaXN0ZW5lcktleV8pO1xuICAgICAgdGhpcy52aWV3Q2hhbmdlTGlzdGVuZXJLZXlfID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgdmlldyA9IHRoaXMuZ2V0VmlldygpO1xuXG4gICAgaWYgKHZpZXcpIHtcbiAgICAgIHRoaXMudXBkYXRlVmlld3BvcnRTaXplXygpO1xuICAgICAgdGhpcy52aWV3UHJvcGVydHlMaXN0ZW5lcktleV8gPSBsaXN0ZW4odmlldywgT2JqZWN0RXZlbnRUeXBlLlBST1BFUlRZQ0hBTkdFLCB0aGlzLmhhbmRsZVZpZXdQcm9wZXJ0eUNoYW5nZWRfLCB0aGlzKTtcbiAgICAgIHRoaXMudmlld0NoYW5nZUxpc3RlbmVyS2V5XyA9IGxpc3Rlbih2aWV3LCBFdmVudFR5cGUuQ0hBTkdFLCB0aGlzLmhhbmRsZVZpZXdQcm9wZXJ0eUNoYW5nZWRfLCB0aGlzKTtcbiAgICAgIHZpZXcucmVzb2x2ZUNvbnN0cmFpbnRzKDApO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuaGFuZGxlTGF5ZXJHcm91cENoYW5nZWRfID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmxheWVyR3JvdXBQcm9wZXJ0eUxpc3RlbmVyS2V5c18pIHtcbiAgICAgIHRoaXMubGF5ZXJHcm91cFByb3BlcnR5TGlzdGVuZXJLZXlzXy5mb3JFYWNoKHVubGlzdGVuQnlLZXkpO1xuICAgICAgdGhpcy5sYXllckdyb3VwUHJvcGVydHlMaXN0ZW5lcktleXNfID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgbGF5ZXJHcm91cCA9IHRoaXMuZ2V0TGF5ZXJHcm91cCgpO1xuXG4gICAgaWYgKGxheWVyR3JvdXApIHtcbiAgICAgIHRoaXMubGF5ZXJHcm91cFByb3BlcnR5TGlzdGVuZXJLZXlzXyA9IFtsaXN0ZW4obGF5ZXJHcm91cCwgT2JqZWN0RXZlbnRUeXBlLlBST1BFUlRZQ0hBTkdFLCB0aGlzLnJlbmRlciwgdGhpcyksIGxpc3RlbihsYXllckdyb3VwLCBFdmVudFR5cGUuQ0hBTkdFLCB0aGlzLnJlbmRlciwgdGhpcyldO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJcyByZW5kZXJlZC5cbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmlzUmVuZGVyZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICEhdGhpcy5mcmFtZVN0YXRlXztcbiAgfTtcbiAgLyoqXG4gICAqIFJlcXVlc3RzIGFuIGltbWVkaWF0ZSByZW5kZXIgaW4gYSBzeW5jaHJvbm91cyBtYW5uZXIuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLnJlbmRlclN5bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuYW5pbWF0aW9uRGVsYXlLZXlfKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGlvbkRlbGF5S2V5Xyk7XG4gICAgfVxuXG4gICAgdGhpcy5hbmltYXRpb25EZWxheV8oKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlZHJhd3MgYWxsIHRleHQgYWZ0ZXIgbmV3IGZvbnRzIGhhdmUgbG9hZGVkXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5yZWRyYXdUZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBsYXllclN0YXRlcyA9IHRoaXMuZ2V0TGF5ZXJHcm91cCgpLmdldExheWVyU3RhdGVzQXJyYXkoKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGxheWVyU3RhdGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBsYXllciA9IGxheWVyU3RhdGVzW2ldLmxheWVyO1xuXG4gICAgICBpZiAobGF5ZXIuaGFzUmVuZGVyZXIoKSkge1xuICAgICAgICBsYXllci5nZXRSZW5kZXJlcigpLmhhbmRsZUZvbnRzQ2hhbmdlZCgpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFJlcXVlc3QgYSBtYXAgcmVuZGVyaW5nIChhdCB0aGUgbmV4dCBhbmltYXRpb24gZnJhbWUpLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMucmVuZGVyZXJfICYmIHRoaXMuYW5pbWF0aW9uRGVsYXlLZXlfID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuYW5pbWF0aW9uRGVsYXlLZXlfID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuYW5pbWF0aW9uRGVsYXlfKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIGdpdmVuIGNvbnRyb2wgZnJvbSB0aGUgbWFwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29udHJvbC9Db250cm9sLmpzXCIpLmRlZmF1bHR9IGNvbnRyb2wgQ29udHJvbC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9jb250cm9sL0NvbnRyb2wuanNcIikuZGVmYXVsdHx1bmRlZmluZWR9IFRoZSByZW1vdmVkIGNvbnRyb2wgKG9yIHVuZGVmaW5lZFxuICAgKiAgICAgaWYgdGhlIGNvbnRyb2wgd2FzIG5vdCBmb3VuZCkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLnJlbW92ZUNvbnRyb2wgPSBmdW5jdGlvbiAoY29udHJvbCkge1xuICAgIHJldHVybiB0aGlzLmdldENvbnRyb2xzKCkucmVtb3ZlKGNvbnRyb2wpO1xuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIHRoZSBnaXZlbiBpbnRlcmFjdGlvbiBmcm9tIHRoZSBtYXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9pbnRlcmFjdGlvbi9JbnRlcmFjdGlvbi5qc1wiKS5kZWZhdWx0fSBpbnRlcmFjdGlvbiBJbnRlcmFjdGlvbiB0byByZW1vdmUuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vaW50ZXJhY3Rpb24vSW50ZXJhY3Rpb24uanNcIikuZGVmYXVsdHx1bmRlZmluZWR9IFRoZSByZW1vdmVkIGludGVyYWN0aW9uIChvclxuICAgKiAgICAgdW5kZWZpbmVkIGlmIHRoZSBpbnRlcmFjdGlvbiB3YXMgbm90IGZvdW5kKS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUucmVtb3ZlSW50ZXJhY3Rpb24gPSBmdW5jdGlvbiAoaW50ZXJhY3Rpb24pIHtcbiAgICByZXR1cm4gdGhpcy5nZXRJbnRlcmFjdGlvbnMoKS5yZW1vdmUoaW50ZXJhY3Rpb24pO1xuICB9O1xuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgZ2l2ZW4gbGF5ZXIgZnJvbSB0aGUgbWFwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbGF5ZXIvQmFzZS5qc1wiKS5kZWZhdWx0fSBsYXllciBMYXllci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9sYXllci9CYXNlLmpzXCIpLmRlZmF1bHR8dW5kZWZpbmVkfSBUaGUgcmVtb3ZlZCBsYXllciAob3IgdW5kZWZpbmVkIGlmIHRoZVxuICAgKiAgICAgbGF5ZXIgd2FzIG5vdCBmb3VuZCkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLnJlbW92ZUxheWVyID0gZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgdmFyIGxheWVycyA9IHRoaXMuZ2V0TGF5ZXJHcm91cCgpLmdldExheWVycygpO1xuICAgIHJldHVybiBsYXllcnMucmVtb3ZlKGxheWVyKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgZ2l2ZW4gb3ZlcmxheSBmcm9tIHRoZSBtYXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHR9IG92ZXJsYXkgT3ZlcmxheS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHR8dW5kZWZpbmVkfSBUaGUgcmVtb3ZlZCBvdmVybGF5IChvciB1bmRlZmluZWRcbiAgICogICAgIGlmIHRoZSBvdmVybGF5IHdhcyBub3QgZm91bmQpLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5yZW1vdmVPdmVybGF5ID0gZnVuY3Rpb24gKG92ZXJsYXkpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRPdmVybGF5cygpLnJlbW92ZShvdmVybGF5KTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lIFRpbWUuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5yZW5kZXJGcmFtZV8gPSBmdW5jdGlvbiAodGltZSkge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgc2l6ZSA9IHRoaXMuZ2V0U2l6ZSgpO1xuICAgIHZhciB2aWV3ID0gdGhpcy5nZXRWaWV3KCk7XG4gICAgdmFyIHByZXZpb3VzRnJhbWVTdGF0ZSA9IHRoaXMuZnJhbWVTdGF0ZV87XG4gICAgLyoqIEB0eXBlIHs/RnJhbWVTdGF0ZX0gKi9cblxuICAgIHZhciBmcmFtZVN0YXRlID0gbnVsbDtcblxuICAgIGlmIChzaXplICE9PSB1bmRlZmluZWQgJiYgaGFzQXJlYShzaXplKSAmJiB2aWV3ICYmIHZpZXcuaXNEZWYoKSkge1xuICAgICAgdmFyIHZpZXdIaW50cyA9IHZpZXcuZ2V0SGludHModGhpcy5mcmFtZVN0YXRlXyA/IHRoaXMuZnJhbWVTdGF0ZV8udmlld0hpbnRzIDogdW5kZWZpbmVkKTtcbiAgICAgIHZhciB2aWV3U3RhdGUgPSB2aWV3LmdldFN0YXRlKCk7XG4gICAgICBmcmFtZVN0YXRlID0ge1xuICAgICAgICBhbmltYXRlOiBmYWxzZSxcbiAgICAgICAgY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm06IHRoaXMuY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm1fLFxuICAgICAgICBkZWNsdXR0ZXJUcmVlOiBudWxsLFxuICAgICAgICBleHRlbnQ6IGdldEZvclZpZXdBbmRTaXplKHZpZXdTdGF0ZS5jZW50ZXIsIHZpZXdTdGF0ZS5yZXNvbHV0aW9uLCB2aWV3U3RhdGUucm90YXRpb24sIHNpemUpLFxuICAgICAgICBpbmRleDogdGhpcy5mcmFtZUluZGV4XysrLFxuICAgICAgICBsYXllckluZGV4OiAwLFxuICAgICAgICBsYXllclN0YXRlc0FycmF5OiB0aGlzLmdldExheWVyR3JvdXAoKS5nZXRMYXllclN0YXRlc0FycmF5KCksXG4gICAgICAgIHBpeGVsUmF0aW86IHRoaXMucGl4ZWxSYXRpb18sXG4gICAgICAgIHBpeGVsVG9Db29yZGluYXRlVHJhbnNmb3JtOiB0aGlzLnBpeGVsVG9Db29yZGluYXRlVHJhbnNmb3JtXyxcbiAgICAgICAgcG9zdFJlbmRlckZ1bmN0aW9uczogW10sXG4gICAgICAgIHNpemU6IHNpemUsXG4gICAgICAgIHRpbGVRdWV1ZTogdGhpcy50aWxlUXVldWVfLFxuICAgICAgICB0aW1lOiB0aW1lLFxuICAgICAgICB1c2VkVGlsZXM6IHt9LFxuICAgICAgICB2aWV3U3RhdGU6IHZpZXdTdGF0ZSxcbiAgICAgICAgdmlld0hpbnRzOiB2aWV3SGludHMsXG4gICAgICAgIHdhbnRlZFRpbGVzOiB7fVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLmZyYW1lU3RhdGVfID0gZnJhbWVTdGF0ZTtcbiAgICB0aGlzLnJlbmRlcmVyXy5yZW5kZXJGcmFtZShmcmFtZVN0YXRlKTtcblxuICAgIGlmIChmcmFtZVN0YXRlKSB7XG4gICAgICBpZiAoZnJhbWVTdGF0ZS5hbmltYXRlKSB7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICB9XG5cbiAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHRoaXMucG9zdFJlbmRlckZ1bmN0aW9uc18sIGZyYW1lU3RhdGUucG9zdFJlbmRlckZ1bmN0aW9ucyk7XG5cbiAgICAgIGlmIChwcmV2aW91c0ZyYW1lU3RhdGUpIHtcbiAgICAgICAgdmFyIG1vdmVTdGFydCA9ICF0aGlzLnByZXZpb3VzRXh0ZW50XyB8fCAhaXNFbXB0eSh0aGlzLnByZXZpb3VzRXh0ZW50XykgJiYgIWVxdWFscyhmcmFtZVN0YXRlLmV4dGVudCwgdGhpcy5wcmV2aW91c0V4dGVudF8pO1xuXG4gICAgICAgIGlmIChtb3ZlU3RhcnQpIHtcbiAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IE1hcEV2ZW50KE1hcEV2ZW50VHlwZS5NT1ZFU1RBUlQsIHRoaXMsIHByZXZpb3VzRnJhbWVTdGF0ZSkpO1xuICAgICAgICAgIHRoaXMucHJldmlvdXNFeHRlbnRfID0gY3JlYXRlT3JVcGRhdGVFbXB0eSh0aGlzLnByZXZpb3VzRXh0ZW50Xyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGlkbGUgPSB0aGlzLnByZXZpb3VzRXh0ZW50XyAmJiAhZnJhbWVTdGF0ZS52aWV3SGludHNbVmlld0hpbnQuQU5JTUFUSU5HXSAmJiAhZnJhbWVTdGF0ZS52aWV3SGludHNbVmlld0hpbnQuSU5URVJBQ1RJTkddICYmICFlcXVhbHMoZnJhbWVTdGF0ZS5leHRlbnQsIHRoaXMucHJldmlvdXNFeHRlbnRfKTtcblxuICAgICAgaWYgKGlkbGUpIHtcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBNYXBFdmVudChNYXBFdmVudFR5cGUuTU9WRUVORCwgdGhpcywgZnJhbWVTdGF0ZSkpO1xuICAgICAgICBjbG9uZShmcmFtZVN0YXRlLmV4dGVudCwgdGhpcy5wcmV2aW91c0V4dGVudF8pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgTWFwRXZlbnQoTWFwRXZlbnRUeXBlLlBPU1RSRU5ERVIsIHRoaXMsIGZyYW1lU3RhdGUpKTtcblxuICAgIGlmICghdGhpcy5wb3N0UmVuZGVyVGltZW91dEhhbmRsZV8pIHtcbiAgICAgIHRoaXMucG9zdFJlbmRlclRpbWVvdXRIYW5kbGVfID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIF90aGlzLnBvc3RSZW5kZXJUaW1lb3V0SGFuZGxlXyA9IHVuZGVmaW5lZDtcblxuICAgICAgICBfdGhpcy5oYW5kbGVQb3N0UmVuZGVyKCk7XG4gICAgICB9LCAwKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTZXRzIHRoZSBsYXllcmdyb3VwIG9mIHRoaXMgbWFwLlxuICAgKiBAcGFyYW0ge0xheWVyR3JvdXB9IGxheWVyR3JvdXAgQSBsYXllciBncm91cCBjb250YWluaW5nIHRoZSBsYXllcnMgaW4gdGhpcyBtYXAuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLnNldExheWVyR3JvdXAgPSBmdW5jdGlvbiAobGF5ZXJHcm91cCkge1xuICAgIHRoaXMuc2V0KE1hcFByb3BlcnR5LkxBWUVSR1JPVVAsIGxheWVyR3JvdXApO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBzaXplIG9mIHRoaXMgbWFwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfHVuZGVmaW5lZH0gc2l6ZSBUaGUgc2l6ZSBpbiBwaXhlbHMgb2YgdGhlIG1hcCBpbiB0aGUgRE9NLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5zZXRTaXplID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgICB0aGlzLnNldChNYXBQcm9wZXJ0eS5TSVpFLCBzaXplKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgdGFyZ2V0IGVsZW1lbnQgdG8gcmVuZGVyIHRoaXMgbWFwIGludG8uXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8c3RyaW5nfHVuZGVmaW5lZH0gdGFyZ2V0IFRoZSBFbGVtZW50IG9yIGlkIG9mIHRoZSBFbGVtZW50XG4gICAqICAgICB0aGF0IHRoZSBtYXAgaXMgcmVuZGVyZWQgaW4uXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLnNldFRhcmdldCA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICB0aGlzLnNldChNYXBQcm9wZXJ0eS5UQVJHRVQsIHRhcmdldCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHZpZXcgZm9yIHRoaXMgbWFwLlxuICAgKiBAcGFyYW0ge1ZpZXd9IHZpZXcgVGhlIHZpZXcgdGhhdCBjb250cm9scyB0aGlzIG1hcC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuc2V0VmlldyA9IGZ1bmN0aW9uICh2aWV3KSB7XG4gICAgdGhpcy5zZXQoTWFwUHJvcGVydHkuVklFVywgdmlldyk7XG4gIH07XG4gIC8qKlxuICAgKiBGb3JjZSBhIHJlY2FsY3VsYXRpb24gb2YgdGhlIG1hcCB2aWV3cG9ydCBzaXplLiAgVGhpcyBzaG91bGQgYmUgY2FsbGVkIHdoZW5cbiAgICogdGhpcmQtcGFydHkgY29kZSBjaGFuZ2VzIHRoZSBzaXplIG9mIHRoZSBtYXAgdmlld3BvcnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLnVwZGF0ZVNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRhcmdldEVsZW1lbnQgPSB0aGlzLmdldFRhcmdldEVsZW1lbnQoKTtcblxuICAgIGlmICghdGFyZ2V0RWxlbWVudCkge1xuICAgICAgdGhpcy5zZXRTaXplKHVuZGVmaW5lZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBjb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXRFbGVtZW50KTtcbiAgICAgIHRoaXMuc2V0U2l6ZShbdGFyZ2V0RWxlbWVudC5vZmZzZXRXaWR0aCAtIHBhcnNlRmxvYXQoY29tcHV0ZWRTdHlsZVsnYm9yZGVyTGVmdFdpZHRoJ10pIC0gcGFyc2VGbG9hdChjb21wdXRlZFN0eWxlWydwYWRkaW5nTGVmdCddKSAtIHBhcnNlRmxvYXQoY29tcHV0ZWRTdHlsZVsncGFkZGluZ1JpZ2h0J10pIC0gcGFyc2VGbG9hdChjb21wdXRlZFN0eWxlWydib3JkZXJSaWdodFdpZHRoJ10pLCB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCAtIHBhcnNlRmxvYXQoY29tcHV0ZWRTdHlsZVsnYm9yZGVyVG9wV2lkdGgnXSkgLSBwYXJzZUZsb2F0KGNvbXB1dGVkU3R5bGVbJ3BhZGRpbmdUb3AnXSkgLSBwYXJzZUZsb2F0KGNvbXB1dGVkU3R5bGVbJ3BhZGRpbmdCb3R0b20nXSkgLSBwYXJzZUZsb2F0KGNvbXB1dGVkU3R5bGVbJ2JvcmRlckJvdHRvbVdpZHRoJ10pXSk7XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVWaWV3cG9ydFNpemVfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZWNvbXB1dGVzIHRoZSB2aWV3cG9ydCBzaXplIGFuZCBzYXZlIGl0IG9uIHRoZSB2aWV3IG9iamVjdCAoaWYgYW55KVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUudXBkYXRlVmlld3BvcnRTaXplXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmlldyA9IHRoaXMuZ2V0VmlldygpO1xuXG4gICAgaWYgKHZpZXcpIHtcbiAgICAgIHZhciBzaXplID0gdW5kZWZpbmVkO1xuICAgICAgdmFyIGNvbXB1dGVkU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKHRoaXMudmlld3BvcnRfKTtcblxuICAgICAgaWYgKGNvbXB1dGVkU3R5bGUud2lkdGggJiYgY29tcHV0ZWRTdHlsZS5oZWlnaHQpIHtcbiAgICAgICAgc2l6ZSA9IFtwYXJzZUludChjb21wdXRlZFN0eWxlLndpZHRoLCAxMCksIHBhcnNlSW50KGNvbXB1dGVkU3R5bGUuaGVpZ2h0LCAxMCldO1xuICAgICAgfVxuXG4gICAgICB2aWV3LnNldFZpZXdwb3J0U2l6ZShzaXplKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIFBsdWdnYWJsZU1hcDtcbn0oQmFzZU9iamVjdCk7XG4vKipcbiAqIEBwYXJhbSB7TWFwT3B0aW9uc30gb3B0aW9ucyBNYXAgb3B0aW9ucy5cbiAqIEByZXR1cm4ge01hcE9wdGlvbnNJbnRlcm5hbH0gSW50ZXJuYWwgbWFwIG9wdGlvbnMuXG4gKi9cblxuXG5mdW5jdGlvbiBjcmVhdGVPcHRpb25zSW50ZXJuYWwob3B0aW9ucykge1xuICAvKipcbiAgICogQHR5cGUge0hUTUxFbGVtZW50fERvY3VtZW50fVxuICAgKi9cbiAgdmFyIGtleWJvYXJkRXZlbnRUYXJnZXQgPSBudWxsO1xuXG4gIGlmIChvcHRpb25zLmtleWJvYXJkRXZlbnRUYXJnZXQgIT09IHVuZGVmaW5lZCkge1xuICAgIGtleWJvYXJkRXZlbnRUYXJnZXQgPSB0eXBlb2Ygb3B0aW9ucy5rZXlib2FyZEV2ZW50VGFyZ2V0ID09PSAnc3RyaW5nJyA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG9wdGlvbnMua2V5Ym9hcmRFdmVudFRhcmdldCkgOiBvcHRpb25zLmtleWJvYXJkRXZlbnRUYXJnZXQ7XG4gIH1cbiAgLyoqXG4gICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCAqPn1cbiAgICovXG5cblxuICB2YXIgdmFsdWVzID0ge307XG4gIHZhciBsYXllckdyb3VwID0gb3B0aW9ucy5sYXllcnMgJiYgdHlwZW9mXG4gIC8qKiBAdHlwZSB7P30gKi9cbiAgb3B0aW9ucy5sYXllcnMuZ2V0TGF5ZXJzID09PSAnZnVuY3Rpb24nID9cbiAgLyoqIEB0eXBlIHtMYXllckdyb3VwfSAqL1xuICBvcHRpb25zLmxheWVycyA6IG5ldyBMYXllckdyb3VwKHtcbiAgICBsYXllcnM6XG4gICAgLyoqIEB0eXBlIHtDb2xsZWN0aW9ufSAqL1xuICAgIG9wdGlvbnMubGF5ZXJzXG4gIH0pO1xuICB2YWx1ZXNbTWFwUHJvcGVydHkuTEFZRVJHUk9VUF0gPSBsYXllckdyb3VwO1xuICB2YWx1ZXNbTWFwUHJvcGVydHkuVEFSR0VUXSA9IG9wdGlvbnMudGFyZ2V0O1xuICB2YWx1ZXNbTWFwUHJvcGVydHkuVklFV10gPSBvcHRpb25zLnZpZXcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudmlldyA6IG5ldyBWaWV3KCk7XG4gIHZhciBjb250cm9scztcblxuICBpZiAob3B0aW9ucy5jb250cm9scyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkob3B0aW9ucy5jb250cm9scykpIHtcbiAgICAgIGNvbnRyb2xzID0gbmV3IENvbGxlY3Rpb24ob3B0aW9ucy5jb250cm9scy5zbGljZSgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzZXJ0KHR5cGVvZlxuICAgICAgLyoqIEB0eXBlIHs/fSAqL1xuICAgICAgb3B0aW9ucy5jb250cm9scy5nZXRBcnJheSA9PT0gJ2Z1bmN0aW9uJywgNDcpOyAvLyBFeHBlY3RlZCBgY29udHJvbHNgIHRvIGJlIGFuIGFycmF5IG9yIGFuIGBpbXBvcnQoXCIuL0NvbGxlY3Rpb24uanNcIikuQ29sbGVjdGlvbmBcblxuICAgICAgY29udHJvbHMgPVxuICAgICAgLyoqIEB0eXBlIHtDb2xsZWN0aW9ufSAqL1xuICAgICAgb3B0aW9ucy5jb250cm9scztcbiAgICB9XG4gIH1cblxuICB2YXIgaW50ZXJhY3Rpb25zO1xuXG4gIGlmIChvcHRpb25zLmludGVyYWN0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkob3B0aW9ucy5pbnRlcmFjdGlvbnMpKSB7XG4gICAgICBpbnRlcmFjdGlvbnMgPSBuZXcgQ29sbGVjdGlvbihvcHRpb25zLmludGVyYWN0aW9ucy5zbGljZSgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzZXJ0KHR5cGVvZlxuICAgICAgLyoqIEB0eXBlIHs/fSAqL1xuICAgICAgb3B0aW9ucy5pbnRlcmFjdGlvbnMuZ2V0QXJyYXkgPT09ICdmdW5jdGlvbicsIDQ4KTsgLy8gRXhwZWN0ZWQgYGludGVyYWN0aW9uc2AgdG8gYmUgYW4gYXJyYXkgb3IgYW4gYGltcG9ydChcIi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uYFxuXG4gICAgICBpbnRlcmFjdGlvbnMgPVxuICAgICAgLyoqIEB0eXBlIHtDb2xsZWN0aW9ufSAqL1xuICAgICAgb3B0aW9ucy5pbnRlcmFjdGlvbnM7XG4gICAgfVxuICB9XG5cbiAgdmFyIG92ZXJsYXlzO1xuXG4gIGlmIChvcHRpb25zLm92ZXJsYXlzICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRpb25zLm92ZXJsYXlzKSkge1xuICAgICAgb3ZlcmxheXMgPSBuZXcgQ29sbGVjdGlvbihvcHRpb25zLm92ZXJsYXlzLnNsaWNlKCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhc3NlcnQodHlwZW9mXG4gICAgICAvKiogQHR5cGUgez99ICovXG4gICAgICBvcHRpb25zLm92ZXJsYXlzLmdldEFycmF5ID09PSAnZnVuY3Rpb24nLCA0OSk7IC8vIEV4cGVjdGVkIGBvdmVybGF5c2AgdG8gYmUgYW4gYXJyYXkgb3IgYW4gYGltcG9ydChcIi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uYFxuXG4gICAgICBvdmVybGF5cyA9IG9wdGlvbnMub3ZlcmxheXM7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG92ZXJsYXlzID0gbmV3IENvbGxlY3Rpb24oKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY29udHJvbHM6IGNvbnRyb2xzLFxuICAgIGludGVyYWN0aW9uczogaW50ZXJhY3Rpb25zLFxuICAgIGtleWJvYXJkRXZlbnRUYXJnZXQ6IGtleWJvYXJkRXZlbnRUYXJnZXQsXG4gICAgb3ZlcmxheXM6IG92ZXJsYXlzLFxuICAgIHZhbHVlczogdmFsdWVzXG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBsdWdnYWJsZU1hcDsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2NvbnRyb2wvQ29udHJvbFxuICovXG5cblxuaW1wb3J0IEJhc2VPYmplY3QgZnJvbSAnLi4vT2JqZWN0LmpzJztcbmltcG9ydCBNYXBFdmVudFR5cGUgZnJvbSAnLi4vTWFwRXZlbnRUeXBlLmpzJztcbmltcG9ydCB7IFZPSUQgfSBmcm9tICcuLi9mdW5jdGlvbnMuanMnO1xuaW1wb3J0IHsgbGlzdGVuLCB1bmxpc3RlbkJ5S2V5IH0gZnJvbSAnLi4vZXZlbnRzLmpzJztcbmltcG9ydCB7IHJlbW92ZU5vZGUgfSBmcm9tICcuLi9kb20uanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge0hUTUxFbGVtZW50fSBbZWxlbWVudF0gVGhlIGVsZW1lbnQgaXMgdGhlIGNvbnRyb2wnc1xuICogY29udGFpbmVyIGVsZW1lbnQuIFRoaXMgb25seSBuZWVkcyB0byBiZSBzcGVjaWZpZWQgaWYgeW91J3JlIGRldmVsb3BpbmdcbiAqIGEgY3VzdG9tIGNvbnRyb2wuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKGltcG9ydChcIi4uL01hcEV2ZW50LmpzXCIpLmRlZmF1bHQpOnZvaWR9IFtyZW5kZXJdIEZ1bmN0aW9uIGNhbGxlZCB3aGVuXG4gKiB0aGUgY29udHJvbCBzaG91bGQgYmUgcmUtcmVuZGVyZWQuIFRoaXMgaXMgY2FsbGVkIGluIGEgYHJlcXVlc3RBbmltYXRpb25GcmFtZWBcbiAqIGNhbGxiYWNrLlxuICogQHByb3BlcnR5IHtIVE1MRWxlbWVudHxzdHJpbmd9IFt0YXJnZXRdIFNwZWNpZnkgYSB0YXJnZXQgaWYgeW91IHdhbnRcbiAqIHRoZSBjb250cm9sIHRvIGJlIHJlbmRlcmVkIG91dHNpZGUgb2YgdGhlIG1hcCdzIHZpZXdwb3J0LlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQSBjb250cm9sIGlzIGEgdmlzaWJsZSB3aWRnZXQgd2l0aCBhIERPTSBlbGVtZW50IGluIGEgZml4ZWQgcG9zaXRpb24gb24gdGhlXG4gKiBzY3JlZW4uIFRoZXkgY2FuIGludm9sdmUgdXNlciBpbnB1dCAoYnV0dG9ucyksIG9yIGJlIGluZm9ybWF0aW9uYWwgb25seTtcbiAqIHRoZSBwb3NpdGlvbiBpcyBkZXRlcm1pbmVkIHVzaW5nIENTUy4gQnkgZGVmYXVsdCB0aGVzZSBhcmUgcGxhY2VkIGluIHRoZVxuICogY29udGFpbmVyIHdpdGggQ1NTIGNsYXNzIG5hbWUgYG9sLW92ZXJsYXljb250YWluZXItc3RvcGV2ZW50YCwgYnV0IGNhbiB1c2VcbiAqIGFueSBvdXRzaWRlIERPTSBlbGVtZW50LlxuICpcbiAqIFRoaXMgaXMgdGhlIGJhc2UgY2xhc3MgZm9yIGNvbnRyb2xzLiBZb3UgY2FuIHVzZSBpdCBmb3Igc2ltcGxlIGN1c3RvbVxuICogY29udHJvbHMgYnkgY3JlYXRpbmcgdGhlIGVsZW1lbnQgd2l0aCBsaXN0ZW5lcnMsIGNyZWF0aW5nIGFuIGluc3RhbmNlOlxuICogYGBganNcbiAqIHZhciBteUNvbnRyb2wgPSBuZXcgQ29udHJvbCh7ZWxlbWVudDogbXlFbGVtZW50fSk7XG4gKiBgYGBcbiAqIGFuZCB0aGVuIGFkZGluZyB0aGlzIHRvIHRoZSBtYXAuXG4gKlxuICogVGhlIG1haW4gYWR2YW50YWdlIG9mIGhhdmluZyB0aGlzIGFzIGEgY29udHJvbCByYXRoZXIgdGhhbiBhIHNpbXBsZSBzZXBhcmF0ZVxuICogRE9NIGVsZW1lbnQgaXMgdGhhdCBwcmV2ZW50aW5nIHByb3BhZ2F0aW9uIGlzIGhhbmRsZWQgZm9yIHlvdS4gQ29udHJvbHNcbiAqIHdpbGwgYWxzbyBiZSBvYmplY3RzIGluIGEge0BsaW5rIG1vZHVsZTpvbC9Db2xsZWN0aW9ufkNvbGxlY3Rpb259LCBzbyB5b3UgY2FuIHVzZSB0aGVpciBtZXRob2RzLlxuICpcbiAqIFlvdSBjYW4gYWxzbyBleHRlbmQgdGhpcyBiYXNlIGZvciB5b3VyIG93biBjb250cm9sIGNsYXNzLiBTZWVcbiAqIGV4YW1wbGVzL2N1c3RvbS1jb250cm9scyBmb3IgYW4gZXhhbXBsZSBvZiBob3cgdG8gZG8gdGhpcy5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIENvbnRyb2wgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ29udHJvbCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBDb250cm9sIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQ29udHJvbChvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcblxuICAgIHZhciBlbGVtZW50ID0gb3B0aW9ucy5lbGVtZW50O1xuXG4gICAgaWYgKGVsZW1lbnQgJiYgIW9wdGlvbnMudGFyZ2V0ICYmICFlbGVtZW50LnN0eWxlLnBvaW50ZXJFdmVudHMpIHtcbiAgICAgIGVsZW1lbnQuc3R5bGUucG9pbnRlckV2ZW50cyA9ICdhdXRvJztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtIVE1MRWxlbWVudH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuZWxlbWVudCA9IGVsZW1lbnQgPyBlbGVtZW50IDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtIVE1MRWxlbWVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLnRhcmdldF8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMubWFwXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHshQXJyYXk8aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleT59XG4gICAgICovXG5cbiAgICBfdGhpcy5saXN0ZW5lcktleXMgPSBbXTtcblxuICAgIGlmIChvcHRpb25zLnJlbmRlcikge1xuICAgICAgX3RoaXMucmVuZGVyID0gb3B0aW9ucy5yZW5kZXI7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMudGFyZ2V0KSB7XG4gICAgICBfdGhpcy5zZXRUYXJnZXQob3B0aW9ucy50YXJnZXQpO1xuICAgIH1cblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQ2xlYW4gdXAuXG4gICAqL1xuXG5cbiAgQ29udHJvbC5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsID0gZnVuY3Rpb24gKCkge1xuICAgIHJlbW92ZU5vZGUodGhpcy5lbGVtZW50KTtcblxuICAgIF9zdXBlci5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsLmNhbGwodGhpcyk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1hcCBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb250cm9sLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gTWFwLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29udHJvbC5wcm90b3R5cGUuZ2V0TWFwID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm1hcF87XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIGNvbnRyb2wgZnJvbSBpdHMgY3VycmVudCBtYXAgYW5kIGF0dGFjaCBpdCB0byB0aGUgbmV3IG1hcC5cbiAgICogU3ViY2xhc3NlcyBtYXkgc2V0IHVwIGV2ZW50IGhhbmRsZXJzIHRvIGdldCBub3RpZmllZCBhYm91dCBjaGFuZ2VzIHRvXG4gICAqIHRoZSBtYXAgaGVyZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIE1hcC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENvbnRyb2wucHJvdG90eXBlLnNldE1hcCA9IGZ1bmN0aW9uIChtYXApIHtcbiAgICBpZiAodGhpcy5tYXBfKSB7XG4gICAgICByZW1vdmVOb2RlKHRoaXMuZWxlbWVudCk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5saXN0ZW5lcktleXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdW5saXN0ZW5CeUtleSh0aGlzLmxpc3RlbmVyS2V5c1tpXSk7XG4gICAgfVxuXG4gICAgdGhpcy5saXN0ZW5lcktleXMubGVuZ3RoID0gMDtcbiAgICB0aGlzLm1hcF8gPSBtYXA7XG5cbiAgICBpZiAodGhpcy5tYXBfKSB7XG4gICAgICB2YXIgdGFyZ2V0ID0gdGhpcy50YXJnZXRfID8gdGhpcy50YXJnZXRfIDogbWFwLmdldE92ZXJsYXlDb250YWluZXJTdG9wRXZlbnQoKTtcbiAgICAgIHRhcmdldC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuXG4gICAgICBpZiAodGhpcy5yZW5kZXIgIT09IFZPSUQpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcktleXMucHVzaChsaXN0ZW4obWFwLCBNYXBFdmVudFR5cGUuUE9TVFJFTkRFUiwgdGhpcy5yZW5kZXIsIHRoaXMpKTtcbiAgICAgIH1cblxuICAgICAgbWFwLnJlbmRlcigpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlcnMgdGhlIGNvbnRyb2wuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwRXZlbnQgTWFwIGV2ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29udHJvbC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKG1hcEV2ZW50KSB7fTtcbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBzZXQgYSB0YXJnZXQgZWxlbWVudCBmb3IgdGhlIGNvbnRyb2wuIEl0IGhhcyBub1xuICAgKiBlZmZlY3QgaWYgaXQgaXMgY2FsbGVkIGFmdGVyIHRoZSBjb250cm9sIGhhcyBiZWVuIGFkZGVkIHRvIHRoZSBtYXAgKGkuZS5cbiAgICogYWZ0ZXIgYHNldE1hcGAgaXMgY2FsbGVkIG9uIHRoZSBjb250cm9sKS4gSWYgbm8gYHRhcmdldGAgaXMgc2V0IGluIHRoZVxuICAgKiBvcHRpb25zIHBhc3NlZCB0byB0aGUgY29udHJvbCBjb25zdHJ1Y3RvciBhbmQgaWYgYHNldFRhcmdldGAgaXMgbm90IGNhbGxlZFxuICAgKiB0aGVuIHRoZSBjb250cm9sIGlzIGFkZGVkIHRvIHRoZSBtYXAncyBvdmVybGF5IGNvbnRhaW5lci5cbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudHxzdHJpbmd9IHRhcmdldCBUYXJnZXQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDb250cm9sLnByb3RvdHlwZS5zZXRUYXJnZXQgPSBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgdGhpcy50YXJnZXRfID0gdHlwZW9mIHRhcmdldCA9PT0gJ3N0cmluZycgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXQpIDogdGFyZ2V0O1xuICB9O1xuXG4gIHJldHVybiBDb250cm9sO1xufShCYXNlT2JqZWN0KTtcblxuZXhwb3J0IGRlZmF1bHQgQ29udHJvbDsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2NvbnRyb2wvQXR0cmlidXRpb25cbiAqL1xuXG5cbmltcG9ydCBDb250cm9sIGZyb20gJy4vQ29udHJvbC5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IHsgQ0xBU1NfQ09MTEFQU0VELCBDTEFTU19DT05UUk9MLCBDTEFTU19VTlNFTEVDVEFCTEUgfSBmcm9tICcuLi9jc3MuanMnO1xuaW1wb3J0IHsgZXF1YWxzIH0gZnJvbSAnLi4vYXJyYXkuanMnO1xuaW1wb3J0IHsgaW5WaWV3IH0gZnJvbSAnLi4vbGF5ZXIvTGF5ZXIuanMnO1xuaW1wb3J0IHsgcmVtb3ZlQ2hpbGRyZW4sIHJlcGxhY2VOb2RlIH0gZnJvbSAnLi4vZG9tLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjbGFzc05hbWU9J29sLWF0dHJpYnV0aW9uJ10gQ1NTIGNsYXNzIG5hbWUuXG4gKiBAcHJvcGVydHkge0hUTUxFbGVtZW50fHN0cmluZ30gW3RhcmdldF0gU3BlY2lmeSBhIHRhcmdldCBpZiB5b3VcbiAqIHdhbnQgdGhlIGNvbnRyb2wgdG8gYmUgcmVuZGVyZWQgb3V0c2lkZSBvZiB0aGUgbWFwJ3NcbiAqIHZpZXdwb3J0LlxuICogQHByb3BlcnR5IHtib29sZWFufSBbY29sbGFwc2libGVdIFNwZWNpZnkgaWYgYXR0cmlidXRpb25zIGNhblxuICogYmUgY29sbGFwc2VkLiBJZiBub3Qgc3BlY2lmaWVkLCBzb3VyY2VzIGNvbnRyb2wgdGhpcyBiZWhhdmlvciB3aXRoIHRoZWlyXG4gKiBgYXR0cmlidXRpb25zQ29sbGFwc2libGVgIHNldHRpbmcuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtjb2xsYXBzZWQ9dHJ1ZV0gU3BlY2lmeSBpZiBhdHRyaWJ1dGlvbnMgc2hvdWxkXG4gKiBiZSBjb2xsYXBzZWQgYXQgc3RhcnR1cC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdGlwTGFiZWw9J0F0dHJpYnV0aW9ucyddIFRleHQgbGFiZWwgdG8gdXNlIGZvciB0aGUgYnV0dG9uIHRpcC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbbGFiZWw9J2knXSBUZXh0IGxhYmVsIHRvIHVzZSBmb3IgdGhlXG4gKiBjb2xsYXBzZWQgYXR0cmlidXRpb25zIGJ1dHRvbi5cbiAqIEluc3RlYWQgb2YgdGV4dCwgYWxzbyBhbiBlbGVtZW50IChlLmcuIGEgYHNwYW5gIGVsZW1lbnQpIGNhbiBiZSB1c2VkLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtleHBhbmRDbGFzc05hbWU9Y2xhc3NOYW1lICsgJy1leHBhbmQnXSBDU1MgY2xhc3MgbmFtZSBmb3IgdGhlXG4gKiBjb2xsYXBzZWQgYXR0cmlidXRpb25zIGJ1dHRvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfEhUTUxFbGVtZW50fSBbY29sbGFwc2VMYWJlbD0nwrsnXSBUZXh0IGxhYmVsIHRvIHVzZVxuICogZm9yIHRoZSBleHBhbmRlZCBhdHRyaWJ1dGlvbnMgYnV0dG9uLlxuICogSW5zdGVhZCBvZiB0ZXh0LCBhbHNvIGFuIGVsZW1lbnQgKGUuZy4gYSBgc3BhbmAgZWxlbWVudCkgY2FuIGJlIHVzZWQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NvbGxhcHNlQ2xhc3NOYW1lPWNsYXNzTmFtZSArICctY29sbGFwc2UnXSBDU1MgY2xhc3MgbmFtZSBmb3IgdGhlXG4gKiBleHBhbmRlZCBhdHRyaWJ1dGlvbnMgYnV0dG9uLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbihpbXBvcnQoXCIuLi9NYXBFdmVudC5qc1wiKS5kZWZhdWx0KTp2b2lkfSBbcmVuZGVyXSBGdW5jdGlvbiBjYWxsZWQgd2hlblxuICogdGhlIGNvbnRyb2wgc2hvdWxkIGJlIHJlLXJlbmRlcmVkLiBUaGlzIGlzIGNhbGxlZCBpbiBhIGByZXF1ZXN0QW5pbWF0aW9uRnJhbWVgXG4gKiBjYWxsYmFjay5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIENvbnRyb2wgdG8gc2hvdyBhbGwgdGhlIGF0dHJpYnV0aW9ucyBhc3NvY2lhdGVkIHdpdGggdGhlIGxheWVyIHNvdXJjZXNcbiAqIGluIHRoZSBtYXAuIFRoaXMgY29udHJvbCBpcyBvbmUgb2YgdGhlIGRlZmF1bHQgY29udHJvbHMgaW5jbHVkZWQgaW4gbWFwcy5cbiAqIEJ5IGRlZmF1bHQgaXQgd2lsbCBzaG93IGluIHRoZSBib3R0b20gcmlnaHQgcG9ydGlvbiBvZiB0aGUgbWFwLCBidXQgdGhpcyBjYW5cbiAqIGJlIGNoYW5nZWQgYnkgdXNpbmcgYSBjc3Mgc2VsZWN0b3IgZm9yIGAub2wtYXR0cmlidXRpb25gLlxuICpcbiAqIEBhcGlcbiAqL1xuXG52YXIgQXR0cmlidXRpb24gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQXR0cmlidXRpb24sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBBdHRyaWJ1dGlvbiBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIEF0dHJpYnV0aW9uKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgZWxlbWVudDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JyksXG4gICAgICByZW5kZXI6IG9wdGlvbnMucmVuZGVyLFxuICAgICAgdGFyZ2V0OiBvcHRpb25zLnRhcmdldFxuICAgIH0pIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy51bEVsZW1lbnRfID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndWwnKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29sbGFwc2VkXyA9IG9wdGlvbnMuY29sbGFwc2VkICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNvbGxhcHNlZCA6IHRydWU7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLnVzZXJDb2xsYXBzZWRfID0gX3RoaXMuY29sbGFwc2VkXztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMub3ZlcnJpZGVDb2xsYXBzaWJsZV8gPSBvcHRpb25zLmNvbGxhcHNpYmxlICE9PSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbGxhcHNpYmxlXyA9IG9wdGlvbnMuY29sbGFwc2libGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY29sbGFwc2libGUgOiB0cnVlO1xuXG4gICAgaWYgKCFfdGhpcy5jb2xsYXBzaWJsZV8pIHtcbiAgICAgIF90aGlzLmNvbGxhcHNlZF8gPSBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgY2xhc3NOYW1lID0gb3B0aW9ucy5jbGFzc05hbWUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xhc3NOYW1lIDogJ29sLWF0dHJpYnV0aW9uJztcbiAgICB2YXIgdGlwTGFiZWwgPSBvcHRpb25zLnRpcExhYmVsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnRpcExhYmVsIDogJ0F0dHJpYnV0aW9ucyc7XG4gICAgdmFyIGV4cGFuZENsYXNzTmFtZSA9IG9wdGlvbnMuZXhwYW5kQ2xhc3NOYW1lICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmV4cGFuZENsYXNzTmFtZSA6IGNsYXNzTmFtZSArICctZXhwYW5kJztcbiAgICB2YXIgY29sbGFwc2VMYWJlbCA9IG9wdGlvbnMuY29sbGFwc2VMYWJlbCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jb2xsYXBzZUxhYmVsIDogXCJcXHhCQlwiO1xuICAgIHZhciBjb2xsYXBzZUNsYXNzTmFtZSA9IG9wdGlvbnMuY29sbGFwc2VDbGFzc05hbWUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY29sbGFwc2VDbGFzc05hbWUgOiBjbGFzc05hbWUgKyAnLWNvbGxwYXNlJztcblxuICAgIGlmICh0eXBlb2YgY29sbGFwc2VMYWJlbCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8qKlxuICAgICAgICogQHByaXZhdGVcbiAgICAgICAqIEB0eXBlIHtIVE1MRWxlbWVudH1cbiAgICAgICAqL1xuICAgICAgX3RoaXMuY29sbGFwc2VMYWJlbF8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBfdGhpcy5jb2xsYXBzZUxhYmVsXy50ZXh0Q29udGVudCA9IGNvbGxhcHNlTGFiZWw7XG4gICAgICBfdGhpcy5jb2xsYXBzZUxhYmVsXy5jbGFzc05hbWUgPSBjb2xsYXBzZUNsYXNzTmFtZTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3RoaXMuY29sbGFwc2VMYWJlbF8gPSBjb2xsYXBzZUxhYmVsO1xuICAgIH1cblxuICAgIHZhciBsYWJlbCA9IG9wdGlvbnMubGFiZWwgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubGFiZWwgOiAnaSc7XG5cbiAgICBpZiAodHlwZW9mIGxhYmVsID09PSAnc3RyaW5nJykge1xuICAgICAgLyoqXG4gICAgICAgKiBAcHJpdmF0ZVxuICAgICAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgICAgICovXG4gICAgICBfdGhpcy5sYWJlbF8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBfdGhpcy5sYWJlbF8udGV4dENvbnRlbnQgPSBsYWJlbDtcbiAgICAgIF90aGlzLmxhYmVsXy5jbGFzc05hbWUgPSBleHBhbmRDbGFzc05hbWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIF90aGlzLmxhYmVsXyA9IGxhYmVsO1xuICAgIH1cblxuICAgIHZhciBhY3RpdmVMYWJlbCA9IF90aGlzLmNvbGxhcHNpYmxlXyAmJiAhX3RoaXMuY29sbGFwc2VkXyA/IF90aGlzLmNvbGxhcHNlTGFiZWxfIDogX3RoaXMubGFiZWxfO1xuICAgIHZhciBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICBidXR0b24uc2V0QXR0cmlidXRlKCd0eXBlJywgJ2J1dHRvbicpO1xuICAgIGJ1dHRvbi50aXRsZSA9IHRpcExhYmVsO1xuICAgIGJ1dHRvbi5hcHBlbmRDaGlsZChhY3RpdmVMYWJlbCk7XG4gICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNMSUNLLCBfdGhpcy5oYW5kbGVDbGlja18uYmluZChfdGhpcyksIGZhbHNlKTtcbiAgICB2YXIgY3NzQ2xhc3NlcyA9IGNsYXNzTmFtZSArICcgJyArIENMQVNTX1VOU0VMRUNUQUJMRSArICcgJyArIENMQVNTX0NPTlRST0wgKyAoX3RoaXMuY29sbGFwc2VkXyAmJiBfdGhpcy5jb2xsYXBzaWJsZV8gPyAnICcgKyBDTEFTU19DT0xMQVBTRUQgOiAnJykgKyAoX3RoaXMuY29sbGFwc2libGVfID8gJycgOiAnIG9sLXVuY29sbGFwc2libGUnKTtcbiAgICB2YXIgZWxlbWVudCA9IF90aGlzLmVsZW1lbnQ7XG4gICAgZWxlbWVudC5jbGFzc05hbWUgPSBjc3NDbGFzc2VzO1xuICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoX3RoaXMudWxFbGVtZW50Xyk7XG4gICAgZWxlbWVudC5hcHBlbmRDaGlsZChidXR0b24pO1xuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBjdXJyZW50bHkgcmVuZGVyZWQgcmVzb2x1dGlvbnMuXG4gICAgICogQHR5cGUge0FycmF5PHN0cmluZz59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkQXR0cmlidXRpb25zXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZFZpc2libGVfID0gdHJ1ZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIENvbGxlY3QgYSBsaXN0IG9mIHZpc2libGUgYXR0cmlidXRpb25zIGFuZCBzZXQgdGhlIGNvbGxhcHNpYmxlIHN0YXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcmV0dXJuIHtBcnJheTxzdHJpbmc+fSBBdHRyaWJ1dGlvbnMuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQXR0cmlidXRpb24ucHJvdG90eXBlLmNvbGxlY3RTb3VyY2VBdHRyaWJ1dGlvbnNfID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUpIHtcbiAgICAvKipcbiAgICAgKiBVc2VkIHRvIGRldGVybWluZSBpZiBhbiBhdHRyaWJ1dGlvbiBhbHJlYWR5IGV4aXN0cy5cbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGJvb2xlYW4+fVxuICAgICAqL1xuICAgIHZhciBsb29rdXAgPSB7fTtcbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgdmlzaWJsZSBhdHRyaWJ1dGlvbnMuXG4gICAgICogQHR5cGUge0FycmF5PHN0cmluZz59XG4gICAgICovXG5cbiAgICB2YXIgdmlzaWJsZUF0dHJpYnV0aW9ucyA9IFtdO1xuICAgIHZhciBjb2xsYXBzaWJsZSA9IHRydWU7XG4gICAgdmFyIGxheWVyU3RhdGVzQXJyYXkgPSBmcmFtZVN0YXRlLmxheWVyU3RhdGVzQXJyYXk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBsYXllclN0YXRlc0FycmF5Lmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBsYXllclN0YXRlID0gbGF5ZXJTdGF0ZXNBcnJheVtpXTtcblxuICAgICAgaWYgKCFpblZpZXcobGF5ZXJTdGF0ZSwgZnJhbWVTdGF0ZS52aWV3U3RhdGUpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc291cmNlID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGxheWVyU3RhdGUubGF5ZXIuZ2V0U291cmNlKCk7XG5cbiAgICAgIGlmICghc291cmNlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgYXR0cmlidXRpb25HZXR0ZXIgPSBzb3VyY2UuZ2V0QXR0cmlidXRpb25zKCk7XG5cbiAgICAgIGlmICghYXR0cmlidXRpb25HZXR0ZXIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBhdHRyaWJ1dGlvbnMgPSBhdHRyaWJ1dGlvbkdldHRlcihmcmFtZVN0YXRlKTtcblxuICAgICAgaWYgKCFhdHRyaWJ1dGlvbnMpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbGxhcHNpYmxlID0gY29sbGFwc2libGUgJiYgc291cmNlLmdldEF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlKCkgIT09IGZhbHNlO1xuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShhdHRyaWJ1dGlvbnMpKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwLCBqaiA9IGF0dHJpYnV0aW9ucy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgICAgICAgaWYgKCEoYXR0cmlidXRpb25zW2pdIGluIGxvb2t1cCkpIHtcbiAgICAgICAgICAgIHZpc2libGVBdHRyaWJ1dGlvbnMucHVzaChhdHRyaWJ1dGlvbnNbal0pO1xuICAgICAgICAgICAgbG9va3VwW2F0dHJpYnV0aW9uc1tqXV0gPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCEoYXR0cmlidXRpb25zIGluIGxvb2t1cCkpIHtcbiAgICAgICAgICB2aXNpYmxlQXR0cmlidXRpb25zLnB1c2goYXR0cmlidXRpb25zKTtcbiAgICAgICAgICBsb29rdXBbYXR0cmlidXRpb25zXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMub3ZlcnJpZGVDb2xsYXBzaWJsZV8pIHtcbiAgICAgIHRoaXMuc2V0Q29sbGFwc2libGUoY29sbGFwc2libGUpO1xuICAgIH1cblxuICAgIHJldHVybiB2aXNpYmxlQXR0cmlidXRpb25zO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHs/aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqL1xuXG5cbiAgQXR0cmlidXRpb24ucHJvdG90eXBlLnVwZGF0ZUVsZW1lbnRfID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUpIHtcbiAgICBpZiAoIWZyYW1lU3RhdGUpIHtcbiAgICAgIGlmICh0aGlzLnJlbmRlcmVkVmlzaWJsZV8pIHtcbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHRoaXMucmVuZGVyZWRWaXNpYmxlXyA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGF0dHJpYnV0aW9ucyA9IHRoaXMuY29sbGVjdFNvdXJjZUF0dHJpYnV0aW9uc18oZnJhbWVTdGF0ZSk7XG4gICAgdmFyIHZpc2libGUgPSBhdHRyaWJ1dGlvbnMubGVuZ3RoID4gMDtcblxuICAgIGlmICh0aGlzLnJlbmRlcmVkVmlzaWJsZV8gIT0gdmlzaWJsZSkge1xuICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSB2aXNpYmxlID8gJycgOiAnbm9uZSc7XG4gICAgICB0aGlzLnJlbmRlcmVkVmlzaWJsZV8gPSB2aXNpYmxlO1xuICAgIH1cblxuICAgIGlmIChlcXVhbHMoYXR0cmlidXRpb25zLCB0aGlzLnJlbmRlcmVkQXR0cmlidXRpb25zXykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZW1vdmVDaGlsZHJlbih0aGlzLnVsRWxlbWVudF8pOyAvLyBhcHBlbmQgdGhlIGF0dHJpYnV0aW9uc1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gYXR0cmlidXRpb25zLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcbiAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gYXR0cmlidXRpb25zW2ldO1xuICAgICAgdGhpcy51bEVsZW1lbnRfLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyZWRBdHRyaWJ1dGlvbnNfID0gYXR0cmlidXRpb25zO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBldmVudCBUaGUgZXZlbnQgdG8gaGFuZGxlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQXR0cmlidXRpb24ucHJvdG90eXBlLmhhbmRsZUNsaWNrXyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5oYW5kbGVUb2dnbGVfKCk7XG4gICAgdGhpcy51c2VyQ29sbGFwc2VkXyA9IHRoaXMuY29sbGFwc2VkXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQXR0cmlidXRpb24ucHJvdG90eXBlLmhhbmRsZVRvZ2dsZV8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5lbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoQ0xBU1NfQ09MTEFQU0VEKTtcblxuICAgIGlmICh0aGlzLmNvbGxhcHNlZF8pIHtcbiAgICAgIHJlcGxhY2VOb2RlKHRoaXMuY29sbGFwc2VMYWJlbF8sIHRoaXMubGFiZWxfKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVwbGFjZU5vZGUodGhpcy5sYWJlbF8sIHRoaXMuY29sbGFwc2VMYWJlbF8pO1xuICAgIH1cblxuICAgIHRoaXMuY29sbGFwc2VkXyA9ICF0aGlzLmNvbGxhcHNlZF87XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gYHRydWVgIGlmIHRoZSBhdHRyaWJ1dGlvbiBpcyBjb2xsYXBzaWJsZSwgYGZhbHNlYCBvdGhlcndpc2UuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIHdpZGdldCBpcyBjb2xsYXBzaWJsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEF0dHJpYnV0aW9uLnByb3RvdHlwZS5nZXRDb2xsYXBzaWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jb2xsYXBzaWJsZV87XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgd2hldGhlciB0aGUgYXR0cmlidXRpb24gc2hvdWxkIGJlIGNvbGxhcHNpYmxlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGNvbGxhcHNpYmxlIFRydWUgaWYgdGhlIHdpZGdldCBpcyBjb2xsYXBzaWJsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEF0dHJpYnV0aW9uLnByb3RvdHlwZS5zZXRDb2xsYXBzaWJsZSA9IGZ1bmN0aW9uIChjb2xsYXBzaWJsZSkge1xuICAgIGlmICh0aGlzLmNvbGxhcHNpYmxlXyA9PT0gY29sbGFwc2libGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmNvbGxhcHNpYmxlXyA9IGNvbGxhcHNpYmxlO1xuICAgIHRoaXMuZWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKCdvbC11bmNvbGxhcHNpYmxlJyk7XG5cbiAgICBpZiAodGhpcy51c2VyQ29sbGFwc2VkXykge1xuICAgICAgdGhpcy5oYW5kbGVUb2dnbGVfKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQ29sbGFwc2Ugb3IgZXhwYW5kIHRoZSBhdHRyaWJ1dGlvbiBhY2NvcmRpbmcgdG8gdGhlIHBhc3NlZCBwYXJhbWV0ZXIuIFdpbGxcbiAgICogbm90IGRvIGFueXRoaW5nIGlmIHRoZSBhdHRyaWJ1dGlvbiBpc24ndCBjb2xsYXBzaWJsZSBvciBpZiB0aGUgY3VycmVudFxuICAgKiBjb2xsYXBzZWQgc3RhdGUgaXMgYWxyZWFkeSB0aGUgb25lIHJlcXVlc3RlZC5cbiAgICogQHBhcmFtIHtib29sZWFufSBjb2xsYXBzZWQgVHJ1ZSBpZiB0aGUgd2lkZ2V0IGlzIGNvbGxhcHNlZC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEF0dHJpYnV0aW9uLnByb3RvdHlwZS5zZXRDb2xsYXBzZWQgPSBmdW5jdGlvbiAoY29sbGFwc2VkKSB7XG4gICAgdGhpcy51c2VyQ29sbGFwc2VkXyA9IGNvbGxhcHNlZDtcblxuICAgIGlmICghdGhpcy5jb2xsYXBzaWJsZV8gfHwgdGhpcy5jb2xsYXBzZWRfID09PSBjb2xsYXBzZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmhhbmRsZVRvZ2dsZV8oKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiBgdHJ1ZWAgd2hlbiB0aGUgYXR0cmlidXRpb24gaXMgY3VycmVudGx5IGNvbGxhcHNlZCBvciBgZmFsc2VgXG4gICAqIG90aGVyd2lzZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgd2lkZ2V0IGlzIGNvbGxhcHNlZC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEF0dHJpYnV0aW9uLnByb3RvdHlwZS5nZXRDb2xsYXBzZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29sbGFwc2VkXztcbiAgfTtcbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgYXR0cmlidXRpb24gZWxlbWVudC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBFdmVudCBNYXAgZXZlbnQuXG4gICAqIEBvdmVycmlkZVxuICAgKi9cblxuXG4gIEF0dHJpYnV0aW9uLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAobWFwRXZlbnQpIHtcbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnRfKG1hcEV2ZW50LmZyYW1lU3RhdGUpO1xuICB9O1xuXG4gIHJldHVybiBBdHRyaWJ1dGlvbjtcbn0oQ29udHJvbCk7XG5cbmV4cG9ydCBkZWZhdWx0IEF0dHJpYnV0aW9uOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvY29udHJvbC9Sb3RhdGVcbiAqL1xuXG5cbmltcG9ydCBDb250cm9sIGZyb20gJy4vQ29udHJvbC5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IHsgQ0xBU1NfQ09OVFJPTCwgQ0xBU1NfSElEREVOLCBDTEFTU19VTlNFTEVDVEFCTEUgfSBmcm9tICcuLi9jc3MuanMnO1xuaW1wb3J0IHsgZWFzZU91dCB9IGZyb20gJy4uL2Vhc2luZy5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbY2xhc3NOYW1lPSdvbC1yb3RhdGUnXSBDU1MgY2xhc3MgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfEhUTUxFbGVtZW50fSBbbGFiZWw9J+KHpyddIFRleHQgbGFiZWwgdG8gdXNlIGZvciB0aGUgcm90YXRlIGJ1dHRvbi5cbiAqIEluc3RlYWQgb2YgdGV4dCwgYWxzbyBhbiBlbGVtZW50IChlLmcuIGEgYHNwYW5gIGVsZW1lbnQpIGNhbiBiZSB1c2VkLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFt0aXBMYWJlbD0nUmVzZXQgcm90YXRpb24nXSBUZXh0IGxhYmVsIHRvIHVzZSBmb3IgdGhlIHJvdGF0ZSB0aXAuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NvbXBhc3NDbGFzc05hbWU9J29sLWNvbXBhc3MnXSBDU1MgY2xhc3MgbmFtZSBmb3IgdGhlIGNvbXBhc3MuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2R1cmF0aW9uPTI1MF0gQW5pbWF0aW9uIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2F1dG9IaWRlPXRydWVdIEhpZGUgdGhlIGNvbnRyb2wgd2hlbiByb3RhdGlvbiBpcyAwLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbihpbXBvcnQoXCIuLi9NYXBFdmVudC5qc1wiKS5kZWZhdWx0KTp2b2lkfSBbcmVuZGVyXSBGdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgY29udHJvbCBzaG91bGRcbiAqIGJlIHJlLXJlbmRlcmVkLiBUaGlzIGlzIGNhbGxlZCBpbiBhIGByZXF1ZXN0QW5pbWF0aW9uRnJhbWVgIGNhbGxiYWNrLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbigpOnZvaWR9IFtyZXNldE5vcnRoXSBGdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgY29udHJvbCBpcyBjbGlja2VkLlxuICogVGhpcyB3aWxsIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGByZXNldE5vcnRoYC5cbiAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR8c3RyaW5nfSBbdGFyZ2V0XSBTcGVjaWZ5IGEgdGFyZ2V0IGlmIHlvdSB3YW50IHRoZSBjb250cm9sIHRvIGJlXG4gKiByZW5kZXJlZCBvdXRzaWRlIG9mIHRoZSBtYXAncyB2aWV3cG9ydC5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEEgYnV0dG9uIGNvbnRyb2wgdG8gcmVzZXQgcm90YXRpb24gdG8gMC5cbiAqIFRvIHN0eWxlIHRoaXMgY29udHJvbCB1c2UgY3NzIHNlbGVjdG9yIGAub2wtcm90YXRlYC4gQSBgLm9sLWhpZGRlbmAgY3NzXG4gKiBzZWxlY3RvciBpcyBhZGRlZCB0byB0aGUgYnV0dG9uIHdoZW4gdGhlIHJvdGF0aW9uIGlzIDAuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBSb3RhdGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoUm90YXRlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgUm90YXRlIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gUm90YXRlKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgZWxlbWVudDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JyksXG4gICAgICByZW5kZXI6IG9wdGlvbnMucmVuZGVyLFxuICAgICAgdGFyZ2V0OiBvcHRpb25zLnRhcmdldFxuICAgIH0pIHx8IHRoaXM7XG4gICAgdmFyIGNsYXNzTmFtZSA9IG9wdGlvbnMuY2xhc3NOYW1lICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsYXNzTmFtZSA6ICdvbC1yb3RhdGUnO1xuICAgIHZhciBsYWJlbCA9IG9wdGlvbnMubGFiZWwgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubGFiZWwgOiBcIlxcdTIxRTdcIjtcbiAgICB2YXIgY29tcGFzc0NsYXNzTmFtZSA9IG9wdGlvbnMuY29tcGFzc0NsYXNzTmFtZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jb21wYXNzQ2xhc3NOYW1lIDogJ29sLWNvbXBhc3MnO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtIVE1MRWxlbWVudH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMubGFiZWxfID0gbnVsbDtcblxuICAgIGlmICh0eXBlb2YgbGFiZWwgPT09ICdzdHJpbmcnKSB7XG4gICAgICBfdGhpcy5sYWJlbF8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBfdGhpcy5sYWJlbF8uY2xhc3NOYW1lID0gY29tcGFzc0NsYXNzTmFtZTtcbiAgICAgIF90aGlzLmxhYmVsXy50ZXh0Q29udGVudCA9IGxhYmVsO1xuICAgIH0gZWxzZSB7XG4gICAgICBfdGhpcy5sYWJlbF8gPSBsYWJlbDtcblxuICAgICAgX3RoaXMubGFiZWxfLmNsYXNzTGlzdC5hZGQoY29tcGFzc0NsYXNzTmFtZSk7XG4gICAgfVxuXG4gICAgdmFyIHRpcExhYmVsID0gb3B0aW9ucy50aXBMYWJlbCA/IG9wdGlvbnMudGlwTGFiZWwgOiAnUmVzZXQgcm90YXRpb24nO1xuICAgIHZhciBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICBidXR0b24uY2xhc3NOYW1lID0gY2xhc3NOYW1lICsgJy1yZXNldCc7XG4gICAgYnV0dG9uLnNldEF0dHJpYnV0ZSgndHlwZScsICdidXR0b24nKTtcbiAgICBidXR0b24udGl0bGUgPSB0aXBMYWJlbDtcbiAgICBidXR0b24uYXBwZW5kQ2hpbGQoX3RoaXMubGFiZWxfKTtcbiAgICBidXR0b24uYWRkRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuQ0xJQ0ssIF90aGlzLmhhbmRsZUNsaWNrXy5iaW5kKF90aGlzKSwgZmFsc2UpO1xuICAgIHZhciBjc3NDbGFzc2VzID0gY2xhc3NOYW1lICsgJyAnICsgQ0xBU1NfVU5TRUxFQ1RBQkxFICsgJyAnICsgQ0xBU1NfQ09OVFJPTDtcbiAgICB2YXIgZWxlbWVudCA9IF90aGlzLmVsZW1lbnQ7XG4gICAgZWxlbWVudC5jbGFzc05hbWUgPSBjc3NDbGFzc2VzO1xuICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoYnV0dG9uKTtcbiAgICBfdGhpcy5jYWxsUmVzZXROb3J0aF8gPSBvcHRpb25zLnJlc2V0Tm9ydGggPyBvcHRpb25zLnJlc2V0Tm9ydGggOiB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMuZHVyYXRpb25fID0gb3B0aW9ucy5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kdXJhdGlvbiA6IDI1MDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMuYXV0b0hpZGVfID0gb3B0aW9ucy5hdXRvSGlkZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5hdXRvSGlkZSA6IHRydWU7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJvdGF0aW9uXyA9IHVuZGVmaW5lZDtcblxuICAgIGlmIChfdGhpcy5hdXRvSGlkZV8pIHtcbiAgICAgIF90aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19ISURERU4pO1xuICAgIH1cblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBldmVudCBUaGUgZXZlbnQgdG8gaGFuZGxlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgUm90YXRlLnByb3RvdHlwZS5oYW5kbGVDbGlja18gPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgaWYgKHRoaXMuY2FsbFJlc2V0Tm9ydGhfICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuY2FsbFJlc2V0Tm9ydGhfKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVzZXROb3J0aF8oKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFJvdGF0ZS5wcm90b3R5cGUucmVzZXROb3J0aF8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG1hcCA9IHRoaXMuZ2V0TWFwKCk7XG4gICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuXG4gICAgaWYgKCF2aWV3KSB7XG4gICAgICAvLyB0aGUgbWFwIGRvZXMgbm90IGhhdmUgYSB2aWV3LCBzbyB3ZSBjYW4ndCBhY3RcbiAgICAgIC8vIHVwb24gaXRcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcm90YXRpb24gPSB2aWV3LmdldFJvdGF0aW9uKCk7XG5cbiAgICBpZiAocm90YXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHRoaXMuZHVyYXRpb25fID4gMCAmJiByb3RhdGlvbiAlICgyICogTWF0aC5QSSkgIT09IDApIHtcbiAgICAgICAgdmlldy5hbmltYXRlKHtcbiAgICAgICAgICByb3RhdGlvbjogMCxcbiAgICAgICAgICBkdXJhdGlvbjogdGhpcy5kdXJhdGlvbl8sXG4gICAgICAgICAgZWFzaW5nOiBlYXNlT3V0XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlldy5zZXRSb3RhdGlvbigwKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIHJvdGF0ZSBjb250cm9sIGVsZW1lbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwRXZlbnQgTWFwIGV2ZW50LlxuICAgKiBAb3ZlcnJpZGVcbiAgICovXG5cblxuICBSb3RhdGUucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIChtYXBFdmVudCkge1xuICAgIHZhciBmcmFtZVN0YXRlID0gbWFwRXZlbnQuZnJhbWVTdGF0ZTtcblxuICAgIGlmICghZnJhbWVTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciByb3RhdGlvbiA9IGZyYW1lU3RhdGUudmlld1N0YXRlLnJvdGF0aW9uO1xuXG4gICAgaWYgKHJvdGF0aW9uICE9IHRoaXMucm90YXRpb25fKSB7XG4gICAgICB2YXIgdHJhbnNmb3JtID0gJ3JvdGF0ZSgnICsgcm90YXRpb24gKyAncmFkKSc7XG5cbiAgICAgIGlmICh0aGlzLmF1dG9IaWRlXykge1xuICAgICAgICB2YXIgY29udGFpbnMgPSB0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX0hJRERFTik7XG5cbiAgICAgICAgaWYgKCFjb250YWlucyAmJiByb3RhdGlvbiA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX0hJRERFTik7XG4gICAgICAgIH0gZWxzZSBpZiAoY29udGFpbnMgJiYgcm90YXRpb24gIT09IDApIHtcbiAgICAgICAgICB0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19ISURERU4pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMubGFiZWxfLnN0eWxlLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICB9XG5cbiAgICB0aGlzLnJvdGF0aW9uXyA9IHJvdGF0aW9uO1xuICB9O1xuXG4gIHJldHVybiBSb3RhdGU7XG59KENvbnRyb2wpO1xuXG5leHBvcnQgZGVmYXVsdCBSb3RhdGU7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9jb250cm9sL1pvb21cbiAqL1xuXG5cbmltcG9ydCBDb250cm9sIGZyb20gJy4vQ29udHJvbC5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IHsgQ0xBU1NfQ09OVFJPTCwgQ0xBU1NfVU5TRUxFQ1RBQkxFIH0gZnJvbSAnLi4vY3NzLmpzJztcbmltcG9ydCB7IGVhc2VPdXQgfSBmcm9tICcuLi9lYXNpbmcuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2R1cmF0aW9uPTI1MF0gQW5pbWF0aW9uIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbY2xhc3NOYW1lPSdvbC16b29tJ10gQ1NTIGNsYXNzIG5hbWUuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3pvb21JbkNsYXNzTmFtZT1jbGFzc05hbWUgKyAnLWluJ10gQ1NTIGNsYXNzIG5hbWUgZm9yIHRoZSB6b29tLWluIGJ1dHRvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbem9vbU91dENsYXNzTmFtZT1jbGFzc05hbWUgKyAnLW91dCddIENTUyBjbGFzcyBuYW1lIGZvciB0aGUgem9vbS1vdXQgYnV0dG9uLlxuICogQHByb3BlcnR5IHtzdHJpbmd8SFRNTEVsZW1lbnR9IFt6b29tSW5MYWJlbD0nKyddIFRleHQgbGFiZWwgdG8gdXNlIGZvciB0aGUgem9vbS1pblxuICogYnV0dG9uLiBJbnN0ZWFkIG9mIHRleHQsIGFsc28gYW4gZWxlbWVudCAoZS5nLiBhIGBzcGFuYCBlbGVtZW50KSBjYW4gYmUgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfEhUTUxFbGVtZW50fSBbem9vbU91dExhYmVsPSctJ10gVGV4dCBsYWJlbCB0byB1c2UgZm9yIHRoZSB6b29tLW91dCBidXR0b24uXG4gKiBJbnN0ZWFkIG9mIHRleHQsIGFsc28gYW4gZWxlbWVudCAoZS5nLiBhIGBzcGFuYCBlbGVtZW50KSBjYW4gYmUgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbem9vbUluVGlwTGFiZWw9J1pvb20gaW4nXSBUZXh0IGxhYmVsIHRvIHVzZSBmb3IgdGhlIGJ1dHRvbiB0aXAuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3pvb21PdXRUaXBMYWJlbD0nWm9vbSBvdXQnXSBUZXh0IGxhYmVsIHRvIHVzZSBmb3IgdGhlIGJ1dHRvbiB0aXAuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2RlbHRhPTFdIFRoZSB6b29tIGRlbHRhIGFwcGxpZWQgb24gZWFjaCBjbGljay5cbiAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR8c3RyaW5nfSBbdGFyZ2V0XSBTcGVjaWZ5IGEgdGFyZ2V0IGlmIHlvdSB3YW50IHRoZSBjb250cm9sIHRvIGJlXG4gKiByZW5kZXJlZCBvdXRzaWRlIG9mIHRoZSBtYXAncyB2aWV3cG9ydC5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEEgY29udHJvbCB3aXRoIDIgYnV0dG9ucywgb25lIGZvciB6b29tIGluIGFuZCBvbmUgZm9yIHpvb20gb3V0LlxuICogVGhpcyBjb250cm9sIGlzIG9uZSBvZiB0aGUgZGVmYXVsdCBjb250cm9scyBvZiBhIG1hcC4gVG8gc3R5bGUgdGhpcyBjb250cm9sXG4gKiB1c2UgY3NzIHNlbGVjdG9ycyBgLm9sLXpvb20taW5gIGFuZCBgLm9sLXpvb20tb3V0YC5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIFpvb20gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoWm9vbSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIFpvb20gb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBab29tKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgZWxlbWVudDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JyksXG4gICAgICB0YXJnZXQ6IG9wdGlvbnMudGFyZ2V0XG4gICAgfSkgfHwgdGhpcztcbiAgICB2YXIgY2xhc3NOYW1lID0gb3B0aW9ucy5jbGFzc05hbWUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xhc3NOYW1lIDogJ29sLXpvb20nO1xuICAgIHZhciBkZWx0YSA9IG9wdGlvbnMuZGVsdGEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZGVsdGEgOiAxO1xuICAgIHZhciB6b29tSW5DbGFzc05hbWUgPSBvcHRpb25zLnpvb21JbkNsYXNzTmFtZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy56b29tSW5DbGFzc05hbWUgOiBjbGFzc05hbWUgKyAnLWluJztcbiAgICB2YXIgem9vbU91dENsYXNzTmFtZSA9IG9wdGlvbnMuem9vbU91dENsYXNzTmFtZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy56b29tT3V0Q2xhc3NOYW1lIDogY2xhc3NOYW1lICsgJy1vdXQnO1xuICAgIHZhciB6b29tSW5MYWJlbCA9IG9wdGlvbnMuem9vbUluTGFiZWwgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuem9vbUluTGFiZWwgOiAnKyc7XG4gICAgdmFyIHpvb21PdXRMYWJlbCA9IG9wdGlvbnMuem9vbU91dExhYmVsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnpvb21PdXRMYWJlbCA6IFwiXFx1MjIxMlwiO1xuICAgIHZhciB6b29tSW5UaXBMYWJlbCA9IG9wdGlvbnMuem9vbUluVGlwTGFiZWwgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuem9vbUluVGlwTGFiZWwgOiAnWm9vbSBpbic7XG4gICAgdmFyIHpvb21PdXRUaXBMYWJlbCA9IG9wdGlvbnMuem9vbU91dFRpcExhYmVsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnpvb21PdXRUaXBMYWJlbCA6ICdab29tIG91dCc7XG4gICAgdmFyIGluRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgIGluRWxlbWVudC5jbGFzc05hbWUgPSB6b29tSW5DbGFzc05hbWU7XG4gICAgaW5FbGVtZW50LnNldEF0dHJpYnV0ZSgndHlwZScsICdidXR0b24nKTtcbiAgICBpbkVsZW1lbnQudGl0bGUgPSB6b29tSW5UaXBMYWJlbDtcbiAgICBpbkVsZW1lbnQuYXBwZW5kQ2hpbGQodHlwZW9mIHpvb21JbkxhYmVsID09PSAnc3RyaW5nJyA/IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHpvb21JbkxhYmVsKSA6IHpvb21JbkxhYmVsKTtcbiAgICBpbkVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuQ0xJQ0ssIF90aGlzLmhhbmRsZUNsaWNrXy5iaW5kKF90aGlzLCBkZWx0YSksIGZhbHNlKTtcbiAgICB2YXIgb3V0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgIG91dEVsZW1lbnQuY2xhc3NOYW1lID0gem9vbU91dENsYXNzTmFtZTtcbiAgICBvdXRFbGVtZW50LnNldEF0dHJpYnV0ZSgndHlwZScsICdidXR0b24nKTtcbiAgICBvdXRFbGVtZW50LnRpdGxlID0gem9vbU91dFRpcExhYmVsO1xuICAgIG91dEVsZW1lbnQuYXBwZW5kQ2hpbGQodHlwZW9mIHpvb21PdXRMYWJlbCA9PT0gJ3N0cmluZycgPyBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh6b29tT3V0TGFiZWwpIDogem9vbU91dExhYmVsKTtcbiAgICBvdXRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNMSUNLLCBfdGhpcy5oYW5kbGVDbGlja18uYmluZChfdGhpcywgLWRlbHRhKSwgZmFsc2UpO1xuICAgIHZhciBjc3NDbGFzc2VzID0gY2xhc3NOYW1lICsgJyAnICsgQ0xBU1NfVU5TRUxFQ1RBQkxFICsgJyAnICsgQ0xBU1NfQ09OVFJPTDtcbiAgICB2YXIgZWxlbWVudCA9IF90aGlzLmVsZW1lbnQ7XG4gICAgZWxlbWVudC5jbGFzc05hbWUgPSBjc3NDbGFzc2VzO1xuICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoaW5FbGVtZW50KTtcbiAgICBlbGVtZW50LmFwcGVuZENoaWxkKG91dEVsZW1lbnQpO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmR1cmF0aW9uXyA9IG9wdGlvbnMuZHVyYXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZHVyYXRpb24gOiAyNTA7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gZGVsdGEgWm9vbSBkZWx0YS5cbiAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBldmVudCBUaGUgZXZlbnQgdG8gaGFuZGxlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgWm9vbS5wcm90b3R5cGUuaGFuZGxlQ2xpY2tfID0gZnVuY3Rpb24gKGRlbHRhLCBldmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy56b29tQnlEZWx0YV8oZGVsdGEpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhIFpvb20gZGVsdGEuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgWm9vbS5wcm90b3R5cGUuem9vbUJ5RGVsdGFfID0gZnVuY3Rpb24gKGRlbHRhKSB7XG4gICAgdmFyIG1hcCA9IHRoaXMuZ2V0TWFwKCk7XG4gICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuXG4gICAgaWYgKCF2aWV3KSB7XG4gICAgICAvLyB0aGUgbWFwIGRvZXMgbm90IGhhdmUgYSB2aWV3LCBzbyB3ZSBjYW4ndCBhY3RcbiAgICAgIC8vIHVwb24gaXRcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY3VycmVudFpvb20gPSB2aWV3LmdldFpvb20oKTtcblxuICAgIGlmIChjdXJyZW50Wm9vbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YXIgbmV3Wm9vbSA9IHZpZXcuZ2V0Q29uc3RyYWluZWRab29tKGN1cnJlbnRab29tICsgZGVsdGEpO1xuXG4gICAgICBpZiAodGhpcy5kdXJhdGlvbl8gPiAwKSB7XG4gICAgICAgIGlmICh2aWV3LmdldEFuaW1hdGluZygpKSB7XG4gICAgICAgICAgdmlldy5jYW5jZWxBbmltYXRpb25zKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2aWV3LmFuaW1hdGUoe1xuICAgICAgICAgIHpvb206IG5ld1pvb20sXG4gICAgICAgICAgZHVyYXRpb246IHRoaXMuZHVyYXRpb25fLFxuICAgICAgICAgIGVhc2luZzogZWFzZU91dFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpZXcuc2V0Wm9vbShuZXdab29tKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIFpvb207XG59KENvbnRyb2wpO1xuXG5leHBvcnQgZGVmYXVsdCBab29tOyIsIi8qKlxuICogQG1vZHVsZSBvbC9jb250cm9sXG4gKi9cbmltcG9ydCBBdHRyaWJ1dGlvbiBmcm9tICcuL2NvbnRyb2wvQXR0cmlidXRpb24uanMnO1xuaW1wb3J0IENvbGxlY3Rpb24gZnJvbSAnLi9Db2xsZWN0aW9uLmpzJztcbmltcG9ydCBSb3RhdGUgZnJvbSAnLi9jb250cm9sL1JvdGF0ZS5qcyc7XG5pbXBvcnQgWm9vbSBmcm9tICcuL2NvbnRyb2wvWm9vbS5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIEF0dHJpYnV0aW9uIH0gZnJvbSAnLi9jb250cm9sL0F0dHJpYnV0aW9uLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgQ29udHJvbCB9IGZyb20gJy4vY29udHJvbC9Db250cm9sLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgRnVsbFNjcmVlbiB9IGZyb20gJy4vY29udHJvbC9GdWxsU2NyZWVuLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgTW91c2VQb3NpdGlvbiB9IGZyb20gJy4vY29udHJvbC9Nb3VzZVBvc2l0aW9uLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgT3ZlcnZpZXdNYXAgfSBmcm9tICcuL2NvbnRyb2wvT3ZlcnZpZXdNYXAuanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBSb3RhdGUgfSBmcm9tICcuL2NvbnRyb2wvUm90YXRlLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgU2NhbGVMaW5lIH0gZnJvbSAnLi9jb250cm9sL1NjYWxlTGluZS5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIFpvb20gfSBmcm9tICcuL2NvbnRyb2wvWm9vbS5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIFpvb21TbGlkZXIgfSBmcm9tICcuL2NvbnRyb2wvWm9vbVNsaWRlci5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIFpvb21Ub0V4dGVudCB9IGZyb20gJy4vY29udHJvbC9ab29tVG9FeHRlbnQuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBEZWZhdWx0c09wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2F0dHJpYnV0aW9uPXRydWVdIEluY2x1ZGVcbiAqIHtAbGluayBtb2R1bGU6b2wvY29udHJvbC9BdHRyaWJ1dGlvbn5BdHRyaWJ1dGlvbn0uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vY29udHJvbC9BdHRyaWJ1dGlvbi5qc1wiKS5PcHRpb25zfSBbYXR0cmlidXRpb25PcHRpb25zXVxuICogT3B0aW9ucyBmb3Ige0BsaW5rIG1vZHVsZTpvbC9jb250cm9sL0F0dHJpYnV0aW9ufkF0dHJpYnV0aW9ufS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3JvdGF0ZT10cnVlXSBJbmNsdWRlXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2NvbnRyb2wvUm90YXRlflJvdGF0ZX0uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vY29udHJvbC9Sb3RhdGUuanNcIikuT3B0aW9uc30gW3JvdGF0ZU9wdGlvbnNdIE9wdGlvbnNcbiAqIGZvciB7QGxpbmsgbW9kdWxlOm9sL2NvbnRyb2wvUm90YXRlflJvdGF0ZX0uXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt6b29tXSBJbmNsdWRlIHtAbGluayBtb2R1bGU6b2wvY29udHJvbC9ab29tflpvb219LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2NvbnRyb2wvWm9vbS5qc1wiKS5PcHRpb25zfSBbem9vbU9wdGlvbnNdIE9wdGlvbnMgZm9yXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2NvbnRyb2wvWm9vbX5ab29tfS5cbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIFNldCBvZiBjb250cm9scyBpbmNsdWRlZCBpbiBtYXBzIGJ5IGRlZmF1bHQuIFVubGVzcyBjb25maWd1cmVkIG90aGVyd2lzZSxcbiAqIHRoaXMgcmV0dXJucyBhIGNvbGxlY3Rpb24gY29udGFpbmluZyBhbiBpbnN0YW5jZSBvZiBlYWNoIG9mIHRoZSBmb2xsb3dpbmdcbiAqIGNvbnRyb2xzOlxuICogKiB7QGxpbmsgbW9kdWxlOm9sL2NvbnRyb2wvWm9vbX5ab29tfVxuICogKiB7QGxpbmsgbW9kdWxlOm9sL2NvbnRyb2wvUm90YXRlflJvdGF0ZX1cbiAqICoge0BsaW5rIG1vZHVsZTpvbC9jb250cm9sL0F0dHJpYnV0aW9ufkF0dHJpYnV0aW9ufVxuICpcbiAqIEBwYXJhbSB7RGVmYXVsdHNPcHRpb25zPX0gb3B0X29wdGlvbnNcbiAqIERlZmF1bHRzIG9wdGlvbnMuXG4gKiBAcmV0dXJuIHtDb2xsZWN0aW9uPGltcG9ydChcIi4vY29udHJvbC9Db250cm9sLmpzXCIpLmRlZmF1bHQ+fVxuICogQ29udHJvbHMuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRzKG9wdF9vcHRpb25zKSB7XG4gIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICB2YXIgY29udHJvbHMgPSBuZXcgQ29sbGVjdGlvbigpO1xuICB2YXIgem9vbUNvbnRyb2wgPSBvcHRpb25zLnpvb20gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuem9vbSA6IHRydWU7XG5cbiAgaWYgKHpvb21Db250cm9sKSB7XG4gICAgY29udHJvbHMucHVzaChuZXcgWm9vbShvcHRpb25zLnpvb21PcHRpb25zKSk7XG4gIH1cblxuICB2YXIgcm90YXRlQ29udHJvbCA9IG9wdGlvbnMucm90YXRlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnJvdGF0ZSA6IHRydWU7XG5cbiAgaWYgKHJvdGF0ZUNvbnRyb2wpIHtcbiAgICBjb250cm9scy5wdXNoKG5ldyBSb3RhdGUob3B0aW9ucy5yb3RhdGVPcHRpb25zKSk7XG4gIH1cblxuICB2YXIgYXR0cmlidXRpb25Db250cm9sID0gb3B0aW9ucy5hdHRyaWJ1dGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5hdHRyaWJ1dGlvbiA6IHRydWU7XG5cbiAgaWYgKGF0dHJpYnV0aW9uQ29udHJvbCkge1xuICAgIGNvbnRyb2xzLnB1c2gobmV3IEF0dHJpYnV0aW9uKG9wdGlvbnMuYXR0cmlidXRpb25PcHRpb25zKSk7XG4gIH1cblxuICByZXR1cm4gY29udHJvbHM7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2ludGVyYWN0aW9uL1Byb3BlcnR5XG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIEFDVElWRTogJ2FjdGl2ZSdcbn07IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9JbnRlcmFjdGlvblxuICovXG5cblxuaW1wb3J0IEJhc2VPYmplY3QgZnJvbSAnLi4vT2JqZWN0LmpzJztcbmltcG9ydCBJbnRlcmFjdGlvblByb3BlcnR5IGZyb20gJy4vUHJvcGVydHkuanMnO1xuaW1wb3J0IHsgZWFzZU91dCwgbGluZWFyIH0gZnJvbSAnLi4vZWFzaW5nLmpzJztcbi8qKlxuICogT2JqZWN0IGxpdGVyYWwgd2l0aCBjb25maWcgb3B0aW9ucyBmb3IgaW50ZXJhY3Rpb25zLlxuICogQHR5cGVkZWYge09iamVjdH0gSW50ZXJhY3Rpb25PcHRpb25zXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKGltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0KTpib29sZWFufSBoYW5kbGVFdmVudFxuICogTWV0aG9kIGNhbGxlZCBieSB0aGUgbWFwIHRvIG5vdGlmeSB0aGUgaW50ZXJhY3Rpb24gdGhhdCBhIGJyb3dzZXIgZXZlbnQgd2FzXG4gKiBkaXNwYXRjaGVkIHRvIHRoZSBtYXAuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIGEgZmFsc3kgdmFsdWUsIHByb3BhZ2F0aW9uIG9mXG4gKiB0aGUgZXZlbnQgdG8gb3RoZXIgaW50ZXJhY3Rpb25zIGluIHRoZSBtYXAncyBpbnRlcmFjdGlvbnMgY2hhaW4gd2lsbCBiZVxuICogcHJldmVudGVkICh0aGlzIGluY2x1ZGVzIGZ1bmN0aW9ucyB3aXRoIG5vIGV4cGxpY2l0IHJldHVybikuIFRoZSBpbnRlcmFjdGlvbnNcbiAqIGFyZSB0cmF2ZXJzZWQgaW4gcmV2ZXJzZSBvcmRlciBvZiB0aGUgaW50ZXJhY3Rpb25zIGNvbGxlY3Rpb24gb2YgdGhlIG1hcC5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3M7IG5vcm1hbGx5IG9ubHkgdXNlZCBmb3IgY3JlYXRpbmcgc3ViY2xhc3NlcyBhbmQgbm90XG4gKiBpbnN0YW50aWF0ZWQgaW4gYXBwcy5cbiAqIFVzZXIgYWN0aW9ucyB0aGF0IGNoYW5nZSB0aGUgc3RhdGUgb2YgdGhlIG1hcC4gU29tZSBhcmUgc2ltaWxhciB0byBjb250cm9scyxcbiAqIGJ1dCBhcmUgbm90IGFzc29jaWF0ZWQgd2l0aCBhIERPTSBlbGVtZW50LlxuICogRm9yIGV4YW1wbGUsIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vS2V5Ym9hcmRab29tfktleWJvYXJkWm9vbX0gaXNcbiAqIGZ1bmN0aW9uYWxseSB0aGUgc2FtZSBhcyB7QGxpbmsgbW9kdWxlOm9sL2NvbnRyb2wvWm9vbX5ab29tfSwgYnV0IHRyaWdnZXJlZFxuICogYnkgYSBrZXlib2FyZCBldmVudCBub3QgYSBidXR0b24gZWxlbWVudCBldmVudC5cbiAqIEFsdGhvdWdoIGludGVyYWN0aW9ucyBkbyBub3QgaGF2ZSBhIERPTSBlbGVtZW50LCBzb21lIG9mIHRoZW0gZG8gcmVuZGVyXG4gKiB2ZWN0b3JzIGFuZCBzbyBhcmUgdmlzaWJsZSBvbiB0aGUgc2NyZWVuLlxuICogQGFwaVxuICovXG5cbnZhciBJbnRlcmFjdGlvbiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhJbnRlcmFjdGlvbiwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7SW50ZXJhY3Rpb25PcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBJbnRlcmFjdGlvbihvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG5cbiAgICBpZiAob3B0X29wdGlvbnMgJiYgb3B0X29wdGlvbnMuaGFuZGxlRXZlbnQpIHtcbiAgICAgIF90aGlzLmhhbmRsZUV2ZW50ID0gb3B0X29wdGlvbnMuaGFuZGxlRXZlbnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5tYXBfID0gbnVsbDtcblxuICAgIF90aGlzLnNldEFjdGl2ZSh0cnVlKTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogUmV0dXJuIHdoZXRoZXIgdGhlIGludGVyYWN0aW9uIGlzIGN1cnJlbnRseSBhY3RpdmUuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgaW50ZXJhY3Rpb24gaXMgYWN0aXZlLCBgZmFsc2VgIG90aGVyd2lzZS5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5nZXRBY3RpdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgICAgIHRoaXMuZ2V0KEludGVyYWN0aW9uUHJvcGVydHkuQUNUSVZFKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1hcCBhc3NvY2lhdGVkIHdpdGggdGhpcyBpbnRlcmFjdGlvbi5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IE1hcC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5nZXRNYXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwXztcbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZXMgdGhlIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50IG1hcCBicm93c2VyIGV2ZW50fS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgZmFsc2VgIHRvIHN0b3AgZXZlbnQgcHJvcGFnYXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG4gIC8qKlxuICAgKiBBY3RpdmF0ZSBvciBkZWFjdGl2YXRlIHRoZSBpbnRlcmFjdGlvbi5cbiAgICogQHBhcmFtIHtib29sZWFufSBhY3RpdmUgQWN0aXZlLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnNldEFjdGl2ZSA9IGZ1bmN0aW9uIChhY3RpdmUpIHtcbiAgICB0aGlzLnNldChJbnRlcmFjdGlvblByb3BlcnR5LkFDVElWRSwgYWN0aXZlKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgaW50ZXJhY3Rpb24gZnJvbSBpdHMgY3VycmVudCBtYXAgYW5kIGF0dGFjaCBpdCB0byB0aGUgbmV3IG1hcC5cbiAgICogU3ViY2xhc3NlcyBtYXkgc2V0IHVwIGV2ZW50IGhhbmRsZXJzIHRvIGdldCBub3RpZmllZCBhYm91dCBjaGFuZ2VzIHRvXG4gICAqIHRoZSBtYXAgaGVyZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIE1hcC5cbiAgICovXG5cblxuICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuc2V0TWFwID0gZnVuY3Rpb24gKG1hcCkge1xuICAgIHRoaXMubWFwXyA9IG1hcDtcbiAgfTtcblxuICByZXR1cm4gSW50ZXJhY3Rpb247XG59KEJhc2VPYmplY3QpO1xuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL1ZpZXcuanNcIikuZGVmYXVsdH0gdmlldyBWaWV3LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGRlbHRhIERlbHRhLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZHVyYXRpb24gRHVyYXRpb24uXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gcGFuKHZpZXcsIGRlbHRhLCBvcHRfZHVyYXRpb24pIHtcbiAgdmFyIGN1cnJlbnRDZW50ZXIgPSB2aWV3LmdldENlbnRlckludGVybmFsKCk7XG5cbiAgaWYgKGN1cnJlbnRDZW50ZXIpIHtcbiAgICB2YXIgY2VudGVyID0gW2N1cnJlbnRDZW50ZXJbMF0gKyBkZWx0YVswXSwgY3VycmVudENlbnRlclsxXSArIGRlbHRhWzFdXTtcbiAgICB2aWV3LmFuaW1hdGVJbnRlcm5hbCh7XG4gICAgICBkdXJhdGlvbjogb3B0X2R1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRfZHVyYXRpb24gOiAyNTAsXG4gICAgICBlYXNpbmc6IGxpbmVhcixcbiAgICAgIGNlbnRlcjogdmlldy5nZXRDb25zdHJhaW5lZENlbnRlcihjZW50ZXIpXG4gICAgfSk7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9WaWV3LmpzXCIpLmRlZmF1bHR9IHZpZXcgVmlldy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YSBEZWx0YSBmcm9tIHByZXZpb3VzIHpvb20gbGV2ZWwuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9hbmNob3IgQW5jaG9yIGNvb3JkaW5hdGUgaW4gdGhlIHVzZXIgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2R1cmF0aW9uIER1cmF0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB6b29tQnlEZWx0YSh2aWV3LCBkZWx0YSwgb3B0X2FuY2hvciwgb3B0X2R1cmF0aW9uKSB7XG4gIHZhciBjdXJyZW50Wm9vbSA9IHZpZXcuZ2V0Wm9vbSgpO1xuXG4gIGlmIChjdXJyZW50Wm9vbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG5ld1pvb20gPSB2aWV3LmdldENvbnN0cmFpbmVkWm9vbShjdXJyZW50Wm9vbSArIGRlbHRhKTtcbiAgdmFyIG5ld1Jlc29sdXRpb24gPSB2aWV3LmdldFJlc29sdXRpb25Gb3Jab29tKG5ld1pvb20pO1xuXG4gIGlmICh2aWV3LmdldEFuaW1hdGluZygpKSB7XG4gICAgdmlldy5jYW5jZWxBbmltYXRpb25zKCk7XG4gIH1cblxuICB2aWV3LmFuaW1hdGUoe1xuICAgIHJlc29sdXRpb246IG5ld1Jlc29sdXRpb24sXG4gICAgYW5jaG9yOiBvcHRfYW5jaG9yLFxuICAgIGR1cmF0aW9uOiBvcHRfZHVyYXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdF9kdXJhdGlvbiA6IDI1MCxcbiAgICBlYXNpbmc6IGVhc2VPdXRcbiAgfSk7XG59XG5leHBvcnQgZGVmYXVsdCBJbnRlcmFjdGlvbjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2ludGVyYWN0aW9uL0RvdWJsZUNsaWNrWm9vbVxuICovXG5cblxuaW1wb3J0IEludGVyYWN0aW9uLCB7IHpvb21CeURlbHRhIH0gZnJvbSAnLi9JbnRlcmFjdGlvbi5qcyc7XG5pbXBvcnQgTWFwQnJvd3NlckV2ZW50VHlwZSBmcm9tICcuLi9NYXBCcm93c2VyRXZlbnRUeXBlLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj0yNTBdIEFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2RlbHRhPTFdIFRoZSB6b29tIGRlbHRhIGFwcGxpZWQgb24gZWFjaCBkb3VibGUgY2xpY2suXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBbGxvd3MgdGhlIHVzZXIgdG8gem9vbSBieSBkb3VibGUtY2xpY2tpbmcgb24gdGhlIG1hcC5cbiAqIEBhcGlcbiAqL1xuXG52YXIgRG91YmxlQ2xpY2tab29tID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKERvdWJsZUNsaWNrWm9vbSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gRG91YmxlQ2xpY2tab29tKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmRlbHRhXyA9IG9wdGlvbnMuZGVsdGEgPyBvcHRpb25zLmRlbHRhIDogMTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5kdXJhdGlvbl8gPSBvcHRpb25zLmR1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmR1cmF0aW9uIDogMjUwO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogSGFuZGxlcyB0aGUge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnQgbWFwIGJyb3dzZXIgZXZlbnR9IChpZiBpdCB3YXMgYVxuICAgKiBkb3VibGVjbGljaykgYW5kIGV2ZW50dWFsbHkgem9vbXMgdGhlIG1hcC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgZmFsc2VgIHRvIHN0b3AgZXZlbnQgcHJvcGFnYXRpb24uXG4gICAqL1xuXG5cbiAgRG91YmxlQ2xpY2tab29tLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICB2YXIgc3RvcEV2ZW50ID0gZmFsc2U7XG5cbiAgICBpZiAobWFwQnJvd3NlckV2ZW50LnR5cGUgPT0gTWFwQnJvd3NlckV2ZW50VHlwZS5EQkxDTElDSykge1xuICAgICAgdmFyIGJyb3dzZXJFdmVudCA9XG4gICAgICAvKiogQHR5cGUge01vdXNlRXZlbnR9ICovXG4gICAgICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgICAgdmFyIGFuY2hvciA9IG1hcEJyb3dzZXJFdmVudC5jb29yZGluYXRlO1xuICAgICAgdmFyIGRlbHRhID0gYnJvd3NlckV2ZW50LnNoaWZ0S2V5ID8gLXRoaXMuZGVsdGFfIDogdGhpcy5kZWx0YV87XG4gICAgICB2YXIgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG4gICAgICB6b29tQnlEZWx0YSh2aWV3LCBkZWx0YSwgYW5jaG9yLCB0aGlzLmR1cmF0aW9uXyk7XG4gICAgICBicm93c2VyRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHN0b3BFdmVudCA9IHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuICFzdG9wRXZlbnQ7XG4gIH07XG5cbiAgcmV0dXJuIERvdWJsZUNsaWNrWm9vbTtcbn0oSW50ZXJhY3Rpb24pO1xuXG5leHBvcnQgZGVmYXVsdCBEb3VibGVDbGlja1pvb207IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9Qb2ludGVyXG4gKi9cblxuXG5pbXBvcnQgSW50ZXJhY3Rpb24gZnJvbSAnLi9JbnRlcmFjdGlvbi5qcyc7XG5pbXBvcnQgTWFwQnJvd3NlckV2ZW50VHlwZSBmcm9tICcuLi9NYXBCcm93c2VyRXZlbnRUeXBlLmpzJztcbmltcG9ydCB7IGdldFZhbHVlcyB9IGZyb20gJy4uL29iai5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHQpOmJvb2xlYW59IFtoYW5kbGVEb3duRXZlbnRdXG4gKiBGdW5jdGlvbiBoYW5kbGluZyBcImRvd25cIiBldmVudHMuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIGB0cnVlYCB0aGVuIGEgZHJhZ1xuICogc2VxdWVuY2UgaXMgc3RhcnRlZC5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHQpOnZvaWR9IFtoYW5kbGVEcmFnRXZlbnRdXG4gKiBGdW5jdGlvbiBoYW5kbGluZyBcImRyYWdcIiBldmVudHMuIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG9uIFwibW92ZVwiIGV2ZW50c1xuICogZHVyaW5nIGEgZHJhZyBzZXF1ZW5jZS5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHQpOmJvb2xlYW59IFtoYW5kbGVFdmVudF1cbiAqIE1ldGhvZCBjYWxsZWQgYnkgdGhlIG1hcCB0byBub3RpZnkgdGhlIGludGVyYWN0aW9uIHRoYXQgYSBicm93c2VyIGV2ZW50IHdhc1xuICogZGlzcGF0Y2hlZCB0byB0aGUgbWFwLiBUaGUgZnVuY3Rpb24gbWF5IHJldHVybiBgZmFsc2VgIHRvIHByZXZlbnQgdGhlXG4gKiBwcm9wYWdhdGlvbiBvZiB0aGUgZXZlbnQgdG8gb3RoZXIgaW50ZXJhY3Rpb25zIGluIHRoZSBtYXAncyBpbnRlcmFjdGlvbnNcbiAqIGNoYWluLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbihpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdCk6dm9pZH0gW2hhbmRsZU1vdmVFdmVudF1cbiAqIEZ1bmN0aW9uIGhhbmRsaW5nIFwibW92ZVwiIGV2ZW50cy4gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgb24gXCJtb3ZlXCIgZXZlbnRzLlxuICogVGhpcyBmdW5jdGlvbnMgaXMgYWxzbyBjYWxsZWQgZHVyaW5nIGEgZHJhZyBzZXF1ZW5jZSwgc28gZHVyaW5nIGEgZHJhZ1xuICogc2VxdWVuY2UgYm90aCB0aGUgYGhhbmRsZURyYWdFdmVudGAgZnVuY3Rpb24gYW5kIHRoaXMgZnVuY3Rpb24gYXJlIGNhbGxlZC5cbiAqIElmIGBoYW5kbGVEb3duRXZlbnRgIGlzIGRlZmluZWQgYW5kIGl0IHJldHVybnMgdHJ1ZSB0aGlzIGZ1bmN0aW9uIHdpbGwgbm90XG4gKiBiZSBjYWxsZWQgZHVyaW5nIGEgZHJhZyBzZXF1ZW5jZS5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHQpOmJvb2xlYW59IFtoYW5kbGVVcEV2ZW50XVxuICogIEZ1bmN0aW9uIGhhbmRsaW5nIFwidXBcIiBldmVudHMuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIGBmYWxzZWAgdGhlbiB0aGVcbiAqIGN1cnJlbnQgZHJhZyBzZXF1ZW5jZSBpcyBzdG9wcGVkLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbihib29sZWFuKTpib29sZWFufSBbc3RvcERvd25dXG4gKiBTaG91bGQgdGhlIGRvd24gZXZlbnQgYmUgcHJvcGFnYXRlZCB0byBvdGhlciBpbnRlcmFjdGlvbnMsIG9yIHNob3VsZCBiZVxuICogc3RvcHBlZD9cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEJhc2UgY2xhc3MgdGhhdCBjYWxscyB1c2VyLWRlZmluZWQgZnVuY3Rpb25zIG9uIGBkb3duYCwgYG1vdmVgIGFuZCBgdXBgXG4gKiBldmVudHMuIFRoaXMgY2xhc3MgYWxzbyBtYW5hZ2VzIFwiZHJhZyBzZXF1ZW5jZXNcIi5cbiAqXG4gKiBXaGVuIHRoZSBgaGFuZGxlRG93bkV2ZW50YCB1c2VyIGZ1bmN0aW9uIHJldHVybnMgYHRydWVgIGEgZHJhZyBzZXF1ZW5jZSBpc1xuICogc3RhcnRlZC4gRHVyaW5nIGEgZHJhZyBzZXF1ZW5jZSB0aGUgYGhhbmRsZURyYWdFdmVudGAgdXNlciBmdW5jdGlvbiBpc1xuICogY2FsbGVkIG9uIGBtb3ZlYCBldmVudHMuIFRoZSBkcmFnIHNlcXVlbmNlIGVuZHMgd2hlbiB0aGUgYGhhbmRsZVVwRXZlbnRgXG4gKiB1c2VyIGZ1bmN0aW9uIGlzIGNhbGxlZCBhbmQgcmV0dXJucyBgZmFsc2VgLlxuICogQGFwaVxuICovXG5cbnZhciBQb2ludGVySW50ZXJhY3Rpb24gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoUG9pbnRlckludGVyYWN0aW9uLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBQb2ludGVySW50ZXJhY3Rpb24ob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyA/IG9wdF9vcHRpb25zIDoge307XG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLFxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9JbnRlcmFjdGlvbi5qc1wiKS5JbnRlcmFjdGlvbk9wdGlvbnN9ICovXG4gICAgb3B0aW9ucykgfHwgdGhpcztcblxuICAgIGlmIChvcHRpb25zLmhhbmRsZURvd25FdmVudCkge1xuICAgICAgX3RoaXMuaGFuZGxlRG93bkV2ZW50ID0gb3B0aW9ucy5oYW5kbGVEb3duRXZlbnQ7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuaGFuZGxlRHJhZ0V2ZW50KSB7XG4gICAgICBfdGhpcy5oYW5kbGVEcmFnRXZlbnQgPSBvcHRpb25zLmhhbmRsZURyYWdFdmVudDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5oYW5kbGVNb3ZlRXZlbnQpIHtcbiAgICAgIF90aGlzLmhhbmRsZU1vdmVFdmVudCA9IG9wdGlvbnMuaGFuZGxlTW92ZUV2ZW50O1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmhhbmRsZVVwRXZlbnQpIHtcbiAgICAgIF90aGlzLmhhbmRsZVVwRXZlbnQgPSBvcHRpb25zLmhhbmRsZVVwRXZlbnQ7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuc3RvcERvd24pIHtcbiAgICAgIF90aGlzLnN0b3BEb3duID0gb3B0aW9ucy5zdG9wRG93bjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQHByb3RlY3RlZFxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5oYW5kbGluZ0Rvd25VcFNlcXVlbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBQb2ludGVyRXZlbnQ+fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy50cmFja2VkUG9pbnRlcnNfID0ge307XG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PFBvaW50ZXJFdmVudD59XG4gICAgICogQHByb3RlY3RlZFxuICAgICAqL1xuXG4gICAgX3RoaXMudGFyZ2V0UG9pbnRlcnMgPSBbXTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGN1cnJlbnQgbnVtYmVyIG9mIHBvaW50ZXJzIGludm9sdmVkIGluIHRoZSBpbnRlcmFjdGlvbixcbiAgICogZS5nLiBgMmAgd2hlbiB0d28gZmluZ2VycyBhcmUgdXNlZC5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIHBvaW50ZXJzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9pbnRlckludGVyYWN0aW9uLnByb3RvdHlwZS5nZXRQb2ludGVyQ291bnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGFyZ2V0UG9pbnRlcnMubGVuZ3RoO1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgZG93biBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSWYgdGhlIGV2ZW50IHdhcyBjb25zdW1lZC5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFBvaW50ZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuaGFuZGxlRG93bkV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIGRyYWcgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBQb2ludGVySW50ZXJhY3Rpb24ucHJvdG90eXBlLmhhbmRsZURyYWdFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHt9O1xuICAvKipcbiAgICogSGFuZGxlcyB0aGUge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnQgbWFwIGJyb3dzZXIgZXZlbnR9IGFuZCBtYXkgY2FsbCBpbnRvXG4gICAqIG90aGVyIGZ1bmN0aW9ucywgaWYgZXZlbnQgc2VxdWVuY2VzIGxpa2UgZS5nLiAnZHJhZycgb3IgJ2Rvd24tdXAnIGV0Yy4gYXJlXG4gICAqIGRldGVjdGVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGBmYWxzZWAgdG8gc3RvcCBldmVudCBwcm9wYWdhdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvaW50ZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgaWYgKCFtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdmFyIHN0b3BFdmVudCA9IGZhbHNlO1xuICAgIHRoaXMudXBkYXRlVHJhY2tlZFBvaW50ZXJzXyhtYXBCcm93c2VyRXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuaGFuZGxpbmdEb3duVXBTZXF1ZW5jZSkge1xuICAgICAgaWYgKG1hcEJyb3dzZXJFdmVudC50eXBlID09IE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUkRSQUcpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVEcmFnRXZlbnQobWFwQnJvd3NlckV2ZW50KTsgLy8gcHJldmVudCBwYWdlIHNjcm9sbGluZyBkdXJpbmcgZHJhZ2dpbmdcblxuICAgICAgICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfSBlbHNlIGlmIChtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJVUCkge1xuICAgICAgICB2YXIgaGFuZGxlZFVwID0gdGhpcy5oYW5kbGVVcEV2ZW50KG1hcEJyb3dzZXJFdmVudCk7XG4gICAgICAgIHRoaXMuaGFuZGxpbmdEb3duVXBTZXF1ZW5jZSA9IGhhbmRsZWRVcCAmJiB0aGlzLnRhcmdldFBvaW50ZXJzLmxlbmd0aCA+IDA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJET1dOKSB7XG4gICAgICAgIHZhciBoYW5kbGVkID0gdGhpcy5oYW5kbGVEb3duRXZlbnQobWFwQnJvd3NlckV2ZW50KTtcbiAgICAgICAgdGhpcy5oYW5kbGluZ0Rvd25VcFNlcXVlbmNlID0gaGFuZGxlZDtcbiAgICAgICAgc3RvcEV2ZW50ID0gdGhpcy5zdG9wRG93bihoYW5kbGVkKTtcbiAgICAgIH0gZWxzZSBpZiAobWFwQnJvd3NlckV2ZW50LnR5cGUgPT0gTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSTU9WRSkge1xuICAgICAgICB0aGlzLmhhbmRsZU1vdmVFdmVudChtYXBCcm93c2VyRXZlbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAhc3RvcEV2ZW50O1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgbW92ZSBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFBvaW50ZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuaGFuZGxlTW92ZUV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge307XG4gIC8qKlxuICAgKiBIYW5kbGUgcG9pbnRlciB1cCBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSWYgdGhlIGV2ZW50IHdhcyBjb25zdW1lZC5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFBvaW50ZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuaGFuZGxlVXBFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIFwiZG93blwiIGV2ZW50cyBzaG91bGQgYmUgcHJvcGFnYXRlZFxuICAgKiB0byBvdGhlciBpbnRlcmFjdGlvbnMgb3Igc2hvdWxkIGJlIHN0b3BwZWQuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaGFuZGxlZCBXYXMgdGhlIGV2ZW50IGhhbmRsZWQgYnkgdGhlIGludGVyYWN0aW9uP1xuICAgKiBAcmV0dXJuIHtib29sZWFufSBTaG91bGQgdGhlIGBkb3duYCBldmVudCBiZSBzdG9wcGVkP1xuICAgKi9cblxuXG4gIFBvaW50ZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuc3RvcERvd24gPSBmdW5jdGlvbiAoaGFuZGxlZCkge1xuICAgIHJldHVybiBoYW5kbGVkO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFBvaW50ZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUudXBkYXRlVHJhY2tlZFBvaW50ZXJzXyA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICBpZiAoaXNQb2ludGVyRHJhZ2dpbmdFdmVudChtYXBCcm93c2VyRXZlbnQpKSB7XG4gICAgICB2YXIgZXZlbnRfMSA9IG1hcEJyb3dzZXJFdmVudC5vcmlnaW5hbEV2ZW50O1xuICAgICAgdmFyIGlkID0gZXZlbnRfMS5wb2ludGVySWQudG9TdHJpbmcoKTtcblxuICAgICAgaWYgKG1hcEJyb3dzZXJFdmVudC50eXBlID09IE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUlVQKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnRyYWNrZWRQb2ludGVyc19baWRdO1xuICAgICAgfSBlbHNlIGlmIChtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJET1dOKSB7XG4gICAgICAgIHRoaXMudHJhY2tlZFBvaW50ZXJzX1tpZF0gPSBldmVudF8xO1xuICAgICAgfSBlbHNlIGlmIChpZCBpbiB0aGlzLnRyYWNrZWRQb2ludGVyc18pIHtcbiAgICAgICAgLy8gdXBkYXRlIG9ubHkgd2hlbiB0aGVyZSB3YXMgYSBwb2ludGVyZG93biBldmVudCBmb3IgdGhpcyBwb2ludGVyXG4gICAgICAgIHRoaXMudHJhY2tlZFBvaW50ZXJzX1tpZF0gPSBldmVudF8xO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnRhcmdldFBvaW50ZXJzID0gZ2V0VmFsdWVzKHRoaXMudHJhY2tlZFBvaW50ZXJzXyk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBQb2ludGVySW50ZXJhY3Rpb247XG59KEludGVyYWN0aW9uKTtcbi8qKlxuICogQHBhcmFtIHtBcnJheTxQb2ludGVyRXZlbnQ+fSBwb2ludGVyRXZlbnRzIExpc3Qgb2YgZXZlbnRzLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9IENlbnRyb2lkIHBpeGVsLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGNlbnRyb2lkKHBvaW50ZXJFdmVudHMpIHtcbiAgdmFyIGxlbmd0aCA9IHBvaW50ZXJFdmVudHMubGVuZ3RoO1xuICB2YXIgY2xpZW50WCA9IDA7XG4gIHZhciBjbGllbnRZID0gMDtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY2xpZW50WCArPSBwb2ludGVyRXZlbnRzW2ldLmNsaWVudFg7XG4gICAgY2xpZW50WSArPSBwb2ludGVyRXZlbnRzW2ldLmNsaWVudFk7XG4gIH1cblxuICByZXR1cm4gW2NsaWVudFggLyBsZW5ndGgsIGNsaWVudFkgLyBsZW5ndGhdO1xufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHRoZSBldmVudCBpcyBhIHBvaW50ZXJkb3duLCBwb2ludGVyZHJhZ1xuICogICAgIG9yIHBvaW50ZXJ1cCBldmVudC5cbiAqL1xuXG5mdW5jdGlvbiBpc1BvaW50ZXJEcmFnZ2luZ0V2ZW50KG1hcEJyb3dzZXJFdmVudCkge1xuICB2YXIgdHlwZSA9IG1hcEJyb3dzZXJFdmVudC50eXBlO1xuICByZXR1cm4gdHlwZSA9PT0gTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSRE9XTiB8fCB0eXBlID09PSBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJEUkFHIHx8IHR5cGUgPT09IE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUlVQO1xufVxuXG5leHBvcnQgZGVmYXVsdCBQb2ludGVySW50ZXJhY3Rpb247IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2V2ZW50cy9jb25kaXRpb25cbiAqL1xuaW1wb3J0IE1hcEJyb3dzZXJFdmVudFR5cGUgZnJvbSAnLi4vTWFwQnJvd3NlckV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgeyBGQUxTRSwgVFJVRSB9IGZyb20gJy4uL2Z1bmN0aW9ucy5qcyc7XG5pbXBvcnQgeyBNQUMsIFdFQktJVCB9IGZyb20gJy4uL2hhcy5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi9hc3NlcnRzLmpzJztcbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fSBhbmQgcmV0dXJucyBhXG4gKiBge2Jvb2xlYW59YC4gSWYgdGhlIGNvbmRpdGlvbiBpcyBtZXQsIHRydWUgc2hvdWxkIGJlIHJldHVybmVkLlxuICpcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbih0aGlzOiA/LCBpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdCk6IGJvb2xlYW59IENvbmRpdGlvblxuICovXG5cbi8qKlxuICogQ3JlYXRlcyBhIGNvbmRpdGlvbiBmdW5jdGlvbiB0aGF0IHBhc3NlcyB3aGVuIGFsbCBwcm92aWRlZCBjb25kaXRpb25zIHBhc3MuXG4gKiBAcGFyYW0gey4uLkNvbmRpdGlvbn0gdmFyX2FyZ3MgQ29uZGl0aW9ucyB0byBjaGVjay5cbiAqIEByZXR1cm4ge0NvbmRpdGlvbn0gQ29uZGl0aW9uIGZ1bmN0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhbGwodmFyX2FyZ3MpIHtcbiAgdmFyIGNvbmRpdGlvbnMgPSBhcmd1bWVudHM7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBldmVudCBFdmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQWxsIGNvbmRpdGlvbnMgcGFzc2VkLlxuICAgKi9cblxuICByZXR1cm4gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdmFyIHBhc3MgPSB0cnVlO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gY29uZGl0aW9ucy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBwYXNzID0gcGFzcyAmJiBjb25kaXRpb25zW2ldKGV2ZW50KTtcblxuICAgICAgaWYgKCFwYXNzKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwYXNzO1xuICB9O1xufVxuLyoqXG4gKiBSZXR1cm4gYHRydWVgIGlmIG9ubHkgdGhlIGFsdC1rZXkgaXMgcHJlc3NlZCwgYGZhbHNlYCBvdGhlcndpc2UgKGUuZy4gd2hlblxuICogYWRkaXRpb25hbGx5IHRoZSBzaGlmdC1rZXkgaXMgcHJlc3NlZCkuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBvbmx5IHRoZSBhbHQga2V5IGlzIHByZXNzZWQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBhbHRLZXlPbmx5ID0gZnVuY3Rpb24gYWx0S2V5T25seShtYXBCcm93c2VyRXZlbnQpIHtcbiAgdmFyIG9yaWdpbmFsRXZlbnQgPVxuICAvKiogQHR5cGUge0tleWJvYXJkRXZlbnR8TW91c2VFdmVudHxUb3VjaEV2ZW50fSAqL1xuICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgcmV0dXJuIG9yaWdpbmFsRXZlbnQuYWx0S2V5ICYmICEob3JpZ2luYWxFdmVudC5tZXRhS2V5IHx8IG9yaWdpbmFsRXZlbnQuY3RybEtleSkgJiYgIW9yaWdpbmFsRXZlbnQuc2hpZnRLZXk7XG59O1xuLyoqXG4gKiBSZXR1cm4gYHRydWVgIGlmIG9ubHkgdGhlIGFsdC1rZXkgYW5kIHNoaWZ0LWtleSBpcyBwcmVzc2VkLCBgZmFsc2VgIG90aGVyd2lzZVxuICogKGUuZy4gd2hlbiBhZGRpdGlvbmFsbHkgdGhlIHBsYXRmb3JtLW1vZGlmaWVyLWtleSBpcyBwcmVzc2VkKS5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIG9ubHkgdGhlIGFsdCBhbmQgc2hpZnQga2V5cyBhcmUgcHJlc3NlZC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIGFsdFNoaWZ0S2V5c09ubHkgPSBmdW5jdGlvbiBhbHRTaGlmdEtleXNPbmx5KG1hcEJyb3dzZXJFdmVudCkge1xuICB2YXIgb3JpZ2luYWxFdmVudCA9XG4gIC8qKiBAdHlwZSB7S2V5Ym9hcmRFdmVudHxNb3VzZUV2ZW50fFRvdWNoRXZlbnR9ICovXG4gIG1hcEJyb3dzZXJFdmVudC5vcmlnaW5hbEV2ZW50O1xuICByZXR1cm4gb3JpZ2luYWxFdmVudC5hbHRLZXkgJiYgIShvcmlnaW5hbEV2ZW50Lm1ldGFLZXkgfHwgb3JpZ2luYWxFdmVudC5jdHJsS2V5KSAmJiBvcmlnaW5hbEV2ZW50LnNoaWZ0S2V5O1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgbWFwIGhhcyB0aGUgZm9jdXMuIFRoaXMgY29uZGl0aW9uIHJlcXVpcmVzIGEgbWFwIHRhcmdldFxuICogZWxlbWVudCB3aXRoIGEgYHRhYmluZGV4YCBhdHRyaWJ1dGUsIGUuZy4gYDxkaXYgaWQ9XCJtYXBcIiB0YWJpbmRleD1cIjFcIj5gLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IGV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIG1hcCBoYXMgdGhlIGZvY3VzLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgZm9jdXMgPSBmdW5jdGlvbiBmb2N1cyhldmVudCkge1xuICByZXR1cm4gZXZlbnQudGFyZ2V0LmdldFRhcmdldEVsZW1lbnQoKS5jb250YWlucyhkb2N1bWVudC5hY3RpdmVFbGVtZW50KTtcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIG1hcCBoYXMgdGhlIGZvY3VzIG9yIG5vICd0YWJpbmRleCcgYXR0cmlidXRlIHNldC5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBldmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBtYXAgY29udGFpbmVyIGhhcyB0aGUgZm9jdXMgb3Igbm8gJ3RhYmluZGV4JyBhdHRyaWJ1dGUuXG4gKi9cblxuZXhwb3J0IHZhciBmb2N1c1dpdGhUYWJpbmRleCA9IGZ1bmN0aW9uIGZvY3VzV2l0aFRhYmluZGV4KGV2ZW50KSB7XG4gIHJldHVybiBldmVudC5tYXAuZ2V0VGFyZ2V0RWxlbWVudCgpLmhhc0F0dHJpYnV0ZSgndGFiaW5kZXgnKSA/IGZvY3VzKGV2ZW50KSA6IHRydWU7XG59O1xuLyoqXG4gKiBSZXR1cm4gYWx3YXlzIHRydWUuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIGFsd2F5cyA9IFRSVUU7XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIGV2ZW50IGlzIGEgYGNsaWNrYCBldmVudCwgYGZhbHNlYCBvdGhlcndpc2UuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXZlbnQgaXMgYSBtYXAgYGNsaWNrYCBldmVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIGNsaWNrID0gZnVuY3Rpb24gY2xpY2sobWFwQnJvd3NlckV2ZW50KSB7XG4gIHJldHVybiBtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBNYXBCcm93c2VyRXZlbnRUeXBlLkNMSUNLO1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgZXZlbnQgaGFzIGFuIFwiYWN0aW9uXCItcHJvZHVjaW5nIG1vdXNlIGJ1dHRvbi5cbiAqXG4gKiBCeSBkZWZpbml0aW9uLCB0aGlzIGluY2x1ZGVzIGxlZnQtY2xpY2sgb24gd2luZG93cy9saW51eCwgYW5kIGxlZnQtY2xpY2tcbiAqIHdpdGhvdXQgdGhlIGN0cmwga2V5IG9uIE1hY3MuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHJlc3VsdC5cbiAqL1xuXG5leHBvcnQgdmFyIG1vdXNlQWN0aW9uQnV0dG9uID0gZnVuY3Rpb24gbW91c2VBY3Rpb25CdXR0b24obWFwQnJvd3NlckV2ZW50KSB7XG4gIHZhciBvcmlnaW5hbEV2ZW50ID1cbiAgLyoqIEB0eXBlIHtNb3VzZUV2ZW50fSAqL1xuICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgcmV0dXJuIG9yaWdpbmFsRXZlbnQuYnV0dG9uID09IDAgJiYgIShXRUJLSVQgJiYgTUFDICYmIG9yaWdpbmFsRXZlbnQuY3RybEtleSk7XG59O1xuLyoqXG4gKiBSZXR1cm4gYWx3YXlzIGZhbHNlLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IEZhbHNlLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgbmV2ZXIgPSBGQUxTRTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgYnJvd3NlciBldmVudCBpcyBhIGBwb2ludGVybW92ZWAgZXZlbnQsIGBmYWxzZWBcbiAqIG90aGVyd2lzZS5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBicm93c2VyIGV2ZW50IGlzIGEgYHBvaW50ZXJtb3ZlYCBldmVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIHBvaW50ZXJNb3ZlID0gZnVuY3Rpb24gcG9pbnRlck1vdmUobWFwQnJvd3NlckV2ZW50KSB7XG4gIHJldHVybiBtYXBCcm93c2VyRXZlbnQudHlwZSA9PSAncG9pbnRlcm1vdmUnO1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgZXZlbnQgaXMgYSBtYXAgYHNpbmdsZWNsaWNrYCBldmVudCwgYGZhbHNlYCBvdGhlcndpc2UuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXZlbnQgaXMgYSBtYXAgYHNpbmdsZWNsaWNrYCBldmVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIHNpbmdsZUNsaWNrID0gZnVuY3Rpb24gc2luZ2xlQ2xpY2sobWFwQnJvd3NlckV2ZW50KSB7XG4gIHJldHVybiBtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBNYXBCcm93c2VyRXZlbnRUeXBlLlNJTkdMRUNMSUNLO1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgZXZlbnQgaXMgYSBtYXAgYGRibGNsaWNrYCBldmVudCwgYGZhbHNlYCBvdGhlcndpc2UuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXZlbnQgaXMgYSBtYXAgYGRibGNsaWNrYCBldmVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIGRvdWJsZUNsaWNrID0gZnVuY3Rpb24gZG91YmxlQ2xpY2sobWFwQnJvd3NlckV2ZW50KSB7XG4gIHJldHVybiBtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBNYXBCcm93c2VyRXZlbnRUeXBlLkRCTENMSUNLO1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiBubyBtb2RpZmllciBrZXkgKGFsdC0sIHNoaWZ0LSBvciBwbGF0Zm9ybS1tb2RpZmllci1rZXkpIGlzXG4gKiBwcmVzc2VkLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgb25seSBpZiB0aGVyZSBubyBtb2RpZmllciBrZXlzIGFyZSBwcmVzc2VkLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgbm9Nb2RpZmllcktleXMgPSBmdW5jdGlvbiBub01vZGlmaWVyS2V5cyhtYXBCcm93c2VyRXZlbnQpIHtcbiAgdmFyIG9yaWdpbmFsRXZlbnQgPVxuICAvKiogQHR5cGUge0tleWJvYXJkRXZlbnR8TW91c2VFdmVudHxUb3VjaEV2ZW50fSAqL1xuICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgcmV0dXJuICFvcmlnaW5hbEV2ZW50LmFsdEtleSAmJiAhKG9yaWdpbmFsRXZlbnQubWV0YUtleSB8fCBvcmlnaW5hbEV2ZW50LmN0cmxLZXkpICYmICFvcmlnaW5hbEV2ZW50LnNoaWZ0S2V5O1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiBvbmx5IHRoZSBwbGF0Zm9ybS1tb2RpZmllci1rZXkgKHRoZSBtZXRhLWtleSBvbiBNYWMsXG4gKiBjdHJsLWtleSBvdGhlcndpc2UpIGlzIHByZXNzZWQsIGBmYWxzZWAgb3RoZXJ3aXNlIChlLmcuIHdoZW4gYWRkaXRpb25hbGx5XG4gKiB0aGUgc2hpZnQta2V5IGlzIHByZXNzZWQpLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgb25seSB0aGUgcGxhdGZvcm0gbW9kaWZpZXIga2V5IGlzIHByZXNzZWQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBwbGF0Zm9ybU1vZGlmaWVyS2V5T25seSA9IGZ1bmN0aW9uIHBsYXRmb3JtTW9kaWZpZXJLZXlPbmx5KG1hcEJyb3dzZXJFdmVudCkge1xuICB2YXIgb3JpZ2luYWxFdmVudCA9XG4gIC8qKiBAdHlwZSB7S2V5Ym9hcmRFdmVudHxNb3VzZUV2ZW50fFRvdWNoRXZlbnR9ICovXG4gIG1hcEJyb3dzZXJFdmVudC5vcmlnaW5hbEV2ZW50O1xuICByZXR1cm4gIW9yaWdpbmFsRXZlbnQuYWx0S2V5ICYmIChNQUMgPyBvcmlnaW5hbEV2ZW50Lm1ldGFLZXkgOiBvcmlnaW5hbEV2ZW50LmN0cmxLZXkpICYmICFvcmlnaW5hbEV2ZW50LnNoaWZ0S2V5O1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiBvbmx5IHRoZSBzaGlmdC1rZXkgaXMgcHJlc3NlZCwgYGZhbHNlYCBvdGhlcndpc2UgKGUuZy4gd2hlblxuICogYWRkaXRpb25hbGx5IHRoZSBhbHQta2V5IGlzIHByZXNzZWQpLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgb25seSB0aGUgc2hpZnQga2V5IGlzIHByZXNzZWQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBzaGlmdEtleU9ubHkgPSBmdW5jdGlvbiBzaGlmdEtleU9ubHkobWFwQnJvd3NlckV2ZW50KSB7XG4gIHZhciBvcmlnaW5hbEV2ZW50ID1cbiAgLyoqIEB0eXBlIHtLZXlib2FyZEV2ZW50fE1vdXNlRXZlbnR8VG91Y2hFdmVudH0gKi9cbiAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gIHJldHVybiAhb3JpZ2luYWxFdmVudC5hbHRLZXkgJiYgIShvcmlnaW5hbEV2ZW50Lm1ldGFLZXkgfHwgb3JpZ2luYWxFdmVudC5jdHJsS2V5KSAmJiBvcmlnaW5hbEV2ZW50LnNoaWZ0S2V5O1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgdGFyZ2V0IGVsZW1lbnQgaXMgbm90IGVkaXRhYmxlLCBpLmUuIG5vdCBhIGA8aW5wdXQ+YC0sXG4gKiBgPHNlbGVjdD5gLSBvciBgPHRleHRhcmVhPmAtZWxlbWVudCwgYGZhbHNlYCBvdGhlcndpc2UuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBvbmx5IGlmIHRoZSB0YXJnZXQgZWxlbWVudCBpcyBub3QgZWRpdGFibGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciB0YXJnZXROb3RFZGl0YWJsZSA9IGZ1bmN0aW9uIHRhcmdldE5vdEVkaXRhYmxlKG1hcEJyb3dzZXJFdmVudCkge1xuICB2YXIgb3JpZ2luYWxFdmVudCA9XG4gIC8qKiBAdHlwZSB7S2V5Ym9hcmRFdmVudHxNb3VzZUV2ZW50fFRvdWNoRXZlbnR9ICovXG4gIG1hcEJyb3dzZXJFdmVudC5vcmlnaW5hbEV2ZW50O1xuICB2YXIgdGFnTmFtZSA9XG4gIC8qKiBAdHlwZSB7RWxlbWVudH0gKi9cbiAgb3JpZ2luYWxFdmVudC50YXJnZXQudGFnTmFtZTtcbiAgcmV0dXJuIHRhZ05hbWUgIT09ICdJTlBVVCcgJiYgdGFnTmFtZSAhPT0gJ1NFTEVDVCcgJiYgdGFnTmFtZSAhPT0gJ1RFWFRBUkVBJztcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIGV2ZW50IG9yaWdpbmF0ZXMgZnJvbSBhIG1vdXNlIGRldmljZS5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBldmVudCBvcmlnaW5hdGVzIGZyb20gYSBtb3VzZSBkZXZpY2UuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBtb3VzZU9ubHkgPSBmdW5jdGlvbiBtb3VzZU9ubHkobWFwQnJvd3NlckV2ZW50KSB7XG4gIHZhciBwb2ludGVyRXZlbnQgPVxuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudFwiKS5kZWZhdWx0fSAqL1xuICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgYXNzZXJ0KHBvaW50ZXJFdmVudCAhPT0gdW5kZWZpbmVkLCA1Nik7IC8vIG1hcEJyb3dzZXJFdmVudCBtdXN0IG9yaWdpbmF0ZSBmcm9tIGEgcG9pbnRlciBldmVudFxuICAvLyBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvcG9pbnRlcmV2ZW50cy8jd2lkbC1Qb2ludGVyRXZlbnQtcG9pbnRlclR5cGVcblxuICByZXR1cm4gcG9pbnRlckV2ZW50LnBvaW50ZXJUeXBlID09ICdtb3VzZSc7XG59O1xuLyoqXG4gKiBSZXR1cm4gYHRydWVgIGlmIHRoZSBldmVudCBvcmlnaW5hdGVzIGZyb20gYSB0b3VjaGFibGUgZGV2aWNlLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGV2ZW50IG9yaWdpbmF0ZXMgZnJvbSBhIHRvdWNoYWJsZSBkZXZpY2UuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciB0b3VjaE9ubHkgPSBmdW5jdGlvbiB0b3VjaE9ubHkobWFwQnJvd3NlckV2ZW50KSB7XG4gIHZhciBwb2ludGVyRXZ0ID1cbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnRcIikuZGVmYXVsdH0gKi9cbiAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gIGFzc2VydChwb2ludGVyRXZ0ICE9PSB1bmRlZmluZWQsIDU2KTsgLy8gbWFwQnJvd3NlckV2ZW50IG11c3Qgb3JpZ2luYXRlIGZyb20gYSBwb2ludGVyIGV2ZW50XG4gIC8vIHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9wb2ludGVyZXZlbnRzLyN3aWRsLVBvaW50ZXJFdmVudC1wb2ludGVyVHlwZVxuXG4gIHJldHVybiBwb2ludGVyRXZ0LnBvaW50ZXJUeXBlID09PSAndG91Y2gnO1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgZXZlbnQgb3JpZ2luYXRlcyBmcm9tIGEgZGlnaXRhbCBwZW4uXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXZlbnQgb3JpZ2luYXRlcyBmcm9tIGEgZGlnaXRhbCBwZW4uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBwZW5Pbmx5ID0gZnVuY3Rpb24gcGVuT25seShtYXBCcm93c2VyRXZlbnQpIHtcbiAgdmFyIHBvaW50ZXJFdnQgPVxuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudFwiKS5kZWZhdWx0fSAqL1xuICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgYXNzZXJ0KHBvaW50ZXJFdnQgIT09IHVuZGVmaW5lZCwgNTYpOyAvLyBtYXBCcm93c2VyRXZlbnQgbXVzdCBvcmlnaW5hdGUgZnJvbSBhIHBvaW50ZXIgZXZlbnRcbiAgLy8gc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3BvaW50ZXJldmVudHMvI3dpZGwtUG9pbnRlckV2ZW50LXBvaW50ZXJUeXBlXG5cbiAgcmV0dXJuIHBvaW50ZXJFdnQucG9pbnRlclR5cGUgPT09ICdwZW4nO1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgZXZlbnQgb3JpZ2luYXRlcyBmcm9tIGEgcHJpbWFyeSBwb2ludGVyIGluXG4gKiBjb250YWN0IHdpdGggdGhlIHN1cmZhY2Ugb3IgaWYgdGhlIGxlZnQgbW91c2UgYnV0dG9uIGlzIHByZXNzZWQuXG4gKiBTZWUgaHR0cDovL3d3dy53My5vcmcvVFIvcG9pbnRlcmV2ZW50cy8jYnV0dG9uLXN0YXRlcy5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBldmVudCBvcmlnaW5hdGVzIGZyb20gYSBwcmltYXJ5IHBvaW50ZXIuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBwcmltYXJ5QWN0aW9uID0gZnVuY3Rpb24gcHJpbWFyeUFjdGlvbihtYXBCcm93c2VyRXZlbnQpIHtcbiAgdmFyIHBvaW50ZXJFdmVudCA9XG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50XCIpLmRlZmF1bHR9ICovXG4gIG1hcEJyb3dzZXJFdmVudC5vcmlnaW5hbEV2ZW50O1xuICBhc3NlcnQocG9pbnRlckV2ZW50ICE9PSB1bmRlZmluZWQsIDU2KTsgLy8gbWFwQnJvd3NlckV2ZW50IG11c3Qgb3JpZ2luYXRlIGZyb20gYSBwb2ludGVyIGV2ZW50XG5cbiAgcmV0dXJuIHBvaW50ZXJFdmVudC5pc1ByaW1hcnkgJiYgcG9pbnRlckV2ZW50LmJ1dHRvbiA9PT0gMDtcbn07IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9EcmFnUGFuXG4gKi9cblxuXG5pbXBvcnQgUG9pbnRlckludGVyYWN0aW9uLCB7IGNlbnRyb2lkIGFzIGNlbnRyb2lkRnJvbVBvaW50ZXJzIH0gZnJvbSAnLi9Qb2ludGVyLmpzJztcbmltcG9ydCB7IEZBTFNFIH0gZnJvbSAnLi4vZnVuY3Rpb25zLmpzJztcbmltcG9ydCB7IGFsbCwgZm9jdXNXaXRoVGFiaW5kZXgsIG5vTW9kaWZpZXJLZXlzLCBwcmltYXJ5QWN0aW9uIH0gZnJvbSAnLi4vZXZlbnRzL2NvbmRpdGlvbi5qcyc7XG5pbXBvcnQgeyBlYXNlT3V0IH0gZnJvbSAnLi4vZWFzaW5nLmpzJztcbmltcG9ydCB7IHJvdGF0ZSBhcyByb3RhdGVDb29yZGluYXRlLCBzY2FsZSBhcyBzY2FsZUNvb3JkaW5hdGUgfSBmcm9tICcuLi9jb29yZGluYXRlLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn0gW2NvbmRpdGlvbl0gQSBmdW5jdGlvbiB0aGF0IHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudH0gYW5kIHJldHVybnMgYSBib29sZWFuXG4gKiB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoYXQgZXZlbnQgc2hvdWxkIGJlIGhhbmRsZWQuXG4gKiBEZWZhdWx0IGlzIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzL2NvbmRpdGlvbn5ub01vZGlmaWVyS2V5c30gYW5kIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzL2NvbmRpdGlvbn5wcmltYXJ5QWN0aW9ufS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW29uRm9jdXNPbmx5PWZhbHNlXSBXaGVuIHRoZSBtYXAncyB0YXJnZXQgaGFzIGEgYHRhYmluZGV4YCBhdHRyaWJ1dGUgc2V0LFxuICogdGhlIGludGVyYWN0aW9uIHdpbGwgb25seSBoYW5kbGUgZXZlbnRzIHdoZW4gdGhlIG1hcCBoYXMgdGhlIGZvY3VzLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9LaW5ldGljLmpzXCIpLmRlZmF1bHR9IFtraW5ldGljXSBLaW5ldGljIGluZXJ0aWEgdG8gYXBwbHkgdG8gdGhlIHBhbi5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFsbG93cyB0aGUgdXNlciB0byBwYW4gdGhlIG1hcCBieSBkcmFnZ2luZyB0aGUgbWFwLlxuICogQGFwaVxuICovXG5cbnZhciBEcmFnUGFuID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKERyYWdQYW4sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIERyYWdQYW4ob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB7XG4gICAgICBzdG9wRG93bjogRkFMU0VcbiAgICB9KSB8fCB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyA/IG9wdF9vcHRpb25zIDoge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vS2luZXRpYy5qc1wiKS5kZWZhdWx0fHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLmtpbmV0aWNfID0gb3B0aW9ucy5raW5ldGljO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbH1cbiAgICAgKi9cblxuICAgIF90aGlzLmxhc3RDZW50cm9pZCA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxhc3RQb2ludGVyc0NvdW50XztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLnBhbm5pbmdfID0gZmFsc2U7XG4gICAgdmFyIGNvbmRpdGlvbiA9IG9wdGlvbnMuY29uZGl0aW9uID8gb3B0aW9ucy5jb25kaXRpb24gOiBhbGwobm9Nb2RpZmllcktleXMsIHByaW1hcnlBY3Rpb24pO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2V2ZW50cy9jb25kaXRpb24uanNcIikuQ29uZGl0aW9ufVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29uZGl0aW9uXyA9IG9wdGlvbnMub25Gb2N1c09ubHkgPyBhbGwoZm9jdXNXaXRoVGFiaW5kZXgsIGNvbmRpdGlvbikgOiBjb25kaXRpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLm5vS2luZXRpY18gPSBmYWxzZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIGRyYWcgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqL1xuXG5cbiAgRHJhZ1Bhbi5wcm90b3R5cGUuaGFuZGxlRHJhZ0V2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIGlmICghdGhpcy5wYW5uaW5nXykge1xuICAgICAgdGhpcy5wYW5uaW5nXyA9IHRydWU7XG4gICAgICB0aGlzLmdldE1hcCgpLmdldFZpZXcoKS5iZWdpbkludGVyYWN0aW9uKCk7XG4gICAgfVxuXG4gICAgdmFyIHRhcmdldFBvaW50ZXJzID0gdGhpcy50YXJnZXRQb2ludGVycztcbiAgICB2YXIgY2VudHJvaWQgPSBjZW50cm9pZEZyb21Qb2ludGVycyh0YXJnZXRQb2ludGVycyk7XG5cbiAgICBpZiAodGFyZ2V0UG9pbnRlcnMubGVuZ3RoID09IHRoaXMubGFzdFBvaW50ZXJzQ291bnRfKSB7XG4gICAgICBpZiAodGhpcy5raW5ldGljXykge1xuICAgICAgICB0aGlzLmtpbmV0aWNfLnVwZGF0ZShjZW50cm9pZFswXSwgY2VudHJvaWRbMV0pO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5sYXN0Q2VudHJvaWQpIHtcbiAgICAgICAgdmFyIGRlbHRhID0gW3RoaXMubGFzdENlbnRyb2lkWzBdIC0gY2VudHJvaWRbMF0sIGNlbnRyb2lkWzFdIC0gdGhpcy5sYXN0Q2VudHJvaWRbMV1dO1xuICAgICAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICAgICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuICAgICAgICBzY2FsZUNvb3JkaW5hdGUoZGVsdGEsIHZpZXcuZ2V0UmVzb2x1dGlvbigpKTtcbiAgICAgICAgcm90YXRlQ29vcmRpbmF0ZShkZWx0YSwgdmlldy5nZXRSb3RhdGlvbigpKTtcbiAgICAgICAgdmlldy5hZGp1c3RDZW50ZXJJbnRlcm5hbChkZWx0YSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0aGlzLmtpbmV0aWNfKSB7XG4gICAgICAvLyByZXNldCBzbyB3ZSBkb24ndCBvdmVyZXN0aW1hdGUgdGhlIGtpbmV0aWMgZW5lcmd5IGFmdGVyXG4gICAgICAvLyBhZnRlciBvbmUgZmluZ2VyIGRvd24sIHRpbnkgZHJhZywgc2Vjb25kIGZpbmdlciBkb3duXG4gICAgICB0aGlzLmtpbmV0aWNfLmJlZ2luKCk7XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0Q2VudHJvaWQgPSBjZW50cm9pZDtcbiAgICB0aGlzLmxhc3RQb2ludGVyc0NvdW50XyA9IHRhcmdldFBvaW50ZXJzLmxlbmd0aDtcbiAgICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgdXAgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBldmVudCB3YXMgY29uc3VtZWQuXG4gICAqL1xuXG5cbiAgRHJhZ1Bhbi5wcm90b3R5cGUuaGFuZGxlVXBFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICB2YXIgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG5cbiAgICBpZiAodGhpcy50YXJnZXRQb2ludGVycy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmICghdGhpcy5ub0tpbmV0aWNfICYmIHRoaXMua2luZXRpY18gJiYgdGhpcy5raW5ldGljXy5lbmQoKSkge1xuICAgICAgICB2YXIgZGlzdGFuY2UgPSB0aGlzLmtpbmV0aWNfLmdldERpc3RhbmNlKCk7XG4gICAgICAgIHZhciBhbmdsZSA9IHRoaXMua2luZXRpY18uZ2V0QW5nbGUoKTtcbiAgICAgICAgdmFyIGNlbnRlciA9IHZpZXcuZ2V0Q2VudGVySW50ZXJuYWwoKTtcbiAgICAgICAgdmFyIGNlbnRlcnB4ID0gbWFwLmdldFBpeGVsRnJvbUNvb3JkaW5hdGVJbnRlcm5hbChjZW50ZXIpO1xuICAgICAgICB2YXIgZGVzdCA9IG1hcC5nZXRDb29yZGluYXRlRnJvbVBpeGVsSW50ZXJuYWwoW2NlbnRlcnB4WzBdIC0gZGlzdGFuY2UgKiBNYXRoLmNvcyhhbmdsZSksIGNlbnRlcnB4WzFdIC0gZGlzdGFuY2UgKiBNYXRoLnNpbihhbmdsZSldKTtcbiAgICAgICAgdmlldy5hbmltYXRlSW50ZXJuYWwoe1xuICAgICAgICAgIGNlbnRlcjogdmlldy5nZXRDb25zdHJhaW5lZENlbnRlcihkZXN0KSxcbiAgICAgICAgICBkdXJhdGlvbjogNTAwLFxuICAgICAgICAgIGVhc2luZzogZWFzZU91dFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucGFubmluZ18pIHtcbiAgICAgICAgdGhpcy5wYW5uaW5nXyA9IGZhbHNlO1xuICAgICAgICB2aWV3LmVuZEludGVyYWN0aW9uKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMua2luZXRpY18pIHtcbiAgICAgICAgLy8gcmVzZXQgc28gd2UgZG9uJ3Qgb3ZlcmVzdGltYXRlIHRoZSBraW5ldGljIGVuZXJneSBhZnRlclxuICAgICAgICAvLyBhZnRlciBvbmUgZmluZ2VyIHVwLCB0aW55IGRyYWcsIHNlY29uZCBmaW5nZXIgdXBcbiAgICAgICAgdGhpcy5raW5ldGljXy5iZWdpbigpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxhc3RDZW50cm9pZCA9IG51bGw7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGUgcG9pbnRlciBkb3duIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJZiB0aGUgZXZlbnQgd2FzIGNvbnN1bWVkLlxuICAgKi9cblxuXG4gIERyYWdQYW4ucHJvdG90eXBlLmhhbmRsZURvd25FdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICBpZiAodGhpcy50YXJnZXRQb2ludGVycy5sZW5ndGggPiAwICYmIHRoaXMuY29uZGl0aW9uXyhtYXBCcm93c2VyRXZlbnQpKSB7XG4gICAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcbiAgICAgIHRoaXMubGFzdENlbnRyb2lkID0gbnVsbDsgLy8gc3RvcCBhbnkgY3VycmVudCBhbmltYXRpb25cblxuICAgICAgaWYgKHZpZXcuZ2V0QW5pbWF0aW5nKCkpIHtcbiAgICAgICAgdmlldy5jYW5jZWxBbmltYXRpb25zKCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmtpbmV0aWNfKSB7XG4gICAgICAgIHRoaXMua2luZXRpY18uYmVnaW4oKTtcbiAgICAgIH0gLy8gTm8ga2luZXRpYyBhcyBzb29uIGFzIG1vcmUgdGhhbiBvbmUgcG9pbnRlciBvbiB0aGUgc2NyZWVuIGlzXG4gICAgICAvLyBkZXRlY3RlZC4gVGhpcyBpcyB0byBwcmV2ZW50IG5hc3R5IHBhbnMgYWZ0ZXIgcGluY2guXG5cblxuICAgICAgdGhpcy5ub0tpbmV0aWNfID0gdGhpcy50YXJnZXRQb2ludGVycy5sZW5ndGggPiAxO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIERyYWdQYW47XG59KFBvaW50ZXJJbnRlcmFjdGlvbik7XG5cbmV4cG9ydCBkZWZhdWx0IERyYWdQYW47IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9EcmFnUm90YXRlXG4gKi9cblxuXG5pbXBvcnQgUG9pbnRlckludGVyYWN0aW9uIGZyb20gJy4vUG9pbnRlci5qcyc7XG5pbXBvcnQgeyBGQUxTRSB9IGZyb20gJy4uL2Z1bmN0aW9ucy5qcyc7XG5pbXBvcnQgeyBhbHRTaGlmdEtleXNPbmx5LCBtb3VzZUFjdGlvbkJ1dHRvbiwgbW91c2VPbmx5IH0gZnJvbSAnLi4vZXZlbnRzL2NvbmRpdGlvbi5qcyc7XG5pbXBvcnQgeyBkaXNhYmxlIH0gZnJvbSAnLi4vcm90YXRpb25jb25zdHJhaW50LmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn0gW2NvbmRpdGlvbl0gQSBmdW5jdGlvbiB0aGF0IHRha2VzIGFuXG4gKiB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH5NYXBCcm93c2VyRXZlbnR9IGFuZCByZXR1cm5zIGEgYm9vbGVhblxuICogdG8gaW5kaWNhdGUgd2hldGhlciB0aGF0IGV2ZW50IHNob3VsZCBiZSBoYW5kbGVkLlxuICogRGVmYXVsdCBpcyB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50cy9jb25kaXRpb25+YWx0U2hpZnRLZXlzT25seX0uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2R1cmF0aW9uPTI1MF0gQW5pbWF0aW9uIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcy5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFsbG93cyB0aGUgdXNlciB0byByb3RhdGUgdGhlIG1hcCBieSBjbGlja2luZyBhbmQgZHJhZ2dpbmcgb24gdGhlIG1hcCxcbiAqIG5vcm1hbGx5IGNvbWJpbmVkIHdpdGggYW4ge0BsaW5rIG1vZHVsZTpvbC9ldmVudHMvY29uZGl0aW9ufSB0aGF0IGxpbWl0c1xuICogaXQgdG8gd2hlbiB0aGUgYWx0IGFuZCBzaGlmdCBrZXlzIGFyZSBoZWxkIGRvd24uXG4gKlxuICogVGhpcyBpbnRlcmFjdGlvbiBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgbW91c2UgZGV2aWNlcy5cbiAqIEBhcGlcbiAqL1xuXG52YXIgRHJhZ1JvdGF0ZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhEcmFnUm90YXRlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBEcmFnUm90YXRlKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgc3RvcERvd246IEZBTFNFXG4gICAgfSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbmRpdGlvbl8gPSBvcHRpb25zLmNvbmRpdGlvbiA/IG9wdGlvbnMuY29uZGl0aW9uIDogYWx0U2hpZnRLZXlzT25seTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMubGFzdEFuZ2xlXyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5kdXJhdGlvbl8gPSBvcHRpb25zLmR1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmR1cmF0aW9uIDogMjUwO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgZHJhZyBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICovXG5cblxuICBEcmFnUm90YXRlLnByb3RvdHlwZS5oYW5kbGVEcmFnRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgaWYgKCFtb3VzZU9ubHkobWFwQnJvd3NlckV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcblxuICAgIGlmICh2aWV3LmdldENvbnN0cmFpbnRzKCkucm90YXRpb24gPT09IGRpc2FibGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgc2l6ZSA9IG1hcC5nZXRTaXplKCk7XG4gICAgdmFyIG9mZnNldCA9IG1hcEJyb3dzZXJFdmVudC5waXhlbDtcbiAgICB2YXIgdGhldGEgPSBNYXRoLmF0YW4yKHNpemVbMV0gLyAyIC0gb2Zmc2V0WzFdLCBvZmZzZXRbMF0gLSBzaXplWzBdIC8gMik7XG5cbiAgICBpZiAodGhpcy5sYXN0QW5nbGVfICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciBkZWx0YSA9IHRoZXRhIC0gdGhpcy5sYXN0QW5nbGVfO1xuICAgICAgdmlldy5hZGp1c3RSb3RhdGlvbkludGVybmFsKC1kZWx0YSk7XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0QW5nbGVfID0gdGhldGE7XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGUgcG9pbnRlciB1cCBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSWYgdGhlIGV2ZW50IHdhcyBjb25zdW1lZC5cbiAgICovXG5cblxuICBEcmFnUm90YXRlLnByb3RvdHlwZS5oYW5kbGVVcEV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIGlmICghbW91c2VPbmx5KG1hcEJyb3dzZXJFdmVudCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcbiAgICB2aWV3LmVuZEludGVyYWN0aW9uKHRoaXMuZHVyYXRpb25fKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGUgcG9pbnRlciBkb3duIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJZiB0aGUgZXZlbnQgd2FzIGNvbnN1bWVkLlxuICAgKi9cblxuXG4gIERyYWdSb3RhdGUucHJvdG90eXBlLmhhbmRsZURvd25FdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICBpZiAoIW1vdXNlT25seShtYXBCcm93c2VyRXZlbnQpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKG1vdXNlQWN0aW9uQnV0dG9uKG1hcEJyb3dzZXJFdmVudCkgJiYgdGhpcy5jb25kaXRpb25fKG1hcEJyb3dzZXJFdmVudCkpIHtcbiAgICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgICAgbWFwLmdldFZpZXcoKS5iZWdpbkludGVyYWN0aW9uKCk7XG4gICAgICB0aGlzLmxhc3RBbmdsZV8gPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gRHJhZ1JvdGF0ZTtcbn0oUG9pbnRlckludGVyYWN0aW9uKTtcblxuZXhwb3J0IGRlZmF1bHQgRHJhZ1JvdGF0ZTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL0JveFxuICovXG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuXG5pbXBvcnQgRGlzcG9zYWJsZSBmcm9tICcuLi9EaXNwb3NhYmxlLmpzJztcbmltcG9ydCBQb2x5Z29uIGZyb20gJy4uL2dlb20vUG9seWdvbi5qcyc7XG5cbnZhciBSZW5kZXJCb3ggPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoUmVuZGVyQm94LCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzTmFtZSBDU1MgY2xhc3MgbmFtZS5cbiAgICovXG5cblxuICBmdW5jdGlvbiBSZW5kZXJCb3goY2xhc3NOYW1lKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZ2VvbS9Qb2x5Z29uLmpzXCIpLmRlZmF1bHR9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuXG4gICAgX3RoaXMuZ2VvbWV0cnlfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7SFRNTERpdkVsZW1lbnR9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmVsZW1lbnRfID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgX3RoaXMuZWxlbWVudF8uc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIF90aGlzLmVsZW1lbnRfLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnYXV0byc7XG4gICAgX3RoaXMuZWxlbWVudF8uY2xhc3NOYW1lID0gJ29sLWJveCAnICsgY2xhc3NOYW1lO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMubWFwXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9XG4gICAgICovXG5cbiAgICBfdGhpcy5zdGFydFBpeGVsXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9XG4gICAgICovXG5cbiAgICBfdGhpcy5lbmRQaXhlbF8gPSBudWxsO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQ2xlYW4gdXAuXG4gICAqL1xuXG5cbiAgUmVuZGVyQm94LnByb3RvdHlwZS5kaXNwb3NlSW50ZXJuYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zZXRNYXAobnVsbCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFJlbmRlckJveC5wcm90b3R5cGUucmVuZGVyXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3RhcnRQaXhlbCA9IHRoaXMuc3RhcnRQaXhlbF87XG4gICAgdmFyIGVuZFBpeGVsID0gdGhpcy5lbmRQaXhlbF87XG4gICAgdmFyIHB4ID0gJ3B4JztcbiAgICB2YXIgc3R5bGUgPSB0aGlzLmVsZW1lbnRfLnN0eWxlO1xuICAgIHN0eWxlLmxlZnQgPSBNYXRoLm1pbihzdGFydFBpeGVsWzBdLCBlbmRQaXhlbFswXSkgKyBweDtcbiAgICBzdHlsZS50b3AgPSBNYXRoLm1pbihzdGFydFBpeGVsWzFdLCBlbmRQaXhlbFsxXSkgKyBweDtcbiAgICBzdHlsZS53aWR0aCA9IE1hdGguYWJzKGVuZFBpeGVsWzBdIC0gc3RhcnRQaXhlbFswXSkgKyBweDtcbiAgICBzdHlsZS5oZWlnaHQgPSBNYXRoLmFicyhlbmRQaXhlbFsxXSAtIHN0YXJ0UGl4ZWxbMV0pICsgcHg7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fSBtYXAgTWFwLlxuICAgKi9cblxuXG4gIFJlbmRlckJveC5wcm90b3R5cGUuc2V0TWFwID0gZnVuY3Rpb24gKG1hcCkge1xuICAgIGlmICh0aGlzLm1hcF8pIHtcbiAgICAgIHRoaXMubWFwXy5nZXRPdmVybGF5Q29udGFpbmVyKCkucmVtb3ZlQ2hpbGQodGhpcy5lbGVtZW50Xyk7XG4gICAgICB2YXIgc3R5bGUgPSB0aGlzLmVsZW1lbnRfLnN0eWxlO1xuICAgICAgc3R5bGUubGVmdCA9ICdpbmhlcml0JztcbiAgICAgIHN0eWxlLnRvcCA9ICdpbmhlcml0JztcbiAgICAgIHN0eWxlLndpZHRoID0gJ2luaGVyaXQnO1xuICAgICAgc3R5bGUuaGVpZ2h0ID0gJ2luaGVyaXQnO1xuICAgIH1cblxuICAgIHRoaXMubWFwXyA9IG1hcDtcblxuICAgIGlmICh0aGlzLm1hcF8pIHtcbiAgICAgIHRoaXMubWFwXy5nZXRPdmVybGF5Q29udGFpbmVyKCkuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50Xyk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbH0gc3RhcnRQaXhlbCBTdGFydCBwaXhlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbH0gZW5kUGl4ZWwgRW5kIHBpeGVsLlxuICAgKi9cblxuXG4gIFJlbmRlckJveC5wcm90b3R5cGUuc2V0UGl4ZWxzID0gZnVuY3Rpb24gKHN0YXJ0UGl4ZWwsIGVuZFBpeGVsKSB7XG4gICAgdGhpcy5zdGFydFBpeGVsXyA9IHN0YXJ0UGl4ZWw7XG4gICAgdGhpcy5lbmRQaXhlbF8gPSBlbmRQaXhlbDtcbiAgICB0aGlzLmNyZWF0ZU9yVXBkYXRlR2VvbWV0cnkoKTtcbiAgICB0aGlzLnJlbmRlcl8oKTtcbiAgfTtcbiAgLyoqXG4gICAqIENyZWF0ZXMgb3IgdXBkYXRlcyB0aGUgY2FjaGVkIGdlb21ldHJ5LlxuICAgKi9cblxuXG4gIFJlbmRlckJveC5wcm90b3R5cGUuY3JlYXRlT3JVcGRhdGVHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3RhcnRQaXhlbCA9IHRoaXMuc3RhcnRQaXhlbF87XG4gICAgdmFyIGVuZFBpeGVsID0gdGhpcy5lbmRQaXhlbF87XG4gICAgdmFyIHBpeGVscyA9IFtzdGFydFBpeGVsLCBbc3RhcnRQaXhlbFswXSwgZW5kUGl4ZWxbMV1dLCBlbmRQaXhlbCwgW2VuZFBpeGVsWzBdLCBzdGFydFBpeGVsWzFdXV07XG4gICAgdmFyIGNvb3JkaW5hdGVzID0gcGl4ZWxzLm1hcCh0aGlzLm1hcF8uZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbEludGVybmFsLCB0aGlzLm1hcF8pOyAvLyBjbG9zZSB0aGUgcG9seWdvblxuXG4gICAgY29vcmRpbmF0ZXNbNF0gPSBjb29yZGluYXRlc1swXS5zbGljZSgpO1xuXG4gICAgaWYgKCF0aGlzLmdlb21ldHJ5Xykge1xuICAgICAgdGhpcy5nZW9tZXRyeV8gPSBuZXcgUG9seWdvbihbY29vcmRpbmF0ZXNdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5nZW9tZXRyeV8uc2V0Q29vcmRpbmF0ZXMoW2Nvb3JkaW5hdGVzXSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZ2VvbS9Qb2x5Z29uLmpzXCIpLmRlZmF1bHR9IEdlb21ldHJ5LlxuICAgKi9cblxuXG4gIFJlbmRlckJveC5wcm90b3R5cGUuZ2V0R2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2VvbWV0cnlfO1xuICB9O1xuXG4gIHJldHVybiBSZW5kZXJCb3g7XG59KERpc3Bvc2FibGUpO1xuXG5leHBvcnQgZGVmYXVsdCBSZW5kZXJCb3g7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9EcmFnQm94XG4gKi9cbi8vIEZJWE1FIGRyYXcgZHJhZyBib3hcblxuXG5pbXBvcnQgRXZlbnQgZnJvbSAnLi4vZXZlbnRzL0V2ZW50LmpzJztcbmltcG9ydCBQb2ludGVySW50ZXJhY3Rpb24gZnJvbSAnLi9Qb2ludGVyLmpzJztcbmltcG9ydCBSZW5kZXJCb3ggZnJvbSAnLi4vcmVuZGVyL0JveC5qcyc7XG5pbXBvcnQgeyBtb3VzZUFjdGlvbkJ1dHRvbiB9IGZyb20gJy4uL2V2ZW50cy9jb25kaXRpb24uanMnO1xuLyoqXG4gKiBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYSB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH0gYW5kIHR3b1xuICoge0BsaW5rIG1vZHVsZTpvbC9waXhlbH5QaXhlbH1zIGFuZCByZXR1cm5zIGEgYHtib29sZWFufWAuIElmIHRoZSBjb25kaXRpb24gaXMgbWV0LFxuICogdHJ1ZSBzaG91bGQgYmUgcmV0dXJuZWQuXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24odGhpczogPywgaW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHQsIGltcG9ydChcIi4uL3BpeGVsLmpzXCIpLlBpeGVsLCBpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbCk6Ym9vbGVhbn0gRW5kQ29uZGl0aW9uXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NsYXNzTmFtZT0nb2wtZHJhZ2JveCddIENTUyBjbGFzcyBuYW1lIGZvciBzdHlsaW5nIHRoZSBib3guXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V2ZW50cy9jb25kaXRpb24uanNcIikuQ29uZGl0aW9ufSBbY29uZGl0aW9uXSBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYW4ge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR+TWFwQnJvd3NlckV2ZW50fSBhbmQgcmV0dXJucyBhIGJvb2xlYW5cbiAqIHRvIGluZGljYXRlIHdoZXRoZXIgdGhhdCBldmVudCBzaG91bGQgYmUgaGFuZGxlZC5cbiAqIERlZmF1bHQgaXMge0BsaW5rIG9sL2V2ZW50cy9jb25kaXRpb25+bW91c2VBY3Rpb25CdXR0b259LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5BcmVhPTY0XSBUaGUgbWluaW11bSBhcmVhIG9mIHRoZSBib3ggaW4gcGl4ZWwsIHRoaXMgdmFsdWUgaXMgdXNlZCBieSB0aGUgZGVmYXVsdFxuICogYGJveEVuZENvbmRpdGlvbmAgZnVuY3Rpb24uXG4gKiBAcHJvcGVydHkge0VuZENvbmRpdGlvbn0gW2JveEVuZENvbmRpdGlvbl0gQSBmdW5jdGlvbiB0aGF0IHRha2VzIGEge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR+TWFwQnJvd3NlckV2ZW50fSBhbmQgdHdvXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3BpeGVsflBpeGVsfXMgdG8gaW5kaWNhdGUgd2hldGhlciBhIGBib3hlbmRgIGV2ZW50IHNob3VsZCBiZSBmaXJlZC5cbiAqIERlZmF1bHQgaXMgYHRydWVgIGlmIHRoZSBhcmVhIG9mIHRoZSBib3ggaXMgYmlnZ2VyIHRoYW4gdGhlIGBtaW5BcmVhYCBvcHRpb24uXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKHRoaXM6RHJhZ0JveCwgaW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHQpOnZvaWR9IFtvbkJveEVuZF0gQ29kZSB0byBleGVjdXRlIGp1c3RcbiAqIGJlZm9yZSBgYm94ZW5kYCBpcyBmaXJlZC5cbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cblxudmFyIERyYWdCb3hFdmVudFR5cGUgPSB7XG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgdXBvbiBkcmFnIGJveCBzdGFydC5cbiAgICogQGV2ZW50IERyYWdCb3hFdmVudCNib3hzdGFydFxuICAgKiBAYXBpXG4gICAqL1xuICBCT1hTVEFSVDogJ2JveHN0YXJ0JyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIG9uIGRyYWcgd2hlbiBib3ggaXMgYWN0aXZlLlxuICAgKiBAZXZlbnQgRHJhZ0JveEV2ZW50I2JveGRyYWdcbiAgICogQGFwaVxuICAgKi9cbiAgQk9YRFJBRzogJ2JveGRyYWcnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgdXBvbiBkcmFnIGJveCBlbmQuXG4gICAqIEBldmVudCBEcmFnQm94RXZlbnQjYm94ZW5kXG4gICAqIEBhcGlcbiAgICovXG4gIEJPWEVORDogJ2JveGVuZCcsXG5cbiAgLyoqXG4gICAqIFRyaWdnZXJlZCB1cG9uIGRyYWcgYm94IGNhbmNlbGVkLlxuICAgKiBAZXZlbnQgRHJhZ0JveEV2ZW50I2JveGNhbmNlbFxuICAgKiBAYXBpXG4gICAqL1xuICBCT1hDQU5DRUw6ICdib3hjYW5jZWwnXG59O1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBFdmVudHMgZW1pdHRlZCBieSB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL0RyYWdCb3h+RHJhZ0JveH0gaW5zdGFuY2VzIGFyZSBpbnN0YW5jZXMgb2ZcbiAqIHRoaXMgdHlwZS5cbiAqL1xuXG52YXIgRHJhZ0JveEV2ZW50ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKERyYWdCb3hFdmVudCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSBldmVudCB0eXBlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBUaGUgZXZlbnQgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE9yaWdpbmF0aW5nIGV2ZW50LlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIERyYWdCb3hFdmVudCh0eXBlLCBjb29yZGluYXRlLCBtYXBCcm93c2VyRXZlbnQpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0eXBlKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIFRoZSBjb29yZGluYXRlIG9mIHRoZSBkcmFnIGV2ZW50LlxuICAgICAqIEBjb25zdFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5jb29yZGluYXRlID0gY29vcmRpbmF0ZTtcbiAgICAvKipcbiAgICAgKiBAY29uc3RcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG4gICAgX3RoaXMubWFwQnJvd3NlckV2ZW50ID0gbWFwQnJvd3NlckV2ZW50O1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIHJldHVybiBEcmFnQm94RXZlbnQ7XG59KEV2ZW50KTtcblxuZXhwb3J0IHsgRHJhZ0JveEV2ZW50IH07XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFsbG93cyB0aGUgdXNlciB0byBkcmF3IGEgdmVjdG9yIGJveCBieSBjbGlja2luZyBhbmQgZHJhZ2dpbmcgb24gdGhlIG1hcCxcbiAqIG5vcm1hbGx5IGNvbWJpbmVkIHdpdGggYW4ge0BsaW5rIG1vZHVsZTpvbC9ldmVudHMvY29uZGl0aW9ufSB0aGF0IGxpbWl0c1xuICogaXQgdG8gd2hlbiB0aGUgc2hpZnQgb3Igb3RoZXIga2V5IGlzIGhlbGQgZG93bi4gVGhpcyBpcyB1c2VkLCBmb3IgZXhhbXBsZSxcbiAqIGZvciB6b29taW5nIHRvIGEgc3BlY2lmaWMgYXJlYSBvZiB0aGUgbWFwXG4gKiAoc2VlIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vRHJhZ1pvb21+RHJhZ1pvb219IGFuZFxuICoge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9EcmFnUm90YXRlQW5kWm9vbX0pLlxuICpcbiAqIEBmaXJlcyBEcmFnQm94RXZlbnRcbiAqIEBhcGlcbiAqL1xuXG52YXIgRHJhZ0JveCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhEcmFnQm94LCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBEcmFnQm94KG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9yZW5kZXIvQm94LmpzXCIpLmRlZmF1bHR9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmJveF8gPSBuZXcgUmVuZGVyQm94KG9wdGlvbnMuY2xhc3NOYW1lIHx8ICdvbC1kcmFnYm94Jyk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMubWluQXJlYV8gPSBvcHRpb25zLm1pbkFyZWEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubWluQXJlYSA6IDY0O1xuXG4gICAgaWYgKG9wdGlvbnMub25Cb3hFbmQpIHtcbiAgICAgIF90aGlzLm9uQm94RW5kID0gb3B0aW9ucy5vbkJveEVuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3BpeGVsLmpzXCIpLlBpeGVsfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cblxuICAgIF90aGlzLnN0YXJ0UGl4ZWxfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbmRpdGlvbl8gPSBvcHRpb25zLmNvbmRpdGlvbiA/IG9wdGlvbnMuY29uZGl0aW9uIDogbW91c2VBY3Rpb25CdXR0b247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7RW5kQ29uZGl0aW9ufVxuICAgICAqL1xuXG4gICAgX3RoaXMuYm94RW5kQ29uZGl0aW9uXyA9IG9wdGlvbnMuYm94RW5kQ29uZGl0aW9uID8gb3B0aW9ucy5ib3hFbmRDb25kaXRpb24gOiBfdGhpcy5kZWZhdWx0Qm94RW5kQ29uZGl0aW9uO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogVGhlIGRlZmF1bHQgY29uZGl0aW9uIGZvciBkZXRlcm1pbmluZyB3aGV0aGVyIHRoZSBib3hlbmQgZXZlbnRcbiAgICogc2hvdWxkIGZpcmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBUaGUgb3JpZ2luYXRpbmcgTWFwQnJvd3NlckV2ZW50XG4gICAqICAgICBsZWFkaW5nIHRvIHRoZSBib3ggZW5kLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3BpeGVsLmpzXCIpLlBpeGVsfSBzdGFydFBpeGVsIFRoZSBzdGFydGluZyBwaXhlbCBvZiB0aGUgYm94LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3BpeGVsLmpzXCIpLlBpeGVsfSBlbmRQaXhlbCBUaGUgZW5kIHBpeGVsIG9mIHRoZSBib3guXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgb3Igbm90IHRoZSBib3hlbmQgY29uZGl0aW9uIHNob3VsZCBiZSBmaXJlZC5cbiAgICovXG5cblxuICBEcmFnQm94LnByb3RvdHlwZS5kZWZhdWx0Qm94RW5kQ29uZGl0aW9uID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCwgc3RhcnRQaXhlbCwgZW5kUGl4ZWwpIHtcbiAgICB2YXIgd2lkdGggPSBlbmRQaXhlbFswXSAtIHN0YXJ0UGl4ZWxbMF07XG4gICAgdmFyIGhlaWdodCA9IGVuZFBpeGVsWzFdIC0gc3RhcnRQaXhlbFsxXTtcbiAgICByZXR1cm4gd2lkdGggKiB3aWR0aCArIGhlaWdodCAqIGhlaWdodCA+PSB0aGlzLm1pbkFyZWFfO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyBnZW9tZXRyeSBvZiBsYXN0IGRyYXduIGJveC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZ2VvbS9Qb2x5Z29uLmpzXCIpLmRlZmF1bHR9IEdlb21ldHJ5LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgRHJhZ0JveC5wcm90b3R5cGUuZ2V0R2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuYm94Xy5nZXRHZW9tZXRyeSgpO1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgZHJhZyBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICovXG5cblxuICBEcmFnQm94LnByb3RvdHlwZS5oYW5kbGVEcmFnRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgdGhpcy5ib3hfLnNldFBpeGVscyh0aGlzLnN0YXJ0UGl4ZWxfLCBtYXBCcm93c2VyRXZlbnQucGl4ZWwpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgRHJhZ0JveEV2ZW50KERyYWdCb3hFdmVudFR5cGUuQk9YRFJBRywgbWFwQnJvd3NlckV2ZW50LmNvb3JkaW5hdGUsIG1hcEJyb3dzZXJFdmVudCkpO1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgdXAgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBldmVudCB3YXMgY29uc3VtZWQuXG4gICAqL1xuXG5cbiAgRHJhZ0JveC5wcm90b3R5cGUuaGFuZGxlVXBFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICB0aGlzLmJveF8uc2V0TWFwKG51bGwpO1xuICAgIHZhciBjb21wbGV0ZUJveCA9IHRoaXMuYm94RW5kQ29uZGl0aW9uXyhtYXBCcm93c2VyRXZlbnQsIHRoaXMuc3RhcnRQaXhlbF8sIG1hcEJyb3dzZXJFdmVudC5waXhlbCk7XG5cbiAgICBpZiAoY29tcGxldGVCb3gpIHtcbiAgICAgIHRoaXMub25Cb3hFbmQobWFwQnJvd3NlckV2ZW50KTtcbiAgICB9XG5cbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IERyYWdCb3hFdmVudChjb21wbGV0ZUJveCA/IERyYWdCb3hFdmVudFR5cGUuQk9YRU5EIDogRHJhZ0JveEV2ZW50VHlwZS5CT1hDQU5DRUwsIG1hcEJyb3dzZXJFdmVudC5jb29yZGluYXRlLCBtYXBCcm93c2VyRXZlbnQpKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGUgcG9pbnRlciBkb3duIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJZiB0aGUgZXZlbnQgd2FzIGNvbnN1bWVkLlxuICAgKi9cblxuXG4gIERyYWdCb3gucHJvdG90eXBlLmhhbmRsZURvd25FdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICBpZiAodGhpcy5jb25kaXRpb25fKG1hcEJyb3dzZXJFdmVudCkpIHtcbiAgICAgIHRoaXMuc3RhcnRQaXhlbF8gPSBtYXBCcm93c2VyRXZlbnQucGl4ZWw7XG4gICAgICB0aGlzLmJveF8uc2V0TWFwKG1hcEJyb3dzZXJFdmVudC5tYXApO1xuICAgICAgdGhpcy5ib3hfLnNldFBpeGVscyh0aGlzLnN0YXJ0UGl4ZWxfLCB0aGlzLnN0YXJ0UGl4ZWxfKTtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgRHJhZ0JveEV2ZW50KERyYWdCb3hFdmVudFR5cGUuQk9YU1RBUlQsIG1hcEJyb3dzZXJFdmVudC5jb29yZGluYXRlLCBtYXBCcm93c2VyRXZlbnQpKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogRnVuY3Rpb24gdG8gZXhlY3V0ZSBqdXN0IGJlZm9yZSBgb25ib3hlbmRgIGlzIGZpcmVkXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IGV2ZW50IEV2ZW50LlxuICAgKi9cblxuXG4gIERyYWdCb3gucHJvdG90eXBlLm9uQm94RW5kID0gZnVuY3Rpb24gKGV2ZW50KSB7fTtcblxuICByZXR1cm4gRHJhZ0JveDtcbn0oUG9pbnRlckludGVyYWN0aW9uKTtcblxuZXhwb3J0IGRlZmF1bHQgRHJhZ0JveDsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2ludGVyYWN0aW9uL0RyYWdab29tXG4gKi9cblxuXG5pbXBvcnQgRHJhZ0JveCBmcm9tICcuL0RyYWdCb3guanMnO1xuaW1wb3J0IHsgY3JlYXRlT3JVcGRhdGVGcm9tQ29vcmRpbmF0ZXMsIGdldEJvdHRvbUxlZnQsIGdldENlbnRlciwgZ2V0VG9wUmlnaHQsIHNjYWxlRnJvbUNlbnRlciB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBlYXNlT3V0IH0gZnJvbSAnLi4vZWFzaW5nLmpzJztcbmltcG9ydCB7IHNoaWZ0S2V5T25seSB9IGZyb20gJy4uL2V2ZW50cy9jb25kaXRpb24uanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NsYXNzTmFtZT0nb2wtZHJhZ3pvb20nXSBDU1MgY2xhc3MgbmFtZSBmb3Igc3R5bGluZyB0aGVcbiAqIGJveC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXZlbnRzL2NvbmRpdGlvbi5qc1wiKS5Db25kaXRpb259IFtjb25kaXRpb25dIEEgZnVuY3Rpb24gdGhhdFxuICogdGFrZXMgYW4ge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR+TWFwQnJvd3NlckV2ZW50fSBhbmQgcmV0dXJucyBhXG4gKiBib29sZWFuIHRvIGluZGljYXRlIHdoZXRoZXIgdGhhdCBldmVudCBzaG91bGQgYmUgaGFuZGxlZC5cbiAqIERlZmF1bHQgaXMge0BsaW5rIG1vZHVsZTpvbC9ldmVudHMvY29uZGl0aW9ufnNoaWZ0S2V5T25seX0uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2R1cmF0aW9uPTIwMF0gQW5pbWF0aW9uIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW291dD1mYWxzZV0gVXNlIGludGVyYWN0aW9uIGZvciB6b29taW5nIG91dC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluQXJlYT02NF0gVGhlIG1pbmltdW0gYXJlYSBvZiB0aGUgYm94IGluIHBpeGVsLCB0aGlzIHZhbHVlIGlzIHVzZWQgYnkgdGhlIHBhcmVudCBkZWZhdWx0XG4gKiBgYm94RW5kQ29uZGl0aW9uYCBmdW5jdGlvbi5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFsbG93cyB0aGUgdXNlciB0byB6b29tIHRoZSBtYXAgYnkgY2xpY2tpbmcgYW5kIGRyYWdnaW5nIG9uIHRoZSBtYXAsXG4gKiBub3JtYWxseSBjb21iaW5lZCB3aXRoIGFuIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzL2NvbmRpdGlvbn0gdGhhdCBsaW1pdHNcbiAqIGl0IHRvIHdoZW4gYSBrZXksIHNoaWZ0IGJ5IGRlZmF1bHQsIGlzIGhlbGQgZG93bi5cbiAqXG4gKiBUbyBjaGFuZ2UgdGhlIHN0eWxlIG9mIHRoZSBib3gsIHVzZSBDU1MgYW5kIHRoZSBgLm9sLWRyYWd6b29tYCBzZWxlY3Rvciwgb3JcbiAqIHlvdXIgY3VzdG9tIG9uZSBjb25maWd1cmVkIHdpdGggYGNsYXNzTmFtZWAuXG4gKiBAYXBpXG4gKi9cblxudmFyIERyYWdab29tID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKERyYWdab29tLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBEcmFnWm9vbShvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICB2YXIgY29uZGl0aW9uID0gb3B0aW9ucy5jb25kaXRpb24gPyBvcHRpb25zLmNvbmRpdGlvbiA6IHNoaWZ0S2V5T25seTtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIGNvbmRpdGlvbjogY29uZGl0aW9uLFxuICAgICAgY2xhc3NOYW1lOiBvcHRpb25zLmNsYXNzTmFtZSB8fCAnb2wtZHJhZ3pvb20nLFxuICAgICAgbWluQXJlYTogb3B0aW9ucy5taW5BcmVhXG4gICAgfSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5kdXJhdGlvbl8gPSBvcHRpb25zLmR1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmR1cmF0aW9uIDogMjAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5vdXRfID0gb3B0aW9ucy5vdXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMub3V0IDogZmFsc2U7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBGdW5jdGlvbiB0byBleGVjdXRlIGp1c3QgYmVmb3JlIGBvbmJveGVuZGAgaXMgZmlyZWRcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gZXZlbnQgRXZlbnQuXG4gICAqL1xuXG5cbiAgRHJhZ1pvb20ucHJvdG90eXBlLm9uQm94RW5kID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdmFyIG1hcCA9IHRoaXMuZ2V0TWFwKCk7XG4gICAgdmFyIHZpZXcgPVxuICAgIC8qKiBAdHlwZSB7IWltcG9ydChcIi4uL1ZpZXcuanNcIikuZGVmYXVsdH0gKi9cbiAgICBtYXAuZ2V0VmlldygpO1xuICAgIHZhciBzaXplID1cbiAgICAvKiogQHR5cGUgeyFpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9ICovXG4gICAgbWFwLmdldFNpemUoKTtcbiAgICB2YXIgZXh0ZW50ID0gdGhpcy5nZXRHZW9tZXRyeSgpLmdldEV4dGVudCgpO1xuXG4gICAgaWYgKHRoaXMub3V0Xykge1xuICAgICAgdmFyIG1hcEV4dGVudCA9IHZpZXcuY2FsY3VsYXRlRXh0ZW50SW50ZXJuYWwoc2l6ZSk7XG4gICAgICB2YXIgYm94UGl4ZWxFeHRlbnQgPSBjcmVhdGVPclVwZGF0ZUZyb21Db29yZGluYXRlcyhbbWFwLmdldFBpeGVsRnJvbUNvb3JkaW5hdGVJbnRlcm5hbChnZXRCb3R0b21MZWZ0KGV4dGVudCkpLCBtYXAuZ2V0UGl4ZWxGcm9tQ29vcmRpbmF0ZUludGVybmFsKGdldFRvcFJpZ2h0KGV4dGVudCkpXSk7XG4gICAgICB2YXIgZmFjdG9yID0gdmlldy5nZXRSZXNvbHV0aW9uRm9yRXh0ZW50SW50ZXJuYWwoYm94UGl4ZWxFeHRlbnQsIHNpemUpO1xuICAgICAgc2NhbGVGcm9tQ2VudGVyKG1hcEV4dGVudCwgMSAvIGZhY3Rvcik7XG4gICAgICBleHRlbnQgPSBtYXBFeHRlbnQ7XG4gICAgfVxuXG4gICAgdmFyIHJlc29sdXRpb24gPSB2aWV3LmdldENvbnN0cmFpbmVkUmVzb2x1dGlvbih2aWV3LmdldFJlc29sdXRpb25Gb3JFeHRlbnRJbnRlcm5hbChleHRlbnQsIHNpemUpKTtcbiAgICB2YXIgY2VudGVyID0gdmlldy5nZXRDb25zdHJhaW5lZENlbnRlcihnZXRDZW50ZXIoZXh0ZW50KSwgcmVzb2x1dGlvbik7XG4gICAgdmlldy5hbmltYXRlSW50ZXJuYWwoe1xuICAgICAgcmVzb2x1dGlvbjogcmVzb2x1dGlvbixcbiAgICAgIGNlbnRlcjogY2VudGVyLFxuICAgICAgZHVyYXRpb246IHRoaXMuZHVyYXRpb25fLFxuICAgICAgZWFzaW5nOiBlYXNlT3V0XG4gICAgfSk7XG4gIH07XG5cbiAgcmV0dXJuIERyYWdab29tO1xufShEcmFnQm94KTtcblxuZXhwb3J0IGRlZmF1bHQgRHJhZ1pvb207IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2V2ZW50cy9LZXlDb2RlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7bnVtYmVyfVxuICogQGNvbnN0XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgTEVGVDogMzcsXG4gIFVQOiAzOCxcbiAgUklHSFQ6IDM5LFxuICBET1dOOiA0MFxufTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2ludGVyYWN0aW9uL0tleWJvYXJkUGFuXG4gKi9cblxuXG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IEludGVyYWN0aW9uLCB7IHBhbiB9IGZyb20gJy4vSW50ZXJhY3Rpb24uanMnO1xuaW1wb3J0IEtleUNvZGUgZnJvbSAnLi4vZXZlbnRzL0tleUNvZGUuanMnO1xuaW1wb3J0IHsgbm9Nb2RpZmllcktleXMsIHRhcmdldE5vdEVkaXRhYmxlIH0gZnJvbSAnLi4vZXZlbnRzL2NvbmRpdGlvbi5qcyc7XG5pbXBvcnQgeyByb3RhdGUgYXMgcm90YXRlQ29vcmRpbmF0ZSB9IGZyb20gJy4uL2Nvb3JkaW5hdGUuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V2ZW50cy9jb25kaXRpb24uanNcIikuQ29uZGl0aW9ufSBbY29uZGl0aW9uXSBBIGZ1bmN0aW9uIHRoYXRcbiAqIHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudH0gYW5kIHJldHVybnMgYVxuICogYm9vbGVhbiB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoYXQgZXZlbnQgc2hvdWxkIGJlIGhhbmRsZWQuIERlZmF1bHQgaXNcbiAqIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzL2NvbmRpdGlvbn5ub01vZGlmaWVyS2V5c30gYW5kXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50cy9jb25kaXRpb25+dGFyZ2V0Tm90RWRpdGFibGV9LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj0xMDBdIEFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3BpeGVsRGVsdGE9MTI4XSBUaGUgYW1vdW50IG9mIHBpeGVscyB0byBwYW4gb24gZWFjaCBrZXlcbiAqIHByZXNzLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWxsb3dzIHRoZSB1c2VyIHRvIHBhbiB0aGUgbWFwIHVzaW5nIGtleWJvYXJkIGFycm93cy5cbiAqIE5vdGUgdGhhdCwgYWx0aG91Z2ggdGhpcyBpbnRlcmFjdGlvbiBpcyBieSBkZWZhdWx0IGluY2x1ZGVkIGluIG1hcHMsXG4gKiB0aGUga2V5cyBjYW4gb25seSBiZSB1c2VkIHdoZW4gYnJvd3NlciBmb2N1cyBpcyBvbiB0aGUgZWxlbWVudCB0byB3aGljaFxuICogdGhlIGtleWJvYXJkIGV2ZW50cyBhcmUgYXR0YWNoZWQuIEJ5IGRlZmF1bHQsIHRoaXMgaXMgdGhlIG1hcCBkaXYsXG4gKiB0aG91Z2ggeW91IGNhbiBjaGFuZ2UgdGhpcyB3aXRoIHRoZSBga2V5Ym9hcmRFdmVudFRhcmdldGAgaW5cbiAqIHtAbGluayBtb2R1bGU6b2wvTWFwfk1hcH0uIGBkb2N1bWVudGAgbmV2ZXIgbG9zZXMgZm9jdXMgYnV0LCBmb3IgYW55IG90aGVyXG4gKiBlbGVtZW50LCBmb2N1cyB3aWxsIGhhdmUgdG8gYmUgb24sIGFuZCByZXR1cm5lZCB0bywgdGhpcyBlbGVtZW50IGlmIHRoZSBrZXlzXG4gKiBhcmUgdG8gZnVuY3Rpb24uXG4gKiBTZWUgYWxzbyB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL0tleWJvYXJkWm9vbX5LZXlib2FyZFpvb219LlxuICogQGFwaVxuICovXG5cbnZhciBLZXlib2FyZFBhbiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhLZXlib2FyZFBhbiwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gS2V5Ym9hcmRQYW4ob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyB8fCB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBCcm93c2VyIGV2ZW50LlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IENvbWJpbmVkIGNvbmRpdGlvbiByZXN1bHQuXG4gICAgICovXG5cbiAgICBfdGhpcy5kZWZhdWx0Q29uZGl0aW9uXyA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICAgIHJldHVybiBub01vZGlmaWVyS2V5cyhtYXBCcm93c2VyRXZlbnQpICYmIHRhcmdldE5vdEVkaXRhYmxlKG1hcEJyb3dzZXJFdmVudCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuY29uZGl0aW9uXyA9IG9wdGlvbnMuY29uZGl0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNvbmRpdGlvbiA6IF90aGlzLmRlZmF1bHRDb25kaXRpb25fO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmR1cmF0aW9uXyA9IG9wdGlvbnMuZHVyYXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZHVyYXRpb24gOiAxMDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMucGl4ZWxEZWx0YV8gPSBvcHRpb25zLnBpeGVsRGVsdGEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucGl4ZWxEZWx0YSA6IDEyODtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEhhbmRsZXMgdGhlIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50IG1hcCBicm93c2VyIGV2ZW50fSBpZiBpdCB3YXMgYVxuICAgKiBgS2V5RXZlbnRgLCBhbmQgZGVjaWRlcyB0aGUgZGlyZWN0aW9uIHRvIHBhbiB0byAoaWYgYW4gYXJyb3cga2V5IHdhc1xuICAgKiBwcmVzc2VkKS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgZmFsc2VgIHRvIHN0b3AgZXZlbnQgcHJvcGFnYXRpb24uXG4gICAqIEB0aGlzIHtLZXlib2FyZFBhbn1cbiAgICovXG5cblxuICBLZXlib2FyZFBhbi5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgdmFyIHN0b3BFdmVudCA9IGZhbHNlO1xuXG4gICAgaWYgKG1hcEJyb3dzZXJFdmVudC50eXBlID09IEV2ZW50VHlwZS5LRVlET1dOKSB7XG4gICAgICB2YXIga2V5RXZlbnQgPVxuICAgICAgLyoqIEB0eXBlIHtLZXlib2FyZEV2ZW50fSAqL1xuICAgICAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gICAgICB2YXIga2V5Q29kZSA9IGtleUV2ZW50LmtleUNvZGU7XG5cbiAgICAgIGlmICh0aGlzLmNvbmRpdGlvbl8obWFwQnJvd3NlckV2ZW50KSAmJiAoa2V5Q29kZSA9PSBLZXlDb2RlLkRPV04gfHwga2V5Q29kZSA9PSBLZXlDb2RlLkxFRlQgfHwga2V5Q29kZSA9PSBLZXlDb2RlLlJJR0hUIHx8IGtleUNvZGUgPT0gS2V5Q29kZS5VUCkpIHtcbiAgICAgICAgdmFyIG1hcCA9IG1hcEJyb3dzZXJFdmVudC5tYXA7XG4gICAgICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcbiAgICAgICAgdmFyIG1hcFVuaXRzRGVsdGEgPSB2aWV3LmdldFJlc29sdXRpb24oKSAqIHRoaXMucGl4ZWxEZWx0YV87XG4gICAgICAgIHZhciBkZWx0YVggPSAwLFxuICAgICAgICAgICAgZGVsdGFZID0gMDtcblxuICAgICAgICBpZiAoa2V5Q29kZSA9PSBLZXlDb2RlLkRPV04pIHtcbiAgICAgICAgICBkZWx0YVkgPSAtbWFwVW5pdHNEZWx0YTtcbiAgICAgICAgfSBlbHNlIGlmIChrZXlDb2RlID09IEtleUNvZGUuTEVGVCkge1xuICAgICAgICAgIGRlbHRhWCA9IC1tYXBVbml0c0RlbHRhO1xuICAgICAgICB9IGVsc2UgaWYgKGtleUNvZGUgPT0gS2V5Q29kZS5SSUdIVCkge1xuICAgICAgICAgIGRlbHRhWCA9IG1hcFVuaXRzRGVsdGE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGVsdGFZID0gbWFwVW5pdHNEZWx0YTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBkZWx0YSA9IFtkZWx0YVgsIGRlbHRhWV07XG4gICAgICAgIHJvdGF0ZUNvb3JkaW5hdGUoZGVsdGEsIHZpZXcuZ2V0Um90YXRpb24oKSk7XG4gICAgICAgIHBhbih2aWV3LCBkZWx0YSwgdGhpcy5kdXJhdGlvbl8pO1xuICAgICAgICBrZXlFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBzdG9wRXZlbnQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAhc3RvcEV2ZW50O1xuICB9O1xuXG4gIHJldHVybiBLZXlib2FyZFBhbjtcbn0oSW50ZXJhY3Rpb24pO1xuXG5leHBvcnQgZGVmYXVsdCBLZXlib2FyZFBhbjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2ludGVyYWN0aW9uL0tleWJvYXJkWm9vbVxuICovXG5cblxuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBJbnRlcmFjdGlvbiwgeyB6b29tQnlEZWx0YSB9IGZyb20gJy4vSW50ZXJhY3Rpb24uanMnO1xuaW1wb3J0IHsgdGFyZ2V0Tm90RWRpdGFibGUgfSBmcm9tICcuLi9ldmVudHMvY29uZGl0aW9uLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj0xMDBdIEFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V2ZW50cy9jb25kaXRpb24uanNcIikuQ29uZGl0aW9ufSBbY29uZGl0aW9uXSBBIGZ1bmN0aW9uIHRoYXRcbiAqIHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudH0gYW5kIHJldHVybnMgYVxuICogYm9vbGVhbiB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoYXQgZXZlbnQgc2hvdWxkIGJlIGhhbmRsZWQuIERlZmF1bHQgaXNcbiAqIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzL2NvbmRpdGlvbn50YXJnZXROb3RFZGl0YWJsZX0uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2RlbHRhPTFdIFRoZSB6b29tIGxldmVsIGRlbHRhIG9uIGVhY2gga2V5IHByZXNzLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWxsb3dzIHRoZSB1c2VyIHRvIHpvb20gdGhlIG1hcCB1c2luZyBrZXlib2FyZCArIGFuZCAtLlxuICogTm90ZSB0aGF0LCBhbHRob3VnaCB0aGlzIGludGVyYWN0aW9uIGlzIGJ5IGRlZmF1bHQgaW5jbHVkZWQgaW4gbWFwcyxcbiAqIHRoZSBrZXlzIGNhbiBvbmx5IGJlIHVzZWQgd2hlbiBicm93c2VyIGZvY3VzIGlzIG9uIHRoZSBlbGVtZW50IHRvIHdoaWNoXG4gKiB0aGUga2V5Ym9hcmQgZXZlbnRzIGFyZSBhdHRhY2hlZC4gQnkgZGVmYXVsdCwgdGhpcyBpcyB0aGUgbWFwIGRpdixcbiAqIHRob3VnaCB5b3UgY2FuIGNoYW5nZSB0aGlzIHdpdGggdGhlIGBrZXlib2FyZEV2ZW50VGFyZ2V0YCBpblxuICoge0BsaW5rIG1vZHVsZTpvbC9NYXB+TWFwfS4gYGRvY3VtZW50YCBuZXZlciBsb3NlcyBmb2N1cyBidXQsIGZvciBhbnkgb3RoZXJcbiAqIGVsZW1lbnQsIGZvY3VzIHdpbGwgaGF2ZSB0byBiZSBvbiwgYW5kIHJldHVybmVkIHRvLCB0aGlzIGVsZW1lbnQgaWYgdGhlIGtleXNcbiAqIGFyZSB0byBmdW5jdGlvbi5cbiAqIFNlZSBhbHNvIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vS2V5Ym9hcmRQYW5+S2V5Ym9hcmRQYW59LlxuICogQGFwaVxuICovXG5cbnZhciBLZXlib2FyZFpvb20gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoS2V5Ym9hcmRab29tLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBLZXlib2FyZFpvb20ob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyA/IG9wdF9vcHRpb25zIDoge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXZlbnRzL2NvbmRpdGlvbi5qc1wiKS5Db25kaXRpb259XG4gICAgICovXG5cbiAgICBfdGhpcy5jb25kaXRpb25fID0gb3B0aW9ucy5jb25kaXRpb24gPyBvcHRpb25zLmNvbmRpdGlvbiA6IHRhcmdldE5vdEVkaXRhYmxlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmRlbHRhXyA9IG9wdGlvbnMuZGVsdGEgPyBvcHRpb25zLmRlbHRhIDogMTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5kdXJhdGlvbl8gPSBvcHRpb25zLmR1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmR1cmF0aW9uIDogMTAwO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogSGFuZGxlcyB0aGUge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnQgbWFwIGJyb3dzZXIgZXZlbnR9IGlmIGl0IHdhcyBhXG4gICAqIGBLZXlFdmVudGAsIGFuZCBkZWNpZGVzIHdoZXRoZXIgdG8gem9vbSBpbiBvciBvdXQgKGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZVxuICAgKiBrZXkgcHJlc3NlZCB3YXMgJysnIG9yICctJykuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYGZhbHNlYCB0byBzdG9wIGV2ZW50IHByb3BhZ2F0aW9uLlxuICAgKiBAdGhpcyB7S2V5Ym9hcmRab29tfVxuICAgKi9cblxuXG4gIEtleWJvYXJkWm9vbS5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgdmFyIHN0b3BFdmVudCA9IGZhbHNlO1xuXG4gICAgaWYgKG1hcEJyb3dzZXJFdmVudC50eXBlID09IEV2ZW50VHlwZS5LRVlET1dOIHx8IG1hcEJyb3dzZXJFdmVudC50eXBlID09IEV2ZW50VHlwZS5LRVlQUkVTUykge1xuICAgICAgdmFyIGtleUV2ZW50ID1cbiAgICAgIC8qKiBAdHlwZSB7S2V5Ym9hcmRFdmVudH0gKi9cbiAgICAgIG1hcEJyb3dzZXJFdmVudC5vcmlnaW5hbEV2ZW50O1xuICAgICAgdmFyIGNoYXJDb2RlID0ga2V5RXZlbnQuY2hhckNvZGU7XG5cbiAgICAgIGlmICh0aGlzLmNvbmRpdGlvbl8obWFwQnJvd3NlckV2ZW50KSAmJiAoY2hhckNvZGUgPT0gJysnLmNoYXJDb2RlQXQoMCkgfHwgY2hhckNvZGUgPT0gJy0nLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgICAgICB2YXIgZGVsdGEgPSBjaGFyQ29kZSA9PSAnKycuY2hhckNvZGVBdCgwKSA/IHRoaXMuZGVsdGFfIDogLXRoaXMuZGVsdGFfO1xuICAgICAgICB2YXIgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG4gICAgICAgIHpvb21CeURlbHRhKHZpZXcsIGRlbHRhLCB1bmRlZmluZWQsIHRoaXMuZHVyYXRpb25fKTtcbiAgICAgICAga2V5RXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgc3RvcEV2ZW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gIXN0b3BFdmVudDtcbiAgfTtcblxuICByZXR1cm4gS2V5Ym9hcmRab29tO1xufShJbnRlcmFjdGlvbik7XG5cbmV4cG9ydCBkZWZhdWx0IEtleWJvYXJkWm9vbTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvS2luZXRpY1xuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogSW1wbGVtZW50YXRpb24gb2YgaW5lcnRpYWwgZGVjZWxlcmF0aW9uIGZvciBtYXAgbW92ZW1lbnQuXG4gKlxuICogQGFwaVxuICovXG52YXIgS2luZXRpYyA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gZGVjYXkgUmF0ZSBvZiBkZWNheSAobXVzdCBiZSBuZWdhdGl2ZSkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtaW5WZWxvY2l0eSBNaW5pbXVtIHZlbG9jaXR5IChwaXhlbHMvbWlsbGlzZWNvbmQpLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZGVsYXkgRGVsYXkgdG8gY29uc2lkZXIgdG8gY2FsY3VsYXRlIHRoZSBraW5ldGljXG4gICAqICAgICBpbml0aWFsIHZhbHVlcyAobWlsbGlzZWNvbmRzKS5cbiAgICovXG4gIGZ1bmN0aW9uIEtpbmV0aWMoZGVjYXksIG1pblZlbG9jaXR5LCBkZWxheSkge1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmRlY2F5XyA9IGRlY2F5O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMubWluVmVsb2NpdHlfID0gbWluVmVsb2NpdHk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5kZWxheV8gPSBkZWxheTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgdGhpcy5wb2ludHNfID0gW107XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5hbmdsZV8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMuaW5pdGlhbFZlbG9jaXR5XyA9IDA7XG4gIH1cbiAgLyoqXG4gICAqIEZJWE1FIGVtcHR5IGRlc2NyaXB0aW9uIGZvciBqc2RvY1xuICAgKi9cblxuXG4gIEtpbmV0aWMucHJvdG90eXBlLmJlZ2luID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucG9pbnRzXy5sZW5ndGggPSAwO1xuICAgIHRoaXMuYW5nbGVfID0gMDtcbiAgICB0aGlzLmluaXRpYWxWZWxvY2l0eV8gPSAwO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAgICovXG5cblxuICBLaW5ldGljLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIHRoaXMucG9pbnRzXy5wdXNoKHgsIHksIERhdGUubm93KCkpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB3ZSBzaG91bGQgZG8ga2luZXRpYyBhbmltYXRpb24uXG4gICAqL1xuXG5cbiAgS2luZXRpYy5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnBvaW50c18ubGVuZ3RoIDwgNikge1xuICAgICAgLy8gYXQgbGVhc3QgMiBwb2ludHMgYXJlIHJlcXVpcmVkIChpLmUuIHRoZXJlIG11c3QgYmUgYXQgbGVhc3QgNiBlbGVtZW50c1xuICAgICAgLy8gaW4gdGhlIGFycmF5KVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBkZWxheSA9IERhdGUubm93KCkgLSB0aGlzLmRlbGF5XztcbiAgICB2YXIgbGFzdEluZGV4ID0gdGhpcy5wb2ludHNfLmxlbmd0aCAtIDM7XG5cbiAgICBpZiAodGhpcy5wb2ludHNfW2xhc3RJbmRleCArIDJdIDwgZGVsYXkpIHtcbiAgICAgIC8vIHRoZSBsYXN0IHRyYWNrZWQgcG9pbnQgaXMgdG9vIG9sZCwgd2hpY2ggbWVhbnMgdGhhdCB0aGUgdXNlciBzdG9wcGVkXG4gICAgICAvLyBwYW5uaW5nIGJlZm9yZSByZWxlYXNpbmcgdGhlIG1hcFxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gLy8gZ2V0IHRoZSBmaXJzdCBwb2ludCB3aGljaCBzdGlsbCBmYWxscyBpbnRvIHRoZSBkZWxheSB0aW1lXG5cblxuICAgIHZhciBmaXJzdEluZGV4ID0gbGFzdEluZGV4IC0gMztcblxuICAgIHdoaWxlIChmaXJzdEluZGV4ID4gMCAmJiB0aGlzLnBvaW50c19bZmlyc3RJbmRleCArIDJdID4gZGVsYXkpIHtcbiAgICAgIGZpcnN0SW5kZXggLT0gMztcbiAgICB9XG5cbiAgICB2YXIgZHVyYXRpb24gPSB0aGlzLnBvaW50c19bbGFzdEluZGV4ICsgMl0gLSB0aGlzLnBvaW50c19bZmlyc3RJbmRleCArIDJdOyAvLyB3ZSBkb24ndCB3YW50IGEgZHVyYXRpb24gb2YgMCAoZGl2aWRlIGJ5IHplcm8pXG4gICAgLy8gd2UgYWxzbyBtYWtlIHN1cmUgdGhlIHVzZXIgcGFubmVkIGZvciBhIGR1cmF0aW9uIG9mIGF0IGxlYXN0IG9uZSBmcmFtZVxuICAgIC8vICgxLzYwcykgdG8gY29tcHV0ZSBzYW5lIGRpc3BsYWNlbWVudCB2YWx1ZXNcblxuICAgIGlmIChkdXJhdGlvbiA8IDEwMDAgLyA2MCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBkeCA9IHRoaXMucG9pbnRzX1tsYXN0SW5kZXhdIC0gdGhpcy5wb2ludHNfW2ZpcnN0SW5kZXhdO1xuICAgIHZhciBkeSA9IHRoaXMucG9pbnRzX1tsYXN0SW5kZXggKyAxXSAtIHRoaXMucG9pbnRzX1tmaXJzdEluZGV4ICsgMV07XG4gICAgdGhpcy5hbmdsZV8gPSBNYXRoLmF0YW4yKGR5LCBkeCk7XG4gICAgdGhpcy5pbml0aWFsVmVsb2NpdHlfID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KSAvIGR1cmF0aW9uO1xuICAgIHJldHVybiB0aGlzLmluaXRpYWxWZWxvY2l0eV8gPiB0aGlzLm1pblZlbG9jaXR5XztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn0gVG90YWwgZGlzdGFuY2UgdHJhdmVsbGVkIChwaXhlbHMpLlxuICAgKi9cblxuXG4gIEtpbmV0aWMucHJvdG90eXBlLmdldERpc3RhbmNlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAodGhpcy5taW5WZWxvY2l0eV8gLSB0aGlzLmluaXRpYWxWZWxvY2l0eV8pIC8gdGhpcy5kZWNheV87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEFuZ2xlIG9mIHRoZSBraW5ldGljIHBhbm5pbmcgYW5pbWF0aW9uIChyYWRpYW5zKS5cbiAgICovXG5cblxuICBLaW5ldGljLnByb3RvdHlwZS5nZXRBbmdsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5hbmdsZV87XG4gIH07XG5cbiAgcmV0dXJuIEtpbmV0aWM7XG59KCk7XG5cbmV4cG9ydCBkZWZhdWx0IEtpbmV0aWM7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9Nb3VzZVdoZWVsWm9vbVxuICovXG5cblxuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBJbnRlcmFjdGlvbiwgeyB6b29tQnlEZWx0YSB9IGZyb20gJy4vSW50ZXJhY3Rpb24uanMnO1xuaW1wb3J0IHsgREVWSUNFX1BJWEVMX1JBVElPLCBGSVJFRk9YIH0gZnJvbSAnLi4vaGFzLmpzJztcbmltcG9ydCB7IGFsbCwgYWx3YXlzLCBmb2N1c1dpdGhUYWJpbmRleCB9IGZyb20gJy4uL2V2ZW50cy9jb25kaXRpb24uanMnO1xuaW1wb3J0IHsgY2xhbXAgfSBmcm9tICcuLi9tYXRoLmpzJztcbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuXG5leHBvcnQgdmFyIE1vZGUgPSB7XG4gIFRSQUNLUEFEOiAndHJhY2twYWQnLFxuICBXSEVFTDogJ3doZWVsJ1xufTtcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn0gW2NvbmRpdGlvbl0gQSBmdW5jdGlvbiB0aGF0XG4gKiB0YWtlcyBhbiB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH5NYXBCcm93c2VyRXZlbnR9IGFuZCByZXR1cm5zIGFcbiAqIGJvb2xlYW4gdG8gaW5kaWNhdGUgd2hldGhlciB0aGF0IGV2ZW50IHNob3VsZCBiZSBoYW5kbGVkLiBEZWZhdWx0IGlzXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50cy9jb25kaXRpb25+YWx3YXlzfS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW29uRm9jdXNPbmx5PWZhbHNlXSBXaGVuIHRoZSBtYXAncyB0YXJnZXQgaGFzIGEgYHRhYmluZGV4YCBhdHRyaWJ1dGUgc2V0LFxuICogdGhlIGludGVyYWN0aW9uIHdpbGwgb25seSBoYW5kbGUgZXZlbnRzIHdoZW4gdGhlIG1hcCBoYXMgdGhlIGZvY3VzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhEZWx0YT0xXSBNYXhpbXVtIG1vdXNlIHdoZWVsIGRlbHRhLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj0yNTBdIEFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RpbWVvdXQ9ODBdIE1vdXNlIHdoZWVsIHRpbWVvdXQgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbdXNlQW5jaG9yPXRydWVdIEVuYWJsZSB6b29taW5nIHVzaW5nIHRoZSBtb3VzZSdzXG4gKiBsb2NhdGlvbiBhcyB0aGUgYW5jaG9yLiBXaGVuIHNldCB0byBgZmFsc2VgLCB6b29taW5nIGluIGFuZCBvdXQgd2lsbCB6b29tIHRvXG4gKiB0aGUgY2VudGVyIG9mIHRoZSBzY3JlZW4gaW5zdGVhZCBvZiB6b29taW5nIG9uIHRoZSBtb3VzZSdzIGxvY2F0aW9uLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbY29uc3RyYWluUmVzb2x1dGlvbj1mYWxzZV0gSWYgdHJ1ZSwgdGhlIG1vdXNlIHdoZWVsIHpvb21cbiAqIGV2ZW50IHdpbGwgYWx3YXlzIGFuaW1hdGUgdG8gdGhlIGNsb3Nlc3Qgem9vbSBsZXZlbCBhZnRlciBhbiBpbnRlcmFjdGlvbjtcbiAqIGZhbHNlIG1lYW5zIGludGVybWVkaWFyeSB6b29tIGxldmVscyBhcmUgYWxsb3dlZC5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFsbG93cyB0aGUgdXNlciB0byB6b29tIHRoZSBtYXAgYnkgc2Nyb2xsaW5nIHRoZSBtb3VzZSB3aGVlbC5cbiAqIEBhcGlcbiAqL1xuXG52YXIgTW91c2VXaGVlbFpvb20gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoTW91c2VXaGVlbFpvb20sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIE1vdXNlV2hlZWxab29tKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcyxcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vSW50ZXJhY3Rpb24uanNcIikuSW50ZXJhY3Rpb25PcHRpb25zfSAqL1xuICAgIG9wdGlvbnMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMudG90YWxEZWx0YV8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxhc3REZWx0YV8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLm1heERlbHRhXyA9IG9wdGlvbnMubWF4RGVsdGEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubWF4RGVsdGEgOiAxO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmR1cmF0aW9uXyA9IG9wdGlvbnMuZHVyYXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZHVyYXRpb24gOiAyNTA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGltZW91dF8gPSBvcHRpb25zLnRpbWVvdXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudGltZW91dCA6IDgwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy51c2VBbmNob3JfID0gb3B0aW9ucy51c2VBbmNob3IgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudXNlQW5jaG9yIDogdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29uc3RyYWluUmVzb2x1dGlvbl8gPSBvcHRpb25zLmNvbnN0cmFpblJlc29sdXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY29uc3RyYWluUmVzb2x1dGlvbiA6IGZhbHNlO1xuICAgIHZhciBjb25kaXRpb24gPSBvcHRpb25zLmNvbmRpdGlvbiA/IG9wdGlvbnMuY29uZGl0aW9uIDogYWx3YXlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2V2ZW50cy9jb25kaXRpb24uanNcIikuQ29uZGl0aW9ufVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29uZGl0aW9uXyA9IG9wdGlvbnMub25Gb2N1c09ubHkgPyBhbGwoZm9jdXNXaXRoVGFiaW5kZXgsIGNvbmRpdGlvbikgOiBjb25kaXRpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmxhc3RBbmNob3JfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3RhcnRUaW1lXyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/fVxuICAgICAqL1xuXG4gICAgX3RoaXMudGltZW91dElkXztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtNb2RlfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLm1vZGVfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIFRyYWNrcGFkIGV2ZW50cyBzZXBhcmF0ZWQgYnkgdGhpcyBkZWxheSB3aWxsIGJlIGNvbnNpZGVyZWQgc2VwYXJhdGVcbiAgICAgKiBpbnRlcmFjdGlvbnMuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRyYWNrcGFkRXZlbnRHYXBfID0gNDAwO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHs/fVxuICAgICAqL1xuXG4gICAgX3RoaXMudHJhY2twYWRUaW1lb3V0SWRfO1xuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgZGVsdGEgdmFsdWVzIHBlciB6b29tIGxldmVsXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZGVsdGFQZXJab29tXyA9IDMwMDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTW91c2VXaGVlbFpvb20ucHJvdG90eXBlLmVuZEludGVyYWN0aW9uXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRyYWNrcGFkVGltZW91dElkXyA9IHVuZGVmaW5lZDtcbiAgICB2YXIgdmlldyA9IHRoaXMuZ2V0TWFwKCkuZ2V0VmlldygpO1xuICAgIHZpZXcuZW5kSW50ZXJhY3Rpb24odW5kZWZpbmVkLCB0aGlzLmxhc3REZWx0YV8gPyB0aGlzLmxhc3REZWx0YV8gPiAwID8gMSA6IC0xIDogMCwgdGhpcy5sYXN0QW5jaG9yXyk7XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudCBtYXAgYnJvd3NlciBldmVudH0gKGlmIGl0IHdhcyBhIG1vdXNld2hlZWwtZXZlbnQpIGFuZCBldmVudHVhbGx5XG4gICAqIHpvb21zIHRoZSBtYXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYGZhbHNlYCB0byBzdG9wIGV2ZW50IHByb3BhZ2F0aW9uLlxuICAgKi9cblxuXG4gIE1vdXNlV2hlZWxab29tLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuY29uZGl0aW9uXyhtYXBCcm93c2VyRXZlbnQpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgdHlwZSA9IG1hcEJyb3dzZXJFdmVudC50eXBlO1xuXG4gICAgaWYgKHR5cGUgIT09IEV2ZW50VHlwZS5XSEVFTCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdmFyIG1hcCA9IG1hcEJyb3dzZXJFdmVudC5tYXA7XG4gICAgdmFyIHdoZWVsRXZlbnQgPVxuICAgIC8qKiBAdHlwZSB7V2hlZWxFdmVudH0gKi9cbiAgICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgICB3aGVlbEV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAodGhpcy51c2VBbmNob3JfKSB7XG4gICAgICB0aGlzLmxhc3RBbmNob3JfID0gbWFwQnJvd3NlckV2ZW50LmNvb3JkaW5hdGU7XG4gICAgfSAvLyBEZWx0YSBub3JtYWxpc2F0aW9uIGluc3BpcmVkIGJ5XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvYmxvYi8wMDFjN2I5L2pzL3VpL2hhbmRsZXIvc2Nyb2xsX3pvb20uanNcblxuXG4gICAgdmFyIGRlbHRhO1xuXG4gICAgaWYgKG1hcEJyb3dzZXJFdmVudC50eXBlID09IEV2ZW50VHlwZS5XSEVFTCkge1xuICAgICAgZGVsdGEgPSB3aGVlbEV2ZW50LmRlbHRhWTtcblxuICAgICAgaWYgKEZJUkVGT1ggJiYgd2hlZWxFdmVudC5kZWx0YU1vZGUgPT09IFdoZWVsRXZlbnQuRE9NX0RFTFRBX1BJWEVMKSB7XG4gICAgICAgIGRlbHRhIC89IERFVklDRV9QSVhFTF9SQVRJTztcbiAgICAgIH1cblxuICAgICAgaWYgKHdoZWVsRXZlbnQuZGVsdGFNb2RlID09PSBXaGVlbEV2ZW50LkRPTV9ERUxUQV9MSU5FKSB7XG4gICAgICAgIGRlbHRhICo9IDQwO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkZWx0YSA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxhc3REZWx0YV8gPSBkZWx0YTtcbiAgICB9XG5cbiAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTtcblxuICAgIGlmICh0aGlzLnN0YXJ0VGltZV8gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zdGFydFRpbWVfID0gbm93O1xuICAgIH1cblxuICAgIGlmICghdGhpcy5tb2RlXyB8fCBub3cgLSB0aGlzLnN0YXJ0VGltZV8gPiB0aGlzLnRyYWNrcGFkRXZlbnRHYXBfKSB7XG4gICAgICB0aGlzLm1vZGVfID0gTWF0aC5hYnMoZGVsdGEpIDwgNCA/IE1vZGUuVFJBQ0tQQUQgOiBNb2RlLldIRUVMO1xuICAgIH1cblxuICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcblxuICAgIGlmICh0aGlzLm1vZGVfID09PSBNb2RlLlRSQUNLUEFEICYmICEodmlldy5nZXRDb25zdHJhaW5SZXNvbHV0aW9uKCkgfHwgdGhpcy5jb25zdHJhaW5SZXNvbHV0aW9uXykpIHtcbiAgICAgIGlmICh0aGlzLnRyYWNrcGFkVGltZW91dElkXykge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50cmFja3BhZFRpbWVvdXRJZF8pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHZpZXcuZ2V0QW5pbWF0aW5nKCkpIHtcbiAgICAgICAgICB2aWV3LmNhbmNlbEFuaW1hdGlvbnMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZpZXcuYmVnaW5JbnRlcmFjdGlvbigpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnRyYWNrcGFkVGltZW91dElkXyA9IHNldFRpbWVvdXQodGhpcy5lbmRJbnRlcmFjdGlvbl8uYmluZCh0aGlzKSwgdGhpcy50aW1lb3V0Xyk7XG4gICAgICB2aWV3LmFkanVzdFpvb20oLWRlbHRhIC8gdGhpcy5kZWx0YVBlclpvb21fLCB0aGlzLmxhc3RBbmNob3JfKTtcbiAgICAgIHRoaXMuc3RhcnRUaW1lXyA9IG5vdztcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLnRvdGFsRGVsdGFfICs9IGRlbHRhO1xuICAgIHZhciB0aW1lTGVmdCA9IE1hdGgubWF4KHRoaXMudGltZW91dF8gLSAobm93IC0gdGhpcy5zdGFydFRpbWVfKSwgMCk7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dElkXyk7XG4gICAgdGhpcy50aW1lb3V0SWRfID0gc2V0VGltZW91dCh0aGlzLmhhbmRsZVdoZWVsWm9vbV8uYmluZCh0aGlzLCBtYXApLCB0aW1lTGVmdCk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIE1hcC5cbiAgICovXG5cblxuICBNb3VzZVdoZWVsWm9vbS5wcm90b3R5cGUuaGFuZGxlV2hlZWxab29tXyA9IGZ1bmN0aW9uIChtYXApIHtcbiAgICB2YXIgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG5cbiAgICBpZiAodmlldy5nZXRBbmltYXRpbmcoKSkge1xuICAgICAgdmlldy5jYW5jZWxBbmltYXRpb25zKCk7XG4gICAgfVxuXG4gICAgdmFyIGRlbHRhID0gLWNsYW1wKHRoaXMudG90YWxEZWx0YV8sIC10aGlzLm1heERlbHRhXyAqIHRoaXMuZGVsdGFQZXJab29tXywgdGhpcy5tYXhEZWx0YV8gKiB0aGlzLmRlbHRhUGVyWm9vbV8pIC8gdGhpcy5kZWx0YVBlclpvb21fO1xuXG4gICAgaWYgKHZpZXcuZ2V0Q29uc3RyYWluUmVzb2x1dGlvbigpIHx8IHRoaXMuY29uc3RyYWluUmVzb2x1dGlvbl8pIHtcbiAgICAgIC8vIHZpZXcgaGFzIGEgem9vbSBjb25zdHJhaW50LCB6b29tIGJ5IDFcbiAgICAgIGRlbHRhID0gZGVsdGEgPyBkZWx0YSA+IDAgPyAxIDogLTEgOiAwO1xuICAgIH1cblxuICAgIHpvb21CeURlbHRhKHZpZXcsIGRlbHRhLCB0aGlzLmxhc3RBbmNob3JfLCB0aGlzLmR1cmF0aW9uXyk7XG4gICAgdGhpcy5tb2RlXyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnRvdGFsRGVsdGFfID0gMDtcbiAgICB0aGlzLmxhc3RBbmNob3JfID0gbnVsbDtcbiAgICB0aGlzLnN0YXJ0VGltZV8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy50aW1lb3V0SWRfID0gdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogRW5hYmxlIG9yIGRpc2FibGUgdXNpbmcgdGhlIG1vdXNlJ3MgbG9jYXRpb24gYXMgYW4gYW5jaG9yIHdoZW4gem9vbWluZ1xuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHVzZUFuY2hvciB0cnVlIHRvIHpvb20gdG8gdGhlIG1vdXNlJ3MgbG9jYXRpb24sIGZhbHNlXG4gICAqIHRvIHpvb20gdG8gdGhlIGNlbnRlciBvZiB0aGUgbWFwXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNb3VzZVdoZWVsWm9vbS5wcm90b3R5cGUuc2V0TW91c2VBbmNob3IgPSBmdW5jdGlvbiAodXNlQW5jaG9yKSB7XG4gICAgdGhpcy51c2VBbmNob3JfID0gdXNlQW5jaG9yO1xuXG4gICAgaWYgKCF1c2VBbmNob3IpIHtcbiAgICAgIHRoaXMubGFzdEFuY2hvcl8gPSBudWxsO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gTW91c2VXaGVlbFpvb207XG59KEludGVyYWN0aW9uKTtcblxuZXhwb3J0IGRlZmF1bHQgTW91c2VXaGVlbFpvb207IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9QaW5jaFJvdGF0ZVxuICovXG5cblxuaW1wb3J0IFBvaW50ZXJJbnRlcmFjdGlvbiwgeyBjZW50cm9pZCBhcyBjZW50cm9pZEZyb21Qb2ludGVycyB9IGZyb20gJy4vUG9pbnRlci5qcyc7XG5pbXBvcnQgeyBGQUxTRSB9IGZyb20gJy4uL2Z1bmN0aW9ucy5qcyc7XG5pbXBvcnQgeyBkaXNhYmxlIH0gZnJvbSAnLi4vcm90YXRpb25jb25zdHJhaW50LmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj0yNTBdIFRoZSBkdXJhdGlvbiBvZiB0aGUgYW5pbWF0aW9uIGluXG4gKiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RocmVzaG9sZD0wLjNdIE1pbmltYWwgYW5nbGUgaW4gcmFkaWFucyB0byBzdGFydCBhIHJvdGF0aW9uLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWxsb3dzIHRoZSB1c2VyIHRvIHJvdGF0ZSB0aGUgbWFwIGJ5IHR3aXN0aW5nIHdpdGggdHdvIGZpbmdlcnNcbiAqIG9uIGEgdG91Y2ggc2NyZWVuLlxuICogQGFwaVxuICovXG5cbnZhciBQaW5jaFJvdGF0ZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhQaW5jaFJvdGF0ZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gUGluY2hSb3RhdGUob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyA/IG9wdF9vcHRpb25zIDoge307XG4gICAgdmFyIHBvaW50ZXJPcHRpb25zID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vUG9pbnRlci5qc1wiKS5PcHRpb25zfSAqL1xuICAgIG9wdGlvbnM7XG5cbiAgICBpZiAoIXBvaW50ZXJPcHRpb25zLnN0b3BEb3duKSB7XG4gICAgICBwb2ludGVyT3B0aW9ucy5zdG9wRG93biA9IEZBTFNFO1xuICAgIH1cblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgcG9pbnRlck9wdGlvbnMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMuYW5jaG9yXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLmxhc3RBbmdsZV8gPSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJvdGF0aW5nXyA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJvdGF0aW9uRGVsdGFfID0gMC4wO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRocmVzaG9sZF8gPSBvcHRpb25zLnRocmVzaG9sZCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy50aHJlc2hvbGQgOiAwLjM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZHVyYXRpb25fID0gb3B0aW9ucy5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kdXJhdGlvbiA6IDI1MDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIGRyYWcgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqL1xuXG5cbiAgUGluY2hSb3RhdGUucHJvdG90eXBlLmhhbmRsZURyYWdFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICB2YXIgcm90YXRpb25EZWx0YSA9IDAuMDtcbiAgICB2YXIgdG91Y2gwID0gdGhpcy50YXJnZXRQb2ludGVyc1swXTtcbiAgICB2YXIgdG91Y2gxID0gdGhpcy50YXJnZXRQb2ludGVyc1sxXTsgLy8gYW5nbGUgYmV0d2VlbiB0b3VjaGVzXG5cbiAgICB2YXIgYW5nbGUgPSBNYXRoLmF0YW4yKHRvdWNoMS5jbGllbnRZIC0gdG91Y2gwLmNsaWVudFksIHRvdWNoMS5jbGllbnRYIC0gdG91Y2gwLmNsaWVudFgpO1xuXG4gICAgaWYgKHRoaXMubGFzdEFuZ2xlXyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YXIgZGVsdGEgPSBhbmdsZSAtIHRoaXMubGFzdEFuZ2xlXztcbiAgICAgIHRoaXMucm90YXRpb25EZWx0YV8gKz0gZGVsdGE7XG5cbiAgICAgIGlmICghdGhpcy5yb3RhdGluZ18gJiYgTWF0aC5hYnModGhpcy5yb3RhdGlvbkRlbHRhXykgPiB0aGlzLnRocmVzaG9sZF8pIHtcbiAgICAgICAgdGhpcy5yb3RhdGluZ18gPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICByb3RhdGlvbkRlbHRhID0gZGVsdGE7XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0QW5nbGVfID0gYW5nbGU7XG4gICAgdmFyIG1hcCA9IG1hcEJyb3dzZXJFdmVudC5tYXA7XG4gICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuXG4gICAgaWYgKHZpZXcuZ2V0Q29uc3RyYWludHMoKS5yb3RhdGlvbiA9PT0gZGlzYWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gcm90YXRlIGFuY2hvciBwb2ludC5cbiAgICAvLyBGSVhNRTogc2hvdWxkIGJlIHRoZSBpbnRlcnNlY3Rpb24gcG9pbnQgYmV0d2VlbiB0aGUgbGluZXM6XG4gICAgLy8gICAgIHRvdWNoMCx0b3VjaDEgYW5kIHByZXZpb3VzVG91Y2gwLHByZXZpb3VzVG91Y2gxXG5cblxuICAgIHZhciB2aWV3cG9ydFBvc2l0aW9uID0gbWFwLmdldFZpZXdwb3J0KCkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdmFyIGNlbnRyb2lkID0gY2VudHJvaWRGcm9tUG9pbnRlcnModGhpcy50YXJnZXRQb2ludGVycyk7XG4gICAgY2VudHJvaWRbMF0gLT0gdmlld3BvcnRQb3NpdGlvbi5sZWZ0O1xuICAgIGNlbnRyb2lkWzFdIC09IHZpZXdwb3J0UG9zaXRpb24udG9wO1xuICAgIHRoaXMuYW5jaG9yXyA9IG1hcC5nZXRDb29yZGluYXRlRnJvbVBpeGVsSW50ZXJuYWwoY2VudHJvaWQpOyAvLyByb3RhdGVcblxuICAgIGlmICh0aGlzLnJvdGF0aW5nXykge1xuICAgICAgbWFwLnJlbmRlcigpO1xuICAgICAgdmlldy5hZGp1c3RSb3RhdGlvbkludGVybmFsKHJvdGF0aW9uRGVsdGEsIHRoaXMuYW5jaG9yXyk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgdXAgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBldmVudCB3YXMgY29uc3VtZWQuXG4gICAqL1xuXG5cbiAgUGluY2hSb3RhdGUucHJvdG90eXBlLmhhbmRsZVVwRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgaWYgKHRoaXMudGFyZ2V0UG9pbnRlcnMubGVuZ3RoIDwgMikge1xuICAgICAgdmFyIG1hcCA9IG1hcEJyb3dzZXJFdmVudC5tYXA7XG4gICAgICB2YXIgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG4gICAgICB2aWV3LmVuZEludGVyYWN0aW9uKHRoaXMuZHVyYXRpb25fKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgZG93biBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSWYgdGhlIGV2ZW50IHdhcyBjb25zdW1lZC5cbiAgICovXG5cblxuICBQaW5jaFJvdGF0ZS5wcm90b3R5cGUuaGFuZGxlRG93bkV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIGlmICh0aGlzLnRhcmdldFBvaW50ZXJzLmxlbmd0aCA+PSAyKSB7XG4gICAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICAgIHRoaXMuYW5jaG9yXyA9IG51bGw7XG4gICAgICB0aGlzLmxhc3RBbmdsZV8gPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnJvdGF0aW5nXyA9IGZhbHNlO1xuICAgICAgdGhpcy5yb3RhdGlvbkRlbHRhXyA9IDAuMDtcblxuICAgICAgaWYgKCF0aGlzLmhhbmRsaW5nRG93blVwU2VxdWVuY2UpIHtcbiAgICAgICAgbWFwLmdldFZpZXcoKS5iZWdpbkludGVyYWN0aW9uKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBQaW5jaFJvdGF0ZTtcbn0oUG9pbnRlckludGVyYWN0aW9uKTtcblxuZXhwb3J0IGRlZmF1bHQgUGluY2hSb3RhdGU7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9QaW5jaFpvb21cbiAqL1xuXG5cbmltcG9ydCBQb2ludGVySW50ZXJhY3Rpb24sIHsgY2VudHJvaWQgYXMgY2VudHJvaWRGcm9tUG9pbnRlcnMgfSBmcm9tICcuL1BvaW50ZXIuanMnO1xuaW1wb3J0IHsgRkFMU0UgfSBmcm9tICcuLi9mdW5jdGlvbnMuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2R1cmF0aW9uPTQwMF0gQW5pbWF0aW9uIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcy5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFsbG93cyB0aGUgdXNlciB0byB6b29tIHRoZSBtYXAgYnkgcGluY2hpbmcgd2l0aCB0d28gZmluZ2Vyc1xuICogb24gYSB0b3VjaCBzY3JlZW4uXG4gKiBAYXBpXG4gKi9cblxudmFyIFBpbmNoWm9vbSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhQaW5jaFpvb20sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFBpbmNoWm9vbShvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICB2YXIgcG9pbnRlck9wdGlvbnMgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9Qb2ludGVyLmpzXCIpLk9wdGlvbnN9ICovXG4gICAgb3B0aW9ucztcblxuICAgIGlmICghcG9pbnRlck9wdGlvbnMuc3RvcERvd24pIHtcbiAgICAgIHBvaW50ZXJPcHRpb25zLnN0b3BEb3duID0gRkFMU0U7XG4gICAgfVxuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBwb2ludGVyT3B0aW9ucykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5hbmNob3JfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5kdXJhdGlvbl8gPSBvcHRpb25zLmR1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmR1cmF0aW9uIDogNDAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXN0RGlzdGFuY2VfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxhc3RTY2FsZURlbHRhXyA9IDE7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBIYW5kbGUgcG9pbnRlciBkcmFnIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKi9cblxuXG4gIFBpbmNoWm9vbS5wcm90b3R5cGUuaGFuZGxlRHJhZ0V2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIHZhciBzY2FsZURlbHRhID0gMS4wO1xuICAgIHZhciB0b3VjaDAgPSB0aGlzLnRhcmdldFBvaW50ZXJzWzBdO1xuICAgIHZhciB0b3VjaDEgPSB0aGlzLnRhcmdldFBvaW50ZXJzWzFdO1xuICAgIHZhciBkeCA9IHRvdWNoMC5jbGllbnRYIC0gdG91Y2gxLmNsaWVudFg7XG4gICAgdmFyIGR5ID0gdG91Y2gwLmNsaWVudFkgLSB0b3VjaDEuY2xpZW50WTsgLy8gZGlzdGFuY2UgYmV0d2VlbiB0b3VjaGVzXG5cbiAgICB2YXIgZGlzdGFuY2UgPSBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpO1xuXG4gICAgaWYgKHRoaXMubGFzdERpc3RhbmNlXyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBzY2FsZURlbHRhID0gdGhpcy5sYXN0RGlzdGFuY2VfIC8gZGlzdGFuY2U7XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0RGlzdGFuY2VfID0gZGlzdGFuY2U7XG4gICAgdmFyIG1hcCA9IG1hcEJyb3dzZXJFdmVudC5tYXA7XG4gICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuXG4gICAgaWYgKHNjYWxlRGVsdGEgIT0gMS4wKSB7XG4gICAgICB0aGlzLmxhc3RTY2FsZURlbHRhXyA9IHNjYWxlRGVsdGE7XG4gICAgfSAvLyBzY2FsZSBhbmNob3IgcG9pbnQuXG5cblxuICAgIHZhciB2aWV3cG9ydFBvc2l0aW9uID0gbWFwLmdldFZpZXdwb3J0KCkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdmFyIGNlbnRyb2lkID0gY2VudHJvaWRGcm9tUG9pbnRlcnModGhpcy50YXJnZXRQb2ludGVycyk7XG4gICAgY2VudHJvaWRbMF0gLT0gdmlld3BvcnRQb3NpdGlvbi5sZWZ0O1xuICAgIGNlbnRyb2lkWzFdIC09IHZpZXdwb3J0UG9zaXRpb24udG9wO1xuICAgIHRoaXMuYW5jaG9yXyA9IG1hcC5nZXRDb29yZGluYXRlRnJvbVBpeGVsSW50ZXJuYWwoY2VudHJvaWQpOyAvLyBzY2FsZSwgYnlwYXNzIHRoZSByZXNvbHV0aW9uIGNvbnN0cmFpbnRcblxuICAgIG1hcC5yZW5kZXIoKTtcbiAgICB2aWV3LmFkanVzdFJlc29sdXRpb25JbnRlcm5hbChzY2FsZURlbHRhLCB0aGlzLmFuY2hvcl8pO1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgdXAgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBldmVudCB3YXMgY29uc3VtZWQuXG4gICAqL1xuXG5cbiAgUGluY2hab29tLnByb3RvdHlwZS5oYW5kbGVVcEV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIGlmICh0aGlzLnRhcmdldFBvaW50ZXJzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuICAgICAgdmFyIGRpcmVjdGlvbiA9IHRoaXMubGFzdFNjYWxlRGVsdGFfID4gMSA/IDEgOiAtMTtcbiAgICAgIHZpZXcuZW5kSW50ZXJhY3Rpb24odGhpcy5kdXJhdGlvbl8sIGRpcmVjdGlvbik7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIGRvd24gZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBldmVudCB3YXMgY29uc3VtZWQuXG4gICAqL1xuXG5cbiAgUGluY2hab29tLnByb3RvdHlwZS5oYW5kbGVEb3duRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgaWYgKHRoaXMudGFyZ2V0UG9pbnRlcnMubGVuZ3RoID49IDIpIHtcbiAgICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgICAgdGhpcy5hbmNob3JfID0gbnVsbDtcbiAgICAgIHRoaXMubGFzdERpc3RhbmNlXyA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMubGFzdFNjYWxlRGVsdGFfID0gMTtcblxuICAgICAgaWYgKCF0aGlzLmhhbmRsaW5nRG93blVwU2VxdWVuY2UpIHtcbiAgICAgICAgbWFwLmdldFZpZXcoKS5iZWdpbkludGVyYWN0aW9uKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBQaW5jaFpvb207XG59KFBvaW50ZXJJbnRlcmFjdGlvbik7XG5cbmV4cG9ydCBkZWZhdWx0IFBpbmNoWm9vbTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvaW50ZXJhY3Rpb25cbiAqL1xuaW1wb3J0IENvbGxlY3Rpb24gZnJvbSAnLi9Db2xsZWN0aW9uLmpzJztcbmltcG9ydCBEb3VibGVDbGlja1pvb20gZnJvbSAnLi9pbnRlcmFjdGlvbi9Eb3VibGVDbGlja1pvb20uanMnO1xuaW1wb3J0IERyYWdQYW4gZnJvbSAnLi9pbnRlcmFjdGlvbi9EcmFnUGFuLmpzJztcbmltcG9ydCBEcmFnUm90YXRlIGZyb20gJy4vaW50ZXJhY3Rpb24vRHJhZ1JvdGF0ZS5qcyc7XG5pbXBvcnQgRHJhZ1pvb20gZnJvbSAnLi9pbnRlcmFjdGlvbi9EcmFnWm9vbS5qcyc7XG5pbXBvcnQgS2V5Ym9hcmRQYW4gZnJvbSAnLi9pbnRlcmFjdGlvbi9LZXlib2FyZFBhbi5qcyc7XG5pbXBvcnQgS2V5Ym9hcmRab29tIGZyb20gJy4vaW50ZXJhY3Rpb24vS2V5Ym9hcmRab29tLmpzJztcbmltcG9ydCBLaW5ldGljIGZyb20gJy4vS2luZXRpYy5qcyc7XG5pbXBvcnQgTW91c2VXaGVlbFpvb20gZnJvbSAnLi9pbnRlcmFjdGlvbi9Nb3VzZVdoZWVsWm9vbS5qcyc7XG5pbXBvcnQgUGluY2hSb3RhdGUgZnJvbSAnLi9pbnRlcmFjdGlvbi9QaW5jaFJvdGF0ZS5qcyc7XG5pbXBvcnQgUGluY2hab29tIGZyb20gJy4vaW50ZXJhY3Rpb24vUGluY2hab29tLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgRG91YmxlQ2xpY2tab29tIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9Eb3VibGVDbGlja1pvb20uanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBEcmFnQW5kRHJvcCB9IGZyb20gJy4vaW50ZXJhY3Rpb24vRHJhZ0FuZERyb3AuanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBEcmFnQm94IH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9EcmFnQm94LmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgRHJhZ1BhbiB9IGZyb20gJy4vaW50ZXJhY3Rpb24vRHJhZ1Bhbi5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIERyYWdSb3RhdGUgfSBmcm9tICcuL2ludGVyYWN0aW9uL0RyYWdSb3RhdGUuanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBEcmFnUm90YXRlQW5kWm9vbSB9IGZyb20gJy4vaW50ZXJhY3Rpb24vRHJhZ1JvdGF0ZUFuZFpvb20uanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBEcmFnWm9vbSB9IGZyb20gJy4vaW50ZXJhY3Rpb24vRHJhZ1pvb20uanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBEcmF3IH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9EcmF3LmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgRXh0ZW50IH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9FeHRlbnQuanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBJbnRlcmFjdGlvbiB9IGZyb20gJy4vaW50ZXJhY3Rpb24vSW50ZXJhY3Rpb24uanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBLZXlib2FyZFBhbiB9IGZyb20gJy4vaW50ZXJhY3Rpb24vS2V5Ym9hcmRQYW4uanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBLZXlib2FyZFpvb20gfSBmcm9tICcuL2ludGVyYWN0aW9uL0tleWJvYXJkWm9vbS5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIE1vZGlmeSB9IGZyb20gJy4vaW50ZXJhY3Rpb24vTW9kaWZ5LmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgTW91c2VXaGVlbFpvb20gfSBmcm9tICcuL2ludGVyYWN0aW9uL01vdXNlV2hlZWxab29tLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgUGluY2hSb3RhdGUgfSBmcm9tICcuL2ludGVyYWN0aW9uL1BpbmNoUm90YXRlLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgUGluY2hab29tIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9QaW5jaFpvb20uanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBQb2ludGVyIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9Qb2ludGVyLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgU2VsZWN0IH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9TZWxlY3QuanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBTbmFwIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9TbmFwLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgVHJhbnNsYXRlIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9UcmFuc2xhdGUuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBEZWZhdWx0c09wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2FsdFNoaWZ0RHJhZ1JvdGF0ZT10cnVlXSBXaGV0aGVyIEFsdC1TaGlmdC1kcmFnIHJvdGF0ZSBpc1xuICogZGVzaXJlZC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW29uRm9jdXNPbmx5PWZhbHNlXSBJbnRlcmFjdCBvbmx5IHdoZW4gdGhlIG1hcCBoYXMgdGhlXG4gKiBmb2N1cy4gVGhpcyBhZmZlY3RzIHRoZSBgTW91c2VXaGVlbFpvb21gIGFuZCBgRHJhZ1BhbmAgaW50ZXJhY3Rpb25zIGFuZCBpc1xuICogdXNlZnVsIHdoZW4gcGFnZSBzY3JvbGwgaXMgZGVzaXJlZCBmb3IgbWFwcyB0aGF0IGRvIG5vdCBoYXZlIHRoZSBicm93c2VyJ3NcbiAqIGZvY3VzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZG91YmxlQ2xpY2tab29tPXRydWVdIFdoZXRoZXIgZG91YmxlIGNsaWNrIHpvb20gaXNcbiAqIGRlc2lyZWQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtrZXlib2FyZD10cnVlXSBXaGV0aGVyIGtleWJvYXJkIGludGVyYWN0aW9uIGlzIGRlc2lyZWQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFttb3VzZVdoZWVsWm9vbT10cnVlXSBXaGV0aGVyIG1vdXNld2hlZWwgem9vbSBpcyBkZXNpcmVkLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbc2hpZnREcmFnWm9vbT10cnVlXSBXaGV0aGVyIFNoaWZ0LWRyYWcgem9vbSBpcyBkZXNpcmVkLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZHJhZ1Bhbj10cnVlXSBXaGV0aGVyIGRyYWcgcGFuIGlzIGRlc2lyZWQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtwaW5jaFJvdGF0ZT10cnVlXSBXaGV0aGVyIHBpbmNoIHJvdGF0ZSBpcyBkZXNpcmVkLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbcGluY2hab29tPXRydWVdIFdoZXRoZXIgcGluY2ggem9vbSBpcyBkZXNpcmVkLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6b29tRGVsdGFdIFpvb20gbGV2ZWwgZGVsdGEgd2hlbiB1c2luZyBrZXlib2FyZCBvciBkb3VibGUgY2xpY2sgem9vbS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbem9vbUR1cmF0aW9uXSBEdXJhdGlvbiBvZiB0aGUgem9vbSBhbmltYXRpb24gaW5cbiAqIG1pbGxpc2Vjb25kcy5cbiAqL1xuXG4vKipcbiAqIFNldCBvZiBpbnRlcmFjdGlvbnMgaW5jbHVkZWQgaW4gbWFwcyBieSBkZWZhdWx0LiBTcGVjaWZpYyBpbnRlcmFjdGlvbnMgY2FuIGJlXG4gKiBleGNsdWRlZCBieSBzZXR0aW5nIHRoZSBhcHByb3ByaWF0ZSBvcHRpb24gdG8gZmFsc2UgaW4gdGhlIGNvbnN0cnVjdG9yXG4gKiBvcHRpb25zLCBidXQgdGhlIG9yZGVyIG9mIHRoZSBpbnRlcmFjdGlvbnMgaXMgZml4ZWQuICBJZiB5b3Ugd2FudCB0byBzcGVjaWZ5XG4gKiBhIGRpZmZlcmVudCBvcmRlciBmb3IgaW50ZXJhY3Rpb25zLCB5b3Ugd2lsbCBuZWVkIHRvIGNyZWF0ZSB5b3VyIG93blxuICoge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9JbnRlcmFjdGlvbn0gaW5zdGFuY2VzIGFuZCBpbnNlcnRcbiAqIHRoZW0gaW50byBhIHtAbGluayBtb2R1bGU6b2wvQ29sbGVjdGlvbn0gaW4gdGhlIG9yZGVyIHlvdSB3YW50XG4gKiBiZWZvcmUgY3JlYXRpbmcgeW91ciB7QGxpbmsgbW9kdWxlOm9sL01hcH5NYXB9IGluc3RhbmNlLiBDaGFuZ2luZyB0aGUgb3JkZXIgY2FuXG4gKiBiZSBvZiBpbnRlcmVzdCBpZiB0aGUgZXZlbnQgcHJvcGFnYXRpb24gbmVlZHMgdG8gYmUgc3RvcHBlZCBhdCBhIHBvaW50LlxuICogVGhlIGRlZmF1bHQgc2V0IG9mIGludGVyYWN0aW9ucywgaW4gc2VxdWVuY2UsIGlzOlxuICogKiB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL0RyYWdSb3RhdGV+RHJhZ1JvdGF0ZX1cbiAqICoge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9Eb3VibGVDbGlja1pvb21+RG91YmxlQ2xpY2tab29tfVxuICogKiB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL0RyYWdQYW5+RHJhZ1Bhbn1cbiAqICoge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9QaW5jaFJvdGF0ZX5QaW5jaFJvdGF0ZX1cbiAqICoge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9QaW5jaFpvb21+UGluY2hab29tfVxuICogKiB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL0tleWJvYXJkUGFufktleWJvYXJkUGFufVxuICogKiB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL0tleWJvYXJkWm9vbX5LZXlib2FyZFpvb219XG4gKiAqIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vTW91c2VXaGVlbFpvb21+TW91c2VXaGVlbFpvb219XG4gKiAqIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vRHJhZ1pvb21+RHJhZ1pvb219XG4gKlxuICogQHBhcmFtIHtEZWZhdWx0c09wdGlvbnM9fSBvcHRfb3B0aW9ucyBEZWZhdWx0cyBvcHRpb25zLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9Db2xsZWN0aW9uLmpzXCIpLmRlZmF1bHQ8aW1wb3J0KFwiLi9pbnRlcmFjdGlvbi9JbnRlcmFjdGlvbi5qc1wiKS5kZWZhdWx0Pn1cbiAqIEEgY29sbGVjdGlvbiBvZiBpbnRlcmFjdGlvbnMgdG8gYmUgdXNlZCB3aXRoIHRoZSB7QGxpbmsgbW9kdWxlOm9sL01hcH5NYXB9XG4gKiBjb25zdHJ1Y3RvcidzIGBpbnRlcmFjdGlvbnNgIG9wdGlvbi5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdHMob3B0X29wdGlvbnMpIHtcbiAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyA/IG9wdF9vcHRpb25zIDoge307XG4gIHZhciBpbnRlcmFjdGlvbnMgPSBuZXcgQ29sbGVjdGlvbigpO1xuICB2YXIga2luZXRpYyA9IG5ldyBLaW5ldGljKC0wLjAwNSwgMC4wNSwgMTAwKTtcbiAgdmFyIGFsdFNoaWZ0RHJhZ1JvdGF0ZSA9IG9wdGlvbnMuYWx0U2hpZnREcmFnUm90YXRlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmFsdFNoaWZ0RHJhZ1JvdGF0ZSA6IHRydWU7XG5cbiAgaWYgKGFsdFNoaWZ0RHJhZ1JvdGF0ZSkge1xuICAgIGludGVyYWN0aW9ucy5wdXNoKG5ldyBEcmFnUm90YXRlKCkpO1xuICB9XG5cbiAgdmFyIGRvdWJsZUNsaWNrWm9vbSA9IG9wdGlvbnMuZG91YmxlQ2xpY2tab29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmRvdWJsZUNsaWNrWm9vbSA6IHRydWU7XG5cbiAgaWYgKGRvdWJsZUNsaWNrWm9vbSkge1xuICAgIGludGVyYWN0aW9ucy5wdXNoKG5ldyBEb3VibGVDbGlja1pvb20oe1xuICAgICAgZGVsdGE6IG9wdGlvbnMuem9vbURlbHRhLFxuICAgICAgZHVyYXRpb246IG9wdGlvbnMuem9vbUR1cmF0aW9uXG4gICAgfSkpO1xuICB9XG5cbiAgdmFyIGRyYWdQYW4gPSBvcHRpb25zLmRyYWdQYW4gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZHJhZ1BhbiA6IHRydWU7XG5cbiAgaWYgKGRyYWdQYW4pIHtcbiAgICBpbnRlcmFjdGlvbnMucHVzaChuZXcgRHJhZ1Bhbih7XG4gICAgICBvbkZvY3VzT25seTogb3B0aW9ucy5vbkZvY3VzT25seSxcbiAgICAgIGtpbmV0aWM6IGtpbmV0aWNcbiAgICB9KSk7XG4gIH1cblxuICB2YXIgcGluY2hSb3RhdGUgPSBvcHRpb25zLnBpbmNoUm90YXRlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnBpbmNoUm90YXRlIDogdHJ1ZTtcblxuICBpZiAocGluY2hSb3RhdGUpIHtcbiAgICBpbnRlcmFjdGlvbnMucHVzaChuZXcgUGluY2hSb3RhdGUoKSk7XG4gIH1cblxuICB2YXIgcGluY2hab29tID0gb3B0aW9ucy5waW5jaFpvb20gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucGluY2hab29tIDogdHJ1ZTtcblxuICBpZiAocGluY2hab29tKSB7XG4gICAgaW50ZXJhY3Rpb25zLnB1c2gobmV3IFBpbmNoWm9vbSh7XG4gICAgICBkdXJhdGlvbjogb3B0aW9ucy56b29tRHVyYXRpb25cbiAgICB9KSk7XG4gIH1cblxuICB2YXIga2V5Ym9hcmQgPSBvcHRpb25zLmtleWJvYXJkICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmtleWJvYXJkIDogdHJ1ZTtcblxuICBpZiAoa2V5Ym9hcmQpIHtcbiAgICBpbnRlcmFjdGlvbnMucHVzaChuZXcgS2V5Ym9hcmRQYW4oKSk7XG4gICAgaW50ZXJhY3Rpb25zLnB1c2gobmV3IEtleWJvYXJkWm9vbSh7XG4gICAgICBkZWx0YTogb3B0aW9ucy56b29tRGVsdGEsXG4gICAgICBkdXJhdGlvbjogb3B0aW9ucy56b29tRHVyYXRpb25cbiAgICB9KSk7XG4gIH1cblxuICB2YXIgbW91c2VXaGVlbFpvb20gPSBvcHRpb25zLm1vdXNlV2hlZWxab29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1vdXNlV2hlZWxab29tIDogdHJ1ZTtcblxuICBpZiAobW91c2VXaGVlbFpvb20pIHtcbiAgICBpbnRlcmFjdGlvbnMucHVzaChuZXcgTW91c2VXaGVlbFpvb20oe1xuICAgICAgb25Gb2N1c09ubHk6IG9wdGlvbnMub25Gb2N1c09ubHksXG4gICAgICBkdXJhdGlvbjogb3B0aW9ucy56b29tRHVyYXRpb25cbiAgICB9KSk7XG4gIH1cblxuICB2YXIgc2hpZnREcmFnWm9vbSA9IG9wdGlvbnMuc2hpZnREcmFnWm9vbSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zaGlmdERyYWdab29tIDogdHJ1ZTtcblxuICBpZiAoc2hpZnREcmFnWm9vbSkge1xuICAgIGludGVyYWN0aW9ucy5wdXNoKG5ldyBEcmFnWm9vbSh7XG4gICAgICBkdXJhdGlvbjogb3B0aW9ucy56b29tRHVyYXRpb25cbiAgICB9KSk7XG4gIH1cblxuICByZXR1cm4gaW50ZXJhY3Rpb25zO1xufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvTWFwXG4gKi9cblxuXG5pbXBvcnQgQ29tcG9zaXRlTWFwUmVuZGVyZXIgZnJvbSAnLi9yZW5kZXJlci9Db21wb3NpdGUuanMnO1xuaW1wb3J0IFBsdWdnYWJsZU1hcCBmcm9tICcuL1BsdWdnYWJsZU1hcC5qcyc7XG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICcuL29iai5qcyc7XG5pbXBvcnQgeyBkZWZhdWx0cyBhcyBkZWZhdWx0Q29udHJvbHMgfSBmcm9tICcuL2NvbnRyb2wuanMnO1xuaW1wb3J0IHsgZGVmYXVsdHMgYXMgZGVmYXVsdEludGVyYWN0aW9ucyB9IGZyb20gJy4vaW50ZXJhY3Rpb24uanMnO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBUaGUgbWFwIGlzIHRoZSBjb3JlIGNvbXBvbmVudCBvZiBPcGVuTGF5ZXJzLiBGb3IgYSBtYXAgdG8gcmVuZGVyLCBhIHZpZXcsXG4gKiBvbmUgb3IgbW9yZSBsYXllcnMsIGFuZCBhIHRhcmdldCBjb250YWluZXIgYXJlIG5lZWRlZDpcbiAqXG4gKiAgICAgaW1wb3J0IE1hcCBmcm9tICdvbC9NYXAnO1xuICogICAgIGltcG9ydCBWaWV3IGZyb20gJ29sL1ZpZXcnO1xuICogICAgIGltcG9ydCBUaWxlTGF5ZXIgZnJvbSAnb2wvbGF5ZXIvVGlsZSc7XG4gKiAgICAgaW1wb3J0IE9TTSBmcm9tICdvbC9zb3VyY2UvT1NNJztcbiAqXG4gKiAgICAgdmFyIG1hcCA9IG5ldyBNYXAoe1xuICogICAgICAgdmlldzogbmV3IFZpZXcoe1xuICogICAgICAgICBjZW50ZXI6IFswLCAwXSxcbiAqICAgICAgICAgem9vbTogMVxuICogICAgICAgfSksXG4gKiAgICAgICBsYXllcnM6IFtcbiAqICAgICAgICAgbmV3IFRpbGVMYXllcih7XG4gKiAgICAgICAgICAgc291cmNlOiBuZXcgT1NNKClcbiAqICAgICAgICAgfSlcbiAqICAgICAgIF0sXG4gKiAgICAgICB0YXJnZXQ6ICdtYXAnXG4gKiAgICAgfSk7XG4gKlxuICogVGhlIGFib3ZlIHNuaXBwZXQgY3JlYXRlcyBhIG1hcCB1c2luZyBhIHtAbGluayBtb2R1bGU6b2wvbGF5ZXIvVGlsZX0gdG9cbiAqIGRpc3BsYXkge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvT1NNfk9TTX0gT1NNIGRhdGEgYW5kIHJlbmRlciBpdCB0byBhIERPTVxuICogZWxlbWVudCB3aXRoIHRoZSBpZCBgbWFwYC5cbiAqXG4gKiBUaGUgY29uc3RydWN0b3IgcGxhY2VzIGEgdmlld3BvcnQgY29udGFpbmVyICh3aXRoIENTUyBjbGFzcyBuYW1lXG4gKiBgb2wtdmlld3BvcnRgKSBpbiB0aGUgdGFyZ2V0IGVsZW1lbnQgKHNlZSBgZ2V0Vmlld3BvcnQoKWApLCBhbmQgdGhlbiB0d29cbiAqIGZ1cnRoZXIgZWxlbWVudHMgd2l0aGluIHRoZSB2aWV3cG9ydDogb25lIHdpdGggQ1NTIGNsYXNzIG5hbWVcbiAqIGBvbC1vdmVybGF5Y29udGFpbmVyLXN0b3BldmVudGAgZm9yIGNvbnRyb2xzIGFuZCBzb21lIG92ZXJsYXlzLCBhbmQgb25lIHdpdGhcbiAqIENTUyBjbGFzcyBuYW1lIGBvbC1vdmVybGF5Y29udGFpbmVyYCBmb3Igb3RoZXIgb3ZlcmxheXMgKHNlZSB0aGUgYHN0b3BFdmVudGBcbiAqIG9wdGlvbiBvZiB7QGxpbmsgbW9kdWxlOm9sL092ZXJsYXl+T3ZlcmxheX0gZm9yIHRoZSBkaWZmZXJlbmNlKS4gVGhlIG1hcFxuICogaXRzZWxmIGlzIHBsYWNlZCBpbiBhIGZ1cnRoZXIgZWxlbWVudCB3aXRoaW4gdGhlIHZpZXdwb3J0LlxuICpcbiAqIExheWVycyBhcmUgc3RvcmVkIGFzIGEge0BsaW5rIG1vZHVsZTpvbC9Db2xsZWN0aW9ufkNvbGxlY3Rpb259IGluXG4gKiBsYXllckdyb3Vwcy4gQSB0b3AtbGV2ZWwgZ3JvdXAgaXMgcHJvdmlkZWQgYnkgdGhlIGxpYnJhcnkuIFRoaXMgaXMgd2hhdCBpc1xuICogYWNjZXNzZWQgYnkgYGdldExheWVyR3JvdXBgIGFuZCBgc2V0TGF5ZXJHcm91cGAuIExheWVycyBlbnRlcmVkIGluIHRoZVxuICogb3B0aW9ucyBhcmUgYWRkZWQgdG8gdGhpcyBncm91cCwgYW5kIGBhZGRMYXllcmAgYW5kIGByZW1vdmVMYXllcmAgY2hhbmdlIHRoZVxuICogbGF5ZXIgY29sbGVjdGlvbiBpbiB0aGUgZ3JvdXAuIGBnZXRMYXllcnNgIGlzIGEgY29udmVuaWVuY2UgZnVuY3Rpb24gZm9yXG4gKiBgZ2V0TGF5ZXJHcm91cCgpLmdldExheWVycygpYC4gTm90ZSB0aGF0IHtAbGluayBtb2R1bGU6b2wvbGF5ZXIvR3JvdXB+R3JvdXB9XG4gKiBpcyBhIHN1YmNsYXNzIG9mIHtAbGluayBtb2R1bGU6b2wvbGF5ZXIvQmFzZX0sIHNvIGxheWVycyBlbnRlcmVkIGluIHRoZVxuICogb3B0aW9ucyBvciBhZGRlZCB3aXRoIGBhZGRMYXllcmAgY2FuIGJlIGdyb3Vwcywgd2hpY2ggY2FuIGNvbnRhaW4gZnVydGhlclxuICogZ3JvdXBzLCBhbmQgc28gb24uXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBNYXAgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoTWFwLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1BsdWdnYWJsZU1hcC5qc1wiKS5NYXBPcHRpb25zfSBvcHRpb25zIE1hcCBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIE1hcChvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIG9wdGlvbnMgPSBhc3NpZ24oe30sIG9wdGlvbnMpO1xuXG4gICAgaWYgKCFvcHRpb25zLmNvbnRyb2xzKSB7XG4gICAgICBvcHRpb25zLmNvbnRyb2xzID0gZGVmYXVsdENvbnRyb2xzKCk7XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLmludGVyYWN0aW9ucykge1xuICAgICAgb3B0aW9ucy5pbnRlcmFjdGlvbnMgPSBkZWZhdWx0SW50ZXJhY3Rpb25zKHtcbiAgICAgICAgb25Gb2N1c09ubHk6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgb3B0aW9ucykgfHwgdGhpcztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBNYXAucHJvdG90eXBlLmNyZWF0ZVJlbmRlcmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBuZXcgQ29tcG9zaXRlTWFwUmVuZGVyZXIodGhpcyk7XG4gIH07XG5cbiAgcmV0dXJuIE1hcDtcbn0oUGx1Z2dhYmxlTWFwKTtcblxuZXhwb3J0IGRlZmF1bHQgTWFwOyIsIi8qKlxuICogQG1vZHVsZSBvbC9JbWFnZVN0YXRlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7bnVtYmVyfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIElETEU6IDAsXG4gIExPQURJTkc6IDEsXG4gIExPQURFRDogMixcbiAgRVJST1I6IDMsXG4gIEVNUFRZOiA0XG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHlsZS9JbWFnZVxuICovXG5pbXBvcnQgeyBhYnN0cmFjdCB9IGZyb20gJy4uL3V0aWwuanMnO1xuaW1wb3J0IHsgdG9TaXplIH0gZnJvbSAnLi4vc2l6ZS5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBvcGFjaXR5XG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHJvdGF0ZVdpdGhWaWV3XG4gKiBAcHJvcGVydHkge251bWJlcn0gcm90YXRpb25cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gc2NhbGVcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gZGlzcGxhY2VtZW50XG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBIGJhc2UgY2xhc3MgdXNlZCBmb3IgY3JlYXRpbmcgc3ViY2xhc3NlcyBhbmQgbm90IGluc3RhbnRpYXRlZCBpblxuICogYXBwcy4gQmFzZSBjbGFzcyBmb3Ige0BsaW5rIG1vZHVsZTpvbC9zdHlsZS9JY29ufkljb259LCB7QGxpbmsgbW9kdWxlOm9sL3N0eWxlL0NpcmNsZX5DaXJjbGVTdHlsZX0gYW5kXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3N0eWxlL1JlZ3VsYXJTaGFwZX5SZWd1bGFyU2hhcGV9LlxuICogQGFic3RyYWN0XG4gKiBAYXBpXG4gKi9cblxudmFyIEltYWdlU3R5bGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuICBmdW5jdGlvbiBJbWFnZVN0eWxlKG9wdGlvbnMpIHtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5vcGFjaXR5XyA9IG9wdGlvbnMub3BhY2l0eTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgdGhpcy5yb3RhdGVXaXRoVmlld18gPSBvcHRpb25zLnJvdGF0ZVdpdGhWaWV3O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMucm90YXRpb25fID0gb3B0aW9ucy5yb3RhdGlvbjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfVxuICAgICAqL1xuXG4gICAgdGhpcy5zY2FsZV8gPSBvcHRpb25zLnNjYWxlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIHRoaXMuc2NhbGVBcnJheV8gPSB0b1NpemUob3B0aW9ucy5zY2FsZSk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIHRoaXMuZGlzcGxhY2VtZW50XyA9IG9wdGlvbnMuZGlzcGxhY2VtZW50O1xuICB9XG4gIC8qKlxuICAgKiBDbG9uZXMgdGhlIHN0eWxlLlxuICAgKiBAcmV0dXJuIHtJbWFnZVN0eWxlfSBUaGUgY2xvbmVkIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNjYWxlID0gdGhpcy5nZXRTY2FsZSgpO1xuICAgIHJldHVybiBuZXcgSW1hZ2VTdHlsZSh7XG4gICAgICBvcGFjaXR5OiB0aGlzLmdldE9wYWNpdHkoKSxcbiAgICAgIHNjYWxlOiBBcnJheS5pc0FycmF5KHNjYWxlKSA/IHNjYWxlLnNsaWNlKCkgOiBzY2FsZSxcbiAgICAgIHJvdGF0aW9uOiB0aGlzLmdldFJvdGF0aW9uKCksXG4gICAgICByb3RhdGVXaXRoVmlldzogdGhpcy5nZXRSb3RhdGVXaXRoVmlldygpLFxuICAgICAgZGlzcGxhY2VtZW50OiB0aGlzLmdldERpc3BsYWNlbWVudCgpLnNsaWNlKClcbiAgICB9KTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc3ltYm9saXplciBvcGFjaXR5LlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE9wYWNpdHkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5nZXRPcGFjaXR5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm9wYWNpdHlfO1xuICB9O1xuICAvKipcbiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHN5bWJvbGl6ZXIgcm90YXRlcyB3aXRoIHRoZSBtYXAuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFJvdGF0ZSB3aXRoIG1hcC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldFJvdGF0ZVdpdGhWaWV3ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJvdGF0ZVdpdGhWaWV3XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc3ltb2JsaXplciByb3RhdGlvbi5cbiAgICogQHJldHVybiB7bnVtYmVyfSBSb3RhdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldFJvdGF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJvdGF0aW9uXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc3ltYm9saXplciBzY2FsZS5cbiAgICogQHJldHVybiB7bnVtYmVyfGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gU2NhbGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5nZXRTY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zY2FsZV87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHN5bWJvbGl6ZXIgc2NhbGUgYXJyYXkuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gU2NhbGUgYXJyYXkuXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuZ2V0U2NhbGVBcnJheSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zY2FsZUFycmF5XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZGlzcGxhY2VtZW50IG9mIHRoZSBzaGFwZVxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBTaGFwZSdzIGNlbnRlciBkaXNwbGFjZW1lbnRcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldERpc3BsYWNlbWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwbGFjZW1lbnRfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBhbmNob3IgcG9pbnQgaW4gcGl4ZWxzLiBUaGUgYW5jaG9yIGRldGVybWluZXMgdGhlIGNlbnRlciBwb2ludCBmb3IgdGhlXG4gICAqIHN5bWJvbGl6ZXIuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBBbmNob3IuXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuZ2V0QW5jaG9yID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBpbWFnZSBlbGVtZW50IGZvciB0aGUgc3ltYm9saXplci5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcmV0dXJuIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR9IEltYWdlIGVsZW1lbnQuXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuZ2V0SW1hZ2UgPSBmdW5jdGlvbiAocGl4ZWxSYXRpbykge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEByZXR1cm4ge0hUTUxDYW52YXNFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudH0gSW1hZ2UgZWxlbWVudC5cbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5nZXRIaXREZXRlY3Rpb25JbWFnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLypcbiAgICogR2V0IHRoZSBpbWFnZSBwaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5nZXRQaXhlbFJhdGlvID0gZnVuY3Rpb24gKHBpeGVsUmF0aW8pIHtcbiAgICByZXR1cm4gMTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9JbWFnZVN0YXRlLmpzXCIpLmRlZmF1bHR9IEltYWdlIHN0YXRlLlxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldEltYWdlU3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBJbWFnZSBzaXplLlxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldEltYWdlU2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFNpemUgb2YgdGhlIGhpdC1kZXRlY3Rpb24gaW1hZ2UuXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuZ2V0SGl0RGV0ZWN0aW9uSW1hZ2VTaXplID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBvcmlnaW4gb2YgdGhlIHN5bWJvbGl6ZXIuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBPcmlnaW4uXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuZ2V0T3JpZ2luID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzaXplIG9mIHRoZSBzeW1ib2xpemVyIChpbiBwaXhlbHMpLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBTaXplLlxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldFNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIG9wYWNpdHkuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcGFjaXR5IE9wYWNpdHkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5zZXRPcGFjaXR5ID0gZnVuY3Rpb24gKG9wYWNpdHkpIHtcbiAgICB0aGlzLm9wYWNpdHlfID0gb3BhY2l0eTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB3aGV0aGVyIHRvIHJvdGF0ZSB0aGUgc3R5bGUgd2l0aCB0aGUgdmlldy5cbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFufSByb3RhdGVXaXRoVmlldyBSb3RhdGUgd2l0aCBtYXAuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5zZXRSb3RhdGVXaXRoVmlldyA9IGZ1bmN0aW9uIChyb3RhdGVXaXRoVmlldykge1xuICAgIHRoaXMucm90YXRlV2l0aFZpZXdfID0gcm90YXRlV2l0aFZpZXc7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHJvdGF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gcm90YXRpb24gUm90YXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5zZXRSb3RhdGlvbiA9IGZ1bmN0aW9uIChyb3RhdGlvbikge1xuICAgIHRoaXMucm90YXRpb25fID0gcm90YXRpb247XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHNjYWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IHNjYWxlIFNjYWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuc2V0U2NhbGUgPSBmdW5jdGlvbiAoc2NhbGUpIHtcbiAgICB0aGlzLnNjYWxlXyA9IHNjYWxlO1xuICAgIHRoaXMuc2NhbGVBcnJheV8gPSB0b1NpemUoc2NhbGUpO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHQpOiB2b2lkfSBsaXN0ZW5lciBMaXN0ZW5lciBmdW5jdGlvbi5cbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5saXN0ZW5JbWFnZUNoYW5nZSA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge1xuICAgIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBMb2FkIG5vdCB5ZXQgbG9hZGVkIFVSSS5cbiAgICogQGFic3RyYWN0XG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHQpOiB2b2lkfSBsaXN0ZW5lciBMaXN0ZW5lciBmdW5jdGlvbi5cbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS51bmxpc3RlbkltYWdlQ2hhbmdlID0gZnVuY3Rpb24gKGxpc3RlbmVyKSB7XG4gICAgYWJzdHJhY3QoKTtcbiAgfTtcblxuICByZXR1cm4gSW1hZ2VTdHlsZTtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgSW1hZ2VTdHlsZTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvY29sb3JsaWtlXG4gKi9cbmltcG9ydCB7IHRvU3RyaW5nIH0gZnJvbSAnLi9jb2xvci5qcyc7XG4vKipcbiAqIEEgdHlwZSBhY2NlcHRlZCBieSBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQuZmlsbFN0eWxlXG4gKiBvciBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQuc3Ryb2tlU3R5bGUuXG4gKiBSZXByZXNlbnRzIGEgY29sb3IsIHBhdHRlcm4sIG9yIGdyYWRpZW50LiBUaGUgb3JpZ2luIGZvciBwYXR0ZXJucyBhbmRcbiAqIGdyYWRpZW50cyBhcyBmaWxsIHN0eWxlIGlzIGFuIGluY3JlbWVudCBvZiA1MTIgY3NzIHBpeGVscyBmcm9tIG1hcCBjb29yZGluYXRlXG4gKiBgWzAsIDBdYC4gRm9yIHNlYW1sZXNzIHJlcGVhdCBwYXR0ZXJucywgd2lkdGggYW5kIGhlaWdodCBvZiB0aGUgcGF0dGVybiBpbWFnZVxuICogbXVzdCBiZSBhIGZhY3RvciBvZiB0d28gKDIsIDQsIDgsIC4uLiwgNTEyKS5cbiAqXG4gKiBAdHlwZWRlZiB7c3RyaW5nfENhbnZhc1BhdHRlcm58Q2FudmFzR3JhZGllbnR9IENvbG9yTGlrZVxuICogQGFwaVxuICovXG5cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbG9yLmpzXCIpLkNvbG9yfENvbG9yTGlrZX0gY29sb3IgQ29sb3IuXG4gKiBAcmV0dXJuIHtDb2xvckxpa2V9IFRoZSBjb2xvciBhcyBhbiB7QGxpbmsgb2wvY29sb3JsaWtlfkNvbG9yTGlrZX0uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFzQ29sb3JMaWtlKGNvbG9yKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGNvbG9yKSkge1xuICAgIHJldHVybiB0b1N0cmluZyhjb2xvcik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNvbG9yO1xuICB9XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL1JlZ3VsYXJTaGFwZVxuICovXG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuXG5pbXBvcnQgSW1hZ2VTdGF0ZSBmcm9tICcuLi9JbWFnZVN0YXRlLmpzJztcbmltcG9ydCBJbWFnZVN0eWxlIGZyb20gJy4vSW1hZ2UuanMnO1xuaW1wb3J0IHsgYXNBcnJheSB9IGZyb20gJy4uL2NvbG9yLmpzJztcbmltcG9ydCB7IGFzQ29sb3JMaWtlIH0gZnJvbSAnLi4vY29sb3JsaWtlLmpzJztcbmltcG9ydCB7IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCB9IGZyb20gJy4uL2RvbS5qcyc7XG5pbXBvcnQgeyBkZWZhdWx0RmlsbFN0eWxlLCBkZWZhdWx0TGluZUNhcCwgZGVmYXVsdExpbmVKb2luLCBkZWZhdWx0TGluZVdpZHRoLCBkZWZhdWx0TWl0ZXJMaW1pdCwgZGVmYXVsdFN0cm9rZVN0eWxlIH0gZnJvbSAnLi4vcmVuZGVyL2NhbnZhcy5qcyc7XG4vKipcbiAqIFNwZWNpZnkgcmFkaXVzIGZvciByZWd1bGFyIHBvbHlnb25zLCBvciByYWRpdXMxIGFuZCByYWRpdXMyIGZvciBzdGFycy5cbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9GaWxsLmpzXCIpLmRlZmF1bHR9IFtmaWxsXSBGaWxsIHN0eWxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHBvaW50cyBOdW1iZXIgb2YgcG9pbnRzIGZvciBzdGFycyBhbmQgcmVndWxhciBwb2x5Z29ucy4gSW4gY2FzZSBvZiBhIHBvbHlnb24sIHRoZSBudW1iZXIgb2YgcG9pbnRzXG4gKiBpcyB0aGUgbnVtYmVyIG9mIHNpZGVzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyYWRpdXNdIFJhZGl1cyBvZiBhIHJlZ3VsYXIgcG9seWdvbi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmFkaXVzMV0gT3V0ZXIgcmFkaXVzIG9mIGEgc3Rhci5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmFkaXVzMl0gSW5uZXIgcmFkaXVzIG9mIGEgc3Rhci5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbYW5nbGU9MF0gU2hhcGUncyBhbmdsZSBpbiByYWRpYW5zLiBBIHZhbHVlIG9mIDAgd2lsbCBoYXZlIG9uZSBvZiB0aGUgc2hhcGUncyBwb2ludCBmYWNpbmcgdXAuXG4gKiBAcHJvcGVydHkge0FycmF5PG51bWJlcj59IFtkaXNwbGFjZW1lbnQ9WzAsMF1dIERpc3BsYWNlbWVudCBvZiB0aGUgc2hhcGVcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH0gW3N0cm9rZV0gU3Ryb2tlIHN0eWxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyb3RhdGlvbj0wXSBSb3RhdGlvbiBpbiByYWRpYW5zIChwb3NpdGl2ZSByb3RhdGlvbiBjbG9ja3dpc2UpLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbcm90YXRlV2l0aFZpZXc9ZmFsc2VdIFdoZXRoZXIgdG8gcm90YXRlIHRoZSBzaGFwZSB3aXRoIHRoZSB2aWV3LlxuICogQHByb3BlcnR5IHtudW1iZXJ8aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBbc2NhbGU9MV0gU2NhbGUuIFVubGVzcyB0d28gZGltZW5zaW9uYWwgc2NhbGluZyBpcyByZXF1aXJlZCBhIGJldHRlclxuICogcmVzdWx0IG1heSBiZSBvYnRhaW5lZCB3aXRoIGFwcHJvcHJpYXRlIHNldHRpbmdzIGZvciBgcmFkaXVzYCwgYHJhZGl1czFgIGFuZCBgcmFkaXVzMmAuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBSZW5kZXJPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9IFtzdHJva2VTdHlsZV1cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBzdHJva2VXaWR0aFxuICogQHByb3BlcnR5IHtudW1iZXJ9IHNpemVcbiAqIEBwcm9wZXJ0eSB7Q2FudmFzTGluZUNhcH0gbGluZUNhcFxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBsaW5lRGFzaFxuICogQHByb3BlcnR5IHtudW1iZXJ9IGxpbmVEYXNoT2Zmc2V0XG4gKiBAcHJvcGVydHkge0NhbnZhc0xpbmVKb2lufSBsaW5lSm9pblxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1pdGVyTGltaXRcbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIFNldCByZWd1bGFyIHNoYXBlIHN0eWxlIGZvciB2ZWN0b3IgZmVhdHVyZXMuIFRoZSByZXN1bHRpbmcgc2hhcGUgd2lsbCBiZVxuICogYSByZWd1bGFyIHBvbHlnb24gd2hlbiBgcmFkaXVzYCBpcyBwcm92aWRlZCwgb3IgYSBzdGFyIHdoZW4gYHJhZGl1czFgIGFuZFxuICogYHJhZGl1czJgIGFyZSBwcm92aWRlZC5cbiAqIEBhcGlcbiAqL1xuXG52YXIgUmVndWxhclNoYXBlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFJlZ3VsYXJTaGFwZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFJlZ3VsYXJTaGFwZShvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuXG4gICAgdmFyIHJvdGF0ZVdpdGhWaWV3ID0gb3B0aW9ucy5yb3RhdGVXaXRoVmlldyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yb3RhdGVXaXRoVmlldyA6IGZhbHNlO1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgb3BhY2l0eTogMSxcbiAgICAgIHJvdGF0ZVdpdGhWaWV3OiByb3RhdGVXaXRoVmlldyxcbiAgICAgIHJvdGF0aW9uOiBvcHRpb25zLnJvdGF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnJvdGF0aW9uIDogMCxcbiAgICAgIHNjYWxlOiBvcHRpb25zLnNjYWxlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnNjYWxlIDogMSxcbiAgICAgIGRpc3BsYWNlbWVudDogb3B0aW9ucy5kaXNwbGFjZW1lbnQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZGlzcGxhY2VtZW50IDogWzAsIDBdXG4gICAgfSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8bnVtYmVyLCBIVE1MQ2FudmFzRWxlbWVudD59XG4gICAgICovXG5cbiAgICBfdGhpcy5jYW52YXNfID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7SFRNTENhbnZhc0VsZW1lbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5oaXREZXRlY3Rpb25DYW52YXNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL0ZpbGwuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLmZpbGxfID0gb3B0aW9ucy5maWxsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZpbGwgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5vcmlnaW5fID0gWzAsIDBdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnBvaW50c18gPSBvcHRpb25zLnBvaW50cztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJhZGl1c18gPSBvcHRpb25zLnJhZGl1cyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yYWRpdXMgOiBvcHRpb25zLnJhZGl1czE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJhZGl1czJfID0gb3B0aW9ucy5yYWRpdXMyO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmFuZ2xlXyA9IG9wdGlvbnMuYW5nbGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuYW5nbGUgOiAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vU3Ryb2tlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5zdHJva2VfID0gb3B0aW9ucy5zdHJva2UgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc3Ryb2tlIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuYW5jaG9yXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfVxuICAgICAqL1xuXG4gICAgX3RoaXMuc2l6ZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlU2l6ZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmhpdERldGVjdGlvbkltYWdlU2l6ZV8gPSBudWxsO1xuXG4gICAgX3RoaXMucmVuZGVyKCk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIENsb25lcyB0aGUgc3R5bGUuXG4gICAqIEByZXR1cm4ge1JlZ3VsYXJTaGFwZX0gVGhlIGNsb25lZCBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNjYWxlID0gdGhpcy5nZXRTY2FsZSgpO1xuICAgIHZhciBzdHlsZSA9IG5ldyBSZWd1bGFyU2hhcGUoe1xuICAgICAgZmlsbDogdGhpcy5nZXRGaWxsKCkgPyB0aGlzLmdldEZpbGwoKS5jbG9uZSgpIDogdW5kZWZpbmVkLFxuICAgICAgcG9pbnRzOiB0aGlzLmdldFBvaW50cygpLFxuICAgICAgcmFkaXVzOiB0aGlzLmdldFJhZGl1cygpLFxuICAgICAgcmFkaXVzMjogdGhpcy5nZXRSYWRpdXMyKCksXG4gICAgICBhbmdsZTogdGhpcy5nZXRBbmdsZSgpLFxuICAgICAgc3Ryb2tlOiB0aGlzLmdldFN0cm9rZSgpID8gdGhpcy5nZXRTdHJva2UoKS5jbG9uZSgpIDogdW5kZWZpbmVkLFxuICAgICAgcm90YXRpb246IHRoaXMuZ2V0Um90YXRpb24oKSxcbiAgICAgIHJvdGF0ZVdpdGhWaWV3OiB0aGlzLmdldFJvdGF0ZVdpdGhWaWV3KCksXG4gICAgICBzY2FsZTogQXJyYXkuaXNBcnJheShzY2FsZSkgPyBzY2FsZS5zbGljZSgpIDogc2NhbGUsXG4gICAgICBkaXNwbGFjZW1lbnQ6IHRoaXMuZ2V0RGlzcGxhY2VtZW50KCkuc2xpY2UoKVxuICAgIH0pO1xuICAgIHN0eWxlLnNldE9wYWNpdHkodGhpcy5nZXRPcGFjaXR5KCkpO1xuICAgIHJldHVybiBzdHlsZTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgYW5jaG9yIHBvaW50IGluIHBpeGVscy4gVGhlIGFuY2hvciBkZXRlcm1pbmVzIHRoZSBjZW50ZXIgcG9pbnQgZm9yIHRoZVxuICAgKiBzeW1ib2xpemVyLlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBBbmNob3IuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmdldEFuY2hvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5hbmNob3JfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBhbmdsZSB1c2VkIGluIGdlbmVyYXRpbmcgdGhlIHNoYXBlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFNoYXBlJ3Mgcm90YXRpb24gaW4gcmFkaWFucy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0QW5nbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuYW5nbGVfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBmaWxsIHN0eWxlIGZvciB0aGUgc2hhcGUuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vRmlsbC5qc1wiKS5kZWZhdWx0fSBGaWxsIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5nZXRGaWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZpbGxfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR9IEltYWdlIGVsZW1lbnQuXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5nZXRIaXREZXRlY3Rpb25JbWFnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuaGl0RGV0ZWN0aW9uQ2FudmFzXykge1xuICAgICAgdmFyIHJlbmRlck9wdGlvbnMgPSB0aGlzLmNyZWF0ZVJlbmRlck9wdGlvbnMoKTtcbiAgICAgIHRoaXMuY3JlYXRlSGl0RGV0ZWN0aW9uQ2FudmFzXyhyZW5kZXJPcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5oaXREZXRlY3Rpb25DYW52YXNfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBpbWFnZSBpY29uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR9IEltYWdlIG9yIENhbnZhcyBlbGVtZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5nZXRJbWFnZSA9IGZ1bmN0aW9uIChwaXhlbFJhdGlvKSB7XG4gICAgaWYgKCF0aGlzLmNhbnZhc19bcGl4ZWxSYXRpbyB8fCAxXSkge1xuICAgICAgdmFyIHJlbmRlck9wdGlvbnMgPSB0aGlzLmNyZWF0ZVJlbmRlck9wdGlvbnMoKTtcbiAgICAgIHZhciBjb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKHJlbmRlck9wdGlvbnMuc2l6ZSAqIHBpeGVsUmF0aW8gfHwgMSwgcmVuZGVyT3B0aW9ucy5zaXplICogcGl4ZWxSYXRpbyB8fCAxKTtcbiAgICAgIHRoaXMuZHJhd18ocmVuZGVyT3B0aW9ucywgY29udGV4dCwgMCwgMCwgcGl4ZWxSYXRpbyB8fCAxKTtcbiAgICAgIHRoaXMuY2FudmFzX1twaXhlbFJhdGlvIHx8IDFdID0gY29udGV4dC5jYW52YXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY2FudmFzX1twaXhlbFJhdGlvIHx8IDFdO1xuICB9O1xuICAvKlxuICAgKiBHZXQgdGhlIGltYWdlIHBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0UGl4ZWxSYXRpbyA9IGZ1bmN0aW9uIChwaXhlbFJhdGlvKSB7XG4gICAgcmV0dXJuIHBpeGVsUmF0aW87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IEltYWdlIHNpemUuXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5nZXRJbWFnZVNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VTaXplXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gU2l6ZSBvZiB0aGUgaGl0LWRldGVjdGlvbiBpbWFnZS5cbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmdldEhpdERldGVjdGlvbkltYWdlU2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5oaXREZXRlY3Rpb25JbWFnZVNpemVfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vSW1hZ2VTdGF0ZS5qc1wiKS5kZWZhdWx0fSBJbWFnZSBzdGF0ZS5cbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmdldEltYWdlU3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIEltYWdlU3RhdGUuTE9BREVEO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBvcmlnaW4gb2YgdGhlIHN5bWJvbGl6ZXIuXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IE9yaWdpbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0T3JpZ2luID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm9yaWdpbl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG51bWJlciBvZiBwb2ludHMgZm9yIGdlbmVyYXRpbmcgdGhlIHNoYXBlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE51bWJlciBvZiBwb2ludHMgZm9yIHN0YXJzIGFuZCByZWd1bGFyIHBvbHlnb25zLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5nZXRQb2ludHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucG9pbnRzXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgKHByaW1hcnkpIHJhZGl1cyBmb3IgdGhlIHNoYXBlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFJhZGl1cy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0UmFkaXVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJhZGl1c187XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHNlY29uZGFyeSByYWRpdXMgZm9yIHRoZSBzaGFwZS5cbiAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gUmFkaXVzMi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0UmFkaXVzMiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yYWRpdXMyXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc2l6ZSBvZiB0aGUgc3ltYm9saXplciAoaW4gcGl4ZWxzKS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBTaXplLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5nZXRTaXplID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnNpemVfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzdHJva2Ugc3R5bGUgZm9yIHRoZSBzaGFwZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH0gU3Ryb2tlIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5nZXRTdHJva2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3Ryb2tlXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHQpOiB2b2lkfSBsaXN0ZW5lciBMaXN0ZW5lciBmdW5jdGlvbi5cbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmxpc3RlbkltYWdlQ2hhbmdlID0gZnVuY3Rpb24gKGxpc3RlbmVyKSB7fTtcbiAgLyoqXG4gICAqIExvYWQgbm90IHlldCBsb2FkZWQgVVJJLlxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICgpIHt9O1xuICAvKipcbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9ldmVudHMvRXZlbnQuanNcIikuZGVmYXVsdCk6IHZvaWR9IGxpc3RlbmVyIExpc3RlbmVyIGZ1bmN0aW9uLlxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUudW5saXN0ZW5JbWFnZUNoYW5nZSA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge307XG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UmVuZGVyT3B0aW9uc30gIFRoZSByZW5kZXIgb3B0aW9uc1xuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5jcmVhdGVSZW5kZXJPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBsaW5lQ2FwID0gZGVmYXVsdExpbmVDYXA7XG4gICAgdmFyIGxpbmVKb2luID0gZGVmYXVsdExpbmVKb2luO1xuICAgIHZhciBtaXRlckxpbWl0ID0gMDtcbiAgICB2YXIgbGluZURhc2ggPSBudWxsO1xuICAgIHZhciBsaW5lRGFzaE9mZnNldCA9IDA7XG4gICAgdmFyIHN0cm9rZVN0eWxlO1xuICAgIHZhciBzdHJva2VXaWR0aCA9IDA7XG5cbiAgICBpZiAodGhpcy5zdHJva2VfKSB7XG4gICAgICBzdHJva2VTdHlsZSA9IHRoaXMuc3Ryb2tlXy5nZXRDb2xvcigpO1xuXG4gICAgICBpZiAoc3Ryb2tlU3R5bGUgPT09IG51bGwpIHtcbiAgICAgICAgc3Ryb2tlU3R5bGUgPSBkZWZhdWx0U3Ryb2tlU3R5bGU7XG4gICAgICB9XG5cbiAgICAgIHN0cm9rZVN0eWxlID0gYXNDb2xvckxpa2Uoc3Ryb2tlU3R5bGUpO1xuICAgICAgc3Ryb2tlV2lkdGggPSB0aGlzLnN0cm9rZV8uZ2V0V2lkdGgoKTtcblxuICAgICAgaWYgKHN0cm9rZVdpZHRoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3Ryb2tlV2lkdGggPSBkZWZhdWx0TGluZVdpZHRoO1xuICAgICAgfVxuXG4gICAgICBsaW5lRGFzaCA9IHRoaXMuc3Ryb2tlXy5nZXRMaW5lRGFzaCgpO1xuICAgICAgbGluZURhc2hPZmZzZXQgPSB0aGlzLnN0cm9rZV8uZ2V0TGluZURhc2hPZmZzZXQoKTtcbiAgICAgIGxpbmVKb2luID0gdGhpcy5zdHJva2VfLmdldExpbmVKb2luKCk7XG5cbiAgICAgIGlmIChsaW5lSm9pbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxpbmVKb2luID0gZGVmYXVsdExpbmVKb2luO1xuICAgICAgfVxuXG4gICAgICBsaW5lQ2FwID0gdGhpcy5zdHJva2VfLmdldExpbmVDYXAoKTtcblxuICAgICAgaWYgKGxpbmVDYXAgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsaW5lQ2FwID0gZGVmYXVsdExpbmVDYXA7XG4gICAgICB9XG5cbiAgICAgIG1pdGVyTGltaXQgPSB0aGlzLnN0cm9rZV8uZ2V0TWl0ZXJMaW1pdCgpO1xuXG4gICAgICBpZiAobWl0ZXJMaW1pdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG1pdGVyTGltaXQgPSBkZWZhdWx0TWl0ZXJMaW1pdDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc2l6ZSA9IDIgKiAodGhpcy5yYWRpdXNfICsgc3Ryb2tlV2lkdGgpICsgMTtcbiAgICByZXR1cm4ge1xuICAgICAgc3Ryb2tlU3R5bGU6IHN0cm9rZVN0eWxlLFxuICAgICAgc3Ryb2tlV2lkdGg6IHN0cm9rZVdpZHRoLFxuICAgICAgc2l6ZTogc2l6ZSxcbiAgICAgIGxpbmVDYXA6IGxpbmVDYXAsXG4gICAgICBsaW5lRGFzaDogbGluZURhc2gsXG4gICAgICBsaW5lRGFzaE9mZnNldDogbGluZURhc2hPZmZzZXQsXG4gICAgICBsaW5lSm9pbjogbGluZUpvaW4sXG4gICAgICBtaXRlckxpbWl0OiBtaXRlckxpbWl0XG4gICAgfTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmVuZGVyT3B0aW9ucyA9IHRoaXMuY3JlYXRlUmVuZGVyT3B0aW9ucygpO1xuICAgIHZhciBjb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKHJlbmRlck9wdGlvbnMuc2l6ZSwgcmVuZGVyT3B0aW9ucy5zaXplKTtcbiAgICB0aGlzLmRyYXdfKHJlbmRlck9wdGlvbnMsIGNvbnRleHQsIDAsIDAsIDEpO1xuICAgIHRoaXMuY2FudmFzXyA9IHt9O1xuICAgIHRoaXMuY2FudmFzX1sxXSA9IGNvbnRleHQuY2FudmFzOyAvLyBjYW52YXMud2lkdGggYW5kIGhlaWdodCBhcmUgcm91bmRlZCB0byB0aGUgY2xvc2VzdCBpbnRlZ2VyXG5cbiAgICB2YXIgc2l6ZSA9IGNvbnRleHQuY2FudmFzLndpZHRoO1xuICAgIHZhciBpbWFnZVNpemUgPSBzaXplO1xuICAgIHZhciBkaXNwbGFjZW1lbnQgPSB0aGlzLmdldERpc3BsYWNlbWVudCgpO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VTaXplXyA9IFtyZW5kZXJPcHRpb25zLnNpemUsIHJlbmRlck9wdGlvbnMuc2l6ZV07XG4gICAgdGhpcy5jcmVhdGVIaXREZXRlY3Rpb25DYW52YXNfKHJlbmRlck9wdGlvbnMpO1xuICAgIHRoaXMuYW5jaG9yXyA9IFtzaXplIC8gMiAtIGRpc3BsYWNlbWVudFswXSwgc2l6ZSAvIDIgKyBkaXNwbGFjZW1lbnRbMV1dO1xuICAgIHRoaXMuc2l6ZV8gPSBbc2l6ZSwgc2l6ZV07XG4gICAgdGhpcy5pbWFnZVNpemVfID0gW2ltYWdlU2l6ZSwgaW1hZ2VTaXplXTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7UmVuZGVyT3B0aW9uc30gcmVuZGVyT3B0aW9ucyBSZW5kZXIgb3B0aW9ucy5cbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgVGhlIHJlbmRlcmluZyBjb250ZXh0LlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBUaGUgb3JpZ2luIGZvciB0aGUgc3ltYm9sICh4KS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgVGhlIG9yaWdpbiBmb3IgdGhlIHN5bWJvbCAoeSkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFRoZSBwaXhlbCByYXRpby5cbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmRyYXdfID0gZnVuY3Rpb24gKHJlbmRlck9wdGlvbnMsIGNvbnRleHQsIHgsIHksIHBpeGVsUmF0aW8pIHtcbiAgICB2YXIgaSwgYW5nbGUwLCByYWRpdXNDOyAvLyByZXNldCB0cmFuc2Zvcm1cblxuICAgIGNvbnRleHQuc2V0VHJhbnNmb3JtKHBpeGVsUmF0aW8sIDAsIDAsIHBpeGVsUmF0aW8sIDAsIDApOyAvLyB0aGVuIG1vdmUgdG8gKHgsIHkpXG5cbiAgICBjb250ZXh0LnRyYW5zbGF0ZSh4LCB5KTtcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgIHZhciBwb2ludHMgPSB0aGlzLnBvaW50c187XG5cbiAgICBpZiAocG9pbnRzID09PSBJbmZpbml0eSkge1xuICAgICAgY29udGV4dC5hcmMocmVuZGVyT3B0aW9ucy5zaXplIC8gMiwgcmVuZGVyT3B0aW9ucy5zaXplIC8gMiwgdGhpcy5yYWRpdXNfLCAwLCAyICogTWF0aC5QSSwgdHJ1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciByYWRpdXMyID0gdGhpcy5yYWRpdXMyXyAhPT0gdW5kZWZpbmVkID8gdGhpcy5yYWRpdXMyXyA6IHRoaXMucmFkaXVzXztcblxuICAgICAgaWYgKHJhZGl1czIgIT09IHRoaXMucmFkaXVzXykge1xuICAgICAgICBwb2ludHMgPSAyICogcG9pbnRzO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGkgPSAwOyBpIDw9IHBvaW50czsgaSsrKSB7XG4gICAgICAgIGFuZ2xlMCA9IGkgKiAyICogTWF0aC5QSSAvIHBvaW50cyAtIE1hdGguUEkgLyAyICsgdGhpcy5hbmdsZV87XG4gICAgICAgIHJhZGl1c0MgPSBpICUgMiA9PT0gMCA/IHRoaXMucmFkaXVzXyA6IHJhZGl1czI7XG4gICAgICAgIGNvbnRleHQubGluZVRvKHJlbmRlck9wdGlvbnMuc2l6ZSAvIDIgKyByYWRpdXNDICogTWF0aC5jb3MoYW5nbGUwKSwgcmVuZGVyT3B0aW9ucy5zaXplIC8gMiArIHJhZGl1c0MgKiBNYXRoLnNpbihhbmdsZTApKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5maWxsXykge1xuICAgICAgdmFyIGNvbG9yID0gdGhpcy5maWxsXy5nZXRDb2xvcigpO1xuXG4gICAgICBpZiAoY29sb3IgPT09IG51bGwpIHtcbiAgICAgICAgY29sb3IgPSBkZWZhdWx0RmlsbFN0eWxlO1xuICAgICAgfVxuXG4gICAgICBjb250ZXh0LmZpbGxTdHlsZSA9IGFzQ29sb3JMaWtlKGNvbG9yKTtcbiAgICAgIGNvbnRleHQuZmlsbCgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0cm9rZV8pIHtcbiAgICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSByZW5kZXJPcHRpb25zLnN0cm9rZVN0eWxlO1xuICAgICAgY29udGV4dC5saW5lV2lkdGggPSByZW5kZXJPcHRpb25zLnN0cm9rZVdpZHRoO1xuXG4gICAgICBpZiAoY29udGV4dC5zZXRMaW5lRGFzaCAmJiByZW5kZXJPcHRpb25zLmxpbmVEYXNoKSB7XG4gICAgICAgIGNvbnRleHQuc2V0TGluZURhc2gocmVuZGVyT3B0aW9ucy5saW5lRGFzaCk7XG4gICAgICAgIGNvbnRleHQubGluZURhc2hPZmZzZXQgPSByZW5kZXJPcHRpb25zLmxpbmVEYXNoT2Zmc2V0O1xuICAgICAgfVxuXG4gICAgICBjb250ZXh0LmxpbmVDYXAgPSByZW5kZXJPcHRpb25zLmxpbmVDYXA7XG4gICAgICBjb250ZXh0LmxpbmVKb2luID0gcmVuZGVyT3B0aW9ucy5saW5lSm9pbjtcbiAgICAgIGNvbnRleHQubWl0ZXJMaW1pdCA9IHJlbmRlck9wdGlvbnMubWl0ZXJMaW1pdDtcbiAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7UmVuZGVyT3B0aW9uc30gcmVuZGVyT3B0aW9ucyBSZW5kZXIgb3B0aW9ucy5cbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmNyZWF0ZUhpdERldGVjdGlvbkNhbnZhc18gPSBmdW5jdGlvbiAocmVuZGVyT3B0aW9ucykge1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uQ2FudmFzXyA9IHRoaXMuZ2V0SW1hZ2UoMSk7XG5cbiAgICBpZiAodGhpcy5maWxsXykge1xuICAgICAgdmFyIGNvbG9yID0gdGhpcy5maWxsXy5nZXRDb2xvcigpOyAvLyBkZXRlcm1pbmUgaWYgZmlsbCBpcyB0cmFuc3BhcmVudCAob3IgcGF0dGVybiBvciBncmFkaWVudClcblxuICAgICAgdmFyIG9wYWNpdHkgPSAwO1xuXG4gICAgICBpZiAodHlwZW9mIGNvbG9yID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb2xvciA9IGFzQXJyYXkoY29sb3IpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29sb3IgPT09IG51bGwpIHtcbiAgICAgICAgb3BhY2l0eSA9IDE7XG4gICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoY29sb3IpKSB7XG4gICAgICAgIG9wYWNpdHkgPSBjb2xvci5sZW5ndGggPT09IDQgPyBjb2xvclszXSA6IDE7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcGFjaXR5ID09PSAwKSB7XG4gICAgICAgIC8vIGlmIGEgdHJhbnNwYXJlbnQgZmlsbCBzdHlsZSBpcyBzZXQsIGNyZWF0ZSBhbiBleHRyYSBoaXQtZGV0ZWN0aW9uIGltYWdlXG4gICAgICAgIC8vIHdpdGggYSBkZWZhdWx0IGZpbGwgc3R5bGVcbiAgICAgICAgdmFyIGNvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0MkQocmVuZGVyT3B0aW9ucy5zaXplLCByZW5kZXJPcHRpb25zLnNpemUpO1xuICAgICAgICB0aGlzLmhpdERldGVjdGlvbkNhbnZhc18gPSBjb250ZXh0LmNhbnZhcztcbiAgICAgICAgdGhpcy5kcmF3SGl0RGV0ZWN0aW9uQ2FudmFzXyhyZW5kZXJPcHRpb25zLCBjb250ZXh0LCAwLCAwKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge1JlbmRlck9wdGlvbnN9IHJlbmRlck9wdGlvbnMgUmVuZGVyIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IFRoZSBjb250ZXh0LlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBUaGUgb3JpZ2luIGZvciB0aGUgc3ltYm9sICh4KS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgVGhlIG9yaWdpbiBmb3IgdGhlIHN5bWJvbCAoeSkuXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5kcmF3SGl0RGV0ZWN0aW9uQ2FudmFzXyA9IGZ1bmN0aW9uIChyZW5kZXJPcHRpb25zLCBjb250ZXh0LCB4LCB5KSB7XG4gICAgLy8gbW92ZSB0byAoeCwgeSlcbiAgICBjb250ZXh0LnRyYW5zbGF0ZSh4LCB5KTtcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgIHZhciBwb2ludHMgPSB0aGlzLnBvaW50c187XG5cbiAgICBpZiAocG9pbnRzID09PSBJbmZpbml0eSkge1xuICAgICAgY29udGV4dC5hcmMocmVuZGVyT3B0aW9ucy5zaXplIC8gMiwgcmVuZGVyT3B0aW9ucy5zaXplIC8gMiwgdGhpcy5yYWRpdXNfLCAwLCAyICogTWF0aC5QSSwgdHJ1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciByYWRpdXMyID0gdGhpcy5yYWRpdXMyXyAhPT0gdW5kZWZpbmVkID8gdGhpcy5yYWRpdXMyXyA6IHRoaXMucmFkaXVzXztcblxuICAgICAgaWYgKHJhZGl1czIgIT09IHRoaXMucmFkaXVzXykge1xuICAgICAgICBwb2ludHMgPSAyICogcG9pbnRzO1xuICAgICAgfVxuXG4gICAgICB2YXIgaSA9IHZvaWQgMCxcbiAgICAgICAgICByYWRpdXNDID0gdm9pZCAwLFxuICAgICAgICAgIGFuZ2xlMCA9IHZvaWQgMDtcblxuICAgICAgZm9yIChpID0gMDsgaSA8PSBwb2ludHM7IGkrKykge1xuICAgICAgICBhbmdsZTAgPSBpICogMiAqIE1hdGguUEkgLyBwb2ludHMgLSBNYXRoLlBJIC8gMiArIHRoaXMuYW5nbGVfO1xuICAgICAgICByYWRpdXNDID0gaSAlIDIgPT09IDAgPyB0aGlzLnJhZGl1c18gOiByYWRpdXMyO1xuICAgICAgICBjb250ZXh0LmxpbmVUbyhyZW5kZXJPcHRpb25zLnNpemUgLyAyICsgcmFkaXVzQyAqIE1hdGguY29zKGFuZ2xlMCksIHJlbmRlck9wdGlvbnMuc2l6ZSAvIDIgKyByYWRpdXNDICogTWF0aC5zaW4oYW5nbGUwKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29udGV4dC5maWxsU3R5bGUgPSBkZWZhdWx0RmlsbFN0eWxlO1xuICAgIGNvbnRleHQuZmlsbCgpO1xuXG4gICAgaWYgKHRoaXMuc3Ryb2tlXykge1xuICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IHJlbmRlck9wdGlvbnMuc3Ryb2tlU3R5bGU7XG4gICAgICBjb250ZXh0LmxpbmVXaWR0aCA9IHJlbmRlck9wdGlvbnMuc3Ryb2tlV2lkdGg7XG5cbiAgICAgIGlmIChyZW5kZXJPcHRpb25zLmxpbmVEYXNoKSB7XG4gICAgICAgIGNvbnRleHQuc2V0TGluZURhc2gocmVuZGVyT3B0aW9ucy5saW5lRGFzaCk7XG4gICAgICAgIGNvbnRleHQubGluZURhc2hPZmZzZXQgPSByZW5kZXJPcHRpb25zLmxpbmVEYXNoT2Zmc2V0O1xuICAgICAgfVxuXG4gICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgIH1cblxuICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gIH07XG5cbiAgcmV0dXJuIFJlZ3VsYXJTaGFwZTtcbn0oSW1hZ2VTdHlsZSk7XG5cbmV4cG9ydCBkZWZhdWx0IFJlZ3VsYXJTaGFwZTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvc3R5bGUvQ2lyY2xlXG4gKi9cbnZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG5cbmltcG9ydCBSZWd1bGFyU2hhcGUgZnJvbSAnLi9SZWd1bGFyU2hhcGUuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vRmlsbC5qc1wiKS5kZWZhdWx0fSBbZmlsbF0gRmlsbCBzdHlsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSByYWRpdXMgQ2lyY2xlIHJhZGl1cy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH0gW3N0cm9rZV0gU3Ryb2tlIHN0eWxlLlxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBbZGlzcGxhY2VtZW50PVswLDBdXSBkaXNwbGFjZW1lbnRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gW3NjYWxlPTFdIFNjYWxlLiBBIHR3byBkaW1lbnNpb25hbCBzY2FsZSB3aWxsIHByb2R1Y2UgYW4gZWxsaXBzZS5cbiAqIFVubGVzcyB0d28gZGltZW5zaW9uYWwgc2NhbGluZyBpcyByZXF1aXJlZCBhIGJldHRlciByZXN1bHQgbWF5IGJlIG9idGFpbmVkIHdpdGggYW4gYXBwcm9wcmlhdGUgc2V0dGluZyBmb3IgYHJhZGl1c2AuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3JvdGF0aW9uPTBdIFJvdGF0aW9uIGluIHJhZGlhbnNcbiAqIChwb3NpdGl2ZSByb3RhdGlvbiBjbG9ja3dpc2UsIG1lYW5pbmdmdWwgb25seSB3aGVuIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBhIHR3byBkaW1lbnNpb25hbCBzY2FsZSkuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtyb3RhdGVXaXRoVmlldz1mYWxzZV0gV2hldGhlciB0byByb3RhdGUgdGhlIHNoYXBlIHdpdGggdGhlIHZpZXdcbiAqIChtZWFuaW5nZnVsIG9ubHkgd2hlbiB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggYSB0d28gZGltZW5zaW9uYWwgc2NhbGUpLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogU2V0IGNpcmNsZSBzdHlsZSBmb3IgdmVjdG9yIGZlYXR1cmVzLlxuICogQGFwaVxuICovXG5cbnZhciBDaXJjbGVTdHlsZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhDaXJjbGVTdHlsZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQ2lyY2xlU3R5bGUob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyA/IG9wdF9vcHRpb25zIDoge307XG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB7XG4gICAgICBwb2ludHM6IEluZmluaXR5LFxuICAgICAgZmlsbDogb3B0aW9ucy5maWxsLFxuICAgICAgcmFkaXVzOiBvcHRpb25zLnJhZGl1cyxcbiAgICAgIHN0cm9rZTogb3B0aW9ucy5zdHJva2UsXG4gICAgICBzY2FsZTogb3B0aW9ucy5zY2FsZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zY2FsZSA6IDEsXG4gICAgICByb3RhdGlvbjogb3B0aW9ucy5yb3RhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yb3RhdGlvbiA6IDAsXG4gICAgICByb3RhdGVXaXRoVmlldzogb3B0aW9ucy5yb3RhdGVXaXRoVmlldyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yb3RhdGVXaXRoVmlldyA6IGZhbHNlLFxuICAgICAgZGlzcGxhY2VtZW50OiBvcHRpb25zLmRpc3BsYWNlbWVudCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kaXNwbGFjZW1lbnQgOiBbMCwgMF1cbiAgICB9KSB8fCB0aGlzO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQ2xvbmVzIHRoZSBzdHlsZS5cbiAgICogQHJldHVybiB7Q2lyY2xlU3R5bGV9IFRoZSBjbG9uZWQgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDaXJjbGVTdHlsZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNjYWxlID0gdGhpcy5nZXRTY2FsZSgpO1xuICAgIHZhciBzdHlsZSA9IG5ldyBDaXJjbGVTdHlsZSh7XG4gICAgICBmaWxsOiB0aGlzLmdldEZpbGwoKSA/IHRoaXMuZ2V0RmlsbCgpLmNsb25lKCkgOiB1bmRlZmluZWQsXG4gICAgICBzdHJva2U6IHRoaXMuZ2V0U3Ryb2tlKCkgPyB0aGlzLmdldFN0cm9rZSgpLmNsb25lKCkgOiB1bmRlZmluZWQsXG4gICAgICByYWRpdXM6IHRoaXMuZ2V0UmFkaXVzKCksXG4gICAgICBzY2FsZTogQXJyYXkuaXNBcnJheShzY2FsZSkgPyBzY2FsZS5zbGljZSgpIDogc2NhbGUsXG4gICAgICByb3RhdGlvbjogdGhpcy5nZXRSb3RhdGlvbigpLFxuICAgICAgcm90YXRlV2l0aFZpZXc6IHRoaXMuZ2V0Um90YXRlV2l0aFZpZXcoKSxcbiAgICAgIGRpc3BsYWNlbWVudDogdGhpcy5nZXREaXNwbGFjZW1lbnQoKS5zbGljZSgpXG4gICAgfSk7XG4gICAgc3R5bGUuc2V0T3BhY2l0eSh0aGlzLmdldE9wYWNpdHkoKSk7XG4gICAgcmV0dXJuIHN0eWxlO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBjaXJjbGUgcmFkaXVzLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmFkaXVzIENpcmNsZSByYWRpdXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDaXJjbGVTdHlsZS5wcm90b3R5cGUuc2V0UmFkaXVzID0gZnVuY3Rpb24gKHJhZGl1cykge1xuICAgIHRoaXMucmFkaXVzXyA9IHJhZGl1cztcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9O1xuXG4gIHJldHVybiBDaXJjbGVTdHlsZTtcbn0oUmVndWxhclNoYXBlKTtcblxuZXhwb3J0IGRlZmF1bHQgQ2lyY2xlU3R5bGU7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL0ZpbGxcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J8aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gW2NvbG9yPW51bGxdIEEgY29sb3IsIGdyYWRpZW50IG9yIHBhdHRlcm4uXG4gKiBTZWUge0BsaW5rIG1vZHVsZTpvbC9jb2xvcn5Db2xvcn0gYW5kIHtAbGluayBtb2R1bGU6b2wvY29sb3JsaWtlfkNvbG9yTGlrZX0gZm9yIHBvc3NpYmxlIGZvcm1hdHMuXG4gKiBEZWZhdWx0IG51bGw7IGlmIG51bGwsIHRoZSBDYW52YXMvcmVuZGVyZXIgZGVmYXVsdCBibGFjayB3aWxsIGJlIHVzZWQuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBTZXQgZmlsbCBzdHlsZSBmb3IgdmVjdG9yIGZlYXR1cmVzLlxuICogQGFwaVxuICovXG52YXIgRmlsbCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cbiAgZnVuY3Rpb24gRmlsbChvcHRfb3B0aW9ucykge1xuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgfHwge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J8aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX1cbiAgICAgKi9cblxuICAgIHRoaXMuY29sb3JfID0gb3B0aW9ucy5jb2xvciAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jb2xvciA6IG51bGw7XG4gIH1cbiAgLyoqXG4gICAqIENsb25lcyB0aGUgc3R5bGUuIFRoZSBjb2xvciBpcyBub3QgY2xvbmVkIGlmIGl0IGlzIGFuIHtAbGluayBtb2R1bGU6b2wvY29sb3JsaWtlfkNvbG9yTGlrZX0uXG4gICAqIEByZXR1cm4ge0ZpbGx9IFRoZSBjbG9uZWQgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBGaWxsLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY29sb3IgPSB0aGlzLmdldENvbG9yKCk7XG4gICAgcmV0dXJuIG5ldyBGaWxsKHtcbiAgICAgIGNvbG9yOiBBcnJheS5pc0FycmF5KGNvbG9yKSA/IGNvbG9yLnNsaWNlKCkgOiBjb2xvciB8fCB1bmRlZmluZWRcbiAgICB9KTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZmlsbCBjb2xvci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J8aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gQ29sb3IuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBGaWxsLnByb3RvdHlwZS5nZXRDb2xvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jb2xvcl87XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGNvbG9yLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbG9yLmpzXCIpLkNvbG9yfGltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9IGNvbG9yIENvbG9yLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgRmlsbC5wcm90b3R5cGUuc2V0Q29sb3IgPSBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICB0aGlzLmNvbG9yXyA9IGNvbG9yO1xuICB9O1xuXG4gIHJldHVybiBGaWxsO1xufSgpO1xuXG5leHBvcnQgZGVmYXVsdCBGaWxsOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHlsZS9TdHJva2VcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J8aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gW2NvbG9yXSBBIGNvbG9yLCBncmFkaWVudCBvciBwYXR0ZXJuLlxuICogU2VlIHtAbGluayBtb2R1bGU6b2wvY29sb3J+Q29sb3J9IGFuZCB7QGxpbmsgbW9kdWxlOm9sL2NvbG9ybGlrZX5Db2xvckxpa2V9IGZvciBwb3NzaWJsZSBmb3JtYXRzLlxuICogRGVmYXVsdCBudWxsOyBpZiBudWxsLCB0aGUgQ2FudmFzL3JlbmRlcmVyIGRlZmF1bHQgYmxhY2sgd2lsbCBiZSB1c2VkLlxuICogQHByb3BlcnR5IHtDYW52YXNMaW5lQ2FwfSBbbGluZUNhcD0ncm91bmQnXSBMaW5lIGNhcCBzdHlsZTogYGJ1dHRgLCBgcm91bmRgLCBvciBgc3F1YXJlYC5cbiAqIEBwcm9wZXJ0eSB7Q2FudmFzTGluZUpvaW59IFtsaW5lSm9pbj0ncm91bmQnXSBMaW5lIGpvaW4gc3R5bGU6IGBiZXZlbGAsIGByb3VuZGAsIG9yIGBtaXRlcmAuXG4gKiBAcHJvcGVydHkge0FycmF5PG51bWJlcj59IFtsaW5lRGFzaF0gTGluZSBkYXNoIHBhdHRlcm4uIERlZmF1bHQgaXMgYG51bGxgIChubyBkYXNoKS5cbiAqIFBsZWFzZSBub3RlIHRoYXQgSW50ZXJuZXQgRXhwbG9yZXIgMTAgYW5kIGxvd2VyIGRvIG5vdCBzdXBwb3J0IHRoZSBgc2V0TGluZURhc2hgIG1ldGhvZCBvblxuICogdGhlIGBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkRgIGFuZCB0aGVyZWZvcmUgdGhpcyBvcHRpb24gd2lsbCBoYXZlIG5vIHZpc3VhbCBlZmZlY3QgaW4gdGhlc2UgYnJvd3NlcnMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2xpbmVEYXNoT2Zmc2V0PTBdIExpbmUgZGFzaCBvZmZzZXQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pdGVyTGltaXQ9MTBdIE1pdGVyIGxpbWl0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt3aWR0aF0gV2lkdGguXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBTZXQgc3Ryb2tlIHN0eWxlIGZvciB2ZWN0b3IgZmVhdHVyZXMuXG4gKiBOb3RlIHRoYXQgdGhlIGRlZmF1bHRzIGdpdmVuIGFyZSB0aGUgQ2FudmFzIGRlZmF1bHRzLCB3aGljaCB3aWxsIGJlIHVzZWQgaWZcbiAqIG9wdGlvbiBpcyBub3QgZGVmaW5lZC4gVGhlIGBnZXRgIGZ1bmN0aW9ucyByZXR1cm4gd2hhdGV2ZXIgd2FzIGVudGVyZWQgaW5cbiAqIHRoZSBvcHRpb25zOyB0aGV5IHdpbGwgbm90IHJldHVybiB0aGUgZGVmYXVsdC5cbiAqIEBhcGlcbiAqL1xudmFyIFN0cm9rZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cbiAgZnVuY3Rpb24gU3Ryb2tlKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyB8fCB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9jb2xvci5qc1wiKS5Db2xvcnxpbXBvcnQoXCIuLi9jb2xvcmxpa2UuanNcIikuQ29sb3JMaWtlfVxuICAgICAqL1xuXG4gICAgdGhpcy5jb2xvcl8gPSBvcHRpb25zLmNvbG9yICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNvbG9yIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtDYW52YXNMaW5lQ2FwfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHRoaXMubGluZUNhcF8gPSBvcHRpb25zLmxpbmVDYXA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIHRoaXMubGluZURhc2hfID0gb3B0aW9ucy5saW5lRGFzaCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5saW5lRGFzaCA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHRoaXMubGluZURhc2hPZmZzZXRfID0gb3B0aW9ucy5saW5lRGFzaE9mZnNldDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtDYW52YXNMaW5lSm9pbnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLmxpbmVKb2luXyA9IG9wdGlvbnMubGluZUpvaW47XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHRoaXMubWl0ZXJMaW1pdF8gPSBvcHRpb25zLm1pdGVyTGltaXQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHRoaXMud2lkdGhfID0gb3B0aW9ucy53aWR0aDtcbiAgfVxuICAvKipcbiAgICogQ2xvbmVzIHRoZSBzdHlsZS5cbiAgICogQHJldHVybiB7U3Ryb2tlfSBUaGUgY2xvbmVkIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3Ryb2tlLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY29sb3IgPSB0aGlzLmdldENvbG9yKCk7XG4gICAgcmV0dXJuIG5ldyBTdHJva2Uoe1xuICAgICAgY29sb3I6IEFycmF5LmlzQXJyYXkoY29sb3IpID8gY29sb3Iuc2xpY2UoKSA6IGNvbG9yIHx8IHVuZGVmaW5lZCxcbiAgICAgIGxpbmVDYXA6IHRoaXMuZ2V0TGluZUNhcCgpLFxuICAgICAgbGluZURhc2g6IHRoaXMuZ2V0TGluZURhc2goKSA/IHRoaXMuZ2V0TGluZURhc2goKS5zbGljZSgpIDogdW5kZWZpbmVkLFxuICAgICAgbGluZURhc2hPZmZzZXQ6IHRoaXMuZ2V0TGluZURhc2hPZmZzZXQoKSxcbiAgICAgIGxpbmVKb2luOiB0aGlzLmdldExpbmVKb2luKCksXG4gICAgICBtaXRlckxpbWl0OiB0aGlzLmdldE1pdGVyTGltaXQoKSxcbiAgICAgIHdpZHRoOiB0aGlzLmdldFdpZHRoKClcbiAgICB9KTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc3Ryb2tlIGNvbG9yLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9jb2xvci5qc1wiKS5Db2xvcnxpbXBvcnQoXCIuLi9jb2xvcmxpa2UuanNcIikuQ29sb3JMaWtlfSBDb2xvci5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuZ2V0Q29sb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29sb3JfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBsaW5lIGNhcCB0eXBlIGZvciB0aGUgc3Ryb2tlLlxuICAgKiBAcmV0dXJuIHtDYW52YXNMaW5lQ2FwfHVuZGVmaW5lZH0gTGluZSBjYXAuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHJva2UucHJvdG90eXBlLmdldExpbmVDYXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubGluZUNhcF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGxpbmUgZGFzaCBzdHlsZSBmb3IgdGhlIHN0cm9rZS5cbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gTGluZSBkYXNoLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3Ryb2tlLnByb3RvdHlwZS5nZXRMaW5lRGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5saW5lRGFzaF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGxpbmUgZGFzaCBvZmZzZXQgZm9yIHRoZSBzdHJva2UuXG4gICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IExpbmUgZGFzaCBvZmZzZXQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHJva2UucHJvdG90eXBlLmdldExpbmVEYXNoT2Zmc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmxpbmVEYXNoT2Zmc2V0XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbGluZSBqb2luIHR5cGUgZm9yIHRoZSBzdHJva2UuXG4gICAqIEByZXR1cm4ge0NhbnZhc0xpbmVKb2lufHVuZGVmaW5lZH0gTGluZSBqb2luLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3Ryb2tlLnByb3RvdHlwZS5nZXRMaW5lSm9pbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5saW5lSm9pbl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1pdGVyIGxpbWl0IGZvciB0aGUgc3Ryb2tlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBNaXRlciBsaW1pdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuZ2V0TWl0ZXJMaW1pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5taXRlckxpbWl0XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc3Ryb2tlIHdpZHRoLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBXaWR0aC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuZ2V0V2lkdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMud2lkdGhfO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBjb2xvci5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb2xvci5qc1wiKS5Db2xvcnxpbXBvcnQoXCIuLi9jb2xvcmxpa2UuanNcIikuQ29sb3JMaWtlfSBjb2xvciBDb2xvci5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuc2V0Q29sb3IgPSBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICB0aGlzLmNvbG9yXyA9IGNvbG9yO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBsaW5lIGNhcC5cbiAgICpcbiAgICogQHBhcmFtIHtDYW52YXNMaW5lQ2FwfHVuZGVmaW5lZH0gbGluZUNhcCBMaW5lIGNhcC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuc2V0TGluZUNhcCA9IGZ1bmN0aW9uIChsaW5lQ2FwKSB7XG4gICAgdGhpcy5saW5lQ2FwXyA9IGxpbmVDYXA7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGxpbmUgZGFzaC5cbiAgICpcbiAgICogUGxlYXNlIG5vdGUgdGhhdCBJbnRlcm5ldCBFeHBsb3JlciAxMCBhbmQgbG93ZXIgW2RvIG5vdCBzdXBwb3J0XVttZG5dIHRoZVxuICAgKiBgc2V0TGluZURhc2hgIG1ldGhvZCBvbiB0aGUgYENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRGAgYW5kIHRoZXJlZm9yZSB0aGlzXG4gICAqIHByb3BlcnR5IHdpbGwgaGF2ZSBubyB2aXN1YWwgZWZmZWN0IGluIHRoZXNlIGJyb3dzZXJzLlxuICAgKlxuICAgKiBbbWRuXTogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRC9zZXRMaW5lRGFzaCNCcm93c2VyX2NvbXBhdGliaWxpdHlcbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBsaW5lRGFzaCBMaW5lIGRhc2guXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHJva2UucHJvdG90eXBlLnNldExpbmVEYXNoID0gZnVuY3Rpb24gKGxpbmVEYXNoKSB7XG4gICAgdGhpcy5saW5lRGFzaF8gPSBsaW5lRGFzaDtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgbGluZSBkYXNoIG9mZnNldC5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSBsaW5lRGFzaE9mZnNldCBMaW5lIGRhc2ggb2Zmc2V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3Ryb2tlLnByb3RvdHlwZS5zZXRMaW5lRGFzaE9mZnNldCA9IGZ1bmN0aW9uIChsaW5lRGFzaE9mZnNldCkge1xuICAgIHRoaXMubGluZURhc2hPZmZzZXRfID0gbGluZURhc2hPZmZzZXQ7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGxpbmUgam9pbi5cbiAgICpcbiAgICogQHBhcmFtIHtDYW52YXNMaW5lSm9pbnx1bmRlZmluZWR9IGxpbmVKb2luIExpbmUgam9pbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuc2V0TGluZUpvaW4gPSBmdW5jdGlvbiAobGluZUpvaW4pIHtcbiAgICB0aGlzLmxpbmVKb2luXyA9IGxpbmVKb2luO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBtaXRlciBsaW1pdC5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSBtaXRlckxpbWl0IE1pdGVyIGxpbWl0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3Ryb2tlLnByb3RvdHlwZS5zZXRNaXRlckxpbWl0ID0gZnVuY3Rpb24gKG1pdGVyTGltaXQpIHtcbiAgICB0aGlzLm1pdGVyTGltaXRfID0gbWl0ZXJMaW1pdDtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgd2lkdGguXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfHVuZGVmaW5lZH0gd2lkdGggV2lkdGguXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHJva2UucHJvdG90eXBlLnNldFdpZHRoID0gZnVuY3Rpb24gKHdpZHRoKSB7XG4gICAgdGhpcy53aWR0aF8gPSB3aWR0aDtcbiAgfTtcblxuICByZXR1cm4gU3Ryb2tlO1xufSgpO1xuXG5leHBvcnQgZGVmYXVsdCBTdHJva2U7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL1N0eWxlXG4gKi9cbmltcG9ydCBDaXJjbGVTdHlsZSBmcm9tICcuL0NpcmNsZS5qcyc7XG5pbXBvcnQgRmlsbCBmcm9tICcuL0ZpbGwuanMnO1xuaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICcuLi9nZW9tL0dlb21ldHJ5VHlwZS5qcyc7XG5pbXBvcnQgU3Ryb2tlIGZyb20gJy4vU3Ryb2tlLmpzJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uL2Fzc2VydHMuanMnO1xuLyoqXG4gKiBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYW4ge0BsaW5rIG1vZHVsZTpvbC9GZWF0dXJlfSBhbmQgYSBge251bWJlcn1gXG4gKiByZXByZXNlbnRpbmcgdGhlIHZpZXcncyByZXNvbHV0aW9uLiBUaGUgZnVuY3Rpb24gc2hvdWxkIHJldHVybiBhXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3N0eWxlL1N0eWxlfSBvciBhbiBhcnJheSBvZiB0aGVtLiBUaGlzIHdheSBlLmcuIGFcbiAqIHZlY3RvciBsYXllciBjYW4gYmUgc3R5bGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyBgdW5kZWZpbmVkYCwgdGhlXG4gKiBmZWF0dXJlIHdpbGwgbm90IGJlIHJlbmRlcmVkLlxuICpcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlLCBudW1iZXIpOihTdHlsZXxBcnJheTxTdHlsZT58dm9pZCl9IFN0eWxlRnVuY3Rpb25cbiAqL1xuXG4vKipcbiAqIEEge0BsaW5rIFN0eWxlfSwgYW4gYXJyYXkgb2Yge0BsaW5rIFN0eWxlfSwgb3IgYSB7QGxpbmsgU3R5bGVGdW5jdGlvbn0uXG4gKiBAdHlwZWRlZiB7U3R5bGV8QXJyYXk8U3R5bGU+fFN0eWxlRnVuY3Rpb259IFN0eWxlTGlrZVxuICovXG5cbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvRmVhdHVyZX0gYXMgYXJndW1lbnQgYW5kIHJldHVybnMgYW5cbiAqIHtAbGluayBtb2R1bGU6b2wvZ2VvbS9HZW9tZXRyeX0gdGhhdCB3aWxsIGJlIHJlbmRlcmVkIGFuZCBzdHlsZWQgZm9yIHRoZSBmZWF0dXJlLlxuICpcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlKTpcbiAqICAgICAoaW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL3JlbmRlci9GZWF0dXJlLmpzXCIpLmRlZmF1bHR8dW5kZWZpbmVkKX0gR2VvbWV0cnlGdW5jdGlvblxuICovXG5cbi8qKlxuICogQ3VzdG9tIHJlbmRlcmVyIGZ1bmN0aW9uLiBUYWtlcyB0d28gYXJndW1lbnRzOlxuICpcbiAqIDEuIFRoZSBwaXhlbCBjb29yZGluYXRlcyBvZiB0aGUgZ2VvbWV0cnkgaW4gR2VvSlNPTiBub3RhdGlvbi5cbiAqIDIuIFRoZSB7QGxpbmsgbW9kdWxlOm9sL3JlbmRlcn5TdGF0ZX0gb2YgdGhlIGxheWVyIHJlbmRlcmVyLlxuICpcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbigoaW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT58QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj4pLGltcG9ydChcIi4uL3JlbmRlci5qc1wiKS5TdGF0ZSk6IHZvaWR9XG4gKiBSZW5kZXJGdW5jdGlvblxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd8aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fEdlb21ldHJ5RnVuY3Rpb259IFtnZW9tZXRyeV0gRmVhdHVyZSBwcm9wZXJ0eSBvciBnZW9tZXRyeVxuICogb3IgZnVuY3Rpb24gcmV0dXJuaW5nIGEgZ2VvbWV0cnkgdG8gcmVuZGVyIGZvciB0aGlzIHN0eWxlLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL0ZpbGwuanNcIikuZGVmYXVsdH0gW2ZpbGxdIEZpbGwgc3R5bGUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vSW1hZ2UuanNcIikuZGVmYXVsdH0gW2ltYWdlXSBJbWFnZSBzdHlsZS5cbiAqIEBwcm9wZXJ0eSB7UmVuZGVyRnVuY3Rpb259IFtyZW5kZXJlcl0gQ3VzdG9tIHJlbmRlcmVyLiBXaGVuIGNvbmZpZ3VyZWQsIGBmaWxsYCwgYHN0cm9rZWAgYW5kIGBpbWFnZWAgd2lsbCBiZVxuICogaWdub3JlZCwgYW5kIHRoZSBwcm92aWRlZCBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCB3aXRoIGVhY2ggcmVuZGVyIGZyYW1lIGZvciBlYWNoIGdlb21ldHJ5LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1N0cm9rZS5qc1wiKS5kZWZhdWx0fSBbc3Ryb2tlXSBTdHJva2Ugc3R5bGUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vVGV4dC5qc1wiKS5kZWZhdWx0fSBbdGV4dF0gVGV4dCBzdHlsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbekluZGV4XSBaIGluZGV4LlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQ29udGFpbmVyIGZvciB2ZWN0b3IgZmVhdHVyZSByZW5kZXJpbmcgc3R5bGVzLiBBbnkgY2hhbmdlcyBtYWRlIHRvIHRoZSBzdHlsZVxuICogb3IgaXRzIGNoaWxkcmVuIHRocm91Z2ggYHNldCooKWAgbWV0aG9kcyB3aWxsIG5vdCB0YWtlIGVmZmVjdCB1bnRpbCB0aGVcbiAqIGZlYXR1cmUgb3IgbGF5ZXIgdGhhdCB1c2VzIHRoZSBzdHlsZSBpcyByZS1yZW5kZXJlZC5cbiAqXG4gKiAjIyBGZWF0dXJlIHN0eWxlc1xuICpcbiAqIElmIG5vIHN0eWxlIGlzIGRlZmluZWQsIHRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzdHlsZSBpcyB1c2VkOlxuICogYGBganNcbiAqICBpbXBvcnQge0ZpbGwsIFN0cm9rZSwgQ2lyY2xlLCBTdHlsZX0gZnJvbSAnb2wvc3R5bGUnO1xuICpcbiAqICB2YXIgZmlsbCA9IG5ldyBGaWxsKHtcbiAqICAgIGNvbG9yOiAncmdiYSgyNTUsMjU1LDI1NSwwLjQpJ1xuICogIH0pO1xuICogIHZhciBzdHJva2UgPSBuZXcgU3Ryb2tlKHtcbiAqICAgIGNvbG9yOiAnIzMzOTlDQycsXG4gKiAgICB3aWR0aDogMS4yNVxuICogIH0pO1xuICogIHZhciBzdHlsZXMgPSBbXG4gKiAgICBuZXcgU3R5bGUoe1xuICogICAgICBpbWFnZTogbmV3IENpcmNsZSh7XG4gKiAgICAgICAgZmlsbDogZmlsbCxcbiAqICAgICAgICBzdHJva2U6IHN0cm9rZSxcbiAqICAgICAgICByYWRpdXM6IDVcbiAqICAgICAgfSksXG4gKiAgICAgIGZpbGw6IGZpbGwsXG4gKiAgICAgIHN0cm9rZTogc3Ryb2tlXG4gKiAgICB9KVxuICogIF07XG4gKiBgYGBcbiAqXG4gKiBBIHNlcGFyYXRlIGVkaXRpbmcgc3R5bGUgaGFzIHRoZSBmb2xsb3dpbmcgZGVmYXVsdHM6XG4gKiBgYGBqc1xuICogIGltcG9ydCB7RmlsbCwgU3Ryb2tlLCBDaXJjbGUsIFN0eWxlfSBmcm9tICdvbC9zdHlsZSc7XG4gKiAgaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICdvbC9nZW9tL0dlb21ldHJ5VHlwZSc7XG4gKlxuICogIHZhciB3aGl0ZSA9IFsyNTUsIDI1NSwgMjU1LCAxXTtcbiAqICB2YXIgYmx1ZSA9IFswLCAxNTMsIDI1NSwgMV07XG4gKiAgdmFyIHdpZHRoID0gMztcbiAqICBzdHlsZXNbR2VvbWV0cnlUeXBlLlBPTFlHT05dID0gW1xuICogICAgbmV3IFN0eWxlKHtcbiAqICAgICAgZmlsbDogbmV3IEZpbGwoe1xuICogICAgICAgIGNvbG9yOiBbMjU1LCAyNTUsIDI1NSwgMC41XVxuICogICAgICB9KVxuICogICAgfSlcbiAqICBdO1xuICogIHN0eWxlc1tHZW9tZXRyeVR5cGUuTVVMVElfUE9MWUdPTl0gPVxuICogICAgICBzdHlsZXNbR2VvbWV0cnlUeXBlLlBPTFlHT05dO1xuICogIHN0eWxlc1tHZW9tZXRyeVR5cGUuTElORV9TVFJJTkddID0gW1xuICogICAgbmV3IFN0eWxlKHtcbiAqICAgICAgc3Ryb2tlOiBuZXcgU3Ryb2tlKHtcbiAqICAgICAgICBjb2xvcjogd2hpdGUsXG4gKiAgICAgICAgd2lkdGg6IHdpZHRoICsgMlxuICogICAgICB9KVxuICogICAgfSksXG4gKiAgICBuZXcgU3R5bGUoe1xuICogICAgICBzdHJva2U6IG5ldyBTdHJva2Uoe1xuICogICAgICAgIGNvbG9yOiBibHVlLFxuICogICAgICAgIHdpZHRoOiB3aWR0aFxuICogICAgICB9KVxuICogICAgfSlcbiAqICBdO1xuICogIHN0eWxlc1tHZW9tZXRyeVR5cGUuTVVMVElfTElORV9TVFJJTkddID1cbiAqICAgICAgc3R5bGVzW0dlb21ldHJ5VHlwZS5MSU5FX1NUUklOR107XG4gKiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0lOVF0gPSBbXG4gKiAgICBuZXcgU3R5bGUoe1xuICogICAgICBpbWFnZTogbmV3IENpcmNsZSh7XG4gKiAgICAgICAgcmFkaXVzOiB3aWR0aCAqIDIsXG4gKiAgICAgICAgZmlsbDogbmV3IEZpbGwoe1xuICogICAgICAgICAgY29sb3I6IGJsdWVcbiAqICAgICAgICB9KSxcbiAqICAgICAgICBzdHJva2U6IG5ldyBTdHJva2Uoe1xuICogICAgICAgICAgY29sb3I6IHdoaXRlLFxuICogICAgICAgICAgd2lkdGg6IHdpZHRoIC8gMlxuICogICAgICAgIH0pXG4gKiAgICAgIH0pLFxuICogICAgICB6SW5kZXg6IEluZmluaXR5XG4gKiAgICB9KVxuICogIF07XG4gKiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5NVUxUSV9QT0lOVF0gPVxuICogICAgICBzdHlsZXNbR2VvbWV0cnlUeXBlLlBPSU5UXTtcbiAqICBzdHlsZXNbR2VvbWV0cnlUeXBlLkdFT01FVFJZX0NPTExFQ1RJT05dID1cbiAqICAgICAgc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0xZR09OXS5jb25jYXQoXG4gKiAgICAgICAgICBzdHlsZXNbR2VvbWV0cnlUeXBlLkxJTkVfU1RSSU5HXSxcbiAqICAgICAgICAgIHN0eWxlc1tHZW9tZXRyeVR5cGUuUE9JTlRdXG4gKiAgICAgICk7XG4gKiBgYGBcbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIFN0eWxlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIFN0eWxlIG9wdGlvbnMuXG4gICAqL1xuICBmdW5jdGlvbiBTdHlsZShvcHRfb3B0aW9ucykge1xuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgfHwge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfGltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdHxHZW9tZXRyeUZ1bmN0aW9ufVxuICAgICAqL1xuXG4gICAgdGhpcy5nZW9tZXRyeV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFHZW9tZXRyeUZ1bmN0aW9ufVxuICAgICAqL1xuXG4gICAgdGhpcy5nZW9tZXRyeUZ1bmN0aW9uXyA9IGRlZmF1bHRHZW9tZXRyeUZ1bmN0aW9uO1xuXG4gICAgaWYgKG9wdGlvbnMuZ2VvbWV0cnkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zZXRHZW9tZXRyeShvcHRpb25zLmdlb21ldHJ5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9GaWxsLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cblxuICAgIHRoaXMuZmlsbF8gPSBvcHRpb25zLmZpbGwgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZmlsbCA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9JbWFnZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgdGhpcy5pbWFnZV8gPSBvcHRpb25zLmltYWdlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmltYWdlIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtSZW5kZXJGdW5jdGlvbnxudWxsfVxuICAgICAqL1xuXG4gICAgdGhpcy5yZW5kZXJlcl8gPSBvcHRpb25zLnJlbmRlcmVyICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnJlbmRlcmVyIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL1N0cm9rZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgdGhpcy5zdHJva2VfID0gb3B0aW9ucy5zdHJva2UgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc3Ryb2tlIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL1RleHQuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIHRoaXMudGV4dF8gPSBvcHRpb25zLnRleHQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudGV4dCA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHRoaXMuekluZGV4XyA9IG9wdGlvbnMuekluZGV4O1xuICB9XG4gIC8qKlxuICAgKiBDbG9uZXMgdGhlIHN0eWxlLlxuICAgKiBAcmV0dXJuIHtTdHlsZX0gVGhlIGNsb25lZCBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZ2VvbWV0cnkgPSB0aGlzLmdldEdlb21ldHJ5KCk7XG5cbiAgICBpZiAoZ2VvbWV0cnkgJiYgdHlwZW9mIGdlb21ldHJ5ID09PSAnb2JqZWN0Jykge1xuICAgICAgZ2VvbWV0cnkgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBnZW9tZXRyeS5jbG9uZSgpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgU3R5bGUoe1xuICAgICAgZ2VvbWV0cnk6IGdlb21ldHJ5LFxuICAgICAgZmlsbDogdGhpcy5nZXRGaWxsKCkgPyB0aGlzLmdldEZpbGwoKS5jbG9uZSgpIDogdW5kZWZpbmVkLFxuICAgICAgaW1hZ2U6IHRoaXMuZ2V0SW1hZ2UoKSA/IHRoaXMuZ2V0SW1hZ2UoKS5jbG9uZSgpIDogdW5kZWZpbmVkLFxuICAgICAgc3Ryb2tlOiB0aGlzLmdldFN0cm9rZSgpID8gdGhpcy5nZXRTdHJva2UoKS5jbG9uZSgpIDogdW5kZWZpbmVkLFxuICAgICAgdGV4dDogdGhpcy5nZXRUZXh0KCkgPyB0aGlzLmdldFRleHQoKS5jbG9uZSgpIDogdW5kZWZpbmVkLFxuICAgICAgekluZGV4OiB0aGlzLmdldFpJbmRleCgpXG4gICAgfSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1c3RvbSByZW5kZXJlciBmdW5jdGlvbiB0aGF0IHdhcyBjb25maWd1cmVkIHdpdGhcbiAgICoge0BsaW5rICNzZXRSZW5kZXJlcn0gb3IgdGhlIGByZW5kZXJlcmAgY29uc3RydWN0b3Igb3B0aW9uLlxuICAgKiBAcmV0dXJuIHtSZW5kZXJGdW5jdGlvbnxudWxsfSBDdXN0b20gcmVuZGVyZXIgZnVuY3Rpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuZ2V0UmVuZGVyZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXJfO1xuICB9O1xuICAvKipcbiAgICogU2V0cyBhIGN1c3RvbSByZW5kZXJlciBmdW5jdGlvbiBmb3IgdGhpcyBzdHlsZS4gV2hlbiBzZXQsIGBmaWxsYCwgYHN0cm9rZWBcbiAgICogYW5kIGBpbWFnZWAgb3B0aW9ucyBvZiB0aGUgc3R5bGUgd2lsbCBiZSBpZ25vcmVkLlxuICAgKiBAcGFyYW0ge1JlbmRlckZ1bmN0aW9ufG51bGx9IHJlbmRlcmVyIEN1c3RvbSByZW5kZXJlciBmdW5jdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5zZXRSZW5kZXJlciA9IGZ1bmN0aW9uIChyZW5kZXJlcikge1xuICAgIHRoaXMucmVuZGVyZXJfID0gcmVuZGVyZXI7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGdlb21ldHJ5IHRvIGJlIHJlbmRlcmVkLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd8aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fEdlb21ldHJ5RnVuY3Rpb259XG4gICAqIEZlYXR1cmUgcHJvcGVydHkgb3IgZ2VvbWV0cnkgb3IgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBnZW9tZXRyeSB0aGF0IHdpbGxcbiAgICogYmUgcmVuZGVyZWQgd2l0aCB0aGlzIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3R5bGUucHJvdG90eXBlLmdldEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdlb21ldHJ5XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZnVuY3Rpb24gdXNlZCB0byBnZW5lcmF0ZSBhIGdlb21ldHJ5IGZvciByZW5kZXJpbmcuXG4gICAqIEByZXR1cm4geyFHZW9tZXRyeUZ1bmN0aW9ufSBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aXRoIGEgZmVhdHVyZVxuICAgKiBhbmQgcmV0dXJucyB0aGUgZ2VvbWV0cnkgdG8gcmVuZGVyIGluc3RlYWQgb2YgdGhlIGZlYXR1cmUncyBnZW9tZXRyeS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5nZXRHZW9tZXRyeUZ1bmN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdlb21ldHJ5RnVuY3Rpb25fO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBmaWxsIHN0eWxlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0ZpbGwuanNcIikuZGVmYXVsdH0gRmlsbCBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5nZXRGaWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZpbGxfO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBmaWxsIHN0eWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vRmlsbC5qc1wiKS5kZWZhdWx0fSBmaWxsIEZpbGwgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuc2V0RmlsbCA9IGZ1bmN0aW9uIChmaWxsKSB7XG4gICAgdGhpcy5maWxsXyA9IGZpbGw7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGltYWdlIHN0eWxlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0ltYWdlLmpzXCIpLmRlZmF1bHR9IEltYWdlIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3R5bGUucHJvdG90eXBlLmdldEltYWdlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmltYWdlXztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgaW1hZ2Ugc3R5bGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9JbWFnZS5qc1wiKS5kZWZhdWx0fSBpbWFnZSBJbWFnZSBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5zZXRJbWFnZSA9IGZ1bmN0aW9uIChpbWFnZSkge1xuICAgIHRoaXMuaW1hZ2VfID0gaW1hZ2U7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHN0cm9rZSBzdHlsZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH0gU3Ryb2tlIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3R5bGUucHJvdG90eXBlLmdldFN0cm9rZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zdHJva2VfO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBzdHJva2Ugc3R5bGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH0gc3Ryb2tlIFN0cm9rZSBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5zZXRTdHJva2UgPSBmdW5jdGlvbiAoc3Ryb2tlKSB7XG4gICAgdGhpcy5zdHJva2VfID0gc3Ryb2tlO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB0ZXh0IHN0eWxlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL1RleHQuanNcIikuZGVmYXVsdH0gVGV4dCBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5nZXRUZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnRleHRfO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB0ZXh0IHN0eWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vVGV4dC5qc1wiKS5kZWZhdWx0fSB0ZXh0IFRleHQgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuc2V0VGV4dCA9IGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgdGhpcy50ZXh0XyA9IHRleHQ7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHotaW5kZXggZm9yIHRoZSBzdHlsZS5cbiAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gWkluZGV4LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3R5bGUucHJvdG90eXBlLmdldFpJbmRleCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy56SW5kZXhfO1xuICB9O1xuICAvKipcbiAgICogU2V0IGEgZ2VvbWV0cnkgdGhhdCBpcyByZW5kZXJlZCBpbnN0ZWFkIG9mIHRoZSBmZWF0dXJlJ3MgZ2VvbWV0cnkuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfGltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdHxHZW9tZXRyeUZ1bmN0aW9ufSBnZW9tZXRyeVxuICAgKiAgICAgRmVhdHVyZSBwcm9wZXJ0eSBvciBnZW9tZXRyeSBvciBmdW5jdGlvbiByZXR1cm5pbmcgYSBnZW9tZXRyeSB0byByZW5kZXJcbiAgICogICAgIGZvciB0aGlzIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3R5bGUucHJvdG90eXBlLnNldEdlb21ldHJ5ID0gZnVuY3Rpb24gKGdlb21ldHJ5KSB7XG4gICAgaWYgKHR5cGVvZiBnZW9tZXRyeSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5nZW9tZXRyeUZ1bmN0aW9uXyA9IGdlb21ldHJ5O1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGdlb21ldHJ5ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5nZW9tZXRyeUZ1bmN0aW9uXyA9IGZ1bmN0aW9uIChmZWF0dXJlKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgICAgZmVhdHVyZS5nZXQoZ2VvbWV0cnkpXG4gICAgICAgICk7XG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoIWdlb21ldHJ5KSB7XG4gICAgICB0aGlzLmdlb21ldHJ5RnVuY3Rpb25fID0gZGVmYXVsdEdlb21ldHJ5RnVuY3Rpb247XG4gICAgfSBlbHNlIGlmIChnZW9tZXRyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmdlb21ldHJ5RnVuY3Rpb25fID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICAgIGdlb21ldHJ5XG4gICAgICAgICk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMuZ2VvbWV0cnlfID0gZ2VvbWV0cnk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHotaW5kZXguXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfHVuZGVmaW5lZH0gekluZGV4IFpJbmRleC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5zZXRaSW5kZXggPSBmdW5jdGlvbiAoekluZGV4KSB7XG4gICAgdGhpcy56SW5kZXhfID0gekluZGV4O1xuICB9O1xuXG4gIHJldHVybiBTdHlsZTtcbn0oKTtcbi8qKlxuICogQ29udmVydCB0aGUgcHJvdmlkZWQgb2JqZWN0IGludG8gYSBzdHlsZSBmdW5jdGlvbi4gIEZ1bmN0aW9ucyBwYXNzZWQgdGhyb3VnaFxuICogdW5jaGFuZ2VkLiAgQXJyYXlzIG9mIFN0eWxlIG9yIHNpbmdsZSBzdHlsZSBvYmplY3RzIHdyYXBwZWQgaW4gYVxuICogbmV3IHN0eWxlIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtTdHlsZUZ1bmN0aW9ufEFycmF5PFN0eWxlPnxTdHlsZX0gb2JqXG4gKiAgICAgQSBzdHlsZSBmdW5jdGlvbiwgYSBzaW5nbGUgc3R5bGUsIG9yIGFuIGFycmF5IG9mIHN0eWxlcy5cbiAqIEByZXR1cm4ge1N0eWxlRnVuY3Rpb259IEEgc3R5bGUgZnVuY3Rpb24uXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gdG9GdW5jdGlvbihvYmopIHtcbiAgdmFyIHN0eWxlRnVuY3Rpb247XG5cbiAgaWYgKHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICBzdHlsZUZ1bmN0aW9uID0gb2JqO1xuICB9IGVsc2Uge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxTdHlsZT59XG4gICAgICovXG4gICAgdmFyIHN0eWxlc18xO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgICAgc3R5bGVzXzEgPSBvYmo7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2VydCh0eXBlb2ZcbiAgICAgIC8qKiBAdHlwZSB7P30gKi9cbiAgICAgIG9iai5nZXRaSW5kZXggPT09ICdmdW5jdGlvbicsIDQxKTsgLy8gRXhwZWN0ZWQgYW4gYFN0eWxlYCBvciBhbiBhcnJheSBvZiBgU3R5bGVgXG5cbiAgICAgIHZhciBzdHlsZSA9XG4gICAgICAvKiogQHR5cGUge1N0eWxlfSAqL1xuICAgICAgb2JqO1xuICAgICAgc3R5bGVzXzEgPSBbc3R5bGVdO1xuICAgIH1cblxuICAgIHN0eWxlRnVuY3Rpb24gPSBmdW5jdGlvbiBzdHlsZUZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHN0eWxlc18xO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gc3R5bGVGdW5jdGlvbjtcbn1cbi8qKlxuICogQHR5cGUge0FycmF5PFN0eWxlPn1cbiAqL1xuXG52YXIgZGVmYXVsdFN0eWxlcyA9IG51bGw7XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAqIEByZXR1cm4ge0FycmF5PFN0eWxlPn0gU3R5bGUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZURlZmF1bHRTdHlsZShmZWF0dXJlLCByZXNvbHV0aW9uKSB7XG4gIC8vIFdlIGRvbid0IHVzZSBhbiBpbW1lZGlhdGVseS1pbnZva2VkIGZ1bmN0aW9uXG4gIC8vIGFuZCBhIGNsb3N1cmUgc28gd2UgZG9uJ3QgZ2V0IGFuIGVycm9yIGF0IHNjcmlwdCBldmFsdWF0aW9uIHRpbWUgaW5cbiAgLy8gYnJvd3NlcnMgdGhhdCBkbyBub3Qgc3VwcG9ydCBDYW52YXMuIChpbXBvcnQoXCIuL0NpcmNsZS5qc1wiKS5DaXJjbGVTdHlsZSBkb2VzXG4gIC8vIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpIGF0IGNvbnN0cnVjdGlvbiB0aW1lLCB3aGljaCB3aWxsIGNhdXNlIGFuLmVycm9yXG4gIC8vIGluIHN1Y2ggYnJvd3NlcnMuKVxuICBpZiAoIWRlZmF1bHRTdHlsZXMpIHtcbiAgICB2YXIgZmlsbCA9IG5ldyBGaWxsKHtcbiAgICAgIGNvbG9yOiAncmdiYSgyNTUsMjU1LDI1NSwwLjQpJ1xuICAgIH0pO1xuICAgIHZhciBzdHJva2UgPSBuZXcgU3Ryb2tlKHtcbiAgICAgIGNvbG9yOiAnIzMzOTlDQycsXG4gICAgICB3aWR0aDogMS4yNVxuICAgIH0pO1xuICAgIGRlZmF1bHRTdHlsZXMgPSBbbmV3IFN0eWxlKHtcbiAgICAgIGltYWdlOiBuZXcgQ2lyY2xlU3R5bGUoe1xuICAgICAgICBmaWxsOiBmaWxsLFxuICAgICAgICBzdHJva2U6IHN0cm9rZSxcbiAgICAgICAgcmFkaXVzOiA1XG4gICAgICB9KSxcbiAgICAgIGZpbGw6IGZpbGwsXG4gICAgICBzdHJva2U6IHN0cm9rZVxuICAgIH0pXTtcbiAgfVxuXG4gIHJldHVybiBkZWZhdWx0U3R5bGVzO1xufVxuLyoqXG4gKiBEZWZhdWx0IHN0eWxlcyBmb3IgZWRpdGluZyBmZWF0dXJlcy5cbiAqIEByZXR1cm4ge09iamVjdDxpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0LCBBcnJheTxTdHlsZT4+fSBTdHlsZXNcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRWRpdGluZ1N0eWxlKCkge1xuICAvKiogQHR5cGUge09iamVjdDxpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0LCBBcnJheTxTdHlsZT4+fSAqL1xuICB2YXIgc3R5bGVzID0ge307XG4gIHZhciB3aGl0ZSA9IFsyNTUsIDI1NSwgMjU1LCAxXTtcbiAgdmFyIGJsdWUgPSBbMCwgMTUzLCAyNTUsIDFdO1xuICB2YXIgd2lkdGggPSAzO1xuICBzdHlsZXNbR2VvbWV0cnlUeXBlLlBPTFlHT05dID0gW25ldyBTdHlsZSh7XG4gICAgZmlsbDogbmV3IEZpbGwoe1xuICAgICAgY29sb3I6IFsyNTUsIDI1NSwgMjU1LCAwLjVdXG4gICAgfSlcbiAgfSldO1xuICBzdHlsZXNbR2VvbWV0cnlUeXBlLk1VTFRJX1BPTFlHT05dID0gc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0xZR09OXTtcbiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5MSU5FX1NUUklOR10gPSBbbmV3IFN0eWxlKHtcbiAgICBzdHJva2U6IG5ldyBTdHJva2Uoe1xuICAgICAgY29sb3I6IHdoaXRlLFxuICAgICAgd2lkdGg6IHdpZHRoICsgMlxuICAgIH0pXG4gIH0pLCBuZXcgU3R5bGUoe1xuICAgIHN0cm9rZTogbmV3IFN0cm9rZSh7XG4gICAgICBjb2xvcjogYmx1ZSxcbiAgICAgIHdpZHRoOiB3aWR0aFxuICAgIH0pXG4gIH0pXTtcbiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5NVUxUSV9MSU5FX1NUUklOR10gPSBzdHlsZXNbR2VvbWV0cnlUeXBlLkxJTkVfU1RSSU5HXTtcbiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5DSVJDTEVdID0gc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0xZR09OXS5jb25jYXQoc3R5bGVzW0dlb21ldHJ5VHlwZS5MSU5FX1NUUklOR10pO1xuICBzdHlsZXNbR2VvbWV0cnlUeXBlLlBPSU5UXSA9IFtuZXcgU3R5bGUoe1xuICAgIGltYWdlOiBuZXcgQ2lyY2xlU3R5bGUoe1xuICAgICAgcmFkaXVzOiB3aWR0aCAqIDIsXG4gICAgICBmaWxsOiBuZXcgRmlsbCh7XG4gICAgICAgIGNvbG9yOiBibHVlXG4gICAgICB9KSxcbiAgICAgIHN0cm9rZTogbmV3IFN0cm9rZSh7XG4gICAgICAgIGNvbG9yOiB3aGl0ZSxcbiAgICAgICAgd2lkdGg6IHdpZHRoIC8gMlxuICAgICAgfSlcbiAgICB9KSxcbiAgICB6SW5kZXg6IEluZmluaXR5XG4gIH0pXTtcbiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5NVUxUSV9QT0lOVF0gPSBzdHlsZXNbR2VvbWV0cnlUeXBlLlBPSU5UXTtcbiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5HRU9NRVRSWV9DT0xMRUNUSU9OXSA9IHN0eWxlc1tHZW9tZXRyeVR5cGUuUE9MWUdPTl0uY29uY2F0KHN0eWxlc1tHZW9tZXRyeVR5cGUuTElORV9TVFJJTkddLCBzdHlsZXNbR2VvbWV0cnlUeXBlLlBPSU5UXSk7XG4gIHJldHVybiBzdHlsZXM7XG59XG4vKipcbiAqIEZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdpdGggYSBmZWF0dXJlIGFuZCByZXR1cm5zIGl0cyBkZWZhdWx0IGdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUgdG8gZ2V0IHRoZSBnZW9tZXRyeSBmb3IuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vcmVuZGVyL0ZlYXR1cmUuanNcIikuZGVmYXVsdHx1bmRlZmluZWR9IEdlb21ldHJ5IHRvIHJlbmRlci5cbiAqL1xuXG5mdW5jdGlvbiBkZWZhdWx0R2VvbWV0cnlGdW5jdGlvbihmZWF0dXJlKSB7XG4gIHJldHVybiBmZWF0dXJlLmdldEdlb21ldHJ5KCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IFN0eWxlOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvbGF5ZXIvQmFzZVZlY3RvclxuICovXG5cblxuaW1wb3J0IExheWVyIGZyb20gJy4vTGF5ZXIuanMnO1xuaW1wb3J0IFJCdXNoIGZyb20gJ3JidXNoJztcbmltcG9ydCB7IGFzc2lnbiB9IGZyb20gJy4uL29iai5qcyc7XG5pbXBvcnQgeyBjcmVhdGVEZWZhdWx0U3R5bGUsIHRvRnVuY3Rpb24gYXMgdG9TdHlsZUZ1bmN0aW9uIH0gZnJvbSAnLi4vc3R5bGUvU3R5bGUuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NsYXNzTmFtZT0nb2wtbGF5ZXInXSBBIENTUyBjbGFzcyBuYW1lIHRvIHNldCB0byB0aGUgbGF5ZXIgZWxlbWVudC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbb3BhY2l0eT0xXSBPcGFjaXR5ICgwLCAxKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3Zpc2libGU9dHJ1ZV0gVmlzaWJpbGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF0gVGhlIGJvdW5kaW5nIGV4dGVudCBmb3IgbGF5ZXIgcmVuZGVyaW5nLiAgVGhlIGxheWVyIHdpbGwgbm90IGJlXG4gKiByZW5kZXJlZCBvdXRzaWRlIG9mIHRoaXMgZXh0ZW50LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6SW5kZXhdIFRoZSB6LWluZGV4IGZvciBsYXllciByZW5kZXJpbmcuICBBdCByZW5kZXJpbmcgdGltZSwgdGhlIGxheWVyc1xuICogd2lsbCBiZSBvcmRlcmVkLCBmaXJzdCBieSBaLWluZGV4IGFuZCB0aGVuIGJ5IHBvc2l0aW9uLiBXaGVuIGB1bmRlZmluZWRgLCBhIGB6SW5kZXhgIG9mIDAgaXMgYXNzdW1lZFxuICogZm9yIGxheWVycyB0aGF0IGFyZSBhZGRlZCB0byB0aGUgbWFwJ3MgYGxheWVyc2AgY29sbGVjdGlvbiwgb3IgYEluZmluaXR5YCB3aGVuIHRoZSBsYXllcidzIGBzZXRNYXAoKWBcbiAqIG1ldGhvZCB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluUmVzb2x1dGlvbl0gVGhlIG1pbmltdW0gcmVzb2x1dGlvbiAoaW5jbHVzaXZlKSBhdCB3aGljaCB0aGlzIGxheWVyIHdpbGwgYmVcbiAqIHZpc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFJlc29sdXRpb25dIFRoZSBtYXhpbXVtIHJlc29sdXRpb24gKGV4Y2x1c2l2ZSkgYmVsb3cgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5ab29tXSBUaGUgbWluaW11bSB2aWV3IHpvb20gbGV2ZWwgKGV4Y2x1c2l2ZSkgYWJvdmUgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhab29tXSBUaGUgbWF4aW11bSB2aWV3IHpvb20gbGV2ZWwgKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9yZW5kZXIuanNcIikuT3JkZXJGdW5jdGlvbn0gW3JlbmRlck9yZGVyXSBSZW5kZXIgb3JkZXIuIEZ1bmN0aW9uIHRvIGJlIHVzZWQgd2hlbiBzb3J0aW5nXG4gKiBmZWF0dXJlcyBiZWZvcmUgcmVuZGVyaW5nLiBCeSBkZWZhdWx0IGZlYXR1cmVzIGFyZSBkcmF3biBpbiB0aGUgb3JkZXIgdGhhdCB0aGV5IGFyZSBjcmVhdGVkLiBVc2VcbiAqIGBudWxsYCB0byBhdm9pZCB0aGUgc29ydCwgYnV0IGdldCBhbiB1bmRlZmluZWQgZHJhdyBvcmRlci5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmVuZGVyQnVmZmVyPTEwMF0gVGhlIGJ1ZmZlciBpbiBwaXhlbHMgYXJvdW5kIHRoZSB2aWV3cG9ydCBleHRlbnQgdXNlZCBieSB0aGVcbiAqIHJlbmRlcmVyIHdoZW4gZ2V0dGluZyBmZWF0dXJlcyBmcm9tIHRoZSB2ZWN0b3Igc291cmNlIGZvciB0aGUgcmVuZGVyaW5nIG9yIGhpdC1kZXRlY3Rpb24uXG4gKiBSZWNvbW1lbmRlZCB2YWx1ZTogdGhlIHNpemUgb2YgdGhlIGxhcmdlc3Qgc3ltYm9sLCBsaW5lIHdpZHRoIG9yIGxhYmVsLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zb3VyY2UvVmVjdG9yLmpzXCIpLmRlZmF1bHR9IFtzb3VyY2VdIFNvdXJjZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IFttYXBdIFNldHMgdGhlIGxheWVyIGFzIG92ZXJsYXkgb24gYSBtYXAuIFRoZSBtYXAgd2lsbCBub3QgbWFuYWdlXG4gKiB0aGlzIGxheWVyIGluIGl0cyBsYXllcnMgY29sbGVjdGlvbiwgYW5kIHRoZSBsYXllciB3aWxsIGJlIHJlbmRlcmVkIG9uIHRvcC4gVGhpcyBpcyB1c2VmdWwgZm9yXG4gKiB0ZW1wb3JhcnkgbGF5ZXJzLiBUaGUgc3RhbmRhcmQgd2F5IHRvIGFkZCBhIGxheWVyIHRvIGEgbWFwIGFuZCBoYXZlIGl0IG1hbmFnZWQgYnkgdGhlIG1hcCBpcyB0b1xuICogdXNlIHtAbGluayBtb2R1bGU6b2wvTWFwI2FkZExheWVyfS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2RlY2x1dHRlcj1mYWxzZV0gRGVjbHV0dGVyIGltYWdlcyBhbmQgdGV4dC4gRGVjbHV0dGVyaW5nIGlzIGFwcGxpZWQgdG8gYWxsXG4gKiBpbWFnZSBhbmQgdGV4dCBzdHlsZXMgb2YgYWxsIFZlY3RvciBhbmQgVmVjdG9yVGlsZSBsYXllcnMgdGhhdCBoYXZlIHNldCB0aGlzIHRvIGB0cnVlYC4gVGhlIHByaW9yaXR5XG4gKiBpcyBkZWZpbmVkIGJ5IHRoZSB6LWluZGV4IG9mIHRoZSBsYXllciwgdGhlIGB6SW5kZXhgIG9mIHRoZSBzdHlsZSBhbmQgdGhlIHJlbmRlciBvcmRlciBvZiBmZWF0dXJlcy5cbiAqIEhpZ2hlciB6LWluZGV4IG1lYW5zIGhpZ2hlciBwcmlvcml0eS4gV2l0aGluIHRoZSBzYW1lIHotaW5kZXgsIGEgZmVhdHVyZSByZW5kZXJlZCBiZWZvcmUgYW5vdGhlciBoYXNcbiAqIGhpZ2hlciBwcmlvcml0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuU3R5bGVMaWtlfG51bGx9IFtzdHlsZV0gTGF5ZXIgc3R5bGUuIFdoZW4gc2V0IHRvIGBudWxsYCwgb25seVxuICogZmVhdHVyZXMgdGhhdCBoYXZlIHRoZWlyIG93biBzdHlsZSB3aWxsIGJlIHJlbmRlcmVkLiBTZWUge0BsaW5rIG1vZHVsZTpvbC9zdHlsZX0gZm9yIGRlZmF1bHQgc3R5bGVcbiAqIHdoaWNoIHdpbGwgYmUgdXNlZCBpZiB0aGlzIGlzIG5vdCBzZXQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt1cGRhdGVXaGlsZUFuaW1hdGluZz1mYWxzZV0gV2hlbiBzZXQgdG8gYHRydWVgLCBmZWF0dXJlIGJhdGNoZXMgd2lsbFxuICogYmUgcmVjcmVhdGVkIGR1cmluZyBhbmltYXRpb25zLiBUaGlzIG1lYW5zIHRoYXQgbm8gdmVjdG9ycyB3aWxsIGJlIHNob3duIGNsaXBwZWQsIGJ1dCB0aGVcbiAqIHNldHRpbmcgd2lsbCBoYXZlIGEgcGVyZm9ybWFuY2UgaW1wYWN0IGZvciBsYXJnZSBhbW91bnRzIG9mIHZlY3RvciBkYXRhLiBXaGVuIHNldCB0byBgZmFsc2VgLFxuICogYmF0Y2hlcyB3aWxsIGJlIHJlY3JlYXRlZCB3aGVuIG5vIGFuaW1hdGlvbiBpcyBhY3RpdmUuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt1cGRhdGVXaGlsZUludGVyYWN0aW5nPWZhbHNlXSBXaGVuIHNldCB0byBgdHJ1ZWAsIGZlYXR1cmUgYmF0Y2hlcyB3aWxsXG4gKiBiZSByZWNyZWF0ZWQgZHVyaW5nIGludGVyYWN0aW9ucy4gU2VlIGFsc28gYHVwZGF0ZVdoaWxlQW5pbWF0aW5nYC5cbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcHJpdmF0ZVxuICovXG5cbnZhciBQcm9wZXJ0eSA9IHtcbiAgUkVOREVSX09SREVSOiAncmVuZGVyT3JkZXInXG59O1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBWZWN0b3IgZGF0YSB0aGF0IGlzIHJlbmRlcmVkIGNsaWVudC1zaWRlLlxuICogTm90ZSB0aGF0IGFueSBwcm9wZXJ0eSBzZXQgaW4gdGhlIG9wdGlvbnMgaXMgc2V0IGFzIGEge0BsaW5rIG1vZHVsZTpvbC9PYmplY3R+QmFzZU9iamVjdH1cbiAqIHByb3BlcnR5IG9uIHRoZSBsYXllciBvYmplY3Q7IGZvciBleGFtcGxlLCBzZXR0aW5nIGB0aXRsZTogJ015IFRpdGxlJ2AgaW4gdGhlXG4gKiBvcHRpb25zIG1lYW5zIHRoYXQgYHRpdGxlYCBpcyBvYnNlcnZhYmxlLCBhbmQgaGFzIGdldC9zZXQgYWNjZXNzb3JzLlxuICpcbiAqIEB0ZW1wbGF0ZSB7aW1wb3J0KFwiLi4vc291cmNlL1ZlY3Rvci5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL3NvdXJjZS9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9IFZlY3RvclNvdXJjZVR5cGVcbiAqIEBleHRlbmRzIHtMYXllcjxWZWN0b3JTb3VyY2VUeXBlPn1cbiAqIEBhcGlcbiAqL1xuXG52YXIgQmFzZVZlY3RvckxheWVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEJhc2VWZWN0b3JMYXllciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQmFzZVZlY3RvckxheWVyKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIHZhciBiYXNlT3B0aW9ucyA9IGFzc2lnbih7fSwgb3B0aW9ucyk7XG4gICAgZGVsZXRlIGJhc2VPcHRpb25zLnN0eWxlO1xuICAgIGRlbGV0ZSBiYXNlT3B0aW9ucy5yZW5kZXJCdWZmZXI7XG4gICAgZGVsZXRlIGJhc2VPcHRpb25zLnVwZGF0ZVdoaWxlQW5pbWF0aW5nO1xuICAgIGRlbGV0ZSBiYXNlT3B0aW9ucy51cGRhdGVXaGlsZUludGVyYWN0aW5nO1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgYmFzZU9wdGlvbnMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmRlY2x1dHRlcl8gPSBvcHRpb25zLmRlY2x1dHRlciAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kZWNsdXR0ZXIgOiBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJCdWZmZXJfID0gb3B0aW9ucy5yZW5kZXJCdWZmZXIgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucmVuZGVyQnVmZmVyIDogMTAwO1xuICAgIC8qKlxuICAgICAqIFVzZXIgcHJvdmlkZWQgc3R5bGUuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlTGlrZX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3R5bGVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBTdHlsZSBmdW5jdGlvbiBmb3IgdXNlIHdpdGhpbiB0aGUgbGlicmFyeS5cbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuU3R5bGVGdW5jdGlvbnx1bmRlZmluZWR9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLnN0eWxlRnVuY3Rpb25fID0gdW5kZWZpbmVkO1xuXG4gICAgX3RoaXMuc2V0U3R5bGUob3B0aW9ucy5zdHlsZSk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuXG4gICAgX3RoaXMudXBkYXRlV2hpbGVBbmltYXRpbmdfID0gb3B0aW9ucy51cGRhdGVXaGlsZUFuaW1hdGluZyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy51cGRhdGVXaGlsZUFuaW1hdGluZyA6IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy51cGRhdGVXaGlsZUludGVyYWN0aW5nXyA9IG9wdGlvbnMudXBkYXRlV2hpbGVJbnRlcmFjdGluZyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy51cGRhdGVXaGlsZUludGVyYWN0aW5nIDogZmFsc2U7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBEZWNsdXR0ZXIuXG4gICAqL1xuXG5cbiAgQmFzZVZlY3RvckxheWVyLnByb3RvdHlwZS5nZXREZWNsdXR0ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVjbHV0dGVyXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdG9wbW9zdCBmZWF0dXJlIHRoYXQgaW50ZXJzZWN0cyB0aGUgZ2l2ZW4gcGl4ZWwgb24gdGhlIHZpZXdwb3J0LiBSZXR1cm5zIGEgcHJvbWlzZVxuICAgKiB0aGF0IHJlc29sdmVzIHdpdGggYW4gYXJyYXkgb2YgZmVhdHVyZXMuIFRoZSBhcnJheSB3aWxsIGVpdGhlciBjb250YWluIHRoZSB0b3Btb3N0IGZlYXR1cmVcbiAgICogd2hlbiBhIGhpdCB3YXMgZGV0ZWN0ZWQsIG9yIGl0IHdpbGwgYmUgZW1wdHkuXG4gICAqXG4gICAqIFRoZSBoaXQgZGV0ZWN0aW9uIGFsZ29yaXRobSB1c2VkIGZvciB0aGlzIG1ldGhvZCBpcyBvcHRpbWl6ZWQgZm9yIHBlcmZvcm1hbmNlLCBidXQgaXMgbGVzc1xuICAgKiBhY2N1cmF0ZSB0aGFuIHRoZSBvbmUgdXNlZCBpbiB7QGxpbmsgaW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHQjZ2V0RmVhdHVyZXNBdFBpeGVsfTogVGV4dFxuICAgKiBpcyBub3QgY29uc2lkZXJlZCwgYW5kIGljb25zIGFyZSBvbmx5IHJlcHJlc2VudGVkIGJ5IHRoZWlyIGJvdW5kaW5nIGJveCBpbnN0ZWFkIG9mIHRoZSBleGFjdFxuICAgKiBpbWFnZS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZVwiKS5kZWZhdWx0Pj59IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIGFuIGFycmF5IG9mIGZlYXR1cmVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZVZlY3RvckxheWVyLnByb3RvdHlwZS5nZXRGZWF0dXJlcyA9IGZ1bmN0aW9uIChwaXhlbCkge1xuICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLmdldEZlYXR1cmVzLmNhbGwodGhpcywgcGl4ZWwpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gUmVuZGVyIGJ1ZmZlci5cbiAgICovXG5cblxuICBCYXNlVmVjdG9yTGF5ZXIucHJvdG90eXBlLmdldFJlbmRlckJ1ZmZlciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJCdWZmZXJfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0LCBpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQpOiBudW1iZXJ8bnVsbHx1bmRlZmluZWR9IFJlbmRlclxuICAgKiAgICAgb3JkZXIuXG4gICAqL1xuXG5cbiAgQmFzZVZlY3RvckxheWVyLnByb3RvdHlwZS5nZXRSZW5kZXJPcmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9yZW5kZXIuanNcIikuT3JkZXJGdW5jdGlvbnxudWxsfHVuZGVmaW5lZH0gKi9cbiAgICAgIHRoaXMuZ2V0KFByb3BlcnR5LlJFTkRFUl9PUkRFUilcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzdHlsZSBmb3IgZmVhdHVyZXMuICBUaGlzIHJldHVybnMgd2hhdGV2ZXIgd2FzIHBhc3NlZCB0byB0aGUgYHN0eWxlYFxuICAgKiBvcHRpb24gYXQgY29uc3RydWN0aW9uIG9yIHRvIHRoZSBgc2V0U3R5bGVgIG1ldGhvZC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuU3R5bGVMaWtlfG51bGx8dW5kZWZpbmVkfSBMYXllciBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VWZWN0b3JMYXllci5wcm90b3R5cGUuZ2V0U3R5bGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3R5bGVfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzdHlsZSBmdW5jdGlvbi5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuU3R5bGVGdW5jdGlvbnx1bmRlZmluZWR9IExheWVyIHN0eWxlIGZ1bmN0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZVZlY3RvckxheWVyLnByb3RvdHlwZS5nZXRTdHlsZUZ1bmN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnN0eWxlRnVuY3Rpb25fO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgcmVuZGVyZWQgbGF5ZXIgc2hvdWxkIGJlIHVwZGF0ZWQgd2hpbGVcbiAgICogICAgIGFuaW1hdGluZy5cbiAgICovXG5cblxuICBCYXNlVmVjdG9yTGF5ZXIucHJvdG90eXBlLmdldFVwZGF0ZVdoaWxlQW5pbWF0aW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZVdoaWxlQW5pbWF0aW5nXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHJlbmRlcmVkIGxheWVyIHNob3VsZCBiZSB1cGRhdGVkIHdoaWxlXG4gICAqICAgICBpbnRlcmFjdGluZy5cbiAgICovXG5cblxuICBCYXNlVmVjdG9yTGF5ZXIucHJvdG90eXBlLmdldFVwZGF0ZVdoaWxlSW50ZXJhY3RpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlV2hpbGVJbnRlcmFjdGluZ187XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgZGVjbHV0dGVyIGl0ZW1zIGZvciB0aGlzIGxheWVyXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqL1xuXG5cbiAgQmFzZVZlY3RvckxheWVyLnByb3RvdHlwZS5yZW5kZXJEZWNsdXR0ZXIgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgIGlmICghZnJhbWVTdGF0ZS5kZWNsdXR0ZXJUcmVlKSB7XG4gICAgICBmcmFtZVN0YXRlLmRlY2x1dHRlclRyZWUgPSBuZXcgUkJ1c2goOSk7XG4gICAgfVxuICAgIC8qKiBAdHlwZSB7Kn0gKi9cblxuXG4gICAgdGhpcy5nZXRSZW5kZXJlcigpLnJlbmRlckRlY2x1dHRlcihmcmFtZVN0YXRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyLmpzXCIpLk9yZGVyRnVuY3Rpb258bnVsbHx1bmRlZmluZWR9IHJlbmRlck9yZGVyXG4gICAqICAgICBSZW5kZXIgb3JkZXIuXG4gICAqL1xuXG5cbiAgQmFzZVZlY3RvckxheWVyLnByb3RvdHlwZS5zZXRSZW5kZXJPcmRlciA9IGZ1bmN0aW9uIChyZW5kZXJPcmRlcikge1xuICAgIHRoaXMuc2V0KFByb3BlcnR5LlJFTkRFUl9PUkRFUiwgcmVuZGVyT3JkZXIpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBzdHlsZSBmb3IgZmVhdHVyZXMuICBUaGlzIGNhbiBiZSBhIHNpbmdsZSBzdHlsZSBvYmplY3QsIGFuIGFycmF5XG4gICAqIG9mIHN0eWxlcywgb3IgYSBmdW5jdGlvbiB0aGF0IHRha2VzIGEgZmVhdHVyZSBhbmQgcmVzb2x1dGlvbiBhbmQgcmV0dXJuc1xuICAgKiBhbiBhcnJheSBvZiBzdHlsZXMuIElmIHNldCB0byBgbnVsbGAsIHRoZSBsYXllciBoYXMgbm8gc3R5bGUgKGEgYG51bGxgIHN0eWxlKSxcbiAgICogc28gb25seSBmZWF0dXJlcyB0aGF0IGhhdmUgdGhlaXIgb3duIHN0eWxlcyB3aWxsIGJlIHJlbmRlcmVkIGluIHRoZSBsYXllci4gQ2FsbFxuICAgKiBgc2V0U3R5bGUoKWAgd2l0aG91dCBhcmd1bWVudHMgdG8gcmVzZXQgdG8gdGhlIGRlZmF1bHQgc3R5bGUuIFNlZVxuICAgKiB7QGxpbmsgbW9kdWxlOm9sL3N0eWxlfSBmb3IgaW5mb3JtYXRpb24gb24gdGhlIGRlZmF1bHQgc3R5bGUuXG4gICAqIEBwYXJhbSB7KGltcG9ydChcIi4uL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlTGlrZXxudWxsKT19IG9wdF9zdHlsZSBMYXllciBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VWZWN0b3JMYXllci5wcm90b3R5cGUuc2V0U3R5bGUgPSBmdW5jdGlvbiAob3B0X3N0eWxlKSB7XG4gICAgdGhpcy5zdHlsZV8gPSBvcHRfc3R5bGUgIT09IHVuZGVmaW5lZCA/IG9wdF9zdHlsZSA6IGNyZWF0ZURlZmF1bHRTdHlsZTtcbiAgICB0aGlzLnN0eWxlRnVuY3Rpb25fID0gb3B0X3N0eWxlID09PSBudWxsID8gdW5kZWZpbmVkIDogdG9TdHlsZUZ1bmN0aW9uKHRoaXMuc3R5bGVfKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcblxuICByZXR1cm4gQmFzZVZlY3RvckxheWVyO1xufShMYXllcik7XG5cbmV4cG9ydCBkZWZhdWx0IEJhc2VWZWN0b3JMYXllcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL2NhbnZhcy9JbnN0cnVjdGlvblxuICovXG5cbi8qKlxuICogQGVudW0ge251bWJlcn1cbiAqL1xudmFyIEluc3RydWN0aW9uID0ge1xuICBCRUdJTl9HRU9NRVRSWTogMCxcbiAgQkVHSU5fUEFUSDogMSxcbiAgQ0lSQ0xFOiAyLFxuICBDTE9TRV9QQVRIOiAzLFxuICBDVVNUT006IDQsXG4gIERSQVdfQ0hBUlM6IDUsXG4gIERSQVdfSU1BR0U6IDYsXG4gIEVORF9HRU9NRVRSWTogNyxcbiAgRklMTDogOCxcbiAgTU9WRV9UT19MSU5FX1RPOiA5LFxuICBTRVRfRklMTF9TVFlMRTogMTAsXG4gIFNFVF9TVFJPS0VfU1RZTEU6IDExLFxuICBTVFJPS0U6IDEyXG59O1xuLyoqXG4gKiBAdHlwZSB7QXJyYXk8SW5zdHJ1Y3Rpb24+fVxuICovXG5cbmV4cG9ydCB2YXIgZmlsbEluc3RydWN0aW9uID0gW0luc3RydWN0aW9uLkZJTExdO1xuLyoqXG4gKiBAdHlwZSB7QXJyYXk8SW5zdHJ1Y3Rpb24+fVxuICovXG5cbmV4cG9ydCB2YXIgc3Ryb2tlSW5zdHJ1Y3Rpb24gPSBbSW5zdHJ1Y3Rpb24uU1RST0tFXTtcbi8qKlxuICogQHR5cGUge0FycmF5PEluc3RydWN0aW9uPn1cbiAqL1xuXG5leHBvcnQgdmFyIGJlZ2luUGF0aEluc3RydWN0aW9uID0gW0luc3RydWN0aW9uLkJFR0lOX1BBVEhdO1xuLyoqXG4gKiBAdHlwZSB7QXJyYXk8SW5zdHJ1Y3Rpb24+fVxuICovXG5cbmV4cG9ydCB2YXIgY2xvc2VQYXRoSW5zdHJ1Y3Rpb24gPSBbSW5zdHJ1Y3Rpb24uQ0xPU0VfUEFUSF07XG5leHBvcnQgZGVmYXVsdCBJbnN0cnVjdGlvbjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL1ZlY3RvckNvbnRleHRcbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIENvbnRleHQgZm9yIGRyYXdpbmcgZ2VvbWV0cmllcy4gIEEgdmVjdG9yIGNvbnRleHQgaXMgYXZhaWxhYmxlIG9uIHJlbmRlclxuICogZXZlbnRzIGFuZCBkb2VzIG5vdCBuZWVkIHRvIGJlIGNvbnN0cnVjdGVkIGRpcmVjdGx5LlxuICogQGFwaVxuICovXG52YXIgVmVjdG9yQ29udGV4dCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFZlY3RvckNvbnRleHQoKSB7fVxuICAvKipcbiAgICogUmVuZGVyIGEgZ2VvbWV0cnkgd2l0aCBhIGN1c3RvbSByZW5kZXJlci5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gcmVuZGVyZXIgUmVuZGVyZXIuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuZHJhd0N1c3RvbSA9IGZ1bmN0aW9uIChnZW9tZXRyeSwgZmVhdHVyZSwgcmVuZGVyZXIpIHt9O1xuICAvKipcbiAgICogUmVuZGVyIGEgZ2VvbWV0cnkuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBUaGUgZ2VvbWV0cnkgdG8gcmVuZGVyLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLmRyYXdHZW9tZXRyeSA9IGZ1bmN0aW9uIChnZW9tZXRyeSkge307XG4gIC8qKlxuICAgKiBTZXQgdGhlIHJlbmRlcmluZyBzdHlsZS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBUaGUgcmVuZGVyaW5nIHN0eWxlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLnNldFN0eWxlID0gZnVuY3Rpb24gKHN0eWxlKSB7fTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9DaXJjbGUuanNcIikuZGVmYXVsdH0gY2lyY2xlR2VvbWV0cnkgQ2lyY2xlIGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLmRyYXdDaXJjbGUgPSBmdW5jdGlvbiAoY2lyY2xlR2VvbWV0cnksIGZlYXR1cmUpIHt9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAgICovXG5cblxuICBWZWN0b3JDb250ZXh0LnByb3RvdHlwZS5kcmF3RmVhdHVyZSA9IGZ1bmN0aW9uIChmZWF0dXJlLCBzdHlsZSkge307XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnlDb2xsZWN0aW9uLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5Q29sbGVjdGlvbkdlb21ldHJ5IEdlb21ldHJ5IGNvbGxlY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuZHJhd0dlb21ldHJ5Q29sbGVjdGlvbiA9IGZ1bmN0aW9uIChnZW9tZXRyeUNvbGxlY3Rpb25HZW9tZXRyeSwgZmVhdHVyZSkge307XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBsaW5lU3RyaW5nR2VvbWV0cnkgTGluZSBzdHJpbmcgZ2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLmRyYXdMaW5lU3RyaW5nID0gZnVuY3Rpb24gKGxpbmVTdHJpbmdHZW9tZXRyeSwgZmVhdHVyZSkge307XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vTXVsdGlMaW5lU3RyaW5nLmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IG11bHRpTGluZVN0cmluZ0dlb21ldHJ5IE11bHRpTGluZVN0cmluZyBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuZHJhd011bHRpTGluZVN0cmluZyA9IGZ1bmN0aW9uIChtdWx0aUxpbmVTdHJpbmdHZW9tZXRyeSwgZmVhdHVyZSkge307XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vTXVsdGlQb2ludC5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBtdWx0aVBvaW50R2VvbWV0cnkgTXVsdGlQb2ludCBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuZHJhd011bHRpUG9pbnQgPSBmdW5jdGlvbiAobXVsdGlQb2ludEdlb21ldHJ5LCBmZWF0dXJlKSB7fTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9NdWx0aVBvbHlnb24uanNcIikuZGVmYXVsdH0gbXVsdGlQb2x5Z29uR2VvbWV0cnkgTXVsdGlQb2x5Z29uIGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICovXG5cblxuICBWZWN0b3JDb250ZXh0LnByb3RvdHlwZS5kcmF3TXVsdGlQb2x5Z29uID0gZnVuY3Rpb24gKG11bHRpUG9seWdvbkdlb21ldHJ5LCBmZWF0dXJlKSB7fTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9Qb2ludC5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBwb2ludEdlb21ldHJ5IFBvaW50IGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICovXG5cblxuICBWZWN0b3JDb250ZXh0LnByb3RvdHlwZS5kcmF3UG9pbnQgPSBmdW5jdGlvbiAocG9pbnRHZW9tZXRyeSwgZmVhdHVyZSkge307XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBwb2x5Z29uR2VvbWV0cnkgUG9seWdvbiBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuZHJhd1BvbHlnb24gPSBmdW5jdGlvbiAocG9seWdvbkdlb21ldHJ5LCBmZWF0dXJlKSB7fTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuZHJhd1RleHQgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIGZlYXR1cmUpIHt9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9GaWxsLmpzXCIpLmRlZmF1bHR9IGZpbGxTdHlsZSBGaWxsIHN0eWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3N0eWxlL1N0cm9rZS5qc1wiKS5kZWZhdWx0fSBzdHJva2VTdHlsZSBTdHJva2Ugc3R5bGUuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuc2V0RmlsbFN0cm9rZVN0eWxlID0gZnVuY3Rpb24gKGZpbGxTdHlsZSwgc3Ryb2tlU3R5bGUpIHt9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9JbWFnZS5qc1wiKS5kZWZhdWx0fSBpbWFnZVN0eWxlIEltYWdlIHN0eWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMuanNcIikuRGVjbHV0dGVySW1hZ2VXaXRoVGV4dD19IG9wdF9kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0IFNoYXJlZCBkYXRhIGZvciBjb21iaW5lZCBkZWNsdXR0ZXJpbmcgd2l0aCBhIHRleHQgc3R5bGUuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuc2V0SW1hZ2VTdHlsZSA9IGZ1bmN0aW9uIChpbWFnZVN0eWxlLCBvcHRfZGVjbHV0dGVySW1hZ2VXaXRoVGV4dCkge307XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3N0eWxlL1RleHQuanNcIikuZGVmYXVsdH0gdGV4dFN0eWxlIFRleHQgc3R5bGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy5qc1wiKS5EZWNsdXR0ZXJJbWFnZVdpdGhUZXh0PX0gb3B0X2RlY2x1dHRlckltYWdlV2l0aFRleHQgU2hhcmVkIGRhdGEgZm9yIGNvbWJpbmVkIGRlY2x1dHRlcmluZyB3aXRoIGFuIGltYWdlIHN0eWxlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLnNldFRleHRTdHlsZSA9IGZ1bmN0aW9uICh0ZXh0U3R5bGUsIG9wdF9kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0KSB7fTtcblxuICByZXR1cm4gVmVjdG9yQ29udGV4dDtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgVmVjdG9yQ29udGV4dDsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9jYW52YXMvQnVpbGRlclxuICovXG5cblxuaW1wb3J0IENhbnZhc0luc3RydWN0aW9uIGZyb20gJy4vSW5zdHJ1Y3Rpb24uanMnO1xuaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICcuLi8uLi9nZW9tL0dlb21ldHJ5VHlwZS5qcyc7XG5pbXBvcnQgUmVsYXRpb25zaGlwIGZyb20gJy4uLy4uL2V4dGVudC9SZWxhdGlvbnNoaXAuanMnO1xuaW1wb3J0IFZlY3RvckNvbnRleHQgZnJvbSAnLi4vVmVjdG9yQ29udGV4dC5qcyc7XG5pbXBvcnQgeyBhc0NvbG9yTGlrZSB9IGZyb20gJy4uLy4uL2NvbG9ybGlrZS5qcyc7XG5pbXBvcnQgeyBidWZmZXIsIGNsb25lLCBjb250YWluc0Nvb3JkaW5hdGUsIGNvb3JkaW5hdGVSZWxhdGlvbnNoaXAgfSBmcm9tICcuLi8uLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZGVmYXVsdEZpbGxTdHlsZSwgZGVmYXVsdExpbmVDYXAsIGRlZmF1bHRMaW5lRGFzaCwgZGVmYXVsdExpbmVEYXNoT2Zmc2V0LCBkZWZhdWx0TGluZUpvaW4sIGRlZmF1bHRMaW5lV2lkdGgsIGRlZmF1bHRNaXRlckxpbWl0LCBkZWZhdWx0U3Ryb2tlU3R5bGUgfSBmcm9tICcuLi9jYW52YXMuanMnO1xuaW1wb3J0IHsgZXF1YWxzLCByZXZlcnNlU3ViQXJyYXkgfSBmcm9tICcuLi8uLi9hcnJheS5qcyc7XG5pbXBvcnQgeyBpbmZsYXRlQ29vcmRpbmF0ZXMsIGluZmxhdGVDb29yZGluYXRlc0FycmF5LCBpbmZsYXRlTXVsdGlDb29yZGluYXRlc0FycmF5IH0gZnJvbSAnLi4vLi4vZ2VvbS9mbGF0L2luZmxhdGUuanMnO1xuXG52YXIgQ2FudmFzQnVpbGRlciA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhDYW52YXNCdWlsZGVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRvbGVyYW5jZSBUb2xlcmFuY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gbWF4RXh0ZW50IE1heGltdW0gZXh0ZW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDYW52YXNCdWlsZGVyKHRvbGVyYW5jZSwgbWF4RXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMudG9sZXJhbmNlID0gdG9sZXJhbmNlO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAY29uc3RcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLm1heEV4dGVudCA9IG1heEV4dGVudDtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnBpeGVsUmF0aW8gPSBwaXhlbFJhdGlvO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4TGluZVdpZHRoID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQGNvbnN0XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlc29sdXRpb24gPSByZXNvbHV0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PCo+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuYmVnaW5HZW9tZXRyeUluc3RydWN0aW9uMV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PCo+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuYmVnaW5HZW9tZXRyeUluc3RydWN0aW9uMl8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5idWZmZXJlZE1heEV4dGVudF8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7QXJyYXk8Kj59XG4gICAgICovXG5cbiAgICBfdGhpcy5pbnN0cnVjdGlvbnMgPSBbXTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5jb29yZGluYXRlcyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRtcENvb3JkaW5hdGVfID0gW107XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtBcnJheTwqPn1cbiAgICAgKi9cblxuICAgIF90aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkZpbGxTdHJva2VTdGF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnN0YXRlID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3Ryb2tlU3RhdGV9ICovXG4gICAge307XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZGFzaEFycmF5IERhc2ggYXJyYXkuXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IERhc2ggYXJyYXkgd2l0aCBwaXhlbCByYXRpbyBhcHBsaWVkXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUuYXBwbHlQaXhlbFJhdGlvID0gZnVuY3Rpb24gKGRhc2hBcnJheSkge1xuICAgIHZhciBwaXhlbFJhdGlvID0gdGhpcy5waXhlbFJhdGlvO1xuICAgIHJldHVybiBwaXhlbFJhdGlvID09IDEgPyBkYXNoQXJyYXkgOiBkYXNoQXJyYXkubWFwKGZ1bmN0aW9uIChkYXNoKSB7XG4gICAgICByZXR1cm4gZGFzaCAqIHBpeGVsUmF0aW87XG4gICAgfSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAgICogQHByb3RlY3RlZFxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE15IGVuZFxuICAgKi9cblxuXG4gIENhbnZhc0J1aWxkZXIucHJvdG90eXBlLmFwcGVuZEZsYXRQb2ludENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKGZsYXRDb29yZGluYXRlcywgc3RyaWRlKSB7XG4gICAgdmFyIGV4dGVudCA9IHRoaXMuZ2V0QnVmZmVyZWRNYXhFeHRlbnQoKTtcbiAgICB2YXIgdG1wQ29vcmQgPSB0aGlzLnRtcENvb3JkaW5hdGVfO1xuICAgIHZhciBjb29yZGluYXRlcyA9IHRoaXMuY29vcmRpbmF0ZXM7XG4gICAgdmFyIG15RW5kID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZmxhdENvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyBpICs9IHN0cmlkZSkge1xuICAgICAgdG1wQ29vcmRbMF0gPSBmbGF0Q29vcmRpbmF0ZXNbaV07XG4gICAgICB0bXBDb29yZFsxXSA9IGZsYXRDb29yZGluYXRlc1tpICsgMV07XG5cbiAgICAgIGlmIChjb250YWluc0Nvb3JkaW5hdGUoZXh0ZW50LCB0bXBDb29yZCkpIHtcbiAgICAgICAgY29vcmRpbmF0ZXNbbXlFbmQrK10gPSB0bXBDb29yZFswXTtcbiAgICAgICAgY29vcmRpbmF0ZXNbbXlFbmQrK10gPSB0bXBDb29yZFsxXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbXlFbmQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGNsb3NlZCBMYXN0IGlucHV0IGNvb3JkaW5hdGUgZXF1YWxzIGZpcnN0LlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNraXBGaXJzdCBTa2lwIGZpcnN0IGNvb3JkaW5hdGUuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7bnVtYmVyfSBNeSBlbmQuXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUuYXBwZW5kRmxhdExpbmVDb29yZGluYXRlcyA9IGZ1bmN0aW9uIChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGNsb3NlZCwgc2tpcEZpcnN0KSB7XG4gICAgdmFyIGNvb3JkaW5hdGVzID0gdGhpcy5jb29yZGluYXRlcztcbiAgICB2YXIgbXlFbmQgPSBjb29yZGluYXRlcy5sZW5ndGg7XG4gICAgdmFyIGV4dGVudCA9IHRoaXMuZ2V0QnVmZmVyZWRNYXhFeHRlbnQoKTtcblxuICAgIGlmIChza2lwRmlyc3QpIHtcbiAgICAgIG9mZnNldCArPSBzdHJpZGU7XG4gICAgfVxuXG4gICAgdmFyIGxhc3RYQ29vcmQgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgICB2YXIgbGFzdFlDb29yZCA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXTtcbiAgICB2YXIgbmV4dENvb3JkID0gdGhpcy50bXBDb29yZGluYXRlXztcbiAgICB2YXIgc2tpcHBlZCA9IHRydWU7XG4gICAgdmFyIGksIGxhc3RSZWwsIG5leHRSZWw7XG5cbiAgICBmb3IgKGkgPSBvZmZzZXQgKyBzdHJpZGU7IGkgPCBlbmQ7IGkgKz0gc3RyaWRlKSB7XG4gICAgICBuZXh0Q29vcmRbMF0gPSBmbGF0Q29vcmRpbmF0ZXNbaV07XG4gICAgICBuZXh0Q29vcmRbMV0gPSBmbGF0Q29vcmRpbmF0ZXNbaSArIDFdO1xuICAgICAgbmV4dFJlbCA9IGNvb3JkaW5hdGVSZWxhdGlvbnNoaXAoZXh0ZW50LCBuZXh0Q29vcmQpO1xuXG4gICAgICBpZiAobmV4dFJlbCAhPT0gbGFzdFJlbCkge1xuICAgICAgICBpZiAoc2tpcHBlZCkge1xuICAgICAgICAgIGNvb3JkaW5hdGVzW215RW5kKytdID0gbGFzdFhDb29yZDtcbiAgICAgICAgICBjb29yZGluYXRlc1tteUVuZCsrXSA9IGxhc3RZQ29vcmQ7XG4gICAgICAgICAgc2tpcHBlZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29vcmRpbmF0ZXNbbXlFbmQrK10gPSBuZXh0Q29vcmRbMF07XG4gICAgICAgIGNvb3JkaW5hdGVzW215RW5kKytdID0gbmV4dENvb3JkWzFdO1xuICAgICAgfSBlbHNlIGlmIChuZXh0UmVsID09PSBSZWxhdGlvbnNoaXAuSU5URVJTRUNUSU5HKSB7XG4gICAgICAgIGNvb3JkaW5hdGVzW215RW5kKytdID0gbmV4dENvb3JkWzBdO1xuICAgICAgICBjb29yZGluYXRlc1tteUVuZCsrXSA9IG5leHRDb29yZFsxXTtcbiAgICAgICAgc2tpcHBlZCA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2tpcHBlZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGxhc3RYQ29vcmQgPSBuZXh0Q29vcmRbMF07XG4gICAgICBsYXN0WUNvb3JkID0gbmV4dENvb3JkWzFdO1xuICAgICAgbGFzdFJlbCA9IG5leHRSZWw7XG4gICAgfSAvLyBMYXN0IGNvb3JkaW5hdGUgZXF1YWxzIGZpcnN0IG9yIG9ubHkgb25lIHBvaW50IHRvIGFwcGVuZDpcblxuXG4gICAgaWYgKGNsb3NlZCAmJiBza2lwcGVkIHx8IGkgPT09IG9mZnNldCArIHN0cmlkZSkge1xuICAgICAgY29vcmRpbmF0ZXNbbXlFbmQrK10gPSBsYXN0WENvb3JkO1xuICAgICAgY29vcmRpbmF0ZXNbbXlFbmQrK10gPSBsYXN0WUNvb3JkO1xuICAgIH1cblxuICAgIHJldHVybiBteUVuZDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gYnVpbGRlckVuZHMgQnVpbGRlciBlbmRzLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE9mZnNldC5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5kcmF3Q3VzdG9tQ29vcmRpbmF0ZXNfID0gZnVuY3Rpb24gKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIGJ1aWxkZXJFbmRzKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICAgIHZhciBidWlsZGVyRW5kID0gdGhpcy5hcHBlbmRGbGF0TGluZUNvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgZmFsc2UsIGZhbHNlKTtcbiAgICAgIGJ1aWxkZXJFbmRzLnB1c2goYnVpbGRlckVuZCk7XG4gICAgICBvZmZzZXQgPSBlbmQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlbmRlcmVyIFJlbmRlcmVyLlxuICAgKi9cblxuXG4gIENhbnZhc0J1aWxkZXIucHJvdG90eXBlLmRyYXdDdXN0b20gPSBmdW5jdGlvbiAoZ2VvbWV0cnksIGZlYXR1cmUsIHJlbmRlcmVyKSB7XG4gICAgdGhpcy5iZWdpbkdlb21ldHJ5KGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgICB2YXIgdHlwZSA9IGdlb21ldHJ5LmdldFR5cGUoKTtcbiAgICB2YXIgc3RyaWRlID0gZ2VvbWV0cnkuZ2V0U3RyaWRlKCk7XG4gICAgdmFyIGJ1aWxkZXJCZWdpbiA9IHRoaXMuY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMsIGJ1aWxkZXJFbmQsIGJ1aWxkZXJFbmRzLCBidWlsZGVyRW5kc3M7XG4gICAgdmFyIG9mZnNldDtcblxuICAgIGlmICh0eXBlID09IEdlb21ldHJ5VHlwZS5NVUxUSV9QT0xZR09OKSB7XG4gICAgICBmbGF0Q29vcmRpbmF0ZXMgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpUG9seWdvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZ2VvbWV0cnkuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKTtcbiAgICAgIGJ1aWxkZXJFbmRzcyA9IFtdO1xuICAgICAgdmFyIGVuZHNzID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aVBvbHlnb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGdlb21ldHJ5LmdldEVuZHNzKCk7XG4gICAgICBvZmZzZXQgPSAwO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIHZhciBteUVuZHMgPSBbXTtcbiAgICAgICAgb2Zmc2V0ID0gdGhpcy5kcmF3Q3VzdG9tQ29vcmRpbmF0ZXNfKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzc1tpXSwgc3RyaWRlLCBteUVuZHMpO1xuICAgICAgICBidWlsZGVyRW5kc3MucHVzaChteUVuZHMpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5DVVNUT00sIGJ1aWxkZXJCZWdpbiwgYnVpbGRlckVuZHNzLCBnZW9tZXRyeSwgcmVuZGVyZXIsIGluZmxhdGVNdWx0aUNvb3JkaW5hdGVzQXJyYXldKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT0gR2VvbWV0cnlUeXBlLlBPTFlHT04gfHwgdHlwZSA9PSBHZW9tZXRyeVR5cGUuTVVMVElfTElORV9TVFJJTkcpIHtcbiAgICAgIGJ1aWxkZXJFbmRzID0gW107XG4gICAgICBmbGF0Q29vcmRpbmF0ZXMgPSB0eXBlID09IEdlb21ldHJ5VHlwZS5QT0xZR09OID9cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9Qb2x5Z29uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBnZW9tZXRyeS5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpIDogZ2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgICBvZmZzZXQgPSB0aGlzLmRyYXdDdXN0b21Db29yZGluYXRlc18oZmxhdENvb3JkaW5hdGVzLCAwLFxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1BvbHlnb24uanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZ2VvbWV0cnkuZ2V0RW5kcygpLCBzdHJpZGUsIGJ1aWxkZXJFbmRzKTtcbiAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkNVU1RPTSwgYnVpbGRlckJlZ2luLCBidWlsZGVyRW5kcywgZ2VvbWV0cnksIHJlbmRlcmVyLCBpbmZsYXRlQ29vcmRpbmF0ZXNBcnJheV0pO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PSBHZW9tZXRyeVR5cGUuTElORV9TVFJJTkcgfHwgdHlwZSA9PSBHZW9tZXRyeVR5cGUuQ0lSQ0xFKSB7XG4gICAgICBmbGF0Q29vcmRpbmF0ZXMgPSBnZW9tZXRyeS5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcbiAgICAgIGJ1aWxkZXJFbmQgPSB0aGlzLmFwcGVuZEZsYXRMaW5lQ29vcmRpbmF0ZXMoZmxhdENvb3JkaW5hdGVzLCAwLCBmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCBzdHJpZGUsIGZhbHNlLCBmYWxzZSk7XG4gICAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5DVVNUT00sIGJ1aWxkZXJCZWdpbiwgYnVpbGRlckVuZCwgZ2VvbWV0cnksIHJlbmRlcmVyLCBpbmZsYXRlQ29vcmRpbmF0ZXNdKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT0gR2VvbWV0cnlUeXBlLk1VTFRJX1BPSU5UKSB7XG4gICAgICBmbGF0Q29vcmRpbmF0ZXMgPSBnZW9tZXRyeS5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcbiAgICAgIGJ1aWxkZXJFbmQgPSB0aGlzLmFwcGVuZEZsYXRQb2ludENvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgc3RyaWRlKTtcblxuICAgICAgaWYgKGJ1aWxkZXJFbmQgPiBidWlsZGVyQmVnaW4pIHtcbiAgICAgICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uQ1VTVE9NLCBidWlsZGVyQmVnaW4sIGJ1aWxkZXJFbmQsIGdlb21ldHJ5LCByZW5kZXJlciwgaW5mbGF0ZUNvb3JkaW5hdGVzXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09IEdlb21ldHJ5VHlwZS5QT0lOVCkge1xuICAgICAgZmxhdENvb3JkaW5hdGVzID0gZ2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgICB0aGlzLmNvb3JkaW5hdGVzLnB1c2goZmxhdENvb3JkaW5hdGVzWzBdLCBmbGF0Q29vcmRpbmF0ZXNbMV0pO1xuICAgICAgYnVpbGRlckVuZCA9IHRoaXMuY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uQ1VTVE9NLCBidWlsZGVyQmVnaW4sIGJ1aWxkZXJFbmQsIGdlb21ldHJ5LCByZW5kZXJlcl0pO1xuICAgIH1cblxuICAgIHRoaXMuZW5kR2VvbWV0cnkoZmVhdHVyZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9HZW9tZXRyeVwiKS5kZWZhdWx0fGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgVGhlIGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5iZWdpbkdlb21ldHJ5ID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBmZWF0dXJlKSB7XG4gICAgdGhpcy5iZWdpbkdlb21ldHJ5SW5zdHJ1Y3Rpb24xXyA9IFtDYW52YXNJbnN0cnVjdGlvbi5CRUdJTl9HRU9NRVRSWSwgZmVhdHVyZSwgMCwgZ2VvbWV0cnldO1xuICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2godGhpcy5iZWdpbkdlb21ldHJ5SW5zdHJ1Y3Rpb24xXyk7XG4gICAgdGhpcy5iZWdpbkdlb21ldHJ5SW5zdHJ1Y3Rpb24yXyA9IFtDYW52YXNJbnN0cnVjdGlvbi5CRUdJTl9HRU9NRVRSWSwgZmVhdHVyZSwgMCwgZ2VvbWV0cnldO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2godGhpcy5iZWdpbkdlb21ldHJ5SW5zdHJ1Y3Rpb24yXyk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU2VyaWFsaXphYmxlSW5zdHJ1Y3Rpb25zfSB0aGUgc2VyaWFsaXphYmxlIGluc3RydWN0aW9ucy5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGluc3RydWN0aW9uczogdGhpcy5pbnN0cnVjdGlvbnMsXG4gICAgICBoaXREZXRlY3Rpb25JbnN0cnVjdGlvbnM6IHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLFxuICAgICAgY29vcmRpbmF0ZXM6IHRoaXMuY29vcmRpbmF0ZXNcbiAgICB9O1xuICB9O1xuICAvKipcbiAgICogUmV2ZXJzZSB0aGUgaGl0IGRldGVjdGlvbiBpbnN0cnVjdGlvbnMuXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUucmV2ZXJzZUhpdERldGVjdGlvbkluc3RydWN0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zID0gdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnM7IC8vIHN0ZXAgMSAtIHJldmVyc2UgYXJyYXlcblxuICAgIGhpdERldGVjdGlvbkluc3RydWN0aW9ucy5yZXZlcnNlKCk7IC8vIHN0ZXAgMiAtIHJldmVyc2UgaW5zdHJ1Y3Rpb25zIHdpdGhpbiBnZW9tZXRyeSBibG9ja3NcblxuICAgIHZhciBpO1xuICAgIHZhciBuID0gaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLmxlbmd0aDtcbiAgICB2YXIgaW5zdHJ1Y3Rpb247XG4gICAgdmFyIHR5cGU7XG4gICAgdmFyIGJlZ2luID0gLTE7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpbnN0cnVjdGlvbiA9IGhpdERldGVjdGlvbkluc3RydWN0aW9uc1tpXTtcbiAgICAgIHR5cGUgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL0luc3RydWN0aW9uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBpbnN0cnVjdGlvblswXTtcblxuICAgICAgaWYgKHR5cGUgPT0gQ2FudmFzSW5zdHJ1Y3Rpb24uRU5EX0dFT01FVFJZKSB7XG4gICAgICAgIGJlZ2luID0gaTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBDYW52YXNJbnN0cnVjdGlvbi5CRUdJTl9HRU9NRVRSWSkge1xuICAgICAgICBpbnN0cnVjdGlvblsyXSA9IGk7XG4gICAgICAgIHJldmVyc2VTdWJBcnJheSh0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucywgYmVnaW4sIGkpO1xuICAgICAgICBiZWdpbiA9IC0xO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc3R5bGUvRmlsbC5qc1wiKS5kZWZhdWx0fSBmaWxsU3R5bGUgRmlsbCBzdHlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zdHlsZS9TdHJva2UuanNcIikuZGVmYXVsdH0gc3Ryb2tlU3R5bGUgU3Ryb2tlIHN0eWxlLlxuICAgKi9cblxuXG4gIENhbnZhc0J1aWxkZXIucHJvdG90eXBlLnNldEZpbGxTdHJva2VTdHlsZSA9IGZ1bmN0aW9uIChmaWxsU3R5bGUsIHN0cm9rZVN0eWxlKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5zdGF0ZTtcblxuICAgIGlmIChmaWxsU3R5bGUpIHtcbiAgICAgIHZhciBmaWxsU3R5bGVDb2xvciA9IGZpbGxTdHlsZS5nZXRDb2xvcigpO1xuICAgICAgc3RhdGUuZmlsbFN0eWxlID0gYXNDb2xvckxpa2UoZmlsbFN0eWxlQ29sb3IgPyBmaWxsU3R5bGVDb2xvciA6IGRlZmF1bHRGaWxsU3R5bGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5maWxsU3R5bGUgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKHN0cm9rZVN0eWxlKSB7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVDb2xvciA9IHN0cm9rZVN0eWxlLmdldENvbG9yKCk7XG4gICAgICBzdGF0ZS5zdHJva2VTdHlsZSA9IGFzQ29sb3JMaWtlKHN0cm9rZVN0eWxlQ29sb3IgPyBzdHJva2VTdHlsZUNvbG9yIDogZGVmYXVsdFN0cm9rZVN0eWxlKTtcbiAgICAgIHZhciBzdHJva2VTdHlsZUxpbmVDYXAgPSBzdHJva2VTdHlsZS5nZXRMaW5lQ2FwKCk7XG4gICAgICBzdGF0ZS5saW5lQ2FwID0gc3Ryb2tlU3R5bGVMaW5lQ2FwICE9PSB1bmRlZmluZWQgPyBzdHJva2VTdHlsZUxpbmVDYXAgOiBkZWZhdWx0TGluZUNhcDtcbiAgICAgIHZhciBzdHJva2VTdHlsZUxpbmVEYXNoID0gc3Ryb2tlU3R5bGUuZ2V0TGluZURhc2goKTtcbiAgICAgIHN0YXRlLmxpbmVEYXNoID0gc3Ryb2tlU3R5bGVMaW5lRGFzaCA/IHN0cm9rZVN0eWxlTGluZURhc2guc2xpY2UoKSA6IGRlZmF1bHRMaW5lRGFzaDtcbiAgICAgIHZhciBzdHJva2VTdHlsZUxpbmVEYXNoT2Zmc2V0ID0gc3Ryb2tlU3R5bGUuZ2V0TGluZURhc2hPZmZzZXQoKTtcbiAgICAgIHN0YXRlLmxpbmVEYXNoT2Zmc2V0ID0gc3Ryb2tlU3R5bGVMaW5lRGFzaE9mZnNldCA/IHN0cm9rZVN0eWxlTGluZURhc2hPZmZzZXQgOiBkZWZhdWx0TGluZURhc2hPZmZzZXQ7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVMaW5lSm9pbiA9IHN0cm9rZVN0eWxlLmdldExpbmVKb2luKCk7XG4gICAgICBzdGF0ZS5saW5lSm9pbiA9IHN0cm9rZVN0eWxlTGluZUpvaW4gIT09IHVuZGVmaW5lZCA/IHN0cm9rZVN0eWxlTGluZUpvaW4gOiBkZWZhdWx0TGluZUpvaW47XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVXaWR0aCA9IHN0cm9rZVN0eWxlLmdldFdpZHRoKCk7XG4gICAgICBzdGF0ZS5saW5lV2lkdGggPSBzdHJva2VTdHlsZVdpZHRoICE9PSB1bmRlZmluZWQgPyBzdHJva2VTdHlsZVdpZHRoIDogZGVmYXVsdExpbmVXaWR0aDtcbiAgICAgIHZhciBzdHJva2VTdHlsZU1pdGVyTGltaXQgPSBzdHJva2VTdHlsZS5nZXRNaXRlckxpbWl0KCk7XG4gICAgICBzdGF0ZS5taXRlckxpbWl0ID0gc3Ryb2tlU3R5bGVNaXRlckxpbWl0ICE9PSB1bmRlZmluZWQgPyBzdHJva2VTdHlsZU1pdGVyTGltaXQgOiBkZWZhdWx0TWl0ZXJMaW1pdDtcblxuICAgICAgaWYgKHN0YXRlLmxpbmVXaWR0aCA+IHRoaXMubWF4TGluZVdpZHRoKSB7XG4gICAgICAgIHRoaXMubWF4TGluZVdpZHRoID0gc3RhdGUubGluZVdpZHRoOyAvLyBpbnZhbGlkYXRlIHRoZSBidWZmZXJlZCBtYXggZXh0ZW50IGNhY2hlXG5cbiAgICAgICAgdGhpcy5idWZmZXJlZE1heEV4dGVudF8gPSBudWxsO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5zdHJva2VTdHlsZSA9IHVuZGVmaW5lZDtcbiAgICAgIHN0YXRlLmxpbmVDYXAgPSB1bmRlZmluZWQ7XG4gICAgICBzdGF0ZS5saW5lRGFzaCA9IG51bGw7XG4gICAgICBzdGF0ZS5saW5lRGFzaE9mZnNldCA9IHVuZGVmaW5lZDtcbiAgICAgIHN0YXRlLmxpbmVKb2luID0gdW5kZWZpbmVkO1xuICAgICAgc3RhdGUubGluZVdpZHRoID0gdW5kZWZpbmVkO1xuICAgICAgc3RhdGUubWl0ZXJMaW1pdCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3Ryb2tlU3RhdGV9IHN0YXRlIFN0YXRlLlxuICAgKiBAcmV0dXJuIHtBcnJheTwqPn0gRmlsbCBpbnN0cnVjdGlvbi5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5jcmVhdGVGaWxsID0gZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgdmFyIGZpbGxTdHlsZSA9IHN0YXRlLmZpbGxTdHlsZTtcbiAgICAvKiogQHR5cGUge0FycmF5PCo+fSAqL1xuXG4gICAgdmFyIGZpbGxJbnN0cnVjdGlvbiA9IFtDYW52YXNJbnN0cnVjdGlvbi5TRVRfRklMTF9TVFlMRSwgZmlsbFN0eWxlXTtcblxuICAgIGlmICh0eXBlb2YgZmlsbFN0eWxlICE9PSAnc3RyaW5nJykge1xuICAgICAgLy8gRmlsbCBpcyBhIHBhdHRlcm4gb3IgZ3JhZGllbnQgLSBhbGlnbiBpdCFcbiAgICAgIGZpbGxJbnN0cnVjdGlvbi5wdXNoKHRydWUpO1xuICAgIH1cblxuICAgIHJldHVybiBmaWxsSW5zdHJ1Y3Rpb247XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3Ryb2tlU3RhdGV9IHN0YXRlIFN0YXRlLlxuICAgKi9cblxuXG4gIENhbnZhc0J1aWxkZXIucHJvdG90eXBlLmFwcGx5U3Ryb2tlID0gZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaCh0aGlzLmNyZWF0ZVN0cm9rZShzdGF0ZSkpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0cm9rZVN0YXRlfSBzdGF0ZSBTdGF0ZS5cbiAgICogQHJldHVybiB7QXJyYXk8Kj59IFN0cm9rZSBpbnN0cnVjdGlvbi5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5jcmVhdGVTdHJva2UgPSBmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICByZXR1cm4gW0NhbnZhc0luc3RydWN0aW9uLlNFVF9TVFJPS0VfU1RZTEUsIHN0YXRlLnN0cm9rZVN0eWxlLCBzdGF0ZS5saW5lV2lkdGggKiB0aGlzLnBpeGVsUmF0aW8sIHN0YXRlLmxpbmVDYXAsIHN0YXRlLmxpbmVKb2luLCBzdGF0ZS5taXRlckxpbWl0LCB0aGlzLmFwcGx5UGl4ZWxSYXRpbyhzdGF0ZS5saW5lRGFzaCksIHN0YXRlLmxpbmVEYXNoT2Zmc2V0ICogdGhpcy5waXhlbFJhdGlvXTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkZpbGxTdHJva2VTdGF0ZX0gc3RhdGUgU3RhdGUuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24odGhpczpDYW52YXNCdWlsZGVyLCBpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0cm9rZVN0YXRlKTpBcnJheTwqPn0gY3JlYXRlRmlsbCBDcmVhdGUgZmlsbC5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS51cGRhdGVGaWxsU3R5bGUgPSBmdW5jdGlvbiAoc3RhdGUsIGNyZWF0ZUZpbGwpIHtcbiAgICB2YXIgZmlsbFN0eWxlID0gc3RhdGUuZmlsbFN0eWxlO1xuXG4gICAgaWYgKHR5cGVvZiBmaWxsU3R5bGUgIT09ICdzdHJpbmcnIHx8IHN0YXRlLmN1cnJlbnRGaWxsU3R5bGUgIT0gZmlsbFN0eWxlKSB7XG4gICAgICBpZiAoZmlsbFN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChjcmVhdGVGaWxsLmNhbGwodGhpcywgc3RhdGUpKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGUuY3VycmVudEZpbGxTdHlsZSA9IGZpbGxTdHlsZTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3Ryb2tlU3RhdGV9IHN0YXRlIFN0YXRlLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKHRoaXM6Q2FudmFzQnVpbGRlciwgaW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkZpbGxTdHJva2VTdGF0ZSk6IHZvaWR9IGFwcGx5U3Ryb2tlIEFwcGx5IHN0cm9rZS5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS51cGRhdGVTdHJva2VTdHlsZSA9IGZ1bmN0aW9uIChzdGF0ZSwgYXBwbHlTdHJva2UpIHtcbiAgICB2YXIgc3Ryb2tlU3R5bGUgPSBzdGF0ZS5zdHJva2VTdHlsZTtcbiAgICB2YXIgbGluZUNhcCA9IHN0YXRlLmxpbmVDYXA7XG4gICAgdmFyIGxpbmVEYXNoID0gc3RhdGUubGluZURhc2g7XG4gICAgdmFyIGxpbmVEYXNoT2Zmc2V0ID0gc3RhdGUubGluZURhc2hPZmZzZXQ7XG4gICAgdmFyIGxpbmVKb2luID0gc3RhdGUubGluZUpvaW47XG4gICAgdmFyIGxpbmVXaWR0aCA9IHN0YXRlLmxpbmVXaWR0aDtcbiAgICB2YXIgbWl0ZXJMaW1pdCA9IHN0YXRlLm1pdGVyTGltaXQ7XG5cbiAgICBpZiAoc3RhdGUuY3VycmVudFN0cm9rZVN0eWxlICE9IHN0cm9rZVN0eWxlIHx8IHN0YXRlLmN1cnJlbnRMaW5lQ2FwICE9IGxpbmVDYXAgfHwgbGluZURhc2ggIT0gc3RhdGUuY3VycmVudExpbmVEYXNoICYmICFlcXVhbHMoc3RhdGUuY3VycmVudExpbmVEYXNoLCBsaW5lRGFzaCkgfHwgc3RhdGUuY3VycmVudExpbmVEYXNoT2Zmc2V0ICE9IGxpbmVEYXNoT2Zmc2V0IHx8IHN0YXRlLmN1cnJlbnRMaW5lSm9pbiAhPSBsaW5lSm9pbiB8fCBzdGF0ZS5jdXJyZW50TGluZVdpZHRoICE9IGxpbmVXaWR0aCB8fCBzdGF0ZS5jdXJyZW50TWl0ZXJMaW1pdCAhPSBtaXRlckxpbWl0KSB7XG4gICAgICBpZiAoc3Ryb2tlU3R5bGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhcHBseVN0cm9rZS5jYWxsKHRoaXMsIHN0YXRlKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGUuY3VycmVudFN0cm9rZVN0eWxlID0gc3Ryb2tlU3R5bGU7XG4gICAgICBzdGF0ZS5jdXJyZW50TGluZUNhcCA9IGxpbmVDYXA7XG4gICAgICBzdGF0ZS5jdXJyZW50TGluZURhc2ggPSBsaW5lRGFzaDtcbiAgICAgIHN0YXRlLmN1cnJlbnRMaW5lRGFzaE9mZnNldCA9IGxpbmVEYXNoT2Zmc2V0O1xuICAgICAgc3RhdGUuY3VycmVudExpbmVKb2luID0gbGluZUpvaW47XG4gICAgICBzdGF0ZS5jdXJyZW50TGluZVdpZHRoID0gbGluZVdpZHRoO1xuICAgICAgc3RhdGUuY3VycmVudE1pdGVyTGltaXQgPSBtaXRlckxpbWl0O1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIENhbnZhc0J1aWxkZXIucHJvdG90eXBlLmVuZEdlb21ldHJ5ID0gZnVuY3Rpb24gKGZlYXR1cmUpIHtcbiAgICB0aGlzLmJlZ2luR2VvbWV0cnlJbnN0cnVjdGlvbjFfWzJdID0gdGhpcy5pbnN0cnVjdGlvbnMubGVuZ3RoO1xuICAgIHRoaXMuYmVnaW5HZW9tZXRyeUluc3RydWN0aW9uMV8gPSBudWxsO1xuICAgIHRoaXMuYmVnaW5HZW9tZXRyeUluc3RydWN0aW9uMl9bMl0gPSB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5sZW5ndGg7XG4gICAgdGhpcy5iZWdpbkdlb21ldHJ5SW5zdHJ1Y3Rpb24yXyA9IG51bGw7XG4gICAgdmFyIGVuZEdlb21ldHJ5SW5zdHJ1Y3Rpb24gPSBbQ2FudmFzSW5zdHJ1Y3Rpb24uRU5EX0dFT01FVFJZLCBmZWF0dXJlXTtcbiAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKGVuZEdlb21ldHJ5SW5zdHJ1Y3Rpb24pO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goZW5kR2VvbWV0cnlJbnN0cnVjdGlvbik7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGJ1ZmZlcmVkIHJlbmRlcmluZyBleHRlbnQuICBSZW5kZXJpbmcgd2lsbCBiZSBjbGlwcGVkIHRvIHRoZSBleHRlbnRcbiAgICogcHJvdmlkZWQgdG8gdGhlIGNvbnN0cnVjdG9yLiAgVG8gYWNjb3VudCBmb3Igc3ltYm9saXplcnMgdGhhdCBtYXkgaW50ZXJzZWN0XG4gICAqIHRoaXMgZXh0ZW50LCB3ZSBjYWxjdWxhdGUgYSBidWZmZXJlZCBleHRlbnQgKGUuZy4gYmFzZWQgb24gc3Ryb2tlIHdpZHRoKS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gVGhlIGJ1ZmZlcmVkIHJlbmRlcmluZyBleHRlbnQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5nZXRCdWZmZXJlZE1heEV4dGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuYnVmZmVyZWRNYXhFeHRlbnRfKSB7XG4gICAgICB0aGlzLmJ1ZmZlcmVkTWF4RXh0ZW50XyA9IGNsb25lKHRoaXMubWF4RXh0ZW50KTtcblxuICAgICAgaWYgKHRoaXMubWF4TGluZVdpZHRoID4gMCkge1xuICAgICAgICB2YXIgd2lkdGggPSB0aGlzLnJlc29sdXRpb24gKiAodGhpcy5tYXhMaW5lV2lkdGggKyAxKSAvIDI7XG4gICAgICAgIGJ1ZmZlcih0aGlzLmJ1ZmZlcmVkTWF4RXh0ZW50Xywgd2lkdGgsIHRoaXMuYnVmZmVyZWRNYXhFeHRlbnRfKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5idWZmZXJlZE1heEV4dGVudF87XG4gIH07XG5cbiAgcmV0dXJuIENhbnZhc0J1aWxkZXI7XG59KFZlY3RvckNvbnRleHQpO1xuXG5leHBvcnQgZGVmYXVsdCBDYW52YXNCdWlsZGVyOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL2NhbnZhcy9JbWFnZUJ1aWxkZXJcbiAqL1xuXG5cbmltcG9ydCBDYW52YXNCdWlsZGVyIGZyb20gJy4vQnVpbGRlci5qcyc7XG5pbXBvcnQgQ2FudmFzSW5zdHJ1Y3Rpb24gZnJvbSAnLi9JbnN0cnVjdGlvbi5qcyc7XG5cbnZhciBDYW52YXNJbWFnZUJ1aWxkZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ2FudmFzSW1hZ2VCdWlsZGVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRvbGVyYW5jZSBUb2xlcmFuY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gbWF4RXh0ZW50IE1heGltdW0gZXh0ZW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDYW52YXNJbWFnZUJ1aWxkZXIodG9sZXJhbmNlLCBtYXhFeHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8pIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0b2xlcmFuY2UsIG1heEV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR9XG4gICAgICovXG5cblxuICAgIF90aGlzLmhpdERldGVjdGlvbkltYWdlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7SFRNTENhbnZhc0VsZW1lbnR8SFRNTFZpZGVvRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW1hZ2VfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW1hZ2VQaXhlbFJhdGlvXyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMuYW5jaG9yWF8gPSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLmFuY2hvcllfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5oZWlnaHRfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5vcGFjaXR5XyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMub3JpZ2luWF8gPSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLm9yaWdpbllfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW58dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMucm90YXRlV2l0aFZpZXdfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5yb3RhdGlvbl8gPSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vc2l6ZS5qc1wiKS5TaXplfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnNjYWxlXyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMud2lkdGhfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIERhdGEgc2hhcmVkIHdpdGggYSB0ZXh0IGJ1aWxkZXIgZm9yIGNvbWJpbmVkIGRlY2x1dHRlcmluZy5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRGVjbHV0dGVySW1hZ2VXaXRoVGV4dH1cbiAgICAgKi9cblxuICAgIF90aGlzLmRlY2x1dHRlckltYWdlV2l0aFRleHRfID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1BvaW50LmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBwb2ludEdlb21ldHJ5IFBvaW50IGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICovXG5cblxuICBDYW52YXNJbWFnZUJ1aWxkZXIucHJvdG90eXBlLmRyYXdQb2ludCA9IGZ1bmN0aW9uIChwb2ludEdlb21ldHJ5LCBmZWF0dXJlKSB7XG4gICAgaWYgKCF0aGlzLmltYWdlXykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYmVnaW5HZW9tZXRyeShwb2ludEdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gcG9pbnRHZW9tZXRyeS5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcbiAgICB2YXIgc3RyaWRlID0gcG9pbnRHZW9tZXRyeS5nZXRTdHJpZGUoKTtcbiAgICB2YXIgbXlCZWdpbiA9IHRoaXMuY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHZhciBteUVuZCA9IHRoaXMuYXBwZW5kRmxhdFBvaW50Q29vcmRpbmF0ZXMoZmxhdENvb3JkaW5hdGVzLCBzdHJpZGUpO1xuICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkRSQVdfSU1BR0UsIG15QmVnaW4sIG15RW5kLCB0aGlzLmltYWdlXywgLy8gUmVtYWluaW5nIGFyZ3VtZW50cyB0byBEUkFXX0lNQUdFIGFyZSBpbiBhbHBoYWJldGljYWwgb3JkZXJcbiAgICB0aGlzLmFuY2hvclhfICogdGhpcy5pbWFnZVBpeGVsUmF0aW9fLCB0aGlzLmFuY2hvcllfICogdGhpcy5pbWFnZVBpeGVsUmF0aW9fLCBNYXRoLmNlaWwodGhpcy5oZWlnaHRfICogdGhpcy5pbWFnZVBpeGVsUmF0aW9fKSwgdGhpcy5vcGFjaXR5XywgdGhpcy5vcmlnaW5YXywgdGhpcy5vcmlnaW5ZXywgdGhpcy5yb3RhdGVXaXRoVmlld18sIHRoaXMucm90YXRpb25fLCBbdGhpcy5zY2FsZV9bMF0gKiB0aGlzLnBpeGVsUmF0aW8gLyB0aGlzLmltYWdlUGl4ZWxSYXRpb18sIHRoaXMuc2NhbGVfWzFdICogdGhpcy5waXhlbFJhdGlvIC8gdGhpcy5pbWFnZVBpeGVsUmF0aW9fXSwgTWF0aC5jZWlsKHRoaXMud2lkdGhfICogdGhpcy5pbWFnZVBpeGVsUmF0aW9fKSwgdGhpcy5kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0X10pO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkRSQVdfSU1BR0UsIG15QmVnaW4sIG15RW5kLCB0aGlzLmhpdERldGVjdGlvbkltYWdlXywgLy8gUmVtYWluaW5nIGFyZ3VtZW50cyB0byBEUkFXX0lNQUdFIGFyZSBpbiBhbHBoYWJldGljYWwgb3JkZXJcbiAgICB0aGlzLmFuY2hvclhfLCB0aGlzLmFuY2hvcllfLCB0aGlzLmhlaWdodF8sIHRoaXMub3BhY2l0eV8sIHRoaXMub3JpZ2luWF8sIHRoaXMub3JpZ2luWV8sIHRoaXMucm90YXRlV2l0aFZpZXdfLCB0aGlzLnJvdGF0aW9uXywgdGhpcy5zY2FsZV8sIHRoaXMud2lkdGhfLCB0aGlzLmRlY2x1dHRlckltYWdlV2l0aFRleHRfXSk7XG4gICAgdGhpcy5lbmRHZW9tZXRyeShmZWF0dXJlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aVBvaW50LmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBtdWx0aVBvaW50R2VvbWV0cnkgTXVsdGlQb2ludCBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1hZ2VCdWlsZGVyLnByb3RvdHlwZS5kcmF3TXVsdGlQb2ludCA9IGZ1bmN0aW9uIChtdWx0aVBvaW50R2VvbWV0cnksIGZlYXR1cmUpIHtcbiAgICBpZiAoIXRoaXMuaW1hZ2VfKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5iZWdpbkdlb21ldHJ5KG11bHRpUG9pbnRHZW9tZXRyeSwgZmVhdHVyZSk7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IG11bHRpUG9pbnRHZW9tZXRyeS5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcbiAgICB2YXIgc3RyaWRlID0gbXVsdGlQb2ludEdlb21ldHJ5LmdldFN0cmlkZSgpO1xuICAgIHZhciBteUJlZ2luID0gdGhpcy5jb29yZGluYXRlcy5sZW5ndGg7XG4gICAgdmFyIG15RW5kID0gdGhpcy5hcHBlbmRGbGF0UG9pbnRDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIHN0cmlkZSk7XG4gICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uRFJBV19JTUFHRSwgbXlCZWdpbiwgbXlFbmQsIHRoaXMuaW1hZ2VfLCAvLyBSZW1haW5pbmcgYXJndW1lbnRzIHRvIERSQVdfSU1BR0UgYXJlIGluIGFscGhhYmV0aWNhbCBvcmRlclxuICAgIHRoaXMuYW5jaG9yWF8gKiB0aGlzLmltYWdlUGl4ZWxSYXRpb18sIHRoaXMuYW5jaG9yWV8gKiB0aGlzLmltYWdlUGl4ZWxSYXRpb18sIE1hdGguY2VpbCh0aGlzLmhlaWdodF8gKiB0aGlzLmltYWdlUGl4ZWxSYXRpb18pLCB0aGlzLm9wYWNpdHlfLCB0aGlzLm9yaWdpblhfLCB0aGlzLm9yaWdpbllfLCB0aGlzLnJvdGF0ZVdpdGhWaWV3XywgdGhpcy5yb3RhdGlvbl8sIFt0aGlzLnNjYWxlX1swXSAqIHRoaXMucGl4ZWxSYXRpbyAvIHRoaXMuaW1hZ2VQaXhlbFJhdGlvXywgdGhpcy5zY2FsZV9bMV0gKiB0aGlzLnBpeGVsUmF0aW8gLyB0aGlzLmltYWdlUGl4ZWxSYXRpb19dLCBNYXRoLmNlaWwodGhpcy53aWR0aF8gKiB0aGlzLmltYWdlUGl4ZWxSYXRpb18pLCB0aGlzLmRlY2x1dHRlckltYWdlV2l0aFRleHRfXSk7XG4gICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uRFJBV19JTUFHRSwgbXlCZWdpbiwgbXlFbmQsIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VfLCAvLyBSZW1haW5pbmcgYXJndW1lbnRzIHRvIERSQVdfSU1BR0UgYXJlIGluIGFscGhhYmV0aWNhbCBvcmRlclxuICAgIHRoaXMuYW5jaG9yWF8sIHRoaXMuYW5jaG9yWV8sIHRoaXMuaGVpZ2h0XywgdGhpcy5vcGFjaXR5XywgdGhpcy5vcmlnaW5YXywgdGhpcy5vcmlnaW5ZXywgdGhpcy5yb3RhdGVXaXRoVmlld18sIHRoaXMucm90YXRpb25fLCB0aGlzLnNjYWxlXywgdGhpcy53aWR0aF8sIHRoaXMuZGVjbHV0dGVySW1hZ2VXaXRoVGV4dF9dKTtcbiAgICB0aGlzLmVuZEdlb21ldHJ5KGZlYXR1cmUpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlNlcmlhbGl6YWJsZUluc3RydWN0aW9uc30gdGhlIHNlcmlhbGl6YWJsZSBpbnN0cnVjdGlvbnMuXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1hZ2VCdWlsZGVyLnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZXZlcnNlSGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zKCk7IC8vIEZJWE1FIHRoaXMgZG9lc24ndCByZWFsbHkgcHJvdGVjdCB1cyBhZ2FpbnN0IGZ1cnRoZXIgY2FsbHMgdG8gZHJhdypHZW9tZXRyeVxuXG4gICAgdGhpcy5hbmNob3JYXyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmFuY2hvcllfID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VfID0gbnVsbDtcbiAgICB0aGlzLmltYWdlXyA9IG51bGw7XG4gICAgdGhpcy5pbWFnZVBpeGVsUmF0aW9fID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaGVpZ2h0XyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnNjYWxlXyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm9wYWNpdHlfID0gdW5kZWZpbmVkO1xuICAgIHRoaXMub3JpZ2luWF8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5vcmlnaW5ZXyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJvdGF0ZVdpdGhWaWV3XyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJvdGF0aW9uXyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLndpZHRoXyA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5maW5pc2guY2FsbCh0aGlzKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc3R5bGUvSW1hZ2UuanNcIikuZGVmYXVsdH0gaW1hZ2VTdHlsZSBJbWFnZSBzdHlsZS5cbiAgICogQHBhcmFtIHtPYmplY3Q9fSBvcHRfc2hhcmVkRGF0YSBTaGFyZWQgZGF0YS5cbiAgICovXG5cblxuICBDYW52YXNJbWFnZUJ1aWxkZXIucHJvdG90eXBlLnNldEltYWdlU3R5bGUgPSBmdW5jdGlvbiAoaW1hZ2VTdHlsZSwgb3B0X3NoYXJlZERhdGEpIHtcbiAgICB2YXIgYW5jaG9yID0gaW1hZ2VTdHlsZS5nZXRBbmNob3IoKTtcbiAgICB2YXIgc2l6ZSA9IGltYWdlU3R5bGUuZ2V0U2l6ZSgpO1xuICAgIHZhciBoaXREZXRlY3Rpb25JbWFnZSA9IGltYWdlU3R5bGUuZ2V0SGl0RGV0ZWN0aW9uSW1hZ2UoKTtcbiAgICB2YXIgaW1hZ2UgPSBpbWFnZVN0eWxlLmdldEltYWdlKHRoaXMucGl4ZWxSYXRpbyk7XG4gICAgdmFyIG9yaWdpbiA9IGltYWdlU3R5bGUuZ2V0T3JpZ2luKCk7XG4gICAgdGhpcy5pbWFnZVBpeGVsUmF0aW9fID0gaW1hZ2VTdHlsZS5nZXRQaXhlbFJhdGlvKHRoaXMucGl4ZWxSYXRpbyk7XG4gICAgdGhpcy5hbmNob3JYXyA9IGFuY2hvclswXTtcbiAgICB0aGlzLmFuY2hvcllfID0gYW5jaG9yWzFdO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VfID0gaGl0RGV0ZWN0aW9uSW1hZ2U7XG4gICAgdGhpcy5pbWFnZV8gPSBpbWFnZTtcbiAgICB0aGlzLmhlaWdodF8gPSBzaXplWzFdO1xuICAgIHRoaXMub3BhY2l0eV8gPSBpbWFnZVN0eWxlLmdldE9wYWNpdHkoKTtcbiAgICB0aGlzLm9yaWdpblhfID0gb3JpZ2luWzBdO1xuICAgIHRoaXMub3JpZ2luWV8gPSBvcmlnaW5bMV07XG4gICAgdGhpcy5yb3RhdGVXaXRoVmlld18gPSBpbWFnZVN0eWxlLmdldFJvdGF0ZVdpdGhWaWV3KCk7XG4gICAgdGhpcy5yb3RhdGlvbl8gPSBpbWFnZVN0eWxlLmdldFJvdGF0aW9uKCk7XG4gICAgdGhpcy5zY2FsZV8gPSBpbWFnZVN0eWxlLmdldFNjYWxlQXJyYXkoKTtcbiAgICB0aGlzLndpZHRoXyA9IHNpemVbMF07XG4gICAgdGhpcy5kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0XyA9IG9wdF9zaGFyZWREYXRhO1xuICB9O1xuXG4gIHJldHVybiBDYW52YXNJbWFnZUJ1aWxkZXI7XG59KENhbnZhc0J1aWxkZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBDYW52YXNJbWFnZUJ1aWxkZXI7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXIvY2FudmFzL0xpbmVTdHJpbmdCdWlsZGVyXG4gKi9cblxuXG5pbXBvcnQgQ2FudmFzQnVpbGRlciBmcm9tICcuL0J1aWxkZXIuanMnO1xuaW1wb3J0IENhbnZhc0luc3RydWN0aW9uLCB7IGJlZ2luUGF0aEluc3RydWN0aW9uLCBzdHJva2VJbnN0cnVjdGlvbiB9IGZyb20gJy4vSW5zdHJ1Y3Rpb24uanMnO1xuXG52YXIgQ2FudmFzTGluZVN0cmluZ0J1aWxkZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ2FudmFzTGluZVN0cmluZ0J1aWxkZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdG9sZXJhbmNlIFRvbGVyYW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBtYXhFeHRlbnQgTWF4aW11bSBleHRlbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIENhbnZhc0xpbmVTdHJpbmdCdWlsZGVyKHRvbGVyYW5jZSwgbWF4RXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSB7XG4gICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIHRvbGVyYW5jZSwgbWF4RXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSB8fCB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IGVuZC5cbiAgICovXG5cblxuICBDYW52YXNMaW5lU3RyaW5nQnVpbGRlci5wcm90b3R5cGUuZHJhd0ZsYXRDb29yZGluYXRlc18gPSBmdW5jdGlvbiAoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKSB7XG4gICAgdmFyIG15QmVnaW4gPSB0aGlzLmNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICB2YXIgbXlFbmQgPSB0aGlzLmFwcGVuZEZsYXRMaW5lQ29vcmRpbmF0ZXMoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBmYWxzZSwgZmFsc2UpO1xuICAgIHZhciBtb3ZlVG9MaW5lVG9JbnN0cnVjdGlvbiA9IFtDYW52YXNJbnN0cnVjdGlvbi5NT1ZFX1RPX0xJTkVfVE8sIG15QmVnaW4sIG15RW5kXTtcbiAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKG1vdmVUb0xpbmVUb0luc3RydWN0aW9uKTtcbiAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKG1vdmVUb0xpbmVUb0luc3RydWN0aW9uKTtcbiAgICByZXR1cm4gZW5kO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL0xpbmVTdHJpbmcuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGxpbmVTdHJpbmdHZW9tZXRyeSBMaW5lIHN0cmluZyBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgQ2FudmFzTGluZVN0cmluZ0J1aWxkZXIucHJvdG90eXBlLmRyYXdMaW5lU3RyaW5nID0gZnVuY3Rpb24gKGxpbmVTdHJpbmdHZW9tZXRyeSwgZmVhdHVyZSkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgdmFyIHN0cm9rZVN0eWxlID0gc3RhdGUuc3Ryb2tlU3R5bGU7XG4gICAgdmFyIGxpbmVXaWR0aCA9IHN0YXRlLmxpbmVXaWR0aDtcblxuICAgIGlmIChzdHJva2VTdHlsZSA9PT0gdW5kZWZpbmVkIHx8IGxpbmVXaWR0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVTdHJva2VTdHlsZShzdGF0ZSwgdGhpcy5hcHBseVN0cm9rZSk7XG4gICAgdGhpcy5iZWdpbkdlb21ldHJ5KGxpbmVTdHJpbmdHZW9tZXRyeSwgZmVhdHVyZSk7XG4gICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uU0VUX1NUUk9LRV9TVFlMRSwgc3RhdGUuc3Ryb2tlU3R5bGUsIHN0YXRlLmxpbmVXaWR0aCwgc3RhdGUubGluZUNhcCwgc3RhdGUubGluZUpvaW4sIHN0YXRlLm1pdGVyTGltaXQsIHN0YXRlLmxpbmVEYXNoLCBzdGF0ZS5saW5lRGFzaE9mZnNldF0sIGJlZ2luUGF0aEluc3RydWN0aW9uKTtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gbGluZVN0cmluZ0dlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpO1xuICAgIHZhciBzdHJpZGUgPSBsaW5lU3RyaW5nR2VvbWV0cnkuZ2V0U3RyaWRlKCk7XG4gICAgdGhpcy5kcmF3RmxhdENvb3JkaW5hdGVzXyhmbGF0Q29vcmRpbmF0ZXMsIDAsIGZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHN0cmlkZSk7XG4gICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChzdHJva2VJbnN0cnVjdGlvbik7XG4gICAgdGhpcy5lbmRHZW9tZXRyeShmZWF0dXJlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aUxpbmVTdHJpbmcuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IG11bHRpTGluZVN0cmluZ0dlb21ldHJ5IE11bHRpTGluZVN0cmluZyBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgQ2FudmFzTGluZVN0cmluZ0J1aWxkZXIucHJvdG90eXBlLmRyYXdNdWx0aUxpbmVTdHJpbmcgPSBmdW5jdGlvbiAobXVsdGlMaW5lU3RyaW5nR2VvbWV0cnksIGZlYXR1cmUpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgIHZhciBzdHJva2VTdHlsZSA9IHN0YXRlLnN0cm9rZVN0eWxlO1xuICAgIHZhciBsaW5lV2lkdGggPSBzdGF0ZS5saW5lV2lkdGg7XG5cbiAgICBpZiAoc3Ryb2tlU3R5bGUgPT09IHVuZGVmaW5lZCB8fCBsaW5lV2lkdGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlU3Ryb2tlU3R5bGUoc3RhdGUsIHRoaXMuYXBwbHlTdHJva2UpO1xuICAgIHRoaXMuYmVnaW5HZW9tZXRyeShtdWx0aUxpbmVTdHJpbmdHZW9tZXRyeSwgZmVhdHVyZSk7XG4gICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uU0VUX1NUUk9LRV9TVFlMRSwgc3RhdGUuc3Ryb2tlU3R5bGUsIHN0YXRlLmxpbmVXaWR0aCwgc3RhdGUubGluZUNhcCwgc3RhdGUubGluZUpvaW4sIHN0YXRlLm1pdGVyTGltaXQsIHN0YXRlLmxpbmVEYXNoLCBzdGF0ZS5saW5lRGFzaE9mZnNldF0sIGJlZ2luUGF0aEluc3RydWN0aW9uKTtcbiAgICB2YXIgZW5kcyA9IG11bHRpTGluZVN0cmluZ0dlb21ldHJ5LmdldEVuZHMoKTtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gbXVsdGlMaW5lU3RyaW5nR2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgdmFyIHN0cmlkZSA9IG11bHRpTGluZVN0cmluZ0dlb21ldHJ5LmdldFN0cmlkZSgpO1xuICAgIHZhciBvZmZzZXQgPSAwO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBvZmZzZXQgPSB0aGlzLmRyYXdGbGF0Q29vcmRpbmF0ZXNfKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICBlbmRzW2ldLCBzdHJpZGUpO1xuICAgIH1cblxuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goc3Ryb2tlSW5zdHJ1Y3Rpb24pO1xuICAgIHRoaXMuZW5kR2VvbWV0cnkoZmVhdHVyZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU2VyaWFsaXphYmxlSW5zdHJ1Y3Rpb25zfSB0aGUgc2VyaWFsaXphYmxlIGluc3RydWN0aW9ucy5cbiAgICovXG5cblxuICBDYW52YXNMaW5lU3RyaW5nQnVpbGRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuc3RhdGU7XG5cbiAgICBpZiAoc3RhdGUubGFzdFN0cm9rZSAhPSB1bmRlZmluZWQgJiYgc3RhdGUubGFzdFN0cm9rZSAhPSB0aGlzLmNvb3JkaW5hdGVzLmxlbmd0aCkge1xuICAgICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChzdHJva2VJbnN0cnVjdGlvbik7XG4gICAgfVxuXG4gICAgdGhpcy5yZXZlcnNlSGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zKCk7XG4gICAgdGhpcy5zdGF0ZSA9IG51bGw7XG4gICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUuZmluaXNoLmNhbGwodGhpcyk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3Ryb2tlU3RhdGV9IHN0YXRlIFN0YXRlLlxuICAgKi9cblxuXG4gIENhbnZhc0xpbmVTdHJpbmdCdWlsZGVyLnByb3RvdHlwZS5hcHBseVN0cm9rZSA9IGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgIGlmIChzdGF0ZS5sYXN0U3Ryb2tlICE9IHVuZGVmaW5lZCAmJiBzdGF0ZS5sYXN0U3Ryb2tlICE9IHRoaXMuY29vcmRpbmF0ZXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKHN0cm9rZUluc3RydWN0aW9uKTtcbiAgICAgIHN0YXRlLmxhc3RTdHJva2UgPSB0aGlzLmNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICB9XG5cbiAgICBzdGF0ZS5sYXN0U3Ryb2tlID0gMDtcblxuICAgIF9zdXBlci5wcm90b3R5cGUuYXBwbHlTdHJva2UuY2FsbCh0aGlzLCBzdGF0ZSk7XG5cbiAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKGJlZ2luUGF0aEluc3RydWN0aW9uKTtcbiAgfTtcblxuICByZXR1cm4gQ2FudmFzTGluZVN0cmluZ0J1aWxkZXI7XG59KENhbnZhc0J1aWxkZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBDYW52YXNMaW5lU3RyaW5nQnVpbGRlcjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9jYW52YXMvUG9seWdvbkJ1aWxkZXJcbiAqL1xuXG5cbmltcG9ydCBDYW52YXNCdWlsZGVyIGZyb20gJy4vQnVpbGRlci5qcyc7XG5pbXBvcnQgQ2FudmFzSW5zdHJ1Y3Rpb24sIHsgYmVnaW5QYXRoSW5zdHJ1Y3Rpb24sIGNsb3NlUGF0aEluc3RydWN0aW9uLCBmaWxsSW5zdHJ1Y3Rpb24sIHN0cm9rZUluc3RydWN0aW9uIH0gZnJvbSAnLi9JbnN0cnVjdGlvbi5qcyc7XG5pbXBvcnQgeyBkZWZhdWx0RmlsbFN0eWxlIH0gZnJvbSAnLi4vY2FudmFzLmpzJztcbmltcG9ydCB7IHNuYXAgfSBmcm9tICcuLi8uLi9nZW9tL2ZsYXQvc2ltcGxpZnkuanMnO1xuXG52YXIgQ2FudmFzUG9seWdvbkJ1aWxkZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ2FudmFzUG9seWdvbkJ1aWxkZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdG9sZXJhbmNlIFRvbGVyYW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBtYXhFeHRlbnQgTWF4aW11bSBleHRlbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIENhbnZhc1BvbHlnb25CdWlsZGVyKHRvbGVyYW5jZSwgbWF4RXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSB7XG4gICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIHRvbGVyYW5jZSwgbWF4RXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSB8fCB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBlbmRzIEVuZHMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEVuZC5cbiAgICovXG5cblxuICBDYW52YXNQb2x5Z29uQnVpbGRlci5wcm90b3R5cGUuZHJhd0ZsYXRDb29yZGluYXRlc3NfID0gZnVuY3Rpb24gKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgIHZhciBmaWxsID0gc3RhdGUuZmlsbFN0eWxlICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIHN0cm9rZSA9IHN0YXRlLnN0cm9rZVN0eWxlICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIG51bUVuZHMgPSBlbmRzLmxlbmd0aDtcbiAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKGJlZ2luUGF0aEluc3RydWN0aW9uKTtcbiAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKGJlZ2luUGF0aEluc3RydWN0aW9uKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtRW5kczsgKytpKSB7XG4gICAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICAgIHZhciBteUJlZ2luID0gdGhpcy5jb29yZGluYXRlcy5sZW5ndGg7XG4gICAgICB2YXIgbXlFbmQgPSB0aGlzLmFwcGVuZEZsYXRMaW5lQ29vcmRpbmF0ZXMoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCB0cnVlLCAhc3Ryb2tlKTtcbiAgICAgIHZhciBtb3ZlVG9MaW5lVG9JbnN0cnVjdGlvbiA9IFtDYW52YXNJbnN0cnVjdGlvbi5NT1ZFX1RPX0xJTkVfVE8sIG15QmVnaW4sIG15RW5kXTtcbiAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2gobW92ZVRvTGluZVRvSW5zdHJ1Y3Rpb24pO1xuICAgICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChtb3ZlVG9MaW5lVG9JbnN0cnVjdGlvbik7XG5cbiAgICAgIGlmIChzdHJva2UpIHtcbiAgICAgICAgLy8gUGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uOiBvbmx5IGNhbGwgY2xvc2VQYXRoKCkgd2hlbiB3ZSBoYXZlIGEgc3Ryb2tlLlxuICAgICAgICAvLyBPdGhlcndpc2UgdGhlIHJpbmcgaXMgY2xvc2VkIGFscmVhZHkgKHNlZSBhcHBlbmRGbGF0TGluZUNvb3JkaW5hdGVzIGFib3ZlKS5cbiAgICAgICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChjbG9zZVBhdGhJbnN0cnVjdGlvbik7XG4gICAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goY2xvc2VQYXRoSW5zdHJ1Y3Rpb24pO1xuICAgICAgfVxuXG4gICAgICBvZmZzZXQgPSBlbmQ7XG4gICAgfVxuXG4gICAgaWYgKGZpbGwpIHtcbiAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goZmlsbEluc3RydWN0aW9uKTtcbiAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goZmlsbEluc3RydWN0aW9uKTtcbiAgICB9XG5cbiAgICBpZiAoc3Ryb2tlKSB7XG4gICAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKHN0cm9rZUluc3RydWN0aW9uKTtcbiAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goc3Ryb2tlSW5zdHJ1Y3Rpb24pO1xuICAgIH1cblxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vQ2lyY2xlLmpzXCIpLmRlZmF1bHR9IGNpcmNsZUdlb21ldHJ5IENpcmNsZSBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICovXG5cblxuICBDYW52YXNQb2x5Z29uQnVpbGRlci5wcm90b3R5cGUuZHJhd0NpcmNsZSA9IGZ1bmN0aW9uIChjaXJjbGVHZW9tZXRyeSwgZmVhdHVyZSkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgdmFyIGZpbGxTdHlsZSA9IHN0YXRlLmZpbGxTdHlsZTtcbiAgICB2YXIgc3Ryb2tlU3R5bGUgPSBzdGF0ZS5zdHJva2VTdHlsZTtcblxuICAgIGlmIChmaWxsU3R5bGUgPT09IHVuZGVmaW5lZCAmJiBzdHJva2VTdHlsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZXRGaWxsU3Ryb2tlU3R5bGVzXygpO1xuICAgIHRoaXMuYmVnaW5HZW9tZXRyeShjaXJjbGVHZW9tZXRyeSwgZmVhdHVyZSk7XG5cbiAgICBpZiAoc3RhdGUuZmlsbFN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLlNFVF9GSUxMX1NUWUxFLCBkZWZhdWx0RmlsbFN0eWxlXSk7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLnN0cm9rZVN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLlNFVF9TVFJPS0VfU1RZTEUsIHN0YXRlLnN0cm9rZVN0eWxlLCBzdGF0ZS5saW5lV2lkdGgsIHN0YXRlLmxpbmVDYXAsIHN0YXRlLmxpbmVKb2luLCBzdGF0ZS5taXRlckxpbWl0LCBzdGF0ZS5saW5lRGFzaCwgc3RhdGUubGluZURhc2hPZmZzZXRdKTtcbiAgICB9XG5cbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gY2lyY2xlR2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgdmFyIHN0cmlkZSA9IGNpcmNsZUdlb21ldHJ5LmdldFN0cmlkZSgpO1xuICAgIHZhciBteUJlZ2luID0gdGhpcy5jb29yZGluYXRlcy5sZW5ndGg7XG4gICAgdGhpcy5hcHBlbmRGbGF0TGluZUNvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlLCBmYWxzZSwgZmFsc2UpO1xuICAgIHZhciBjaXJjbGVJbnN0cnVjdGlvbiA9IFtDYW52YXNJbnN0cnVjdGlvbi5DSVJDTEUsIG15QmVnaW5dO1xuICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goYmVnaW5QYXRoSW5zdHJ1Y3Rpb24sIGNpcmNsZUluc3RydWN0aW9uKTtcbiAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKGJlZ2luUGF0aEluc3RydWN0aW9uLCBjaXJjbGVJbnN0cnVjdGlvbik7XG5cbiAgICBpZiAoc3RhdGUuZmlsbFN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goZmlsbEluc3RydWN0aW9uKTtcbiAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goZmlsbEluc3RydWN0aW9uKTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUuc3Ryb2tlU3R5bGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChzdHJva2VJbnN0cnVjdGlvbik7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKHN0cm9rZUluc3RydWN0aW9uKTtcbiAgICB9XG5cbiAgICB0aGlzLmVuZEdlb21ldHJ5KGZlYXR1cmUpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1BvbHlnb24uanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IHBvbHlnb25HZW9tZXRyeSBQb2x5Z29uIGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICovXG5cblxuICBDYW52YXNQb2x5Z29uQnVpbGRlci5wcm90b3R5cGUuZHJhd1BvbHlnb24gPSBmdW5jdGlvbiAocG9seWdvbkdlb21ldHJ5LCBmZWF0dXJlKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5zdGF0ZTtcbiAgICB2YXIgZmlsbFN0eWxlID0gc3RhdGUuZmlsbFN0eWxlO1xuICAgIHZhciBzdHJva2VTdHlsZSA9IHN0YXRlLnN0cm9rZVN0eWxlO1xuXG4gICAgaWYgKGZpbGxTdHlsZSA9PT0gdW5kZWZpbmVkICYmIHN0cm9rZVN0eWxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldEZpbGxTdHJva2VTdHlsZXNfKCk7XG4gICAgdGhpcy5iZWdpbkdlb21ldHJ5KHBvbHlnb25HZW9tZXRyeSwgZmVhdHVyZSk7XG5cbiAgICBpZiAoc3RhdGUuZmlsbFN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLlNFVF9GSUxMX1NUWUxFLCBkZWZhdWx0RmlsbFN0eWxlXSk7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLnN0cm9rZVN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLlNFVF9TVFJPS0VfU1RZTEUsIHN0YXRlLnN0cm9rZVN0eWxlLCBzdGF0ZS5saW5lV2lkdGgsIHN0YXRlLmxpbmVDYXAsIHN0YXRlLmxpbmVKb2luLCBzdGF0ZS5taXRlckxpbWl0LCBzdGF0ZS5saW5lRGFzaCwgc3RhdGUubGluZURhc2hPZmZzZXRdKTtcbiAgICB9XG5cbiAgICB2YXIgZW5kcyA9IHBvbHlnb25HZW9tZXRyeS5nZXRFbmRzKCk7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IHBvbHlnb25HZW9tZXRyeS5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpO1xuICAgIHZhciBzdHJpZGUgPSBwb2x5Z29uR2VvbWV0cnkuZ2V0U3RyaWRlKCk7XG4gICAgdGhpcy5kcmF3RmxhdENvb3JkaW5hdGVzc18oZmxhdENvb3JkaW5hdGVzLCAwLFxuICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICBlbmRzLCBzdHJpZGUpO1xuICAgIHRoaXMuZW5kR2VvbWV0cnkoZmVhdHVyZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2x5Z29uLmpzXCIpLmRlZmF1bHR9IG11bHRpUG9seWdvbkdlb21ldHJ5IE11bHRpUG9seWdvbiBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgQ2FudmFzUG9seWdvbkJ1aWxkZXIucHJvdG90eXBlLmRyYXdNdWx0aVBvbHlnb24gPSBmdW5jdGlvbiAobXVsdGlQb2x5Z29uR2VvbWV0cnksIGZlYXR1cmUpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgIHZhciBmaWxsU3R5bGUgPSBzdGF0ZS5maWxsU3R5bGU7XG4gICAgdmFyIHN0cm9rZVN0eWxlID0gc3RhdGUuc3Ryb2tlU3R5bGU7XG5cbiAgICBpZiAoZmlsbFN0eWxlID09PSB1bmRlZmluZWQgJiYgc3Ryb2tlU3R5bGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2V0RmlsbFN0cm9rZVN0eWxlc18oKTtcbiAgICB0aGlzLmJlZ2luR2VvbWV0cnkobXVsdGlQb2x5Z29uR2VvbWV0cnksIGZlYXR1cmUpO1xuXG4gICAgaWYgKHN0YXRlLmZpbGxTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5TRVRfRklMTF9TVFlMRSwgZGVmYXVsdEZpbGxTdHlsZV0pO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5zdHJva2VTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5TRVRfU1RST0tFX1NUWUxFLCBzdGF0ZS5zdHJva2VTdHlsZSwgc3RhdGUubGluZVdpZHRoLCBzdGF0ZS5saW5lQ2FwLCBzdGF0ZS5saW5lSm9pbiwgc3RhdGUubWl0ZXJMaW1pdCwgc3RhdGUubGluZURhc2gsIHN0YXRlLmxpbmVEYXNoT2Zmc2V0XSk7XG4gICAgfVxuXG4gICAgdmFyIGVuZHNzID0gbXVsdGlQb2x5Z29uR2VvbWV0cnkuZ2V0RW5kc3MoKTtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gbXVsdGlQb2x5Z29uR2VvbWV0cnkuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKTtcbiAgICB2YXIgc3RyaWRlID0gbXVsdGlQb2x5Z29uR2VvbWV0cnkuZ2V0U3RyaWRlKCk7XG4gICAgdmFyIG9mZnNldCA9IDA7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBvZmZzZXQgPSB0aGlzLmRyYXdGbGF0Q29vcmRpbmF0ZXNzXyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc3NbaV0sIHN0cmlkZSk7XG4gICAgfVxuXG4gICAgdGhpcy5lbmRHZW9tZXRyeShmZWF0dXJlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5TZXJpYWxpemFibGVJbnN0cnVjdGlvbnN9IHRoZSBzZXJpYWxpemFibGUgaW5zdHJ1Y3Rpb25zLlxuICAgKi9cblxuXG4gIENhbnZhc1BvbHlnb25CdWlsZGVyLnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZXZlcnNlSGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zKCk7XG4gICAgdGhpcy5zdGF0ZSA9IG51bGw7IC8vIFdlIHdhbnQgdG8gcHJlc2VydmUgdG9wb2xvZ3kgd2hlbiBkcmF3aW5nIHBvbHlnb25zLiAgUG9seWdvbnMgYXJlXG4gICAgLy8gc2ltcGxpZmllZCB1c2luZyBxdWFudGl6YXRpb24gYW5kIHBvaW50IGVsaW1pbmF0aW9uLiBIb3dldmVyLCB3ZSBtaWdodFxuICAgIC8vIGhhdmUgcmVjZWl2ZWQgYSBtaXggb2YgcXVhbnRpemVkIGFuZCBub24tcXVhbnRpemVkIGdlb21ldHJpZXMsIHNvIGVuc3VyZVxuICAgIC8vIHRoYXQgYWxsIGFyZSBxdWFudGl6ZWQgYnkgcXVhbnRpemluZyBhbGwgY29vcmRpbmF0ZXMgaW4gdGhlIGJhdGNoLlxuXG4gICAgdmFyIHRvbGVyYW5jZSA9IHRoaXMudG9sZXJhbmNlO1xuXG4gICAgaWYgKHRvbGVyYW5jZSAhPT0gMCkge1xuICAgICAgdmFyIGNvb3JkaW5hdGVzID0gdGhpcy5jb29yZGluYXRlcztcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICBjb29yZGluYXRlc1tpXSA9IHNuYXAoY29vcmRpbmF0ZXNbaV0sIHRvbGVyYW5jZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUuZmluaXNoLmNhbGwodGhpcyk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIENhbnZhc1BvbHlnb25CdWlsZGVyLnByb3RvdHlwZS5zZXRGaWxsU3Ryb2tlU3R5bGVzXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgIHZhciBmaWxsU3R5bGUgPSBzdGF0ZS5maWxsU3R5bGU7XG5cbiAgICBpZiAoZmlsbFN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMudXBkYXRlRmlsbFN0eWxlKHN0YXRlLCB0aGlzLmNyZWF0ZUZpbGwpO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5zdHJva2VTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnVwZGF0ZVN0cm9rZVN0eWxlKHN0YXRlLCB0aGlzLmFwcGx5U3Ryb2tlKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIENhbnZhc1BvbHlnb25CdWlsZGVyO1xufShDYW52YXNCdWlsZGVyKTtcblxuZXhwb3J0IGRlZmF1bHQgQ2FudmFzUG9seWdvbkJ1aWxkZXI7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL1RleHRQbGFjZW1lbnRcbiAqL1xuXG4vKipcbiAqIFRleHQgcGxhY2VtZW50LiBPbmUgb2YgYCdwb2ludCdgLCBgJ2xpbmUnYC4gRGVmYXVsdCBpcyBgJ3BvaW50J2AuIE5vdGUgdGhhdFxuICogYCdsaW5lJ2AgcmVxdWlyZXMgdGhlIHVuZGVybHlpbmcgZ2VvbWV0cnkgdG8gYmUgYSB7QGxpbmsgbW9kdWxlOm9sL2dlb20vTGluZVN0cmluZ35MaW5lU3RyaW5nfSxcbiAqIHtAbGluayBtb2R1bGU6b2wvZ2VvbS9Qb2x5Z29uflBvbHlnb259LCB7QGxpbmsgbW9kdWxlOm9sL2dlb20vTXVsdGlMaW5lU3RyaW5nfk11bHRpTGluZVN0cmluZ30gb3JcbiAqIHtAbGluayBtb2R1bGU6b2wvZ2VvbS9NdWx0aVBvbHlnb25+TXVsdGlQb2x5Z29ufS5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgUE9JTlQ6ICdwb2ludCcsXG4gIExJTkU6ICdsaW5lJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L3N0cmFpZ2h0Y2h1bmtcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhBbmdsZSBNYXhpbXVtIGFjY2VwdGFibGUgYW5nbGUgZGVsdGEgYmV0d2VlbiBzZWdtZW50cy5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBTdGFydCBhbmQgZW5kIG9mIHRoZSBmaXJzdCBzdWl0YWJsZSBjaHVuayBvZiB0aGVcbiAqIGdpdmVuIGBmbGF0Q29vcmRpbmF0ZXNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hpbmdDaHVuayhtYXhBbmdsZSwgZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKSB7XG4gIHZhciBjaHVua1N0YXJ0ID0gb2Zmc2V0O1xuICB2YXIgY2h1bmtFbmQgPSBvZmZzZXQ7XG4gIHZhciBjaHVua00gPSAwO1xuICB2YXIgbSA9IDA7XG4gIHZhciBzdGFydCA9IG9mZnNldDtcbiAgdmFyIGFjb3MsIGksIG0xMiwgbTIzLCB4MSwgeTEsIHgxMiwgeTEyLCB4MjMsIHkyMztcblxuICBmb3IgKGkgPSBvZmZzZXQ7IGkgPCBlbmQ7IGkgKz0gc3RyaWRlKSB7XG4gICAgdmFyIHgyID0gZmxhdENvb3JkaW5hdGVzW2ldO1xuICAgIHZhciB5MiA9IGZsYXRDb29yZGluYXRlc1tpICsgMV07XG5cbiAgICBpZiAoeDEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgeDIzID0geDIgLSB4MTtcbiAgICAgIHkyMyA9IHkyIC0geTE7XG4gICAgICBtMjMgPSBNYXRoLnNxcnQoeDIzICogeDIzICsgeTIzICogeTIzKTtcblxuICAgICAgaWYgKHgxMiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG0gKz0gbTEyO1xuICAgICAgICBhY29zID0gTWF0aC5hY29zKCh4MTIgKiB4MjMgKyB5MTIgKiB5MjMpIC8gKG0xMiAqIG0yMykpO1xuXG4gICAgICAgIGlmIChhY29zID4gbWF4QW5nbGUpIHtcbiAgICAgICAgICBpZiAobSA+IGNodW5rTSkge1xuICAgICAgICAgICAgY2h1bmtNID0gbTtcbiAgICAgICAgICAgIGNodW5rU3RhcnQgPSBzdGFydDtcbiAgICAgICAgICAgIGNodW5rRW5kID0gaTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBtID0gMDtcbiAgICAgICAgICBzdGFydCA9IGkgLSBzdHJpZGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbTEyID0gbTIzO1xuICAgICAgeDEyID0geDIzO1xuICAgICAgeTEyID0geTIzO1xuICAgIH1cblxuICAgIHgxID0geDI7XG4gICAgeTEgPSB5MjtcbiAgfVxuXG4gIG0gKz0gbTIzO1xuICByZXR1cm4gbSA+IGNodW5rTSA/IFtzdGFydCwgaV0gOiBbY2h1bmtTdGFydCwgY2h1bmtFbmRdO1xufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL2NhbnZhcy9UZXh0QnVpbGRlclxuICovXG5cblxuaW1wb3J0IENhbnZhc0J1aWxkZXIgZnJvbSAnLi9CdWlsZGVyLmpzJztcbmltcG9ydCBDYW52YXNJbnN0cnVjdGlvbiBmcm9tICcuL0luc3RydWN0aW9uLmpzJztcbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi4vLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IFRleHRQbGFjZW1lbnQgZnJvbSAnLi4vLi4vc3R5bGUvVGV4dFBsYWNlbWVudC5qcyc7XG5pbXBvcnQgeyBhc0NvbG9yTGlrZSB9IGZyb20gJy4uLy4uL2NvbG9ybGlrZS5qcyc7XG5pbXBvcnQgeyBkZWZhdWx0RmlsbFN0eWxlLCBkZWZhdWx0Rm9udCwgZGVmYXVsdExpbmVDYXAsIGRlZmF1bHRMaW5lRGFzaCwgZGVmYXVsdExpbmVEYXNoT2Zmc2V0LCBkZWZhdWx0TGluZUpvaW4sIGRlZmF1bHRMaW5lV2lkdGgsIGRlZmF1bHRNaXRlckxpbWl0LCBkZWZhdWx0UGFkZGluZywgZGVmYXVsdFN0cm9rZVN0eWxlLCBkZWZhdWx0VGV4dEFsaWduLCBkZWZhdWx0VGV4dEJhc2VsaW5lLCByZWdpc3RlckZvbnQgfSBmcm9tICcuLi9jYW52YXMuanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi4vLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBpbnRlcnNlY3RzIH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IG1hdGNoaW5nQ2h1bmsgfSBmcm9tICcuLi8uLi9nZW9tL2ZsYXQvc3RyYWlnaHRjaHVuay5qcyc7XG4vKipcbiAqIEBjb25zdFxuICogQGVudW0ge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIFRFWFRfQUxJR04gPSB7XG4gICdsZWZ0JzogMCxcbiAgJ2VuZCc6IDAsXG4gICdjZW50ZXInOiAwLjUsXG4gICdyaWdodCc6IDEsXG4gICdzdGFydCc6IDEsXG4gICd0b3AnOiAwLFxuICAnbWlkZGxlJzogMC41LFxuICAnaGFuZ2luZyc6IDAuMixcbiAgJ2FscGhhYmV0aWMnOiAwLjgsXG4gICdpZGVvZ3JhcGhpYyc6IDAuOCxcbiAgJ2JvdHRvbSc6IDFcbn07XG5cbnZhciBDYW52YXNUZXh0QnVpbGRlciA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhDYW52YXNUZXh0QnVpbGRlciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0b2xlcmFuY2UgVG9sZXJhbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IG1heEV4dGVudCBNYXhpbXVtIGV4dGVudC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQ2FudmFzVGV4dEJ1aWxkZXIodG9sZXJhbmNlLCBtYXhFeHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8pIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0b2xlcmFuY2UsIG1heEV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxIVE1MQ2FudmFzRWxlbWVudD59XG4gICAgICovXG5cblxuICAgIF90aGlzLmxhYmVsc18gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRfID0gJyc7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dE9mZnNldFhfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0T2Zmc2V0WV8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW58dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dFJvdGF0ZVdpdGhWaWV3XyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0Um90YXRpb25fID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkZpbGxTdGF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRGaWxsU3RhdGVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3RhdGU+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmlsbFN0YXRlcyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU3Ryb2tlU3RhdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0U3Ryb2tlU3RhdGVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5TdHJva2VTdGF0ZT59XG4gICAgICovXG5cbiAgICBfdGhpcy5zdHJva2VTdGF0ZXMgPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuVGV4dFN0YXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dFN0YXRlXyA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuVGV4dFN0YXRlfSAqL1xuICAgIHt9O1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlRleHRTdGF0ZT59XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0U3RhdGVzID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dEtleV8gPSAnJztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy5maWxsS2V5XyA9ICcnO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cblxuICAgIF90aGlzLnN0cm9rZUtleV8gPSAnJztcbiAgICAvKipcbiAgICAgKiBEYXRhIHNoYXJlZCB3aXRoIGFuIGltYWdlIGJ1aWxkZXIgZm9yIGNvbWJpbmVkIGRlY2x1dHRlcmluZy5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRGVjbHV0dGVySW1hZ2VXaXRoVGV4dH1cbiAgICAgKi9cblxuICAgIF90aGlzLmRlY2x1dHRlckltYWdlV2l0aFRleHRfID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlNlcmlhbGl6YWJsZUluc3RydWN0aW9uc30gdGhlIHNlcmlhbGl6YWJsZSBpbnN0cnVjdGlvbnMuXG4gICAqL1xuXG5cbiAgQ2FudmFzVGV4dEJ1aWxkZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaW5zdHJ1Y3Rpb25zID0gX3N1cGVyLnByb3RvdHlwZS5maW5pc2guY2FsbCh0aGlzKTtcblxuICAgIGluc3RydWN0aW9ucy50ZXh0U3RhdGVzID0gdGhpcy50ZXh0U3RhdGVzO1xuICAgIGluc3RydWN0aW9ucy5maWxsU3RhdGVzID0gdGhpcy5maWxsU3RhdGVzO1xuICAgIGluc3RydWN0aW9ucy5zdHJva2VTdGF0ZXMgPSB0aGlzLnN0cm9rZVN0YXRlcztcbiAgICByZXR1cm4gaW5zdHJ1Y3Rpb25zO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgQ2FudmFzVGV4dEJ1aWxkZXIucHJvdG90eXBlLmRyYXdUZXh0ID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBmZWF0dXJlKSB7XG4gICAgdmFyIGZpbGxTdGF0ZSA9IHRoaXMudGV4dEZpbGxTdGF0ZV87XG4gICAgdmFyIHN0cm9rZVN0YXRlID0gdGhpcy50ZXh0U3Ryb2tlU3RhdGVfO1xuICAgIHZhciB0ZXh0U3RhdGUgPSB0aGlzLnRleHRTdGF0ZV87XG5cbiAgICBpZiAodGhpcy50ZXh0XyA9PT0gJycgfHwgIXRleHRTdGF0ZSB8fCAhZmlsbFN0YXRlICYmICFzdHJva2VTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBjb29yZGluYXRlcyA9IHRoaXMuY29vcmRpbmF0ZXM7XG4gICAgdmFyIGJlZ2luID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHZhciBnZW9tZXRyeVR5cGUgPSBnZW9tZXRyeS5nZXRUeXBlKCk7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IG51bGw7XG4gICAgdmFyIHN0cmlkZSA9IGdlb21ldHJ5LmdldFN0cmlkZSgpO1xuXG4gICAgaWYgKHRleHRTdGF0ZS5wbGFjZW1lbnQgPT09IFRleHRQbGFjZW1lbnQuTElORSAmJiAoZ2VvbWV0cnlUeXBlID09IEdlb21ldHJ5VHlwZS5MSU5FX1NUUklORyB8fCBnZW9tZXRyeVR5cGUgPT0gR2VvbWV0cnlUeXBlLk1VTFRJX0xJTkVfU1RSSU5HIHx8IGdlb21ldHJ5VHlwZSA9PSBHZW9tZXRyeVR5cGUuUE9MWUdPTiB8fCBnZW9tZXRyeVR5cGUgPT0gR2VvbWV0cnlUeXBlLk1VTFRJX1BPTFlHT04pKSB7XG4gICAgICBpZiAoIWludGVyc2VjdHModGhpcy5nZXRCdWZmZXJlZE1heEV4dGVudCgpLCBnZW9tZXRyeS5nZXRFeHRlbnQoKSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgZW5kcyA9IHZvaWQgMDtcbiAgICAgIGZsYXRDb29yZGluYXRlcyA9IGdlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpO1xuXG4gICAgICBpZiAoZ2VvbWV0cnlUeXBlID09IEdlb21ldHJ5VHlwZS5MSU5FX1NUUklORykge1xuICAgICAgICBlbmRzID0gW2ZsYXRDb29yZGluYXRlcy5sZW5ndGhdO1xuICAgICAgfSBlbHNlIGlmIChnZW9tZXRyeVR5cGUgPT0gR2VvbWV0cnlUeXBlLk1VTFRJX0xJTkVfU1RSSU5HKSB7XG4gICAgICAgIGVuZHMgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlMaW5lU3RyaW5nLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5LmdldEVuZHMoKTtcbiAgICAgIH0gZWxzZSBpZiAoZ2VvbWV0cnlUeXBlID09IEdlb21ldHJ5VHlwZS5QT0xZR09OKSB7XG4gICAgICAgIGVuZHMgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeS5nZXRFbmRzKCkuc2xpY2UoMCwgMSk7XG4gICAgICB9IGVsc2UgaWYgKGdlb21ldHJ5VHlwZSA9PSBHZW9tZXRyeVR5cGUuTVVMVElfUE9MWUdPTikge1xuICAgICAgICB2YXIgZW5kc3MgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2x5Z29uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5LmdldEVuZHNzKCk7XG4gICAgICAgIGVuZHMgPSBbXTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgICAgZW5kcy5wdXNoKGVuZHNzW2ldWzBdKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLmJlZ2luR2VvbWV0cnkoZ2VvbWV0cnksIGZlYXR1cmUpO1xuICAgICAgdmFyIHRleHRBbGlnbiA9IHRleHRTdGF0ZS50ZXh0QWxpZ247XG4gICAgICB2YXIgZmxhdE9mZnNldCA9IDA7XG4gICAgICB2YXIgZmxhdEVuZCA9IHZvaWQgMDtcblxuICAgICAgZm9yICh2YXIgbyA9IDAsIG9vID0gZW5kcy5sZW5ndGg7IG8gPCBvbzsgKytvKSB7XG4gICAgICAgIGlmICh0ZXh0QWxpZ24gPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdmFyIHJhbmdlID0gbWF0Y2hpbmdDaHVuayh0ZXh0U3RhdGUubWF4QW5nbGUsIGZsYXRDb29yZGluYXRlcywgZmxhdE9mZnNldCwgZW5kc1tvXSwgc3RyaWRlKTtcbiAgICAgICAgICBmbGF0T2Zmc2V0ID0gcmFuZ2VbMF07XG4gICAgICAgICAgZmxhdEVuZCA9IHJhbmdlWzFdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZsYXRFbmQgPSBlbmRzW29dO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IGZsYXRPZmZzZXQ7IGkgPCBmbGF0RW5kOyBpICs9IHN0cmlkZSkge1xuICAgICAgICAgIGNvb3JkaW5hdGVzLnB1c2goZmxhdENvb3JkaW5hdGVzW2ldLCBmbGF0Q29vcmRpbmF0ZXNbaSArIDFdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBlbmQgPSBjb29yZGluYXRlcy5sZW5ndGg7XG4gICAgICAgIGZsYXRPZmZzZXQgPSBlbmRzW29dO1xuICAgICAgICB0aGlzLmRyYXdDaGFyc18oYmVnaW4sIGVuZCk7XG4gICAgICAgIGJlZ2luID0gZW5kO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmVuZEdlb21ldHJ5KGZlYXR1cmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZ2VvbWV0cnlXaWR0aHMgPSB0ZXh0U3RhdGUub3ZlcmZsb3cgPyBudWxsIDogW107XG5cbiAgICAgIHN3aXRjaCAoZ2VvbWV0cnlUeXBlKSB7XG4gICAgICAgIGNhc2UgR2VvbWV0cnlUeXBlLlBPSU5UOlxuICAgICAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9QT0lOVDpcbiAgICAgICAgICBmbGF0Q29vcmRpbmF0ZXMgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aVBvaW50LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgICAgZ2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBHZW9tZXRyeVR5cGUuTElORV9TVFJJTkc6XG4gICAgICAgICAgZmxhdENvb3JkaW5hdGVzID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICAgIGdlb21ldHJ5LmdldEZsYXRNaWRwb2ludCgpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgR2VvbWV0cnlUeXBlLkNJUkNMRTpcbiAgICAgICAgICBmbGF0Q29vcmRpbmF0ZXMgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9DaXJjbGUuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgICBnZW9tZXRyeS5nZXRDZW50ZXIoKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9MSU5FX1NUUklORzpcbiAgICAgICAgICBmbGF0Q29vcmRpbmF0ZXMgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aUxpbmVTdHJpbmcuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgICBnZW9tZXRyeS5nZXRGbGF0TWlkcG9pbnRzKCk7XG4gICAgICAgICAgc3RyaWRlID0gMjtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIEdlb21ldHJ5VHlwZS5QT0xZR09OOlxuICAgICAgICAgIGZsYXRDb29yZGluYXRlcyA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1BvbHlnb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgICBnZW9tZXRyeS5nZXRGbGF0SW50ZXJpb3JQb2ludCgpO1xuXG4gICAgICAgICAgaWYgKCF0ZXh0U3RhdGUub3ZlcmZsb3cpIHtcbiAgICAgICAgICAgIGdlb21ldHJ5V2lkdGhzLnB1c2goZmxhdENvb3JkaW5hdGVzWzJdIC8gdGhpcy5yZXNvbHV0aW9uKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzdHJpZGUgPSAzO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgR2VvbWV0cnlUeXBlLk1VTFRJX1BPTFlHT046XG4gICAgICAgICAgdmFyIGludGVyaW9yUG9pbnRzID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2x5Z29uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgICAgZ2VvbWV0cnkuZ2V0RmxhdEludGVyaW9yUG9pbnRzKCk7XG4gICAgICAgICAgZmxhdENvb3JkaW5hdGVzID0gW107XG5cbiAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBpbnRlcmlvclBvaW50cy5sZW5ndGg7IGkgPCBpaTsgaSArPSAzKSB7XG4gICAgICAgICAgICBpZiAoIXRleHRTdGF0ZS5vdmVyZmxvdykge1xuICAgICAgICAgICAgICBnZW9tZXRyeVdpZHRocy5wdXNoKGludGVyaW9yUG9pbnRzW2kgKyAyXSAvIHRoaXMucmVzb2x1dGlvbik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZsYXRDb29yZGluYXRlcy5wdXNoKGludGVyaW9yUG9pbnRzW2ldLCBpbnRlcmlvclBvaW50c1tpICsgMV0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3RyaWRlID0gMjtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgfVxuXG4gICAgICB2YXIgZW5kID0gdGhpcy5hcHBlbmRGbGF0UG9pbnRDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIHN0cmlkZSk7XG5cbiAgICAgIGlmIChlbmQgPT09IGJlZ2luKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zYXZlVGV4dFN0YXRlc18oKTtcblxuICAgICAgaWYgKHRleHRTdGF0ZS5iYWNrZ3JvdW5kRmlsbCB8fCB0ZXh0U3RhdGUuYmFja2dyb3VuZFN0cm9rZSkge1xuICAgICAgICB0aGlzLnNldEZpbGxTdHJva2VTdHlsZSh0ZXh0U3RhdGUuYmFja2dyb3VuZEZpbGwsIHRleHRTdGF0ZS5iYWNrZ3JvdW5kU3Ryb2tlKTtcblxuICAgICAgICBpZiAodGV4dFN0YXRlLmJhY2tncm91bmRGaWxsKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVGaWxsU3R5bGUodGhpcy5zdGF0ZSwgdGhpcy5jcmVhdGVGaWxsKTtcbiAgICAgICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKHRoaXMuY3JlYXRlRmlsbCh0aGlzLnN0YXRlKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGV4dFN0YXRlLmJhY2tncm91bmRTdHJva2UpIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVN0cm9rZVN0eWxlKHRoaXMuc3RhdGUsIHRoaXMuYXBwbHlTdHJva2UpO1xuICAgICAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2godGhpcy5jcmVhdGVTdHJva2UodGhpcy5zdGF0ZSkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYmVnaW5HZW9tZXRyeShnZW9tZXRyeSwgZmVhdHVyZSk7IC8vIGFkanVzdCBwYWRkaW5nIGZvciBuZWdhdGl2ZSBzY2FsZVxuXG4gICAgICB2YXIgcGFkZGluZyA9IHRleHRTdGF0ZS5wYWRkaW5nO1xuXG4gICAgICBpZiAocGFkZGluZyAhPSBkZWZhdWx0UGFkZGluZyAmJiAodGV4dFN0YXRlLnNjYWxlWzBdIDwgMCB8fCB0ZXh0U3RhdGUuc2NhbGVbMV0gPCAwKSkge1xuICAgICAgICB2YXIgcDAgPSB0ZXh0U3RhdGUucGFkZGluZ1swXTtcbiAgICAgICAgdmFyIHAxID0gdGV4dFN0YXRlLnBhZGRpbmdbMV07XG4gICAgICAgIHZhciBwMiA9IHRleHRTdGF0ZS5wYWRkaW5nWzJdO1xuICAgICAgICB2YXIgcDMgPSB0ZXh0U3RhdGUucGFkZGluZ1szXTtcblxuICAgICAgICBpZiAodGV4dFN0YXRlLnNjYWxlWzBdIDwgMCkge1xuICAgICAgICAgIHAxID0gLXAxO1xuICAgICAgICAgIHAzID0gLXAzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRleHRTdGF0ZS5zY2FsZVsxXSA8IDApIHtcbiAgICAgICAgICBwMCA9IC1wMDtcbiAgICAgICAgICBwMiA9IC1wMjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBhZGRpbmcgPSBbcDAsIHAxLCBwMiwgcDNdO1xuICAgICAgfSAvLyBUaGUgaW1hZ2UgaXMgdW5rbm93biBhdCB0aGlzIHN0YWdlIHNvIHdlIHBhc3MgbnVsbDsgaXQgd2lsbCBiZSBjb21wdXRlZCBhdCByZW5kZXIgdGltZS5cbiAgICAgIC8vIEZvciBjbGFyaXR5LCB3ZSBwYXNzIE5hTiBmb3Igb2Zmc2V0WCwgb2Zmc2V0WSwgd2lkdGggYW5kIGhlaWdodCwgd2hpY2ggd2lsbCBiZSBjb21wdXRlZCBhdFxuICAgICAgLy8gcmVuZGVyIHRpbWUuXG5cblxuICAgICAgdmFyIHBpeGVsUmF0aW9fMSA9IHRoaXMucGl4ZWxSYXRpbztcbiAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkRSQVdfSU1BR0UsIGJlZ2luLCBlbmQsIG51bGwsIE5hTiwgTmFOLCBOYU4sIDEsIDAsIDAsIHRoaXMudGV4dFJvdGF0ZVdpdGhWaWV3XywgdGhpcy50ZXh0Um90YXRpb25fLCBbMSwgMV0sIE5hTiwgdGhpcy5kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0XywgcGFkZGluZyA9PSBkZWZhdWx0UGFkZGluZyA/IGRlZmF1bHRQYWRkaW5nIDogcGFkZGluZy5tYXAoZnVuY3Rpb24gKHApIHtcbiAgICAgICAgcmV0dXJuIHAgKiBwaXhlbFJhdGlvXzE7XG4gICAgICB9KSwgISF0ZXh0U3RhdGUuYmFja2dyb3VuZEZpbGwsICEhdGV4dFN0YXRlLmJhY2tncm91bmRTdHJva2UsIHRoaXMudGV4dF8sIHRoaXMudGV4dEtleV8sIHRoaXMuc3Ryb2tlS2V5XywgdGhpcy5maWxsS2V5XywgdGhpcy50ZXh0T2Zmc2V0WF8sIHRoaXMudGV4dE9mZnNldFlfLCBnZW9tZXRyeVdpZHRoc10pO1xuICAgICAgdmFyIHNjYWxlID0gMSAvIHBpeGVsUmF0aW9fMTtcbiAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkRSQVdfSU1BR0UsIGJlZ2luLCBlbmQsIG51bGwsIE5hTiwgTmFOLCBOYU4sIDEsIDAsIDAsIHRoaXMudGV4dFJvdGF0ZVdpdGhWaWV3XywgdGhpcy50ZXh0Um90YXRpb25fLCBbc2NhbGUsIHNjYWxlXSwgTmFOLCB0aGlzLmRlY2x1dHRlckltYWdlV2l0aFRleHRfLCBwYWRkaW5nLCAhIXRleHRTdGF0ZS5iYWNrZ3JvdW5kRmlsbCwgISF0ZXh0U3RhdGUuYmFja2dyb3VuZFN0cm9rZSwgdGhpcy50ZXh0XywgdGhpcy50ZXh0S2V5XywgdGhpcy5zdHJva2VLZXlfLCB0aGlzLmZpbGxLZXlfLCB0aGlzLnRleHRPZmZzZXRYXywgdGhpcy50ZXh0T2Zmc2V0WV8sIGdlb21ldHJ5V2lkdGhzXSk7XG4gICAgICB0aGlzLmVuZEdlb21ldHJ5KGZlYXR1cmUpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQ2FudmFzVGV4dEJ1aWxkZXIucHJvdG90eXBlLnNhdmVUZXh0U3RhdGVzXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3Ryb2tlU3RhdGUgPSB0aGlzLnRleHRTdHJva2VTdGF0ZV87XG4gICAgdmFyIHRleHRTdGF0ZSA9IHRoaXMudGV4dFN0YXRlXztcbiAgICB2YXIgZmlsbFN0YXRlID0gdGhpcy50ZXh0RmlsbFN0YXRlXztcbiAgICB2YXIgc3Ryb2tlS2V5ID0gdGhpcy5zdHJva2VLZXlfO1xuXG4gICAgaWYgKHN0cm9rZVN0YXRlKSB7XG4gICAgICBpZiAoIShzdHJva2VLZXkgaW4gdGhpcy5zdHJva2VTdGF0ZXMpKSB7XG4gICAgICAgIHRoaXMuc3Ryb2tlU3RhdGVzW3N0cm9rZUtleV0gPSB7XG4gICAgICAgICAgc3Ryb2tlU3R5bGU6IHN0cm9rZVN0YXRlLnN0cm9rZVN0eWxlLFxuICAgICAgICAgIGxpbmVDYXA6IHN0cm9rZVN0YXRlLmxpbmVDYXAsXG4gICAgICAgICAgbGluZURhc2hPZmZzZXQ6IHN0cm9rZVN0YXRlLmxpbmVEYXNoT2Zmc2V0LFxuICAgICAgICAgIGxpbmVXaWR0aDogc3Ryb2tlU3RhdGUubGluZVdpZHRoLFxuICAgICAgICAgIGxpbmVKb2luOiBzdHJva2VTdGF0ZS5saW5lSm9pbixcbiAgICAgICAgICBtaXRlckxpbWl0OiBzdHJva2VTdGF0ZS5taXRlckxpbWl0LFxuICAgICAgICAgIGxpbmVEYXNoOiBzdHJva2VTdGF0ZS5saW5lRGFzaFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciB0ZXh0S2V5ID0gdGhpcy50ZXh0S2V5XztcblxuICAgIGlmICghKHRleHRLZXkgaW4gdGhpcy50ZXh0U3RhdGVzKSkge1xuICAgICAgdGhpcy50ZXh0U3RhdGVzW3RleHRLZXldID0ge1xuICAgICAgICBmb250OiB0ZXh0U3RhdGUuZm9udCxcbiAgICAgICAgdGV4dEFsaWduOiB0ZXh0U3RhdGUudGV4dEFsaWduIHx8IGRlZmF1bHRUZXh0QWxpZ24sXG4gICAgICAgIHRleHRCYXNlbGluZTogdGV4dFN0YXRlLnRleHRCYXNlbGluZSB8fCBkZWZhdWx0VGV4dEJhc2VsaW5lLFxuICAgICAgICBzY2FsZTogdGV4dFN0YXRlLnNjYWxlXG4gICAgICB9O1xuICAgIH1cblxuICAgIHZhciBmaWxsS2V5ID0gdGhpcy5maWxsS2V5XztcblxuICAgIGlmIChmaWxsU3RhdGUpIHtcbiAgICAgIGlmICghKGZpbGxLZXkgaW4gdGhpcy5maWxsU3RhdGVzKSkge1xuICAgICAgICB0aGlzLmZpbGxTdGF0ZXNbZmlsbEtleV0gPSB7XG4gICAgICAgICAgZmlsbFN0eWxlOiBmaWxsU3RhdGUuZmlsbFN0eWxlXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IGJlZ2luIEJlZ2luLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAgICovXG5cblxuICBDYW52YXNUZXh0QnVpbGRlci5wcm90b3R5cGUuZHJhd0NoYXJzXyA9IGZ1bmN0aW9uIChiZWdpbiwgZW5kKSB7XG4gICAgdmFyIHN0cm9rZVN0YXRlID0gdGhpcy50ZXh0U3Ryb2tlU3RhdGVfO1xuICAgIHZhciB0ZXh0U3RhdGUgPSB0aGlzLnRleHRTdGF0ZV87XG4gICAgdmFyIHN0cm9rZUtleSA9IHRoaXMuc3Ryb2tlS2V5XztcbiAgICB2YXIgdGV4dEtleSA9IHRoaXMudGV4dEtleV87XG4gICAgdmFyIGZpbGxLZXkgPSB0aGlzLmZpbGxLZXlfO1xuICAgIHRoaXMuc2F2ZVRleHRTdGF0ZXNfKCk7XG4gICAgdmFyIHBpeGVsUmF0aW8gPSB0aGlzLnBpeGVsUmF0aW87XG4gICAgdmFyIGJhc2VsaW5lID0gVEVYVF9BTElHTlt0ZXh0U3RhdGUudGV4dEJhc2VsaW5lXTtcbiAgICB2YXIgb2Zmc2V0WSA9IHRoaXMudGV4dE9mZnNldFlfICogcGl4ZWxSYXRpbztcbiAgICB2YXIgdGV4dCA9IHRoaXMudGV4dF87XG4gICAgdmFyIHN0cm9rZVdpZHRoID0gc3Ryb2tlU3RhdGUgPyBzdHJva2VTdGF0ZS5saW5lV2lkdGggKiBNYXRoLmFicyh0ZXh0U3RhdGUuc2NhbGVbMF0pIC8gMiA6IDA7XG4gICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uRFJBV19DSEFSUywgYmVnaW4sIGVuZCwgYmFzZWxpbmUsIHRleHRTdGF0ZS5vdmVyZmxvdywgZmlsbEtleSwgdGV4dFN0YXRlLm1heEFuZ2xlLCBwaXhlbFJhdGlvLCBvZmZzZXRZLCBzdHJva2VLZXksIHN0cm9rZVdpZHRoICogcGl4ZWxSYXRpbywgdGV4dCwgdGV4dEtleSwgMV0pO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkRSQVdfQ0hBUlMsIGJlZ2luLCBlbmQsIGJhc2VsaW5lLCB0ZXh0U3RhdGUub3ZlcmZsb3csIGZpbGxLZXksIHRleHRTdGF0ZS5tYXhBbmdsZSwgMSwgb2Zmc2V0WSwgc3Ryb2tlS2V5LCBzdHJva2VXaWR0aCwgdGV4dCwgdGV4dEtleSwgMSAvIHBpeGVsUmF0aW9dKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc3R5bGUvVGV4dC5qc1wiKS5kZWZhdWx0fSB0ZXh0U3R5bGUgVGV4dCBzdHlsZS5cbiAgICogQHBhcmFtIHtPYmplY3Q9fSBvcHRfc2hhcmVkRGF0YSBTaGFyZWQgZGF0YS5cbiAgICovXG5cblxuICBDYW52YXNUZXh0QnVpbGRlci5wcm90b3R5cGUuc2V0VGV4dFN0eWxlID0gZnVuY3Rpb24gKHRleHRTdHlsZSwgb3B0X3NoYXJlZERhdGEpIHtcbiAgICB2YXIgdGV4dFN0YXRlLCBmaWxsU3RhdGUsIHN0cm9rZVN0YXRlO1xuXG4gICAgaWYgKCF0ZXh0U3R5bGUpIHtcbiAgICAgIHRoaXMudGV4dF8gPSAnJztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHRleHRGaWxsU3R5bGUgPSB0ZXh0U3R5bGUuZ2V0RmlsbCgpO1xuXG4gICAgICBpZiAoIXRleHRGaWxsU3R5bGUpIHtcbiAgICAgICAgZmlsbFN0YXRlID0gbnVsbDtcbiAgICAgICAgdGhpcy50ZXh0RmlsbFN0YXRlXyA9IGZpbGxTdGF0ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZpbGxTdGF0ZSA9IHRoaXMudGV4dEZpbGxTdGF0ZV87XG5cbiAgICAgICAgaWYgKCFmaWxsU3RhdGUpIHtcbiAgICAgICAgICBmaWxsU3RhdGUgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkZpbGxTdGF0ZX0gKi9cbiAgICAgICAgICB7fTtcbiAgICAgICAgICB0aGlzLnRleHRGaWxsU3RhdGVfID0gZmlsbFN0YXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgZmlsbFN0YXRlLmZpbGxTdHlsZSA9IGFzQ29sb3JMaWtlKHRleHRGaWxsU3R5bGUuZ2V0Q29sb3IoKSB8fCBkZWZhdWx0RmlsbFN0eWxlKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHRleHRTdHJva2VTdHlsZSA9IHRleHRTdHlsZS5nZXRTdHJva2UoKTtcblxuICAgICAgaWYgKCF0ZXh0U3Ryb2tlU3R5bGUpIHtcbiAgICAgICAgc3Ryb2tlU3RhdGUgPSBudWxsO1xuICAgICAgICB0aGlzLnRleHRTdHJva2VTdGF0ZV8gPSBzdHJva2VTdGF0ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cm9rZVN0YXRlID0gdGhpcy50ZXh0U3Ryb2tlU3RhdGVfO1xuXG4gICAgICAgIGlmICghc3Ryb2tlU3RhdGUpIHtcbiAgICAgICAgICBzdHJva2VTdGF0ZSA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU3Ryb2tlU3RhdGV9ICovXG4gICAgICAgICAge307XG4gICAgICAgICAgdGhpcy50ZXh0U3Ryb2tlU3RhdGVfID0gc3Ryb2tlU3RhdGU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGluZURhc2ggPSB0ZXh0U3Ryb2tlU3R5bGUuZ2V0TGluZURhc2goKTtcbiAgICAgICAgdmFyIGxpbmVEYXNoT2Zmc2V0ID0gdGV4dFN0cm9rZVN0eWxlLmdldExpbmVEYXNoT2Zmc2V0KCk7XG4gICAgICAgIHZhciBsaW5lV2lkdGggPSB0ZXh0U3Ryb2tlU3R5bGUuZ2V0V2lkdGgoKTtcbiAgICAgICAgdmFyIG1pdGVyTGltaXQgPSB0ZXh0U3Ryb2tlU3R5bGUuZ2V0TWl0ZXJMaW1pdCgpO1xuICAgICAgICBzdHJva2VTdGF0ZS5saW5lQ2FwID0gdGV4dFN0cm9rZVN0eWxlLmdldExpbmVDYXAoKSB8fCBkZWZhdWx0TGluZUNhcDtcbiAgICAgICAgc3Ryb2tlU3RhdGUubGluZURhc2ggPSBsaW5lRGFzaCA/IGxpbmVEYXNoLnNsaWNlKCkgOiBkZWZhdWx0TGluZURhc2g7XG4gICAgICAgIHN0cm9rZVN0YXRlLmxpbmVEYXNoT2Zmc2V0ID0gbGluZURhc2hPZmZzZXQgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRMaW5lRGFzaE9mZnNldCA6IGxpbmVEYXNoT2Zmc2V0O1xuICAgICAgICBzdHJva2VTdGF0ZS5saW5lSm9pbiA9IHRleHRTdHJva2VTdHlsZS5nZXRMaW5lSm9pbigpIHx8IGRlZmF1bHRMaW5lSm9pbjtcbiAgICAgICAgc3Ryb2tlU3RhdGUubGluZVdpZHRoID0gbGluZVdpZHRoID09PSB1bmRlZmluZWQgPyBkZWZhdWx0TGluZVdpZHRoIDogbGluZVdpZHRoO1xuICAgICAgICBzdHJva2VTdGF0ZS5taXRlckxpbWl0ID0gbWl0ZXJMaW1pdCA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdE1pdGVyTGltaXQgOiBtaXRlckxpbWl0O1xuICAgICAgICBzdHJva2VTdGF0ZS5zdHJva2VTdHlsZSA9IGFzQ29sb3JMaWtlKHRleHRTdHJva2VTdHlsZS5nZXRDb2xvcigpIHx8IGRlZmF1bHRTdHJva2VTdHlsZSk7XG4gICAgICB9XG5cbiAgICAgIHRleHRTdGF0ZSA9IHRoaXMudGV4dFN0YXRlXztcbiAgICAgIHZhciBmb250ID0gdGV4dFN0eWxlLmdldEZvbnQoKSB8fCBkZWZhdWx0Rm9udDtcbiAgICAgIHJlZ2lzdGVyRm9udChmb250KTtcbiAgICAgIHZhciB0ZXh0U2NhbGUgPSB0ZXh0U3R5bGUuZ2V0U2NhbGVBcnJheSgpO1xuICAgICAgdGV4dFN0YXRlLm92ZXJmbG93ID0gdGV4dFN0eWxlLmdldE92ZXJmbG93KCk7XG4gICAgICB0ZXh0U3RhdGUuZm9udCA9IGZvbnQ7XG4gICAgICB0ZXh0U3RhdGUubWF4QW5nbGUgPSB0ZXh0U3R5bGUuZ2V0TWF4QW5nbGUoKTtcbiAgICAgIHRleHRTdGF0ZS5wbGFjZW1lbnQgPSB0ZXh0U3R5bGUuZ2V0UGxhY2VtZW50KCk7XG4gICAgICB0ZXh0U3RhdGUudGV4dEFsaWduID0gdGV4dFN0eWxlLmdldFRleHRBbGlnbigpO1xuICAgICAgdGV4dFN0YXRlLnRleHRCYXNlbGluZSA9IHRleHRTdHlsZS5nZXRUZXh0QmFzZWxpbmUoKSB8fCBkZWZhdWx0VGV4dEJhc2VsaW5lO1xuICAgICAgdGV4dFN0YXRlLmJhY2tncm91bmRGaWxsID0gdGV4dFN0eWxlLmdldEJhY2tncm91bmRGaWxsKCk7XG4gICAgICB0ZXh0U3RhdGUuYmFja2dyb3VuZFN0cm9rZSA9IHRleHRTdHlsZS5nZXRCYWNrZ3JvdW5kU3Ryb2tlKCk7XG4gICAgICB0ZXh0U3RhdGUucGFkZGluZyA9IHRleHRTdHlsZS5nZXRQYWRkaW5nKCkgfHwgZGVmYXVsdFBhZGRpbmc7XG4gICAgICB0ZXh0U3RhdGUuc2NhbGUgPSB0ZXh0U2NhbGUgPT09IHVuZGVmaW5lZCA/IFsxLCAxXSA6IHRleHRTY2FsZTtcbiAgICAgIHZhciB0ZXh0T2Zmc2V0WCA9IHRleHRTdHlsZS5nZXRPZmZzZXRYKCk7XG4gICAgICB2YXIgdGV4dE9mZnNldFkgPSB0ZXh0U3R5bGUuZ2V0T2Zmc2V0WSgpO1xuICAgICAgdmFyIHRleHRSb3RhdGVXaXRoVmlldyA9IHRleHRTdHlsZS5nZXRSb3RhdGVXaXRoVmlldygpO1xuICAgICAgdmFyIHRleHRSb3RhdGlvbiA9IHRleHRTdHlsZS5nZXRSb3RhdGlvbigpO1xuICAgICAgdGhpcy50ZXh0XyA9IHRleHRTdHlsZS5nZXRUZXh0KCkgfHwgJyc7XG4gICAgICB0aGlzLnRleHRPZmZzZXRYXyA9IHRleHRPZmZzZXRYID09PSB1bmRlZmluZWQgPyAwIDogdGV4dE9mZnNldFg7XG4gICAgICB0aGlzLnRleHRPZmZzZXRZXyA9IHRleHRPZmZzZXRZID09PSB1bmRlZmluZWQgPyAwIDogdGV4dE9mZnNldFk7XG4gICAgICB0aGlzLnRleHRSb3RhdGVXaXRoVmlld18gPSB0ZXh0Um90YXRlV2l0aFZpZXcgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogdGV4dFJvdGF0ZVdpdGhWaWV3O1xuICAgICAgdGhpcy50ZXh0Um90YXRpb25fID0gdGV4dFJvdGF0aW9uID09PSB1bmRlZmluZWQgPyAwIDogdGV4dFJvdGF0aW9uO1xuICAgICAgdGhpcy5zdHJva2VLZXlfID0gc3Ryb2tlU3RhdGUgPyAodHlwZW9mIHN0cm9rZVN0YXRlLnN0cm9rZVN0eWxlID09ICdzdHJpbmcnID8gc3Ryb2tlU3RhdGUuc3Ryb2tlU3R5bGUgOiBnZXRVaWQoc3Ryb2tlU3RhdGUuc3Ryb2tlU3R5bGUpKSArIHN0cm9rZVN0YXRlLmxpbmVDYXAgKyBzdHJva2VTdGF0ZS5saW5lRGFzaE9mZnNldCArICd8JyArIHN0cm9rZVN0YXRlLmxpbmVXaWR0aCArIHN0cm9rZVN0YXRlLmxpbmVKb2luICsgc3Ryb2tlU3RhdGUubWl0ZXJMaW1pdCArICdbJyArIHN0cm9rZVN0YXRlLmxpbmVEYXNoLmpvaW4oKSArICddJyA6ICcnO1xuICAgICAgdGhpcy50ZXh0S2V5XyA9IHRleHRTdGF0ZS5mb250ICsgdGV4dFN0YXRlLnNjYWxlICsgKHRleHRTdGF0ZS50ZXh0QWxpZ24gfHwgJz8nKSArICh0ZXh0U3RhdGUudGV4dEJhc2VsaW5lIHx8ICc/Jyk7XG4gICAgICB0aGlzLmZpbGxLZXlfID0gZmlsbFN0YXRlID8gdHlwZW9mIGZpbGxTdGF0ZS5maWxsU3R5bGUgPT0gJ3N0cmluZycgPyBmaWxsU3RhdGUuZmlsbFN0eWxlIDogJ3wnICsgZ2V0VWlkKGZpbGxTdGF0ZS5maWxsU3R5bGUpIDogJyc7XG4gICAgfVxuXG4gICAgdGhpcy5kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0XyA9IG9wdF9zaGFyZWREYXRhO1xuICB9O1xuXG4gIHJldHVybiBDYW52YXNUZXh0QnVpbGRlcjtcbn0oQ2FudmFzQnVpbGRlcik7XG5cbmV4cG9ydCBkZWZhdWx0IENhbnZhc1RleHRCdWlsZGVyOyIsIi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cFxuICovXG5pbXBvcnQgQnVpbGRlciBmcm9tICcuL0J1aWxkZXIuanMnO1xuaW1wb3J0IEltYWdlQnVpbGRlciBmcm9tICcuL0ltYWdlQnVpbGRlci5qcyc7XG5pbXBvcnQgTGluZVN0cmluZ0J1aWxkZXIgZnJvbSAnLi9MaW5lU3RyaW5nQnVpbGRlci5qcyc7XG5pbXBvcnQgUG9seWdvbkJ1aWxkZXIgZnJvbSAnLi9Qb2x5Z29uQnVpbGRlci5qcyc7XG5pbXBvcnQgVGV4dEJ1aWxkZXIgZnJvbSAnLi9UZXh0QnVpbGRlci5qcyc7XG4vKipcbiAqIEB0eXBlIHtPYmplY3Q8aW1wb3J0KFwiLi9CdWlsZGVyVHlwZVwiKS5kZWZhdWx0LCB0eXBlb2YgQnVpbGRlcj59XG4gKi9cblxudmFyIEJBVENIX0NPTlNUUlVDVE9SUyA9IHtcbiAgJ0NpcmNsZSc6IFBvbHlnb25CdWlsZGVyLFxuICAnRGVmYXVsdCc6IEJ1aWxkZXIsXG4gICdJbWFnZSc6IEltYWdlQnVpbGRlcixcbiAgJ0xpbmVTdHJpbmcnOiBMaW5lU3RyaW5nQnVpbGRlcixcbiAgJ1BvbHlnb24nOiBQb2x5Z29uQnVpbGRlcixcbiAgJ1RleHQnOiBUZXh0QnVpbGRlclxufTtcblxudmFyIEJ1aWxkZXJHcm91cCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdG9sZXJhbmNlIFRvbGVyYW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBtYXhFeHRlbnQgTWF4IGV4dGVudC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqL1xuICBmdW5jdGlvbiBCdWlsZGVyR3JvdXAodG9sZXJhbmNlLCBtYXhFeHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8pIHtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy50b2xlcmFuY2VfID0gdG9sZXJhbmNlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG5cbiAgICB0aGlzLm1heEV4dGVudF8gPSBtYXhFeHRlbnQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5waXhlbFJhdGlvXyA9IHBpeGVsUmF0aW87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5yZXNvbHV0aW9uXyA9IHJlc29sdXRpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsICFPYmplY3Q8aW1wb3J0KFwiLi9CdWlsZGVyVHlwZVwiKS5kZWZhdWx0LCBCdWlsZGVyPj59XG4gICAgICovXG5cbiAgICB0aGlzLmJ1aWxkZXJzQnlaSW5kZXhfID0ge307XG4gIH1cbiAgLyoqXG4gICAqIEByZXR1cm4geyFPYmplY3Q8c3RyaW5nLCAhT2JqZWN0PGltcG9ydChcIi4vQnVpbGRlclR5cGVcIikuZGVmYXVsdCwgaW1wb3J0KFwiLi9CdWlsZGVyLmpzXCIpLlNlcmlhbGl6YWJsZUluc3RydWN0aW9ucz4+fSBUaGUgc2VyaWFsaXphYmxlIGluc3RydWN0aW9uc1xuICAgKi9cblxuXG4gIEJ1aWxkZXJHcm91cC5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBidWlsZGVySW5zdHJ1Y3Rpb25zID0ge307XG5cbiAgICBmb3IgKHZhciB6S2V5IGluIHRoaXMuYnVpbGRlcnNCeVpJbmRleF8pIHtcbiAgICAgIGJ1aWxkZXJJbnN0cnVjdGlvbnNbektleV0gPSBidWlsZGVySW5zdHJ1Y3Rpb25zW3pLZXldIHx8IHt9O1xuICAgICAgdmFyIGJ1aWxkZXJzID0gdGhpcy5idWlsZGVyc0J5WkluZGV4X1t6S2V5XTtcblxuICAgICAgZm9yICh2YXIgYnVpbGRlcktleSBpbiBidWlsZGVycykge1xuICAgICAgICB2YXIgYnVpbGRlckluc3RydWN0aW9uID0gYnVpbGRlcnNbYnVpbGRlcktleV0uZmluaXNoKCk7XG4gICAgICAgIGJ1aWxkZXJJbnN0cnVjdGlvbnNbektleV1bYnVpbGRlcktleV0gPSBidWlsZGVySW5zdHJ1Y3Rpb247XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1aWxkZXJJbnN0cnVjdGlvbnM7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHpJbmRleCBaIGluZGV4LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vQnVpbGRlclR5cGUuanNcIikuZGVmYXVsdH0gYnVpbGRlclR5cGUgUmVwbGF5IHR5cGUuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL1ZlY3RvckNvbnRleHQuanNcIikuZGVmYXVsdH0gUmVwbGF5LlxuICAgKi9cblxuXG4gIEJ1aWxkZXJHcm91cC5wcm90b3R5cGUuZ2V0QnVpbGRlciA9IGZ1bmN0aW9uICh6SW5kZXgsIGJ1aWxkZXJUeXBlKSB7XG4gICAgdmFyIHpJbmRleEtleSA9IHpJbmRleCAhPT0gdW5kZWZpbmVkID8gekluZGV4LnRvU3RyaW5nKCkgOiAnMCc7XG4gICAgdmFyIHJlcGxheXMgPSB0aGlzLmJ1aWxkZXJzQnlaSW5kZXhfW3pJbmRleEtleV07XG5cbiAgICBpZiAocmVwbGF5cyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXBsYXlzID0ge307XG4gICAgICB0aGlzLmJ1aWxkZXJzQnlaSW5kZXhfW3pJbmRleEtleV0gPSByZXBsYXlzO1xuICAgIH1cblxuICAgIHZhciByZXBsYXkgPSByZXBsYXlzW2J1aWxkZXJUeXBlXTtcblxuICAgIGlmIChyZXBsYXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIENvbnN0cnVjdG9yID0gQkFUQ0hfQ09OU1RSVUNUT1JTW2J1aWxkZXJUeXBlXTtcbiAgICAgIHJlcGxheSA9IG5ldyBDb25zdHJ1Y3Rvcih0aGlzLnRvbGVyYW5jZV8sIHRoaXMubWF4RXh0ZW50XywgdGhpcy5yZXNvbHV0aW9uXywgdGhpcy5waXhlbFJhdGlvXyk7XG4gICAgICByZXBsYXlzW2J1aWxkZXJUeXBlXSA9IHJlcGxheTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVwbGF5O1xuICB9O1xuXG4gIHJldHVybiBCdWlsZGVyR3JvdXA7XG59KCk7XG5cbmV4cG9ydCBkZWZhdWx0IEJ1aWxkZXJHcm91cDsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlcmVyL0xheWVyXG4gKi9cblxuXG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IEltYWdlU3RhdGUgZnJvbSAnLi4vSW1hZ2VTdGF0ZS5qcyc7XG5pbXBvcnQgT2JzZXJ2YWJsZSBmcm9tICcuLi9PYnNlcnZhYmxlLmpzJztcbmltcG9ydCBTb3VyY2VTdGF0ZSBmcm9tICcuLi9zb3VyY2UvU3RhdGUuanMnO1xuaW1wb3J0IHsgYWJzdHJhY3QgfSBmcm9tICcuLi91dGlsLmpzJztcbi8qKlxuICogQHRlbXBsYXRlIHtpbXBvcnQoXCIuLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0fSBMYXllclR5cGVcbiAqL1xuXG52YXIgTGF5ZXJSZW5kZXJlciA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhMYXllclJlbmRlcmVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtMYXllclR5cGV9IGxheWVyIExheWVyLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIExheWVyUmVuZGVyZXIobGF5ZXIpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKiBAcHJpdmF0ZSAqL1xuXG5cbiAgICBfdGhpcy5ib3VuZEhhbmRsZUltYWdlQ2hhbmdlXyA9IF90aGlzLmhhbmRsZUltYWdlQ2hhbmdlXy5iaW5kKF90aGlzKTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge0xheWVyVHlwZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmxheWVyXyA9IGxheWVyO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0V4ZWN1dG9yR3JvdXBcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXAgPSBudWxsO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQXN5bmNocm9ub3VzIGxheWVyIGxldmVsIGhpdCBkZXRlY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PGltcG9ydChcIi4uL0ZlYXR1cmVcIikuZGVmYXVsdD4+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aFxuICAgKiBhbiBhcnJheSBvZiBmZWF0dXJlcy5cbiAgICovXG5cblxuICBMYXllclJlbmRlcmVyLnByb3RvdHlwZS5nZXRGZWF0dXJlcyA9IGZ1bmN0aW9uIChwaXhlbCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgcmVuZGVyIHNob3VsZCBiZSBjYWxsZWQuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBMYXllciBpcyByZWFkeSB0byBiZSByZW5kZXJlZC5cbiAgICovXG5cblxuICBMYXllclJlbmRlcmVyLnByb3RvdHlwZS5wcmVwYXJlRnJhbWUgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogUmVuZGVyIHRoZSBsYXllci5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRhcmdldCBUYXJnZXQgdGhhdCBtYXkgYmUgdXNlZCB0byByZW5kZXIgY29udGVudCB0by5cbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9IFRoZSByZW5kZXJlZCBlbGVtZW50LlxuICAgKi9cblxuXG4gIExheWVyUmVuZGVyZXIucHJvdG90eXBlLnJlbmRlckZyYW1lID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUsIHRhcmdldCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3Q8bnVtYmVyLCBPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLmRlZmF1bHQ+Pn0gdGlsZXMgTG9va3VwIG9mIGxvYWRlZCB0aWxlcyBieSB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge251bWJlcn0gem9vbSBab29tIGxldmVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1RpbGUuanNcIikuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufHZvaWR9IElmIGBmYWxzZWAsIHRoZSB0aWxlIHdpbGwgbm90IGJlIGNvbnNpZGVyZWQgbG9hZGVkLlxuICAgKi9cblxuXG4gIExheWVyUmVuZGVyZXIucHJvdG90eXBlLmxvYWRlZFRpbGVDYWxsYmFjayA9IGZ1bmN0aW9uICh0aWxlcywgem9vbSwgdGlsZSkge1xuICAgIGlmICghdGlsZXNbem9vbV0pIHtcbiAgICAgIHRpbGVzW3pvb21dID0ge307XG4gICAgfVxuXG4gICAgdGlsZXNbem9vbV1bdGlsZS50aWxlQ29vcmQudG9TdHJpbmcoKV0gPSB0aWxlO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBmdW5jdGlvbiB0aGF0IGFkZHMgbG9hZGVkIHRpbGVzIHRvIHRoZSB0aWxlIGxvb2t1cC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zb3VyY2UvVGlsZS5qc1wiKS5kZWZhdWx0fSBzb3VyY2UgVGlsZSBzb3VyY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbiBvZiB0aGUgdGlsZXMuXG4gICAqIEBwYXJhbSB7T2JqZWN0PG51bWJlciwgT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0Pj59IHRpbGVzIExvb2t1cCBvZiBsb2FkZWQgdGlsZXMgYnkgem9vbSBsZXZlbC5cbiAgICogQHJldHVybiB7ZnVuY3Rpb24obnVtYmVyLCBpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdCk6Ym9vbGVhbn0gQSBmdW5jdGlvbiB0aGF0IGNhbiBiZVxuICAgKiAgICAgY2FsbGVkIHdpdGggYSB6b29tIGxldmVsIGFuZCBhIHRpbGUgcmFuZ2UgdG8gYWRkIGxvYWRlZCB0aWxlcyB0byB0aGUgbG9va3VwLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuY3JlYXRlTG9hZGVkVGlsZUZpbmRlciA9IGZ1bmN0aW9uIChzb3VyY2UsIHByb2plY3Rpb24sIHRpbGVzKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKlxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHpvb20gWm9vbSBsZXZlbC5cbiAgICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vVGlsZVJhbmdlLmpzXCIpLmRlZmF1bHR9IHRpbGVSYW5nZSBUaWxlIHJhbmdlLlxuICAgICAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHRpbGUgcmFuZ2UgaXMgZnVsbHkgbG9hZGVkLlxuICAgICAgICogQHRoaXMge0xheWVyUmVuZGVyZXJ9XG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uICh6b29tLCB0aWxlUmFuZ2UpIHtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gdGhpcy5sb2FkZWRUaWxlQ2FsbGJhY2suYmluZCh0aGlzLCB0aWxlcywgem9vbSk7XG4gICAgICAgIHJldHVybiBzb3VyY2UuZm9yRWFjaExvYWRlZFRpbGUocHJvamVjdGlvbiwgem9vbSwgdGlsZVJhbmdlLCBjYWxsYmFjayk7XG4gICAgICB9LmJpbmQodGhpcylcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoaXRUb2xlcmFuY2UgSGl0IHRvbGVyYW5jZSBpbiBwaXhlbHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi92ZWN0b3IuanNcIikuRmVhdHVyZUNhbGxiYWNrPFQ+fSBjYWxsYmFjayBGZWF0dXJlIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vTWFwLmpzXCIpLkhpdE1hdGNoPFQ+Pn0gbWF0Y2hlcyBUaGUgaGl0IGRldGVjdGVkIG1hdGNoZXMgd2l0aCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqL1xuXG5cbiAgTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGUgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZSwgZnJhbWVTdGF0ZSwgaGl0VG9sZXJhbmNlLCBjYWxsYmFjaywgbWF0Y2hlcykge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWVTdGF0ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGhpdFRvbGVyYW5jZSBIaXQgdG9sZXJhbmNlIGluIHBpeGVscy5cbiAgICogQHJldHVybiB7VWludDhDbGFtcGVkQXJyYXl8VWludDhBcnJheX0gVGhlIHJlc3VsdC4gIElmIHRoZXJlIGlzIG5vIGRhdGEgYXQgdGhlIHBpeGVsXG4gICAqICAgIGxvY2F0aW9uLCBudWxsIHdpbGwgYmUgcmV0dXJuZWQuICBJZiB0aGVyZSBpcyBkYXRhLCBidXQgcGl4ZWwgdmFsdWVzIGNhbm5vdCBiZVxuICAgKiAgICByZXR1cm5lZCwgYW5kIGVtcHR5IGFycmF5IHdpbGwgYmUgcmV0dXJuZWQuXG4gICAqL1xuXG5cbiAgTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0RGF0YUF0UGl4ZWwgPSBmdW5jdGlvbiAocGl4ZWwsIGZyYW1lU3RhdGUsIGhpdFRvbGVyYW5jZSkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7TGF5ZXJUeXBlfSBMYXllci5cbiAgICovXG5cblxuICBMYXllclJlbmRlcmVyLnByb3RvdHlwZS5nZXRMYXllciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5sYXllcl87XG4gIH07XG4gIC8qKlxuICAgKiBQZXJmb3JtIGFjdGlvbiBuZWNlc3NhcnkgdG8gZ2V0IHRoZSBsYXllciByZW5kZXJlZCBhZnRlciBuZXcgZm9udHMgaGF2ZSBsb2FkZWRcbiAgICogQGFic3RyYWN0XG4gICAqL1xuXG5cbiAgTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuaGFuZGxlRm9udHNDaGFuZ2VkID0gZnVuY3Rpb24gKCkge307XG4gIC8qKlxuICAgKiBIYW5kbGUgY2hhbmdlcyBpbiBpbWFnZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9ldmVudHMvRXZlbnQuanNcIikuZGVmYXVsdH0gZXZlbnQgSW1hZ2UgY2hhbmdlIGV2ZW50LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIExheWVyUmVuZGVyZXIucHJvdG90eXBlLmhhbmRsZUltYWdlQ2hhbmdlXyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHZhciBpbWFnZSA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9JbWFnZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIGV2ZW50LnRhcmdldDtcblxuICAgIGlmIChpbWFnZS5nZXRTdGF0ZSgpID09PSBJbWFnZVN0YXRlLkxPQURFRCkge1xuICAgICAgdGhpcy5yZW5kZXJJZlJlYWR5QW5kVmlzaWJsZSgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIExvYWQgdGhlIGltYWdlIGlmIG5vdCBhbHJlYWR5IGxvYWRlZCwgYW5kIHJlZ2lzdGVyIHRoZSBpbWFnZSBjaGFuZ2VcbiAgICogbGlzdGVuZXIgaWYgbmVlZGVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ltYWdlQmFzZS5qc1wiKS5kZWZhdWx0fSBpbWFnZSBJbWFnZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBpbWFnZSBpcyBhbHJlYWR5IGxvYWRlZCwgYGZhbHNlYCBvdGhlcndpc2UuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBMYXllclJlbmRlcmVyLnByb3RvdHlwZS5sb2FkSW1hZ2UgPSBmdW5jdGlvbiAoaW1hZ2UpIHtcbiAgICB2YXIgaW1hZ2VTdGF0ZSA9IGltYWdlLmdldFN0YXRlKCk7XG5cbiAgICBpZiAoaW1hZ2VTdGF0ZSAhPSBJbWFnZVN0YXRlLkxPQURFRCAmJiBpbWFnZVN0YXRlICE9IEltYWdlU3RhdGUuRVJST1IpIHtcbiAgICAgIGltYWdlLmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5ib3VuZEhhbmRsZUltYWdlQ2hhbmdlXyk7XG4gICAgfVxuXG4gICAgaWYgKGltYWdlU3RhdGUgPT0gSW1hZ2VTdGF0ZS5JRExFKSB7XG4gICAgICBpbWFnZS5sb2FkKCk7XG4gICAgICBpbWFnZVN0YXRlID0gaW1hZ2UuZ2V0U3RhdGUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaW1hZ2VTdGF0ZSA9PSBJbWFnZVN0YXRlLkxPQURFRDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBMYXllclJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJJZlJlYWR5QW5kVmlzaWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGF5ZXIgPSB0aGlzLmdldExheWVyKCk7XG5cbiAgICBpZiAobGF5ZXIuZ2V0VmlzaWJsZSgpICYmIGxheWVyLmdldFNvdXJjZVN0YXRlKCkgPT0gU291cmNlU3RhdGUuUkVBRFkpIHtcbiAgICAgIGxheWVyLmNoYW5nZWQoKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIExheWVyUmVuZGVyZXI7XG59KE9ic2VydmFibGUpO1xuXG5leHBvcnQgZGVmYXVsdCBMYXllclJlbmRlcmVyOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyZXIvY2FudmFzL0xheWVyXG4gKi9cblxuXG5pbXBvcnQgTGF5ZXJSZW5kZXJlciBmcm9tICcuLi9MYXllci5qcyc7XG5pbXBvcnQgUmVuZGVyRXZlbnQgZnJvbSAnLi4vLi4vcmVuZGVyL0V2ZW50LmpzJztcbmltcG9ydCBSZW5kZXJFdmVudFR5cGUgZnJvbSAnLi4vLi4vcmVuZGVyL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgeyBhcHBseSBhcyBhcHBseVRyYW5zZm9ybSwgY29tcG9zZSBhcyBjb21wb3NlVHJhbnNmb3JtLCBjcmVhdGUgYXMgY3JlYXRlVHJhbnNmb3JtIH0gZnJvbSAnLi4vLi4vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB7IGNvbnRhaW5zQ29vcmRpbmF0ZSwgZ2V0Qm90dG9tTGVmdCwgZ2V0Qm90dG9tUmlnaHQsIGdldFRvcExlZnQsIGdldFRvcFJpZ2h0IH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCB9IGZyb20gJy4uLy4uL2RvbS5qcyc7XG5pbXBvcnQgeyByb3RhdGVBdE9mZnNldCB9IGZyb20gJy4uLy4uL3JlbmRlci9jYW52YXMuanMnO1xuLyoqXG4gKiBAYWJzdHJhY3RcbiAqIEB0ZW1wbGF0ZSB7aW1wb3J0KFwiLi4vLi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gTGF5ZXJUeXBlXG4gKi9cblxudmFyIENhbnZhc0xheWVyUmVuZGVyZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ2FudmFzTGF5ZXJSZW5kZXJlciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7TGF5ZXJUeXBlfSBsYXllciBMYXllci5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDYW52YXNMYXllclJlbmRlcmVyKGxheWVyKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgbGF5ZXIpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtIVE1MRWxlbWVudH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuY29udGFpbmVyID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkUmVzb2x1dGlvbjtcbiAgICAvKipcbiAgICAgKiBBIHRlbXBvcmFyeSB0cmFuc2Zvcm0uICBUaGUgdmFsdWVzIGluIHRoaXMgdHJhbnNmb3JtIHNob3VsZCBvbmx5IGJlIHVzZWQgaW4gYVxuICAgICAqIGZ1bmN0aW9uIHRoYXQgc2V0cyB0aGUgdmFsdWVzLlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRlbXBUcmFuc2Zvcm0gPSBjcmVhdGVUcmFuc2Zvcm0oKTtcbiAgICAvKipcbiAgICAgKiBUaGUgdHJhbnNmb3JtIGZvciByZW5kZXJlZCBwaXhlbHMgdG8gdmlld3BvcnQgQ1NTIHBpeGVscy4gIFRoaXMgdHJhbnNmb3JtIG11c3RcbiAgICAgKiBiZSBzZXQgd2hlbiByZW5kZXJpbmcgYSBmcmFtZSBhbmQgbWF5IGJlIHVzZWQgYnkgb3RoZXIgZnVuY3Rpb25zIGFmdGVyIHJlbmRlcmluZy5cbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gICAgICovXG5cbiAgICBfdGhpcy5waXhlbFRyYW5zZm9ybSA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xuICAgIC8qKlxuICAgICAqIFRoZSB0cmFuc2Zvcm0gZm9yIHZpZXdwb3J0IENTUyBwaXhlbHMgdG8gcmVuZGVyZWQgcGl4ZWxzLiAgVGhpcyB0cmFuc2Zvcm0gbXVzdFxuICAgICAqIGJlIHNldCB3aGVuIHJlbmRlcmluZyBhIGZyYW1lIGFuZCBtYXkgYmUgdXNlZCBieSBvdGhlciBmdW5jdGlvbnMgYWZ0ZXIgcmVuZGVyaW5nLlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX1cbiAgICAgKi9cblxuICAgIF90aGlzLmludmVyc2VQaXhlbFRyYW5zZm9ybSA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9XG4gICAgICovXG5cbiAgICBfdGhpcy5jb250ZXh0ID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbnRhaW5lclJldXNlZCA9IGZhbHNlO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogR2V0IGEgcmVuZGVyaW5nIGNvbnRhaW5lciBmcm9tIGFuIGV4aXN0aW5nIHRhcmdldCwgaWYgY29tcGF0aWJsZS5cbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gdGFyZ2V0IFBvdGVudGlhbCByZW5kZXIgdGFyZ2V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHJhbnNmb3JtIENTUyBUcmFuc2Zvcm0uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcGFjaXR5IE9wYWNpdHkuXG4gICAqL1xuXG5cbiAgQ2FudmFzTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUudXNlQ29udGFpbmVyID0gZnVuY3Rpb24gKHRhcmdldCwgdHJhbnNmb3JtLCBvcGFjaXR5KSB7XG4gICAgdmFyIGxheWVyQ2xhc3NOYW1lID0gdGhpcy5nZXRMYXllcigpLmdldENsYXNzTmFtZSgpO1xuICAgIHZhciBjb250YWluZXIsIGNvbnRleHQ7XG5cbiAgICBpZiAodGFyZ2V0ICYmIHRhcmdldC5zdHlsZS5vcGFjaXR5ID09PSAnJyAmJiB0YXJnZXQuY2xhc3NOYW1lID09PSBsYXllckNsYXNzTmFtZSkge1xuICAgICAgdmFyIGNhbnZhcyA9IHRhcmdldC5maXJzdEVsZW1lbnRDaGlsZDtcblxuICAgICAgaWYgKGNhbnZhcyBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50KSB7XG4gICAgICAgIGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCAmJiAoY29udGV4dC5jYW52YXMud2lkdGggPT09IDAgfHwgY29udGV4dC5jYW52YXMuc3R5bGUudHJhbnNmb3JtID09PSB0cmFuc2Zvcm0pKSB7XG4gICAgICAvLyBDb250YWluZXIgb2YgdGhlIHByZXZpb3VzIGxheWVyIHJlbmRlcmVyIGNhbiBiZSB1c2VkLlxuICAgICAgdGhpcy5jb250YWluZXIgPSB0YXJnZXQ7XG4gICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgdGhpcy5jb250YWluZXJSZXVzZWQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAodGhpcy5jb250YWluZXJSZXVzZWQpIHtcbiAgICAgIC8vIFByZXZpb3VzbHkgcmV1c2VkIGNvbnRhaW5lciBjYW5ub3QgYmUgdXNlZCBhbnkgbW9yZS5cbiAgICAgIHRoaXMuY29udGFpbmVyID0gbnVsbDtcbiAgICAgIHRoaXMuY29udGV4dCA9IG51bGw7XG4gICAgICB0aGlzLmNvbnRhaW5lclJldXNlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5jb250YWluZXIpIHtcbiAgICAgIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgY29udGFpbmVyLmNsYXNzTmFtZSA9IGxheWVyQ2xhc3NOYW1lO1xuICAgICAgdmFyIHN0eWxlID0gY29udGFpbmVyLnN0eWxlO1xuICAgICAgc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gICAgICBzdHlsZS5oZWlnaHQgPSAnMTAwJSc7XG4gICAgICBjb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKCk7XG4gICAgICB2YXIgY2FudmFzID0gY29udGV4dC5jYW52YXM7XG4gICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoY2FudmFzKTtcbiAgICAgIHN0eWxlID0gY2FudmFzLnN0eWxlO1xuICAgICAgc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgc3R5bGUubGVmdCA9ICcwJztcbiAgICAgIHN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9ICd0b3AgbGVmdCc7XG4gICAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgQ2xpcCBleHRlbnQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBDYW52YXNMYXllclJlbmRlcmVyLnByb3RvdHlwZS5jbGlwID0gZnVuY3Rpb24gKGNvbnRleHQsIGZyYW1lU3RhdGUsIGV4dGVudCkge1xuICAgIHZhciBwaXhlbFJhdGlvID0gZnJhbWVTdGF0ZS5waXhlbFJhdGlvO1xuICAgIHZhciBoYWxmV2lkdGggPSBmcmFtZVN0YXRlLnNpemVbMF0gKiBwaXhlbFJhdGlvIC8gMjtcbiAgICB2YXIgaGFsZkhlaWdodCA9IGZyYW1lU3RhdGUuc2l6ZVsxXSAqIHBpeGVsUmF0aW8gLyAyO1xuICAgIHZhciByb3RhdGlvbiA9IGZyYW1lU3RhdGUudmlld1N0YXRlLnJvdGF0aW9uO1xuICAgIHZhciB0b3BMZWZ0ID0gZ2V0VG9wTGVmdChleHRlbnQpO1xuICAgIHZhciB0b3BSaWdodCA9IGdldFRvcFJpZ2h0KGV4dGVudCk7XG4gICAgdmFyIGJvdHRvbVJpZ2h0ID0gZ2V0Qm90dG9tUmlnaHQoZXh0ZW50KTtcbiAgICB2YXIgYm90dG9tTGVmdCA9IGdldEJvdHRvbUxlZnQoZXh0ZW50KTtcbiAgICBhcHBseVRyYW5zZm9ybShmcmFtZVN0YXRlLmNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtLCB0b3BMZWZ0KTtcbiAgICBhcHBseVRyYW5zZm9ybShmcmFtZVN0YXRlLmNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtLCB0b3BSaWdodCk7XG4gICAgYXBwbHlUcmFuc2Zvcm0oZnJhbWVTdGF0ZS5jb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybSwgYm90dG9tUmlnaHQpO1xuICAgIGFwcGx5VHJhbnNmb3JtKGZyYW1lU3RhdGUuY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm0sIGJvdHRvbUxlZnQpO1xuICAgIGNvbnRleHQuc2F2ZSgpO1xuICAgIHJvdGF0ZUF0T2Zmc2V0KGNvbnRleHQsIC1yb3RhdGlvbiwgaGFsZldpZHRoLCBoYWxmSGVpZ2h0KTtcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgIGNvbnRleHQubW92ZVRvKHRvcExlZnRbMF0gKiBwaXhlbFJhdGlvLCB0b3BMZWZ0WzFdICogcGl4ZWxSYXRpbyk7XG4gICAgY29udGV4dC5saW5lVG8odG9wUmlnaHRbMF0gKiBwaXhlbFJhdGlvLCB0b3BSaWdodFsxXSAqIHBpeGVsUmF0aW8pO1xuICAgIGNvbnRleHQubGluZVRvKGJvdHRvbVJpZ2h0WzBdICogcGl4ZWxSYXRpbywgYm90dG9tUmlnaHRbMV0gKiBwaXhlbFJhdGlvKTtcbiAgICBjb250ZXh0LmxpbmVUbyhib3R0b21MZWZ0WzBdICogcGl4ZWxSYXRpbywgYm90dG9tTGVmdFsxXSAqIHBpeGVsUmF0aW8pO1xuICAgIGNvbnRleHQuY2xpcCgpO1xuICAgIHJvdGF0ZUF0T2Zmc2V0KGNvbnRleHQsIHJvdGF0aW9uLCBoYWxmV2lkdGgsIGhhbGZIZWlnaHQpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgQ2xpcCBleHRlbnQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBDYW52YXNMYXllclJlbmRlcmVyLnByb3RvdHlwZS5jbGlwVW5yb3RhdGVkID0gZnVuY3Rpb24gKGNvbnRleHQsIGZyYW1lU3RhdGUsIGV4dGVudCkge1xuICAgIHZhciB0b3BMZWZ0ID0gZ2V0VG9wTGVmdChleHRlbnQpO1xuICAgIHZhciB0b3BSaWdodCA9IGdldFRvcFJpZ2h0KGV4dGVudCk7XG4gICAgdmFyIGJvdHRvbVJpZ2h0ID0gZ2V0Qm90dG9tUmlnaHQoZXh0ZW50KTtcbiAgICB2YXIgYm90dG9tTGVmdCA9IGdldEJvdHRvbUxlZnQoZXh0ZW50KTtcbiAgICBhcHBseVRyYW5zZm9ybShmcmFtZVN0YXRlLmNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtLCB0b3BMZWZ0KTtcbiAgICBhcHBseVRyYW5zZm9ybShmcmFtZVN0YXRlLmNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtLCB0b3BSaWdodCk7XG4gICAgYXBwbHlUcmFuc2Zvcm0oZnJhbWVTdGF0ZS5jb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybSwgYm90dG9tUmlnaHQpO1xuICAgIGFwcGx5VHJhbnNmb3JtKGZyYW1lU3RhdGUuY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm0sIGJvdHRvbUxlZnQpO1xuICAgIHZhciBpbnZlcnRlZCA9IHRoaXMuaW52ZXJzZVBpeGVsVHJhbnNmb3JtO1xuICAgIGFwcGx5VHJhbnNmb3JtKGludmVydGVkLCB0b3BMZWZ0KTtcbiAgICBhcHBseVRyYW5zZm9ybShpbnZlcnRlZCwgdG9wUmlnaHQpO1xuICAgIGFwcGx5VHJhbnNmb3JtKGludmVydGVkLCBib3R0b21SaWdodCk7XG4gICAgYXBwbHlUcmFuc2Zvcm0oaW52ZXJ0ZWQsIGJvdHRvbUxlZnQpO1xuICAgIGNvbnRleHQuc2F2ZSgpO1xuICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgY29udGV4dC5tb3ZlVG8oTWF0aC5yb3VuZCh0b3BMZWZ0WzBdKSwgTWF0aC5yb3VuZCh0b3BMZWZ0WzFdKSk7XG4gICAgY29udGV4dC5saW5lVG8oTWF0aC5yb3VuZCh0b3BSaWdodFswXSksIE1hdGgucm91bmQodG9wUmlnaHRbMV0pKTtcbiAgICBjb250ZXh0LmxpbmVUbyhNYXRoLnJvdW5kKGJvdHRvbVJpZ2h0WzBdKSwgTWF0aC5yb3VuZChib3R0b21SaWdodFsxXSkpO1xuICAgIGNvbnRleHQubGluZVRvKE1hdGgucm91bmQoYm90dG9tTGVmdFswXSksIE1hdGgucm91bmQoYm90dG9tTGVmdFsxXSkpO1xuICAgIGNvbnRleHQuY2xpcCgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9yZW5kZXIvRXZlbnRUeXBlLmpzXCIpLmRlZmF1bHR9IHR5cGUgRXZlbnQgdHlwZS5cbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBDYW52YXNMYXllclJlbmRlcmVyLnByb3RvdHlwZS5kaXNwYXRjaFJlbmRlckV2ZW50XyA9IGZ1bmN0aW9uICh0eXBlLCBjb250ZXh0LCBmcmFtZVN0YXRlKSB7XG4gICAgdmFyIGxheWVyID0gdGhpcy5nZXRMYXllcigpO1xuXG4gICAgaWYgKGxheWVyLmhhc0xpc3RlbmVyKHR5cGUpKSB7XG4gICAgICB2YXIgZXZlbnRfMSA9IG5ldyBSZW5kZXJFdmVudCh0eXBlLCB0aGlzLmludmVyc2VQaXhlbFRyYW5zZm9ybSwgZnJhbWVTdGF0ZSwgY29udGV4dCk7XG4gICAgICBsYXllci5kaXNwYXRjaEV2ZW50KGV2ZW50XzEpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IENvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBDYW52YXNMYXllclJlbmRlcmVyLnByb3RvdHlwZS5wcmVSZW5kZXIgPSBmdW5jdGlvbiAoY29udGV4dCwgZnJhbWVTdGF0ZSkge1xuICAgIHRoaXMuZGlzcGF0Y2hSZW5kZXJFdmVudF8oUmVuZGVyRXZlbnRUeXBlLlBSRVJFTkRFUiwgY29udGV4dCwgZnJhbWVTdGF0ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgQ2FudmFzTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucG9zdFJlbmRlciA9IGZ1bmN0aW9uIChjb250ZXh0LCBmcmFtZVN0YXRlKSB7XG4gICAgdGhpcy5kaXNwYXRjaFJlbmRlckV2ZW50XyhSZW5kZXJFdmVudFR5cGUuUE9TVFJFTkRFUiwgY29udGV4dCwgZnJhbWVTdGF0ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgdHJhbnNmb3JtIGZvciByZW5kZXJpbmcgdG8gYW4gZWxlbWVudCB0aGF0IHdpbGwgYmUgcm90YXRlZCBhZnRlciByZW5kZXJpbmcuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjZW50ZXIgQ2VudGVyLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcm90YXRpb24gUm90YXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge251bWJlcn0gd2lkdGggV2lkdGggb2YgdGhlIHJlbmRlcmVkIGVsZW1lbnQgKGluIHBpeGVscykuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHQgSGVpZ2h0IG9mIHRoZSByZW5kZXJlZCBlbGVtZW50IChpbiBwaXhlbHMpLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0WCBPZmZzZXQgb24gdGhlIHgtYXhpcyBpbiB2aWV3IGNvb3JkaW5hdGVzLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEByZXR1cm4geyFpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfSBUcmFuc2Zvcm0uXG4gICAqL1xuXG5cbiAgQ2FudmFzTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0UmVuZGVyVHJhbnNmb3JtID0gZnVuY3Rpb24gKGNlbnRlciwgcmVzb2x1dGlvbiwgcm90YXRpb24sIHBpeGVsUmF0aW8sIHdpZHRoLCBoZWlnaHQsIG9mZnNldFgpIHtcbiAgICB2YXIgZHgxID0gd2lkdGggLyAyO1xuICAgIHZhciBkeTEgPSBoZWlnaHQgLyAyO1xuICAgIHZhciBzeCA9IHBpeGVsUmF0aW8gLyByZXNvbHV0aW9uO1xuICAgIHZhciBzeSA9IC1zeDtcbiAgICB2YXIgZHgyID0gLWNlbnRlclswXSArIG9mZnNldFg7XG4gICAgdmFyIGR5MiA9IC1jZW50ZXJbMV07XG4gICAgcmV0dXJuIGNvbXBvc2VUcmFuc2Zvcm0odGhpcy50ZW1wVHJhbnNmb3JtLCBkeDEsIGR5MSwgc3gsIHN5LCAtcm90YXRpb24sIGR4MiwgZHkyKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lU3RhdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoaXRUb2xlcmFuY2UgSGl0IHRvbGVyYW5jZSBpbiBwaXhlbHMuXG4gICAqIEByZXR1cm4ge1VpbnQ4Q2xhbXBlZEFycmF5fFVpbnQ4QXJyYXl9IFRoZSByZXN1bHQuICBJZiB0aGVyZSBpcyBubyBkYXRhIGF0IHRoZSBwaXhlbFxuICAgKiAgICBsb2NhdGlvbiwgbnVsbCB3aWxsIGJlIHJldHVybmVkLiAgSWYgdGhlcmUgaXMgZGF0YSwgYnV0IHBpeGVsIHZhbHVlcyBjYW5ub3QgYmVcbiAgICogICAgcmV0dXJuZWQsIGFuZCBlbXB0eSBhcnJheSB3aWxsIGJlIHJldHVybmVkLlxuICAgKi9cblxuXG4gIENhbnZhc0xheWVyUmVuZGVyZXIucHJvdG90eXBlLmdldERhdGFBdFBpeGVsID0gZnVuY3Rpb24gKHBpeGVsLCBmcmFtZVN0YXRlLCBoaXRUb2xlcmFuY2UpIHtcbiAgICB2YXIgcmVuZGVyUGl4ZWwgPSBhcHBseVRyYW5zZm9ybSh0aGlzLmludmVyc2VQaXhlbFRyYW5zZm9ybSwgcGl4ZWwuc2xpY2UoKSk7XG4gICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgdmFyIGxheWVyID0gdGhpcy5nZXRMYXllcigpO1xuICAgIHZhciBsYXllckV4dGVudCA9IGxheWVyLmdldEV4dGVudCgpO1xuXG4gICAgaWYgKGxheWVyRXh0ZW50KSB7XG4gICAgICB2YXIgcmVuZGVyQ29vcmRpbmF0ZSA9IGFwcGx5VHJhbnNmb3JtKGZyYW1lU3RhdGUucGl4ZWxUb0Nvb3JkaW5hdGVUcmFuc2Zvcm0sIHBpeGVsLnNsaWNlKCkpO1xuICAgICAgLyoqIGdldCBvbmx5IGRhdGEgaW5zaWRlIG9mIHRoZSBsYXllciBleHRlbnQgKi9cblxuICAgICAgaWYgKCFjb250YWluc0Nvb3JkaW5hdGUobGF5ZXJFeHRlbnQsIHJlbmRlckNvb3JkaW5hdGUpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkYXRhO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciB4ID0gTWF0aC5yb3VuZChyZW5kZXJQaXhlbFswXSk7XG4gICAgICB2YXIgeSA9IE1hdGgucm91bmQocmVuZGVyUGl4ZWxbMV0pO1xuICAgICAgdmFyIG5ld0NhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgdmFyIG5ld0NvbnRleHQgPSBuZXdDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgIG5ld0NhbnZhcy53aWR0aCA9IDE7XG4gICAgICBuZXdDYW52YXMuaGVpZ2h0ID0gMTtcbiAgICAgIG5ld0NvbnRleHQuY2xlYXJSZWN0KDAsIDAsIDEsIDEpO1xuICAgICAgbmV3Q29udGV4dC5kcmF3SW1hZ2UoY29udGV4dC5jYW52YXMsIHgsIHksIDEsIDEsIDAsIDAsIDEsIDEpO1xuICAgICAgZGF0YSA9IG5ld0NvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIDEsIDEpLmRhdGE7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyLm5hbWUgPT09ICdTZWN1cml0eUVycm9yJykge1xuICAgICAgICAvLyB0YWludGVkIGNhbnZhcywgd2UgYXNzdW1lIHRoZXJlIGlzIGRhdGEgYXQgdGhlIGdpdmVuIHBpeGVsIChhbHRob3VnaCB0aGVyZSBtaWdodCBub3QgYmUpXG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheSgpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICBpZiAoZGF0YVszXSA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH07XG5cbiAgcmV0dXJuIENhbnZhc0xheWVyUmVuZGVyZXI7XG59KExheWVyUmVuZGVyZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBDYW52YXNMYXllclJlbmRlcmVyOyIsIi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXIvY2FudmFzL0J1aWxkZXJUeXBlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIENJUkNMRTogJ0NpcmNsZScsXG4gIERFRkFVTFQ6ICdEZWZhdWx0JyxcbiAgSU1BR0U6ICdJbWFnZScsXG4gIExJTkVfU1RSSU5HOiAnTGluZVN0cmluZycsXG4gIFBPTFlHT046ICdQb2x5Z29uJyxcbiAgVEVYVDogJ1RleHQnXG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL2ZsYXQvdGV4dHBhdGhcbiAqL1xuaW1wb3J0IHsgbGVycCB9IGZyb20gJy4uLy4uL21hdGguanMnO1xuaW1wb3J0IHsgcm90YXRlIH0gZnJvbSAnLi90cmFuc2Zvcm0uanMnO1xuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBQYXRoIHRvIHB1dCB0ZXh0IG9uLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBTdGFydCBvZmZzZXQgb2YgdGhlIGBmbGF0Q29vcmRpbmF0ZXNgLlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQgb2Zmc2V0IG9mIHRoZSBgZmxhdENvb3JkaW5hdGVzYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGV4dCB0byBwbGFjZSBvbiB0aGUgcGF0aC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydE0gbSBhbG9uZyB0aGUgcGF0aCB3aGVyZSB0aGUgdGV4dCBzdGFydHMuXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4QW5nbGUgTWF4IGFuZ2xlIGJldHdlZW4gYWRqYWNlbnQgY2hhcnMgaW4gcmFkaWFucy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzY2FsZSBUaGUgcHJvZHVjdCBvZiB0aGUgdGV4dCBzY2FsZSBhbmQgdGhlIGRldmljZSBwaXhlbCByYXRpby5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oc3RyaW5nLCBzdHJpbmcsIE9iamVjdDxzdHJpbmcsIG51bWJlcj4pOm51bWJlcn0gbWVhc3VyZUFuZENhY2hlVGV4dFdpZHRoIE1lYXN1cmUgYW5kIGNhY2hlIHRleHQgd2lkdGguXG4gKiBAcGFyYW0ge3N0cmluZ30gZm9udCBUaGUgZm9udC5cbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgbnVtYmVyPn0gY2FjaGUgQSBjYWNoZSBvZiBtZWFzdXJlZCB3aWR0aHMuXG4gKiBAcGFyYW0ge251bWJlcn0gcm90YXRpb24gUm90YXRpb24gdG8gYXBwbHkgdG8gdGhlIGZsYXRDb29yZGluYXRlcyB0byBkZXRlcm1pbmUgd2hldGhlciB0ZXh0IG5lZWRzIHRvIGJlIHJldmVyc2VkLlxuICogQHJldHVybiB7QXJyYXk8QXJyYXk8Kj4+fSBUaGUgcmVzdWx0IGFycmF5IChvciBudWxsIGlmIGBtYXhBbmdsZWAgd2FzXG4gKiBleGNlZWRlZCkuIEVudHJpZXMgb2YgdGhlIGFycmF5IGFyZSB4LCB5LCBhbmNob3JYLCBhbmdsZSwgY2h1bmsuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRyYXdUZXh0T25QYXRoKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgdGV4dCwgc3RhcnRNLCBtYXhBbmdsZSwgc2NhbGUsIG1lYXN1cmVBbmRDYWNoZVRleHRXaWR0aCwgZm9udCwgY2FjaGUsIHJvdGF0aW9uKSB7XG4gIHZhciB4MiA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXRdO1xuICB2YXIgeTIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gIHZhciB4MSA9IDA7XG4gIHZhciB5MSA9IDA7XG4gIHZhciBzZWdtZW50TGVuZ3RoID0gMDtcbiAgdmFyIHNlZ21lbnRNID0gMDtcblxuICBmdW5jdGlvbiBhZHZhbmNlKCkge1xuICAgIHgxID0geDI7XG4gICAgeTEgPSB5MjtcbiAgICBvZmZzZXQgKz0gc3RyaWRlO1xuICAgIHgyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldF07XG4gICAgeTIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gICAgc2VnbWVudE0gKz0gc2VnbWVudExlbmd0aDtcbiAgICBzZWdtZW50TGVuZ3RoID0gTWF0aC5zcXJ0KCh4MiAtIHgxKSAqICh4MiAtIHgxKSArICh5MiAtIHkxKSAqICh5MiAtIHkxKSk7XG4gIH1cblxuICBkbyB7XG4gICAgYWR2YW5jZSgpO1xuICB9IHdoaWxlIChvZmZzZXQgPCBlbmQgLSBzdHJpZGUgJiYgc2VnbWVudE0gKyBzZWdtZW50TGVuZ3RoIDwgc3RhcnRNKTtcblxuICB2YXIgaW50ZXJwb2xhdGUgPSAoc3RhcnRNIC0gc2VnbWVudE0pIC8gc2VnbWVudExlbmd0aDtcbiAgdmFyIGJlZ2luWCA9IGxlcnAoeDEsIHgyLCBpbnRlcnBvbGF0ZSk7XG4gIHZhciBiZWdpblkgPSBsZXJwKHkxLCB5MiwgaW50ZXJwb2xhdGUpO1xuICB2YXIgc3RhcnRPZmZzZXQgPSBvZmZzZXQgLSBzdHJpZGU7XG4gIHZhciBzdGFydExlbmd0aCA9IHNlZ21lbnRNO1xuICB2YXIgZW5kTSA9IHN0YXJ0TSArIHNjYWxlICogbWVhc3VyZUFuZENhY2hlVGV4dFdpZHRoKGZvbnQsIHRleHQsIGNhY2hlKTtcblxuICB3aGlsZSAob2Zmc2V0IDwgZW5kIC0gc3RyaWRlICYmIHNlZ21lbnRNICsgc2VnbWVudExlbmd0aCA8IGVuZE0pIHtcbiAgICBhZHZhbmNlKCk7XG4gIH1cblxuICBpbnRlcnBvbGF0ZSA9IChlbmRNIC0gc2VnbWVudE0pIC8gc2VnbWVudExlbmd0aDtcbiAgdmFyIGVuZFggPSBsZXJwKHgxLCB4MiwgaW50ZXJwb2xhdGUpO1xuICB2YXIgZW5kWSA9IGxlcnAoeTEsIHkyLCBpbnRlcnBvbGF0ZSk7IC8vIEtlZXAgdGV4dCB1cHJpZ2h0XG5cbiAgdmFyIHJldmVyc2U7XG5cbiAgaWYgKHJvdGF0aW9uKSB7XG4gICAgdmFyIGZsYXQgPSBbYmVnaW5YLCBiZWdpblksIGVuZFgsIGVuZFldO1xuICAgIHJvdGF0ZShmbGF0LCAwLCA0LCAyLCByb3RhdGlvbiwgZmxhdCwgZmxhdCk7XG4gICAgcmV2ZXJzZSA9IGZsYXRbMF0gPiBmbGF0WzJdO1xuICB9IGVsc2Uge1xuICAgIHJldmVyc2UgPSBiZWdpblggPiBlbmRYO1xuICB9XG5cbiAgdmFyIFBJID0gTWF0aC5QSTtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIgc2luZ2xlU2VnbWVudCA9IHN0YXJ0T2Zmc2V0ICsgc3RyaWRlID09PSBvZmZzZXQ7XG4gIG9mZnNldCA9IHN0YXJ0T2Zmc2V0O1xuICBzZWdtZW50TGVuZ3RoID0gMDtcbiAgc2VnbWVudE0gPSBzdGFydExlbmd0aDtcbiAgeDIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgeTIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07IC8vIEFsbCBvbiB0aGUgc2FtZSBzZWdtZW50XG5cbiAgaWYgKHNpbmdsZVNlZ21lbnQpIHtcbiAgICBhZHZhbmNlKCk7XG4gICAgdmFyIHByZXZpb3VzQW5nbGVfMSA9IE1hdGguYXRhbjIoeTIgLSB5MSwgeDIgLSB4MSk7XG5cbiAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgcHJldmlvdXNBbmdsZV8xICs9IHByZXZpb3VzQW5nbGVfMSA+IDAgPyAtUEkgOiBQSTtcbiAgICB9XG5cbiAgICB2YXIgeCA9IChlbmRYICsgYmVnaW5YKSAvIDI7XG4gICAgdmFyIHkgPSAoZW5kWSArIGJlZ2luWSkgLyAyO1xuICAgIHJlc3VsdFswXSA9IFt4LCB5LCAoZW5kTSAtIHN0YXJ0TSkgLyAyLCBwcmV2aW91c0FuZ2xlXzEsIHRleHRdO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICB2YXIgcHJldmlvdXNBbmdsZTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSB0ZXh0Lmxlbmd0aDsgaSA8IGlpOykge1xuICAgIGFkdmFuY2UoKTtcbiAgICB2YXIgYW5nbGUgPSBNYXRoLmF0YW4yKHkyIC0geTEsIHgyIC0geDEpO1xuXG4gICAgaWYgKHJldmVyc2UpIHtcbiAgICAgIGFuZ2xlICs9IGFuZ2xlID4gMCA/IC1QSSA6IFBJO1xuICAgIH1cblxuICAgIGlmIChwcmV2aW91c0FuZ2xlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciBkZWx0YSA9IGFuZ2xlIC0gcHJldmlvdXNBbmdsZTtcbiAgICAgIGRlbHRhICs9IGRlbHRhID4gUEkgPyAtMiAqIFBJIDogZGVsdGEgPCAtUEkgPyAyICogUEkgOiAwO1xuXG4gICAgICBpZiAoTWF0aC5hYnMoZGVsdGEpID4gbWF4QW5nbGUpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJldmlvdXNBbmdsZSA9IGFuZ2xlO1xuICAgIHZhciBpU3RhcnQgPSBpO1xuICAgIHZhciBjaGFyTGVuZ3RoID0gMDtcblxuICAgIGZvciAoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdmFyIGluZGV4ID0gcmV2ZXJzZSA/IGlpIC0gaSAtIDEgOiBpO1xuICAgICAgdmFyIGxlbiA9IHNjYWxlICogbWVhc3VyZUFuZENhY2hlVGV4dFdpZHRoKGZvbnQsIHRleHRbaW5kZXhdLCBjYWNoZSk7XG5cbiAgICAgIGlmIChvZmZzZXQgKyBzdHJpZGUgPCBlbmQgJiYgc2VnbWVudE0gKyBzZWdtZW50TGVuZ3RoIDwgc3RhcnRNICsgY2hhckxlbmd0aCArIGxlbiAvIDIpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNoYXJMZW5ndGggKz0gbGVuO1xuICAgIH1cblxuICAgIGlmIChpID09PSBpU3RhcnQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHZhciBjaGFycyA9IHJldmVyc2UgPyB0ZXh0LnN1YnN0cmluZyhpaSAtIGlTdGFydCwgaWkgLSBpKSA6IHRleHQuc3Vic3RyaW5nKGlTdGFydCwgaSk7XG4gICAgaW50ZXJwb2xhdGUgPSAoc3RhcnRNICsgY2hhckxlbmd0aCAvIDIgLSBzZWdtZW50TSkgLyBzZWdtZW50TGVuZ3RoO1xuICAgIHZhciB4ID0gbGVycCh4MSwgeDIsIGludGVycG9sYXRlKTtcbiAgICB2YXIgeSA9IGxlcnAoeTEsIHkyLCBpbnRlcnBvbGF0ZSk7XG4gICAgcmVzdWx0LnB1c2goW3gsIHksIGNoYXJMZW5ndGggLyAyLCBhbmdsZSwgY2hhcnNdKTtcbiAgICBzdGFydE0gKz0gY2hhckxlbmd0aDtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vZmxhdC9sZW5ndGhcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IExlbmd0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpbmVTdHJpbmdMZW5ndGgoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKSB7XG4gIHZhciB4MSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXRdO1xuICB2YXIgeTEgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gIHZhciBsZW5ndGggPSAwO1xuXG4gIGZvciAodmFyIGkgPSBvZmZzZXQgKyBzdHJpZGU7IGkgPCBlbmQ7IGkgKz0gc3RyaWRlKSB7XG4gICAgdmFyIHgyID0gZmxhdENvb3JkaW5hdGVzW2ldO1xuICAgIHZhciB5MiA9IGZsYXRDb29yZGluYXRlc1tpICsgMV07XG4gICAgbGVuZ3RoICs9IE1hdGguc3FydCgoeDIgLSB4MSkgKiAoeDIgLSB4MSkgKyAoeTIgLSB5MSkgKiAoeTIgLSB5MSkpO1xuICAgIHgxID0geDI7XG4gICAgeTEgPSB5MjtcbiAgfVxuXG4gIHJldHVybiBsZW5ndGg7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFBlcmltZXRlci5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbGluZWFyUmluZ0xlbmd0aChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUpIHtcbiAgdmFyIHBlcmltZXRlciA9IGxpbmVTdHJpbmdMZW5ndGgoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKTtcbiAgdmFyIGR4ID0gZmxhdENvb3JkaW5hdGVzW2VuZCAtIHN0cmlkZV0gLSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgdmFyIGR5ID0gZmxhdENvb3JkaW5hdGVzW2VuZCAtIHN0cmlkZSArIDFdIC0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuICBwZXJpbWV0ZXIgKz0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcbiAgcmV0dXJuIHBlcmltZXRlcjtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL2NhbnZhcy9FeGVjdXRvclxuICovXG5pbXBvcnQgQ2FudmFzSW5zdHJ1Y3Rpb24gZnJvbSAnLi9JbnN0cnVjdGlvbi5qcyc7XG5pbXBvcnQgeyBURVhUX0FMSUdOIH0gZnJvbSAnLi9UZXh0QnVpbGRlci5qcyc7XG5pbXBvcnQgeyBXT1JLRVJfT0ZGU0NSRUVOX0NBTlZBUyB9IGZyb20gJy4uLy4uL2hhcy5qcyc7XG5pbXBvcnQgeyBhcHBseSBhcyBhcHBseVRyYW5zZm9ybSwgY29tcG9zZSBhcyBjb21wb3NlVHJhbnNmb3JtLCBjcmVhdGUgYXMgY3JlYXRlVHJhbnNmb3JtLCBzZXRGcm9tQXJyYXkgYXMgdHJhbnNmb3JtU2V0RnJvbUFycmF5IH0gZnJvbSAnLi4vLi4vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB7IGNyZWF0ZUVtcHR5LCBjcmVhdGVPclVwZGF0ZSwgaW50ZXJzZWN0cyB9IGZyb20gJy4uLy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBkZWZhdWx0UGFkZGluZywgZGVmYXVsdFRleHRCYXNlbGluZSwgZHJhd0ltYWdlT3JMYWJlbCB9IGZyb20gJy4uL2NhbnZhcy5qcyc7XG5pbXBvcnQgeyBkZWZhdWx0VGV4dEFsaWduLCBtZWFzdXJlQW5kQ2FjaGVUZXh0V2lkdGgsIG1lYXN1cmVUZXh0SGVpZ2h0LCBtZWFzdXJlVGV4dFdpZHRocyB9IGZyb20gJy4uL2NhbnZhcy5qcyc7XG5pbXBvcnQgeyBkcmF3VGV4dE9uUGF0aCB9IGZyb20gJy4uLy4uL2dlb20vZmxhdC90ZXh0cGF0aC5qcyc7XG5pbXBvcnQgeyBlcXVhbHMgfSBmcm9tICcuLi8uLi9hcnJheS5qcyc7XG5pbXBvcnQgeyBsaW5lU3RyaW5nTGVuZ3RoIH0gZnJvbSAnLi4vLi4vZ2VvbS9mbGF0L2xlbmd0aC5qcyc7XG5pbXBvcnQgeyB0cmFuc2Zvcm0yRCB9IGZyb20gJy4uLy4uL2dlb20vZmxhdC90cmFuc2Zvcm0uanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBCQm94XG4gKiBAcHJvcGVydHkge251bWJlcn0gbWluWFxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1pbllcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtYXhYXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWF4WVxuICogQHByb3BlcnR5IHsqfSB2YWx1ZVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gSW1hZ2VPckxhYmVsRGltZW5zaW9uc1xuICogQHByb3BlcnR5IHtudW1iZXJ9IGRyYXdJbWFnZVhcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkcmF3SW1hZ2VZXG4gKiBAcHJvcGVydHkge251bWJlcn0gZHJhd0ltYWdlV1xuICogQHByb3BlcnR5IHtudW1iZXJ9IGRyYXdJbWFnZUhcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBvcmlnaW5YXG4gKiBAcHJvcGVydHkge251bWJlcn0gb3JpZ2luWVxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBzY2FsZVxuICogQHByb3BlcnR5IHtCQm94fSBkZWNsdXR0ZXJCb3hcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gY2FudmFzVHJhbnNmb3JtXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7ezA6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgMTogbnVtYmVyLCAyOiBpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuTGFiZWx8SFRNTEltYWdlRWxlbWVudHxIVE1MQ2FudmFzRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50LCAzOiBJbWFnZU9yTGFiZWxEaW1lbnNpb25zLCA0OiBudW1iZXIsIDU6IEFycmF5PCo+LCA2OiBBcnJheTwqPn19IFJlcGxheUltYWdlT3JMYWJlbEFyZ3NcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZSwgaW1wb3J0KFwiLi4vLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0KTogVH0gRmVhdHVyZUNhbGxiYWNrXG4gKi9cblxuLyoqXG4gKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAqL1xuXG52YXIgdG1wRXh0ZW50ID0gY3JlYXRlRW1wdHkoKTtcbi8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSAqL1xuXG52YXIgcDEgPSBbXTtcbi8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSAqL1xuXG52YXIgcDIgPSBbXTtcbi8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSAqL1xuXG52YXIgcDMgPSBbXTtcbi8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSAqL1xuXG52YXIgcDQgPSBbXTtcbi8qKlxuICogQHBhcmFtIHtSZXBsYXlJbWFnZU9yTGFiZWxBcmdzfSByZXBsYXlJbWFnZU9yTGFiZWxBcmdzIEFyZ3VtZW50cyB0byByZXBsYXlJbWFnZU9yTGFiZWxcbiAqIEByZXR1cm4ge0JCb3h9IERlY2x1dHRlciBiYm94LlxuICovXG5cbmZ1bmN0aW9uIGdldERlY2x1dHRlckJveChyZXBsYXlJbWFnZU9yTGFiZWxBcmdzKSB7XG4gIHJldHVybiByZXBsYXlJbWFnZU9yTGFiZWxBcmdzWzNdLmRlY2x1dHRlckJveDtcbn1cblxudmFyIHJ0bFJlZ0V4ID0gbmV3IFJlZ0V4cChcbi8qIGVzbGludC1kaXNhYmxlIHByZXR0aWVyL3ByZXR0aWVyICovXG4nWycgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDA1OTEpICsgJy0nICsgU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwOGZmKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwZmIxZCkgKyAnLScgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MGZkZmYpICsgU3RyaW5nLmZyb21DaGFyQ29kZSgweDBmZTcwKSArICctJyArIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwZmVmYykgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MTA4MDApICsgJy0nICsgU3RyaW5nLmZyb21DaGFyQ29kZSgweDEwZmZmKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgxZTgwMCkgKyAnLScgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MWVmZmYpICsgJ10nXG4vKiBlc2xpbnQtZW5hYmxlIHByZXR0aWVyL3ByZXR0aWVyICovXG4pO1xuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCBUZXh0LlxuICogQHBhcmFtIHtzdHJpbmd9IGFsaWduIEFsaWdubWVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gVGV4dCBhbGlnbm1lbnQuXG4gKi9cblxuZnVuY3Rpb24gaG9yaXpvbnRhbFRleHRBbGlnbih0ZXh0LCBhbGlnbikge1xuICBpZiAoKGFsaWduID09PSAnc3RhcnQnIHx8IGFsaWduID09PSAnZW5kJykgJiYgIXJ0bFJlZ0V4LnRlc3QodGV4dCkpIHtcbiAgICBhbGlnbiA9IGFsaWduID09PSAnc3RhcnQnID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgfVxuXG4gIHJldHVybiBURVhUX0FMSUdOW2FsaWduXTtcbn1cblxudmFyIEV4ZWN1dG9yID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IG92ZXJsYXBzIFRoZSByZXBsYXkgY2FuIGhhdmUgb3ZlcmxhcHBpbmcgZ2VvbWV0cmllcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU2VyaWFsaXphYmxlSW5zdHJ1Y3Rpb25zfSBpbnN0cnVjdGlvbnMgVGhlIHNlcmlhbGl6YWJsZSBpbnN0cnVjdGlvbnNcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zaXplLmpzXCIpLlNpemV9IHJlbmRlckJ1ZmZlciBSZW5kZXIgYnVmZmVyICh3aWR0aC9oZWlnaHQpIGluIHBpeGVscy5cbiAgICovXG4gIGZ1bmN0aW9uIEV4ZWN1dG9yKHJlc29sdXRpb24sIHBpeGVsUmF0aW8sIG92ZXJsYXBzLCBpbnN0cnVjdGlvbnMsIHJlbmRlckJ1ZmZlcikge1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLm92ZXJsYXBzID0gb3ZlcmxhcHM7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLnBpeGVsUmF0aW8gPSBwaXhlbFJhdGlvO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAY29uc3RcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5yZXNvbHV0aW9uID0gcmVzb2x1dGlvbjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgdGhpcy5hbGlnbkZpbGxfO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7QXJyYXk8Kj59XG4gICAgICovXG5cbiAgICB0aGlzLmluc3RydWN0aW9ucyA9IGluc3RydWN0aW9ucy5pbnN0cnVjdGlvbnM7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgdGhpcy5jb29yZGluYXRlcyA9IGluc3RydWN0aW9ucy5jb29yZGluYXRlcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PG51bWJlcixpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8QXJyYXk8aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPnxBcnJheTxBcnJheTxpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pj59XG4gICAgICovXG5cbiAgICB0aGlzLmNvb3JkaW5hdGVDYWNoZV8gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICB0aGlzLnJlbmRlckJ1ZmZlcl8gPSByZW5kZXJCdWZmZXI7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IWltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gICAgICovXG5cbiAgICB0aGlzLnJlbmRlcmVkVHJhbnNmb3JtXyA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7QXJyYXk8Kj59XG4gICAgICovXG5cbiAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucyA9IGluc3RydWN0aW9ucy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIHRoaXMucGl4ZWxDb29yZGluYXRlc18gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMudmlld1JvdGF0aW9uXyA9IDA7XG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0YXRlPn1cbiAgICAgKi9cblxuICAgIHRoaXMuZmlsbFN0YXRlcyA9IGluc3RydWN0aW9ucy5maWxsU3RhdGVzIHx8IHt9O1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlN0cm9rZVN0YXRlPn1cbiAgICAgKi9cblxuICAgIHRoaXMuc3Ryb2tlU3RhdGVzID0gaW5zdHJ1Y3Rpb25zLnN0cm9rZVN0YXRlcyB8fCB7fTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5UZXh0U3RhdGU+fVxuICAgICAqL1xuXG4gICAgdGhpcy50ZXh0U3RhdGVzID0gaW5zdHJ1Y3Rpb25zLnRleHRTdGF0ZXMgfHwge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgT2JqZWN0PHN0cmluZywgbnVtYmVyPj59XG4gICAgICovXG5cbiAgICB0aGlzLndpZHRoc18gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuTGFiZWw+fVxuICAgICAqL1xuXG4gICAgdGhpcy5sYWJlbHNfID0ge307XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRleHQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0S2V5IFRleHQgc3R5bGUga2V5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsbEtleSBGaWxsIHN0eWxlIGtleS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cm9rZUtleSBTdHJva2Ugc3R5bGUga2V5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuTGFiZWx9IExhYmVsLlxuICAgKi9cblxuXG4gIEV4ZWN1dG9yLnByb3RvdHlwZS5jcmVhdGVMYWJlbCA9IGZ1bmN0aW9uICh0ZXh0LCB0ZXh0S2V5LCBmaWxsS2V5LCBzdHJva2VLZXkpIHtcbiAgICB2YXIga2V5ID0gdGV4dCArIHRleHRLZXkgKyBmaWxsS2V5ICsgc3Ryb2tlS2V5O1xuXG4gICAgaWYgKHRoaXMubGFiZWxzX1trZXldKSB7XG4gICAgICByZXR1cm4gdGhpcy5sYWJlbHNfW2tleV07XG4gICAgfVxuXG4gICAgdmFyIHN0cm9rZVN0YXRlID0gc3Ryb2tlS2V5ID8gdGhpcy5zdHJva2VTdGF0ZXNbc3Ryb2tlS2V5XSA6IG51bGw7XG4gICAgdmFyIGZpbGxTdGF0ZSA9IGZpbGxLZXkgPyB0aGlzLmZpbGxTdGF0ZXNbZmlsbEtleV0gOiBudWxsO1xuICAgIHZhciB0ZXh0U3RhdGUgPSB0aGlzLnRleHRTdGF0ZXNbdGV4dEtleV07XG4gICAgdmFyIHBpeGVsUmF0aW8gPSB0aGlzLnBpeGVsUmF0aW87XG4gICAgdmFyIHNjYWxlID0gW3RleHRTdGF0ZS5zY2FsZVswXSAqIHBpeGVsUmF0aW8sIHRleHRTdGF0ZS5zY2FsZVsxXSAqIHBpeGVsUmF0aW9dO1xuICAgIHZhciBhbGlnbiA9IGhvcml6b250YWxUZXh0QWxpZ24odGV4dCwgdGV4dFN0YXRlLnRleHRBbGlnbiB8fCBkZWZhdWx0VGV4dEFsaWduKTtcbiAgICB2YXIgc3Ryb2tlV2lkdGggPSBzdHJva2VLZXkgJiYgc3Ryb2tlU3RhdGUubGluZVdpZHRoID8gc3Ryb2tlU3RhdGUubGluZVdpZHRoIDogMDtcbiAgICB2YXIgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcbiAgICB2YXIgbnVtTGluZXMgPSBsaW5lcy5sZW5ndGg7XG4gICAgdmFyIHdpZHRocyA9IFtdO1xuICAgIHZhciB3aWR0aCA9IG1lYXN1cmVUZXh0V2lkdGhzKHRleHRTdGF0ZS5mb250LCBsaW5lcywgd2lkdGhzKTtcbiAgICB2YXIgbGluZUhlaWdodCA9IG1lYXN1cmVUZXh0SGVpZ2h0KHRleHRTdGF0ZS5mb250KTtcbiAgICB2YXIgaGVpZ2h0ID0gbGluZUhlaWdodCAqIG51bUxpbmVzO1xuICAgIHZhciByZW5kZXJXaWR0aCA9IHdpZHRoICsgc3Ryb2tlV2lkdGg7XG4gICAgdmFyIGNvbnRleHRJbnN0cnVjdGlvbnMgPSBbXTsgLy8gbWFrZSBjYW52YXMgMiBwaXhlbHMgd2lkZXIgdG8gYWNjb3VudCBmb3IgaXRhbGljIHRleHQgd2lkdGggbWVhc3VyZW1lbnQgZXJyb3JzXG5cbiAgICB2YXIgdyA9IChyZW5kZXJXaWR0aCArIDIpICogc2NhbGVbMF07XG4gICAgdmFyIGggPSAoaGVpZ2h0ICsgc3Ryb2tlV2lkdGgpICogc2NhbGVbMV07XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuTGFiZWx9ICovXG5cbiAgICB2YXIgbGFiZWwgPSB7XG4gICAgICB3aWR0aDogdyA8IDAgPyBNYXRoLmZsb29yKHcpIDogTWF0aC5jZWlsKHcpLFxuICAgICAgaGVpZ2h0OiBoIDwgMCA/IE1hdGguZmxvb3IoaCkgOiBNYXRoLmNlaWwoaCksXG4gICAgICBjb250ZXh0SW5zdHJ1Y3Rpb25zOiBjb250ZXh0SW5zdHJ1Y3Rpb25zXG4gICAgfTtcblxuICAgIGlmIChzY2FsZVswXSAhPSAxIHx8IHNjYWxlWzFdICE9IDEpIHtcbiAgICAgIGNvbnRleHRJbnN0cnVjdGlvbnMucHVzaCgnc2NhbGUnLCBzY2FsZSk7XG4gICAgfVxuXG4gICAgY29udGV4dEluc3RydWN0aW9ucy5wdXNoKCdmb250JywgdGV4dFN0YXRlLmZvbnQpO1xuXG4gICAgaWYgKHN0cm9rZUtleSkge1xuICAgICAgY29udGV4dEluc3RydWN0aW9ucy5wdXNoKCdzdHJva2VTdHlsZScsIHN0cm9rZVN0YXRlLnN0cm9rZVN0eWxlKTtcbiAgICAgIGNvbnRleHRJbnN0cnVjdGlvbnMucHVzaCgnbGluZVdpZHRoJywgc3Ryb2tlV2lkdGgpO1xuICAgICAgY29udGV4dEluc3RydWN0aW9ucy5wdXNoKCdsaW5lQ2FwJywgc3Ryb2tlU3RhdGUubGluZUNhcCk7XG4gICAgICBjb250ZXh0SW5zdHJ1Y3Rpb25zLnB1c2goJ2xpbmVKb2luJywgc3Ryb2tlU3RhdGUubGluZUpvaW4pO1xuICAgICAgY29udGV4dEluc3RydWN0aW9ucy5wdXNoKCdtaXRlckxpbWl0Jywgc3Ryb2tlU3RhdGUubWl0ZXJMaW1pdCk7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXG4gICAgICB2YXIgQ29udGV4dCA9IFdPUktFUl9PRkZTQ1JFRU5fQ0FOVkFTID8gT2Zmc2NyZWVuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEO1xuXG4gICAgICBpZiAoQ29udGV4dC5wcm90b3R5cGUuc2V0TGluZURhc2gpIHtcbiAgICAgICAgY29udGV4dEluc3RydWN0aW9ucy5wdXNoKCdzZXRMaW5lRGFzaCcsIFtzdHJva2VTdGF0ZS5saW5lRGFzaF0pO1xuICAgICAgICBjb250ZXh0SW5zdHJ1Y3Rpb25zLnB1c2goJ2xpbmVEYXNoT2Zmc2V0Jywgc3Ryb2tlU3RhdGUubGluZURhc2hPZmZzZXQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChmaWxsS2V5KSB7XG4gICAgICBjb250ZXh0SW5zdHJ1Y3Rpb25zLnB1c2goJ2ZpbGxTdHlsZScsIGZpbGxTdGF0ZS5maWxsU3R5bGUpO1xuICAgIH1cblxuICAgIGNvbnRleHRJbnN0cnVjdGlvbnMucHVzaCgndGV4dEJhc2VsaW5lJywgJ21pZGRsZScpO1xuICAgIGNvbnRleHRJbnN0cnVjdGlvbnMucHVzaCgndGV4dEFsaWduJywgJ2NlbnRlcicpO1xuICAgIHZhciBsZWZ0UmlnaHQgPSAwLjUgLSBhbGlnbjtcbiAgICB2YXIgeCA9IGFsaWduICogcmVuZGVyV2lkdGggKyBsZWZ0UmlnaHQgKiBzdHJva2VXaWR0aDtcbiAgICB2YXIgaTtcblxuICAgIGlmIChzdHJva2VLZXkpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1MaW5lczsgKytpKSB7XG4gICAgICAgIGNvbnRleHRJbnN0cnVjdGlvbnMucHVzaCgnc3Ryb2tlVGV4dCcsIFtsaW5lc1tpXSwgeCArIGxlZnRSaWdodCAqIHdpZHRoc1tpXSwgMC41ICogKHN0cm9rZVdpZHRoICsgbGluZUhlaWdodCkgKyBpICogbGluZUhlaWdodF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChmaWxsS2V5KSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtTGluZXM7ICsraSkge1xuICAgICAgICBjb250ZXh0SW5zdHJ1Y3Rpb25zLnB1c2goJ2ZpbGxUZXh0JywgW2xpbmVzW2ldLCB4ICsgbGVmdFJpZ2h0ICogd2lkdGhzW2ldLCAwLjUgKiAoc3Ryb2tlV2lkdGggKyBsaW5lSGVpZ2h0KSArIGkgKiBsaW5lSGVpZ2h0XSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5sYWJlbHNfW2tleV0gPSBsYWJlbDtcbiAgICByZXR1cm4gbGFiZWw7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gcDEgMXN0IHBvaW50IG9mIHRoZSBiYWNrZ3JvdW5kIGJveC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHAyIDJuZCBwb2ludCBvZiB0aGUgYmFja2dyb3VuZCBib3guXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBwMyAzcmQgcG9pbnQgb2YgdGhlIGJhY2tncm91bmQgYm94LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gcDQgNHRoIHBvaW50IG9mIHRoZSBiYWNrZ3JvdW5kIGJveC5cbiAgICogQHBhcmFtIHtBcnJheTwqPn0gZmlsbEluc3RydWN0aW9uIEZpbGwgaW5zdHJ1Y3Rpb24uXG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IHN0cm9rZUluc3RydWN0aW9uIFN0cm9rZSBpbnN0cnVjdGlvbi5cbiAgICovXG5cblxuICBFeGVjdXRvci5wcm90b3R5cGUucmVwbGF5VGV4dEJhY2tncm91bmRfID0gZnVuY3Rpb24gKGNvbnRleHQsIHAxLCBwMiwgcDMsIHA0LCBmaWxsSW5zdHJ1Y3Rpb24sIHN0cm9rZUluc3RydWN0aW9uKSB7XG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICBjb250ZXh0Lm1vdmVUby5hcHBseShjb250ZXh0LCBwMSk7XG4gICAgY29udGV4dC5saW5lVG8uYXBwbHkoY29udGV4dCwgcDIpO1xuICAgIGNvbnRleHQubGluZVRvLmFwcGx5KGNvbnRleHQsIHAzKTtcbiAgICBjb250ZXh0LmxpbmVUby5hcHBseShjb250ZXh0LCBwNCk7XG4gICAgY29udGV4dC5saW5lVG8uYXBwbHkoY29udGV4dCwgcDEpO1xuXG4gICAgaWYgKGZpbGxJbnN0cnVjdGlvbikge1xuICAgICAgdGhpcy5hbGlnbkZpbGxfID1cbiAgICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgICAgIGZpbGxJbnN0cnVjdGlvblsyXTtcbiAgICAgIHRoaXMuZmlsbF8oY29udGV4dCk7XG4gICAgfVxuXG4gICAgaWYgKHN0cm9rZUluc3RydWN0aW9uKSB7XG4gICAgICB0aGlzLnNldFN0cm9rZVN0eWxlXyhjb250ZXh0LFxuICAgICAgLyoqIEB0eXBlIHtBcnJheTwqPn0gKi9cbiAgICAgIHN0cm9rZUluc3RydWN0aW9uKTtcbiAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNoZWV0V2lkdGggV2lkdGggb2YgdGhlIHNwcml0ZSBzaGVldC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHNoZWV0SGVpZ2h0IEhlaWdodCBvZiB0aGUgc3ByaXRlIHNoZWV0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gY2VudGVyWCBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0gY2VudGVyWSBZLlxuICAgKiBAcGFyYW0ge251bWJlcn0gd2lkdGggV2lkdGguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHQgSGVpZ2h0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gYW5jaG9yWCBBbmNob3IgWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFuY2hvclkgQW5jaG9yIFkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcmlnaW5YIE9yaWdpbiBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb3JpZ2luWSBPcmlnaW4gWS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3NpemUuanNcIikuU2l6ZX0gc2NhbGUgU2NhbGUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gc25hcFRvUGl4ZWwgU25hcCB0byBwaXhlbC5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBwYWRkaW5nIFBhZGRpbmcuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZmlsbFN0cm9rZSBCYWNrZ3JvdW5kIGZpbGwgb3Igc3Ryb2tlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICogQHJldHVybiB7SW1hZ2VPckxhYmVsRGltZW5zaW9uc30gRGltZW5zaW9ucyBmb3IgcG9zaXRpb25pbmcgYW5kIGRlY2x1dHRlcmluZyB0aGUgaW1hZ2Ugb3IgbGFiZWwuXG4gICAqL1xuXG5cbiAgRXhlY3V0b3IucHJvdG90eXBlLmNhbGN1bGF0ZUltYWdlT3JMYWJlbERpbWVuc2lvbnNfID0gZnVuY3Rpb24gKHNoZWV0V2lkdGgsIHNoZWV0SGVpZ2h0LCBjZW50ZXJYLCBjZW50ZXJZLCB3aWR0aCwgaGVpZ2h0LCBhbmNob3JYLCBhbmNob3JZLCBvcmlnaW5YLCBvcmlnaW5ZLCByb3RhdGlvbiwgc2NhbGUsIHNuYXBUb1BpeGVsLCBwYWRkaW5nLCBmaWxsU3Ryb2tlLCBmZWF0dXJlKSB7XG4gICAgYW5jaG9yWCAqPSBzY2FsZVswXTtcbiAgICBhbmNob3JZICo9IHNjYWxlWzFdO1xuICAgIHZhciB4ID0gY2VudGVyWCAtIGFuY2hvclg7XG4gICAgdmFyIHkgPSBjZW50ZXJZIC0gYW5jaG9yWTtcbiAgICB2YXIgdyA9IHdpZHRoICsgb3JpZ2luWCA+IHNoZWV0V2lkdGggPyBzaGVldFdpZHRoIC0gb3JpZ2luWCA6IHdpZHRoO1xuICAgIHZhciBoID0gaGVpZ2h0ICsgb3JpZ2luWSA+IHNoZWV0SGVpZ2h0ID8gc2hlZXRIZWlnaHQgLSBvcmlnaW5ZIDogaGVpZ2h0O1xuICAgIHZhciBib3hXID0gcGFkZGluZ1szXSArIHcgKiBzY2FsZVswXSArIHBhZGRpbmdbMV07XG4gICAgdmFyIGJveEggPSBwYWRkaW5nWzBdICsgaCAqIHNjYWxlWzFdICsgcGFkZGluZ1syXTtcbiAgICB2YXIgYm94WCA9IHggLSBwYWRkaW5nWzNdO1xuICAgIHZhciBib3hZID0geSAtIHBhZGRpbmdbMF07XG5cbiAgICBpZiAoZmlsbFN0cm9rZSB8fCByb3RhdGlvbiAhPT0gMCkge1xuICAgICAgcDFbMF0gPSBib3hYO1xuICAgICAgcDRbMF0gPSBib3hYO1xuICAgICAgcDFbMV0gPSBib3hZO1xuICAgICAgcDJbMV0gPSBib3hZO1xuICAgICAgcDJbMF0gPSBib3hYICsgYm94VztcbiAgICAgIHAzWzBdID0gcDJbMF07XG4gICAgICBwM1sxXSA9IGJveFkgKyBib3hIO1xuICAgICAgcDRbMV0gPSBwM1sxXTtcbiAgICB9XG5cbiAgICB2YXIgdHJhbnNmb3JtO1xuXG4gICAgaWYgKHJvdGF0aW9uICE9PSAwKSB7XG4gICAgICB0cmFuc2Zvcm0gPSBjb21wb3NlVHJhbnNmb3JtKGNyZWF0ZVRyYW5zZm9ybSgpLCBjZW50ZXJYLCBjZW50ZXJZLCAxLCAxLCByb3RhdGlvbiwgLWNlbnRlclgsIC1jZW50ZXJZKTtcbiAgICAgIGFwcGx5VHJhbnNmb3JtKHRyYW5zZm9ybSwgcDEpO1xuICAgICAgYXBwbHlUcmFuc2Zvcm0odHJhbnNmb3JtLCBwMik7XG4gICAgICBhcHBseVRyYW5zZm9ybSh0cmFuc2Zvcm0sIHAzKTtcbiAgICAgIGFwcGx5VHJhbnNmb3JtKHRyYW5zZm9ybSwgcDQpO1xuICAgICAgY3JlYXRlT3JVcGRhdGUoTWF0aC5taW4ocDFbMF0sIHAyWzBdLCBwM1swXSwgcDRbMF0pLCBNYXRoLm1pbihwMVsxXSwgcDJbMV0sIHAzWzFdLCBwNFsxXSksIE1hdGgubWF4KHAxWzBdLCBwMlswXSwgcDNbMF0sIHA0WzBdKSwgTWF0aC5tYXgocDFbMV0sIHAyWzFdLCBwM1sxXSwgcDRbMV0pLCB0bXBFeHRlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjcmVhdGVPclVwZGF0ZShNYXRoLm1pbihib3hYLCBib3hYICsgYm94VyksIE1hdGgubWluKGJveFksIGJveFkgKyBib3hIKSwgTWF0aC5tYXgoYm94WCwgYm94WCArIGJveFcpLCBNYXRoLm1heChib3hZLCBib3hZICsgYm94SCksIHRtcEV4dGVudCk7XG4gICAgfVxuXG4gICAgaWYgKHNuYXBUb1BpeGVsKSB7XG4gICAgICB4ID0gTWF0aC5yb3VuZCh4KTtcbiAgICAgIHkgPSBNYXRoLnJvdW5kKHkpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBkcmF3SW1hZ2VYOiB4LFxuICAgICAgZHJhd0ltYWdlWTogeSxcbiAgICAgIGRyYXdJbWFnZVc6IHcsXG4gICAgICBkcmF3SW1hZ2VIOiBoLFxuICAgICAgb3JpZ2luWDogb3JpZ2luWCxcbiAgICAgIG9yaWdpblk6IG9yaWdpblksXG4gICAgICBkZWNsdXR0ZXJCb3g6IHtcbiAgICAgICAgbWluWDogdG1wRXh0ZW50WzBdLFxuICAgICAgICBtaW5ZOiB0bXBFeHRlbnRbMV0sXG4gICAgICAgIG1heFg6IHRtcEV4dGVudFsyXSxcbiAgICAgICAgbWF4WTogdG1wRXh0ZW50WzNdLFxuICAgICAgICB2YWx1ZTogZmVhdHVyZVxuICAgICAgfSxcbiAgICAgIGNhbnZhc1RyYW5zZm9ybTogdHJhbnNmb3JtLFxuICAgICAgc2NhbGU6IHNjYWxlXG4gICAgfTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IENvbnRleHQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjb250ZXh0U2NhbGUgU2NhbGUgb2YgdGhlIGNvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkxhYmVsfEhUTUxJbWFnZUVsZW1lbnR8SFRNTENhbnZhc0VsZW1lbnR8SFRNTFZpZGVvRWxlbWVudH0gaW1hZ2VPckxhYmVsIEltYWdlLlxuICAgKiBAcGFyYW0ge0ltYWdlT3JMYWJlbERpbWVuc2lvbnN9IGRpbWVuc2lvbnMgRGltZW5zaW9ucy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9wYWNpdHkgT3BhY2l0eS5cbiAgICogQHBhcmFtIHtBcnJheTwqPn0gZmlsbEluc3RydWN0aW9uIEZpbGwgaW5zdHJ1Y3Rpb24uXG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IHN0cm9rZUluc3RydWN0aW9uIFN0cm9rZSBpbnN0cnVjdGlvbi5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIGltYWdlIG9yIGxhYmVsIHdhcyByZW5kZXJlZC5cbiAgICovXG5cblxuICBFeGVjdXRvci5wcm90b3R5cGUucmVwbGF5SW1hZ2VPckxhYmVsXyA9IGZ1bmN0aW9uIChjb250ZXh0LCBjb250ZXh0U2NhbGUsIGltYWdlT3JMYWJlbCwgZGltZW5zaW9ucywgb3BhY2l0eSwgZmlsbEluc3RydWN0aW9uLCBzdHJva2VJbnN0cnVjdGlvbikge1xuICAgIHZhciBmaWxsU3Ryb2tlID0gISEoZmlsbEluc3RydWN0aW9uIHx8IHN0cm9rZUluc3RydWN0aW9uKTtcbiAgICB2YXIgYm94ID0gZGltZW5zaW9ucy5kZWNsdXR0ZXJCb3g7XG4gICAgdmFyIGNhbnZhcyA9IGNvbnRleHQuY2FudmFzO1xuICAgIHZhciBzdHJva2VQYWRkaW5nID0gc3Ryb2tlSW5zdHJ1Y3Rpb24gPyBzdHJva2VJbnN0cnVjdGlvblsyXSAqIGRpbWVuc2lvbnMuc2NhbGVbMF0gLyAyIDogMDtcbiAgICB2YXIgaW50ZXJzZWN0cyA9IGJveC5taW5YIC0gc3Ryb2tlUGFkZGluZyA8PSBjYW52YXMud2lkdGggLyBjb250ZXh0U2NhbGUgJiYgYm94Lm1heFggKyBzdHJva2VQYWRkaW5nID49IDAgJiYgYm94Lm1pblkgLSBzdHJva2VQYWRkaW5nIDw9IGNhbnZhcy5oZWlnaHQgLyBjb250ZXh0U2NhbGUgJiYgYm94Lm1heFkgKyBzdHJva2VQYWRkaW5nID49IDA7XG5cbiAgICBpZiAoaW50ZXJzZWN0cykge1xuICAgICAgaWYgKGZpbGxTdHJva2UpIHtcbiAgICAgICAgdGhpcy5yZXBsYXlUZXh0QmFja2dyb3VuZF8oY29udGV4dCwgcDEsIHAyLCBwMywgcDQsXG4gICAgICAgIC8qKiBAdHlwZSB7QXJyYXk8Kj59ICovXG4gICAgICAgIGZpbGxJbnN0cnVjdGlvbixcbiAgICAgICAgLyoqIEB0eXBlIHtBcnJheTwqPn0gKi9cbiAgICAgICAgc3Ryb2tlSW5zdHJ1Y3Rpb24pO1xuICAgICAgfVxuXG4gICAgICBkcmF3SW1hZ2VPckxhYmVsKGNvbnRleHQsIGRpbWVuc2lvbnMuY2FudmFzVHJhbnNmb3JtLCBvcGFjaXR5LCBpbWFnZU9yTGFiZWwsIGRpbWVuc2lvbnMub3JpZ2luWCwgZGltZW5zaW9ucy5vcmlnaW5ZLCBkaW1lbnNpb25zLmRyYXdJbWFnZVcsIGRpbWVuc2lvbnMuZHJhd0ltYWdlSCwgZGltZW5zaW9ucy5kcmF3SW1hZ2VYLCBkaW1lbnNpb25zLmRyYXdJbWFnZVksIGRpbWVuc2lvbnMuc2NhbGUpO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICovXG5cblxuICBFeGVjdXRvci5wcm90b3R5cGUuZmlsbF8gPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIGlmICh0aGlzLmFsaWduRmlsbF8pIHtcbiAgICAgIHZhciBvcmlnaW5fMSA9IGFwcGx5VHJhbnNmb3JtKHRoaXMucmVuZGVyZWRUcmFuc2Zvcm1fLCBbMCwgMF0pO1xuICAgICAgdmFyIHJlcGVhdFNpemUgPSA1MTIgKiB0aGlzLnBpeGVsUmF0aW87XG4gICAgICBjb250ZXh0LnNhdmUoKTtcbiAgICAgIGNvbnRleHQudHJhbnNsYXRlKG9yaWdpbl8xWzBdICUgcmVwZWF0U2l6ZSwgb3JpZ2luXzFbMV0gJSByZXBlYXRTaXplKTtcbiAgICAgIGNvbnRleHQucm90YXRlKHRoaXMudmlld1JvdGF0aW9uXyk7XG4gICAgfVxuXG4gICAgY29udGV4dC5maWxsKCk7XG5cbiAgICBpZiAodGhpcy5hbGlnbkZpbGxfKSB7XG4gICAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICAgKiBAcGFyYW0ge0FycmF5PCo+fSBpbnN0cnVjdGlvbiBJbnN0cnVjdGlvbi5cbiAgICovXG5cblxuICBFeGVjdXRvci5wcm90b3R5cGUuc2V0U3Ryb2tlU3R5bGVfID0gZnVuY3Rpb24gKGNvbnRleHQsIGluc3RydWN0aW9uKSB7XG4gICAgY29udGV4dFsnc3Ryb2tlU3R5bGUnXSA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9jb2xvcmxpa2UuanNcIikuQ29sb3JMaWtlfSAqL1xuICAgIGluc3RydWN0aW9uWzFdO1xuICAgIGNvbnRleHQubGluZVdpZHRoID1cbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICBpbnN0cnVjdGlvblsyXTtcbiAgICBjb250ZXh0LmxpbmVDYXAgPVxuICAgIC8qKiBAdHlwZSB7Q2FudmFzTGluZUNhcH0gKi9cbiAgICBpbnN0cnVjdGlvblszXTtcbiAgICBjb250ZXh0LmxpbmVKb2luID1cbiAgICAvKiogQHR5cGUge0NhbnZhc0xpbmVKb2lufSAqL1xuICAgIGluc3RydWN0aW9uWzRdO1xuICAgIGNvbnRleHQubWl0ZXJMaW1pdCA9XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgaW5zdHJ1Y3Rpb25bNV07XG5cbiAgICBpZiAoY29udGV4dC5zZXRMaW5lRGFzaCkge1xuICAgICAgY29udGV4dC5saW5lRGFzaE9mZnNldCA9XG4gICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgIGluc3RydWN0aW9uWzddO1xuICAgICAgY29udGV4dC5zZXRMaW5lRGFzaChcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIGluc3RydWN0aW9uWzZdKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCBUaGUgdGV4dCB0byBkcmF3LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dEtleSBUaGUga2V5IG9mIHRoZSB0ZXh0IHN0YXRlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3Ryb2tlS2V5IFRoZSBrZXkgZm9yIHRoZSBzdHJva2Ugc3RhdGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxsS2V5IFRoZSBrZXkgZm9yIHRoZSBmaWxsIHN0YXRlLlxuICAgKiBAcmV0dXJuIHt7bGFiZWw6IGltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5MYWJlbCwgYW5jaG9yWDogbnVtYmVyLCBhbmNob3JZOiBudW1iZXJ9fSBUaGUgdGV4dCBpbWFnZSBhbmQgaXRzIGFuY2hvci5cbiAgICovXG5cblxuICBFeGVjdXRvci5wcm90b3R5cGUuZHJhd0xhYmVsV2l0aFBvaW50UGxhY2VtZW50XyA9IGZ1bmN0aW9uICh0ZXh0LCB0ZXh0S2V5LCBzdHJva2VLZXksIGZpbGxLZXkpIHtcbiAgICB2YXIgdGV4dFN0YXRlID0gdGhpcy50ZXh0U3RhdGVzW3RleHRLZXldO1xuICAgIHZhciBsYWJlbCA9IHRoaXMuY3JlYXRlTGFiZWwodGV4dCwgdGV4dEtleSwgZmlsbEtleSwgc3Ryb2tlS2V5KTtcbiAgICB2YXIgc3Ryb2tlU3RhdGUgPSB0aGlzLnN0cm9rZVN0YXRlc1tzdHJva2VLZXldO1xuICAgIHZhciBwaXhlbFJhdGlvID0gdGhpcy5waXhlbFJhdGlvO1xuICAgIHZhciBhbGlnbiA9IGhvcml6b250YWxUZXh0QWxpZ24odGV4dCwgdGV4dFN0YXRlLnRleHRBbGlnbiB8fCBkZWZhdWx0VGV4dEFsaWduKTtcbiAgICB2YXIgYmFzZWxpbmUgPSBURVhUX0FMSUdOW3RleHRTdGF0ZS50ZXh0QmFzZWxpbmUgfHwgZGVmYXVsdFRleHRCYXNlbGluZV07XG4gICAgdmFyIHN0cm9rZVdpZHRoID0gc3Ryb2tlU3RhdGUgJiYgc3Ryb2tlU3RhdGUubGluZVdpZHRoID8gc3Ryb2tlU3RhdGUubGluZVdpZHRoIDogMDsgLy8gUmVtb3ZlIHRoZSAyIHBpeGVscyB3ZSBhZGRlZCBpbiBjcmVhdGVMYWJlbCgpIGZvciB0aGUgYW5jaG9yXG5cbiAgICB2YXIgd2lkdGggPSBsYWJlbC53aWR0aCAvIHBpeGVsUmF0aW8gLSAyICogdGV4dFN0YXRlLnNjYWxlWzBdO1xuICAgIHZhciBhbmNob3JYID0gYWxpZ24gKiB3aWR0aCArIDIgKiAoMC41IC0gYWxpZ24pICogc3Ryb2tlV2lkdGg7XG4gICAgdmFyIGFuY2hvclkgPSBiYXNlbGluZSAqIGxhYmVsLmhlaWdodCAvIHBpeGVsUmF0aW8gKyAyICogKDAuNSAtIGJhc2VsaW5lKSAqIHN0cm9rZVdpZHRoO1xuICAgIHJldHVybiB7XG4gICAgICBsYWJlbDogbGFiZWwsXG4gICAgICBhbmNob3JYOiBhbmNob3JYLFxuICAgICAgYW5jaG9yWTogYW5jaG9yWVxuICAgIH07XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gY29udGV4dFNjYWxlIFNjYWxlIG9mIHRoZSBjb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IGluc3RydWN0aW9ucyBJbnN0cnVjdGlvbnMgYXJyYXkuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gc25hcFRvUGl4ZWwgU25hcCBwb2ludCBzeW1ib2xzIGFuZCB0ZXh0IHRvIGludGVnZXIgcGl4ZWxzLlxuICAgKiBAcGFyYW0ge0ZlYXR1cmVDYWxsYmFjazxUPj19IG9wdF9mZWF0dXJlQ2FsbGJhY2sgRmVhdHVyZSBjYWxsYmFjay5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50PX0gb3B0X2hpdEV4dGVudCBPbmx5IGNoZWNrXG4gICAqICAgICBmZWF0dXJlcyB0aGF0IGludGVyc2VjdCB0aGlzIGV4dGVudC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJyYnVzaFwiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlclRyZWUgRGVjbHV0dGVyIHRyZWUuXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqL1xuXG5cbiAgRXhlY3V0b3IucHJvdG90eXBlLmV4ZWN1dGVfID0gZnVuY3Rpb24gKGNvbnRleHQsIGNvbnRleHRTY2FsZSwgdHJhbnNmb3JtLCBpbnN0cnVjdGlvbnMsIHNuYXBUb1BpeGVsLCBvcHRfZmVhdHVyZUNhbGxiYWNrLCBvcHRfaGl0RXh0ZW50LCBvcHRfZGVjbHV0dGVyVHJlZSkge1xuICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICB2YXIgcGl4ZWxDb29yZGluYXRlcztcblxuICAgIGlmICh0aGlzLnBpeGVsQ29vcmRpbmF0ZXNfICYmIGVxdWFscyh0cmFuc2Zvcm0sIHRoaXMucmVuZGVyZWRUcmFuc2Zvcm1fKSkge1xuICAgICAgcGl4ZWxDb29yZGluYXRlcyA9IHRoaXMucGl4ZWxDb29yZGluYXRlc187XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy5waXhlbENvb3JkaW5hdGVzXykge1xuICAgICAgICB0aGlzLnBpeGVsQ29vcmRpbmF0ZXNfID0gW107XG4gICAgICB9XG5cbiAgICAgIHBpeGVsQ29vcmRpbmF0ZXMgPSB0cmFuc2Zvcm0yRCh0aGlzLmNvb3JkaW5hdGVzLCAwLCB0aGlzLmNvb3JkaW5hdGVzLmxlbmd0aCwgMiwgdHJhbnNmb3JtLCB0aGlzLnBpeGVsQ29vcmRpbmF0ZXNfKTtcbiAgICAgIHRyYW5zZm9ybVNldEZyb21BcnJheSh0aGlzLnJlbmRlcmVkVHJhbnNmb3JtXywgdHJhbnNmb3JtKTtcbiAgICB9XG5cbiAgICB2YXIgaSA9IDA7IC8vIGluc3RydWN0aW9uIGluZGV4XG5cbiAgICB2YXIgaWkgPSBpbnN0cnVjdGlvbnMubGVuZ3RoOyAvLyBlbmQgb2YgaW5zdHJ1Y3Rpb25zXG5cbiAgICB2YXIgZCA9IDA7IC8vIGRhdGEgaW5kZXhcblxuICAgIHZhciBkZDsgLy8gZW5kIG9mIHBlci1pbnN0cnVjdGlvbiBkYXRhXG5cbiAgICB2YXIgYW5jaG9yWCwgYW5jaG9yWSwgcHJldlgsIHByZXZZLCByb3VuZFgsIHJvdW5kWSwgaW1hZ2UsIHRleHQsIHRleHRLZXksIHN0cm9rZUtleSwgZmlsbEtleTtcbiAgICB2YXIgcGVuZGluZ0ZpbGwgPSAwO1xuICAgIHZhciBwZW5kaW5nU3Ryb2tlID0gMDtcbiAgICB2YXIgbGFzdEZpbGxJbnN0cnVjdGlvbiA9IG51bGw7XG4gICAgdmFyIGxhc3RTdHJva2VJbnN0cnVjdGlvbiA9IG51bGw7XG4gICAgdmFyIGNvb3JkaW5hdGVDYWNoZSA9IHRoaXMuY29vcmRpbmF0ZUNhY2hlXztcbiAgICB2YXIgdmlld1JvdGF0aW9uID0gdGhpcy52aWV3Um90YXRpb25fO1xuICAgIHZhciB2aWV3Um90YXRpb25Gcm9tVHJhbnNmb3JtID0gTWF0aC5yb3VuZChNYXRoLmF0YW4yKC10cmFuc2Zvcm1bMV0sIHRyYW5zZm9ybVswXSkgKiAxZTEyKSAvIDFlMTI7XG4gICAgdmFyIHN0YXRlID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL3JlbmRlci5qc1wiKS5TdGF0ZX0gKi9cbiAgICB7XG4gICAgICBjb250ZXh0OiBjb250ZXh0LFxuICAgICAgcGl4ZWxSYXRpbzogdGhpcy5waXhlbFJhdGlvLFxuICAgICAgcmVzb2x1dGlvbjogdGhpcy5yZXNvbHV0aW9uLFxuICAgICAgcm90YXRpb246IHZpZXdSb3RhdGlvblxuICAgIH07IC8vIFdoZW4gdGhlIGJhdGNoIHNpemUgZ2V0cyB0b28gYmlnLCBwZXJmb3JtYW5jZSBkZWNyZWFzZXMuIDIwMCBpcyBhIGdvb2RcbiAgICAvLyBiYWxhbmNlIGJldHdlZW4gYmF0Y2ggc2l6ZSBhbmQgbnVtYmVyIG9mIGZpbGwvc3Ryb2tlIGluc3RydWN0aW9ucy5cblxuICAgIHZhciBiYXRjaFNpemUgPSB0aGlzLmluc3RydWN0aW9ucyAhPSBpbnN0cnVjdGlvbnMgfHwgdGhpcy5vdmVybGFwcyA/IDAgOiAyMDA7XG4gICAgdmFyXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSAqL1xuICAgIGZlYXR1cmU7XG4gICAgdmFyIHgsIHksIGN1cnJlbnRHZW9tZXRyeTtcblxuICAgIHdoaWxlIChpIDwgaWkpIHtcbiAgICAgIHZhciBpbnN0cnVjdGlvbiA9IGluc3RydWN0aW9uc1tpXTtcbiAgICAgIHZhciB0eXBlID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9JbnN0cnVjdGlvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgaW5zdHJ1Y3Rpb25bMF07XG5cbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlIENhbnZhc0luc3RydWN0aW9uLkJFR0lOX0dFT01FVFJZOlxuICAgICAgICAgIGZlYXR1cmUgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxXTtcbiAgICAgICAgICBjdXJyZW50R2VvbWV0cnkgPSBpbnN0cnVjdGlvblszXTtcblxuICAgICAgICAgIGlmICghZmVhdHVyZS5nZXRHZW9tZXRyeSgpKSB7XG4gICAgICAgICAgICBpID1cbiAgICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bMl07XG4gICAgICAgICAgfSBlbHNlIGlmIChvcHRfaGl0RXh0ZW50ICE9PSB1bmRlZmluZWQgJiYgIWludGVyc2VjdHMob3B0X2hpdEV4dGVudCwgY3VycmVudEdlb21ldHJ5LmdldEV4dGVudCgpKSkge1xuICAgICAgICAgICAgaSA9XG4gICAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICAgIGluc3RydWN0aW9uWzJdICsgMTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgKytpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgQ2FudmFzSW5zdHJ1Y3Rpb24uQkVHSU5fUEFUSDpcbiAgICAgICAgICBpZiAocGVuZGluZ0ZpbGwgPiBiYXRjaFNpemUpIHtcbiAgICAgICAgICAgIHRoaXMuZmlsbF8oY29udGV4dCk7XG4gICAgICAgICAgICBwZW5kaW5nRmlsbCA9IDA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHBlbmRpbmdTdHJva2UgPiBiYXRjaFNpemUpIHtcbiAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgICAgICAgICBwZW5kaW5nU3Ryb2tlID0gMDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXBlbmRpbmdGaWxsICYmICFwZW5kaW5nU3Ryb2tlKSB7XG4gICAgICAgICAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgICAgICAgICAgcHJldlggPSBOYU47XG4gICAgICAgICAgICBwcmV2WSA9IE5hTjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICArK2k7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5DSVJDTEU6XG4gICAgICAgICAgZCA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bMV07XG4gICAgICAgICAgdmFyIHgxID0gcGl4ZWxDb29yZGluYXRlc1tkXTtcbiAgICAgICAgICB2YXIgeTEgPSBwaXhlbENvb3JkaW5hdGVzW2QgKyAxXTtcbiAgICAgICAgICB2YXIgeDIgPSBwaXhlbENvb3JkaW5hdGVzW2QgKyAyXTtcbiAgICAgICAgICB2YXIgeTIgPSBwaXhlbENvb3JkaW5hdGVzW2QgKyAzXTtcbiAgICAgICAgICB2YXIgZHggPSB4MiAtIHgxO1xuICAgICAgICAgIHZhciBkeSA9IHkyIC0geTE7XG4gICAgICAgICAgdmFyIHIgPSBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpO1xuICAgICAgICAgIGNvbnRleHQubW92ZVRvKHgxICsgciwgeTEpO1xuICAgICAgICAgIGNvbnRleHQuYXJjKHgxLCB5MSwgciwgMCwgMiAqIE1hdGguUEksIHRydWUpO1xuICAgICAgICAgICsraTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIENhbnZhc0luc3RydWN0aW9uLkNMT1NFX1BBVEg6XG4gICAgICAgICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICAgICAgICArK2k7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5DVVNUT006XG4gICAgICAgICAgZCA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bMV07XG4gICAgICAgICAgZGQgPSBpbnN0cnVjdGlvblsyXTtcbiAgICAgICAgICB2YXIgZ2VvbWV0cnkgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzNdO1xuICAgICAgICAgIHZhciByZW5kZXJlciA9IGluc3RydWN0aW9uWzRdO1xuICAgICAgICAgIHZhciBmbiA9IGluc3RydWN0aW9uLmxlbmd0aCA9PSA2ID8gaW5zdHJ1Y3Rpb25bNV0gOiB1bmRlZmluZWQ7XG4gICAgICAgICAgc3RhdGUuZ2VvbWV0cnkgPSBnZW9tZXRyeTtcbiAgICAgICAgICBzdGF0ZS5mZWF0dXJlID0gZmVhdHVyZTtcblxuICAgICAgICAgIGlmICghKGkgaW4gY29vcmRpbmF0ZUNhY2hlKSkge1xuICAgICAgICAgICAgY29vcmRpbmF0ZUNhY2hlW2ldID0gW107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIGNvb3JkcyA9IGNvb3JkaW5hdGVDYWNoZVtpXTtcblxuICAgICAgICAgIGlmIChmbikge1xuICAgICAgICAgICAgZm4ocGl4ZWxDb29yZGluYXRlcywgZCwgZGQsIDIsIGNvb3Jkcyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvb3Jkc1swXSA9IHBpeGVsQ29vcmRpbmF0ZXNbZF07XG4gICAgICAgICAgICBjb29yZHNbMV0gPSBwaXhlbENvb3JkaW5hdGVzW2QgKyAxXTtcbiAgICAgICAgICAgIGNvb3Jkcy5sZW5ndGggPSAyO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJlbmRlcmVyKGNvb3Jkcywgc3RhdGUpO1xuICAgICAgICAgICsraTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIENhbnZhc0luc3RydWN0aW9uLkRSQVdfSU1BR0U6XG4gICAgICAgICAgZCA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bMV07XG4gICAgICAgICAgZGQgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzJdO1xuICAgICAgICAgIGltYWdlID1cbiAgICAgICAgICAvKiogQHR5cGUge0hUTUxDYW52YXNFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudH0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblszXTsgLy8gUmVtYWluaW5nIGFyZ3VtZW50cyBpbiBEUkFXX0lNQUdFIGFyZSBpbiBhbHBoYWJldGljYWwgb3JkZXJcblxuICAgICAgICAgIGFuY2hvclggPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzRdO1xuICAgICAgICAgIGFuY2hvclkgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzVdO1xuICAgICAgICAgIHZhciBoZWlnaHQgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzZdO1xuICAgICAgICAgIHZhciBvcGFjaXR5ID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvbls3XTtcbiAgICAgICAgICB2YXIgb3JpZ2luWCA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bOF07XG4gICAgICAgICAgdmFyIG9yaWdpblkgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzldO1xuICAgICAgICAgIHZhciByb3RhdGVXaXRoVmlldyA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtib29sZWFufSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzEwXTtcbiAgICAgICAgICB2YXIgcm90YXRpb24gPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzExXTtcbiAgICAgICAgICB2YXIgc2NhbGUgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vc2l6ZS5qc1wiKS5TaXplfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzEyXTtcbiAgICAgICAgICB2YXIgd2lkdGggPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzEzXTtcbiAgICAgICAgICB2YXIgZGVjbHV0dGVySW1hZ2VXaXRoVGV4dCA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRGVjbHV0dGVySW1hZ2VXaXRoVGV4dH0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxNF07XG5cbiAgICAgICAgICBpZiAoIWltYWdlICYmIGluc3RydWN0aW9uLmxlbmd0aCA+PSAxOSkge1xuICAgICAgICAgICAgLy8gY3JlYXRlIGxhYmVsIGltYWdlc1xuICAgICAgICAgICAgdGV4dCA9XG4gICAgICAgICAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICAgICAgICAgIGluc3RydWN0aW9uWzE4XTtcbiAgICAgICAgICAgIHRleHRLZXkgPVxuICAgICAgICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovXG4gICAgICAgICAgICBpbnN0cnVjdGlvblsxOV07XG4gICAgICAgICAgICBzdHJva2VLZXkgPVxuICAgICAgICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovXG4gICAgICAgICAgICBpbnN0cnVjdGlvblsyMF07XG4gICAgICAgICAgICBmaWxsS2V5ID1cbiAgICAgICAgICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bMjFdO1xuICAgICAgICAgICAgdmFyIGxhYmVsV2l0aEFuY2hvciA9IHRoaXMuZHJhd0xhYmVsV2l0aFBvaW50UGxhY2VtZW50Xyh0ZXh0LCB0ZXh0S2V5LCBzdHJva2VLZXksIGZpbGxLZXkpO1xuICAgICAgICAgICAgaW1hZ2UgPSBsYWJlbFdpdGhBbmNob3IubGFiZWw7XG4gICAgICAgICAgICBpbnN0cnVjdGlvblszXSA9IGltYWdlO1xuICAgICAgICAgICAgdmFyIHRleHRPZmZzZXRYID1cbiAgICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bMjJdO1xuICAgICAgICAgICAgYW5jaG9yWCA9IChsYWJlbFdpdGhBbmNob3IuYW5jaG9yWCAtIHRleHRPZmZzZXRYKSAqIHRoaXMucGl4ZWxSYXRpbztcbiAgICAgICAgICAgIGluc3RydWN0aW9uWzRdID0gYW5jaG9yWDtcbiAgICAgICAgICAgIHZhciB0ZXh0T2Zmc2V0WSA9XG4gICAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICAgIGluc3RydWN0aW9uWzIzXTtcbiAgICAgICAgICAgIGFuY2hvclkgPSAobGFiZWxXaXRoQW5jaG9yLmFuY2hvclkgLSB0ZXh0T2Zmc2V0WSkgKiB0aGlzLnBpeGVsUmF0aW87XG4gICAgICAgICAgICBpbnN0cnVjdGlvbls1XSA9IGFuY2hvclk7XG4gICAgICAgICAgICBoZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgICAgICAgICBpbnN0cnVjdGlvbls2XSA9IGhlaWdodDtcbiAgICAgICAgICAgIHdpZHRoID0gaW1hZ2Uud2lkdGg7XG4gICAgICAgICAgICBpbnN0cnVjdGlvblsxM10gPSB3aWR0aDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgZ2VvbWV0cnlXaWR0aHMgPSB2b2lkIDA7XG5cbiAgICAgICAgICBpZiAoaW5zdHJ1Y3Rpb24ubGVuZ3RoID4gMjQpIHtcbiAgICAgICAgICAgIGdlb21ldHJ5V2lkdGhzID1cbiAgICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bMjRdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBwYWRkaW5nID0gdm9pZCAwLFxuICAgICAgICAgICAgICBiYWNrZ3JvdW5kRmlsbCA9IHZvaWQgMCxcbiAgICAgICAgICAgICAgYmFja2dyb3VuZFN0cm9rZSA9IHZvaWQgMDtcblxuICAgICAgICAgIGlmIChpbnN0cnVjdGlvbi5sZW5ndGggPiAxNikge1xuICAgICAgICAgICAgcGFkZGluZyA9XG4gICAgICAgICAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG4gICAgICAgICAgICBpbnN0cnVjdGlvblsxNV07XG4gICAgICAgICAgICBiYWNrZ3JvdW5kRmlsbCA9XG4gICAgICAgICAgICAvKiogQHR5cGUge2Jvb2xlYW59ICovXG4gICAgICAgICAgICBpbnN0cnVjdGlvblsxNl07XG4gICAgICAgICAgICBiYWNrZ3JvdW5kU3Ryb2tlID1cbiAgICAgICAgICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgICAgICAgICAgIGluc3RydWN0aW9uWzE3XTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFkZGluZyA9IGRlZmF1bHRQYWRkaW5nO1xuICAgICAgICAgICAgYmFja2dyb3VuZEZpbGwgPSBmYWxzZTtcbiAgICAgICAgICAgIGJhY2tncm91bmRTdHJva2UgPSBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocm90YXRlV2l0aFZpZXcgJiYgdmlld1JvdGF0aW9uRnJvbVRyYW5zZm9ybSkge1xuICAgICAgICAgICAgLy8gQ2FudmFzIGlzIGV4cGVjdGVkIHRvIGJlIHJvdGF0ZWQgdG8gcmV2ZXJzZSB2aWV3IHJvdGF0aW9uLlxuICAgICAgICAgICAgcm90YXRpb24gKz0gdmlld1JvdGF0aW9uO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIXJvdGF0ZVdpdGhWaWV3ICYmICF2aWV3Um90YXRpb25Gcm9tVHJhbnNmb3JtKSB7XG4gICAgICAgICAgICAvLyBDYW52YXMgaXMgbm90IHJvdGF0ZWQsIGltYWdlcyBuZWVkIHRvIGJlIHJvdGF0ZWQgYmFjayB0byBiZSBub3J0aC11cC5cbiAgICAgICAgICAgIHJvdGF0aW9uIC09IHZpZXdSb3RhdGlvbjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgd2lkdGhJbmRleCA9IDA7XG5cbiAgICAgICAgICBmb3IgKDsgZCA8IGRkOyBkICs9IDIpIHtcbiAgICAgICAgICAgIGlmIChnZW9tZXRyeVdpZHRocyAmJiBnZW9tZXRyeVdpZHRoc1t3aWR0aEluZGV4KytdIDwgd2lkdGggLyB0aGlzLnBpeGVsUmF0aW8pIHtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBkaW1lbnNpb25zID0gdGhpcy5jYWxjdWxhdGVJbWFnZU9yTGFiZWxEaW1lbnNpb25zXyhpbWFnZS53aWR0aCwgaW1hZ2UuaGVpZ2h0LCBwaXhlbENvb3JkaW5hdGVzW2RdLCBwaXhlbENvb3JkaW5hdGVzW2QgKyAxXSwgd2lkdGgsIGhlaWdodCwgYW5jaG9yWCwgYW5jaG9yWSwgb3JpZ2luWCwgb3JpZ2luWSwgcm90YXRpb24sIHNjYWxlLCBzbmFwVG9QaXhlbCwgcGFkZGluZywgYmFja2dyb3VuZEZpbGwgfHwgYmFja2dyb3VuZFN0cm9rZSwgZmVhdHVyZSk7XG4gICAgICAgICAgICAvKiogQHR5cGUge1JlcGxheUltYWdlT3JMYWJlbEFyZ3N9ICovXG5cbiAgICAgICAgICAgIHZhciBhcmdzID0gW2NvbnRleHQsIGNvbnRleHRTY2FsZSwgaW1hZ2UsIGRpbWVuc2lvbnMsIG9wYWNpdHksIGJhY2tncm91bmRGaWxsID9cbiAgICAgICAgICAgIC8qKiBAdHlwZSB7QXJyYXk8Kj59ICovXG4gICAgICAgICAgICBsYXN0RmlsbEluc3RydWN0aW9uIDogbnVsbCwgYmFja2dyb3VuZFN0cm9rZSA/XG4gICAgICAgICAgICAvKiogQHR5cGUge0FycmF5PCo+fSAqL1xuICAgICAgICAgICAgbGFzdFN0cm9rZUluc3RydWN0aW9uIDogbnVsbF07XG4gICAgICAgICAgICB2YXIgaW1hZ2VBcmdzID0gdm9pZCAwO1xuICAgICAgICAgICAgdmFyIGltYWdlRGVjbHV0dGVyQm94ID0gdm9pZCAwO1xuXG4gICAgICAgICAgICBpZiAob3B0X2RlY2x1dHRlclRyZWUgJiYgZGVjbHV0dGVySW1hZ2VXaXRoVGV4dCkge1xuICAgICAgICAgICAgICBpZiAoIWRlY2x1dHRlckltYWdlV2l0aFRleHRbZF0pIHtcbiAgICAgICAgICAgICAgICAvLyBXZSBub3cgaGF2ZSB0aGUgaW1hZ2UgZm9yIGFuIGltYWdlK3RleHQgY29tYmluYXRpb24uXG4gICAgICAgICAgICAgICAgZGVjbHV0dGVySW1hZ2VXaXRoVGV4dFtkXSA9IGFyZ3M7IC8vIERvbid0IHJlbmRlciBhbnl0aGluZyBmb3Igbm93LCB3YWl0IGZvciB0aGUgdGV4dC5cblxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaW1hZ2VBcmdzID0gZGVjbHV0dGVySW1hZ2VXaXRoVGV4dFtkXTtcbiAgICAgICAgICAgICAgZGVsZXRlIGRlY2x1dHRlckltYWdlV2l0aFRleHRbZF07XG4gICAgICAgICAgICAgIGltYWdlRGVjbHV0dGVyQm94ID0gZ2V0RGVjbHV0dGVyQm94KGltYWdlQXJncyk7XG5cbiAgICAgICAgICAgICAgaWYgKG9wdF9kZWNsdXR0ZXJUcmVlLmNvbGxpZGVzKGltYWdlRGVjbHV0dGVyQm94KSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChvcHRfZGVjbHV0dGVyVHJlZSAmJiBvcHRfZGVjbHV0dGVyVHJlZS5jb2xsaWRlcyhkaW1lbnNpb25zLmRlY2x1dHRlckJveCkpIHtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpbWFnZUFyZ3MpIHtcbiAgICAgICAgICAgICAgLy8gV2Ugbm93IGhhdmUgaW1hZ2UgYW5kIHRleHQgZm9yIGFuIGltYWdlK3RleHQgY29tYmluYXRpb24uXG4gICAgICAgICAgICAgIGlmIChvcHRfZGVjbHV0dGVyVHJlZSkge1xuICAgICAgICAgICAgICAgIG9wdF9kZWNsdXR0ZXJUcmVlLmluc2VydChpbWFnZURlY2x1dHRlckJveCk7XG4gICAgICAgICAgICAgIH0gLy8gUmVuZGVyIHRoZSBpbWFnZSBiZWZvcmUgd2UgcmVuZGVyIHRoZSB0ZXh0LlxuXG5cbiAgICAgICAgICAgICAgdGhpcy5yZXBsYXlJbWFnZU9yTGFiZWxfLmFwcGx5KHRoaXMsIGltYWdlQXJncyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChvcHRfZGVjbHV0dGVyVHJlZSkge1xuICAgICAgICAgICAgICBvcHRfZGVjbHV0dGVyVHJlZS5pbnNlcnQoZGltZW5zaW9ucy5kZWNsdXR0ZXJCb3gpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnJlcGxheUltYWdlT3JMYWJlbF8uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgKytpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgQ2FudmFzSW5zdHJ1Y3Rpb24uRFJBV19DSEFSUzpcbiAgICAgICAgICB2YXIgYmVnaW4gPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzFdO1xuICAgICAgICAgIHZhciBlbmQgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzJdO1xuICAgICAgICAgIHZhciBiYXNlbGluZSA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bM107XG4gICAgICAgICAgdmFyIG92ZXJmbG93ID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvbls0XTtcbiAgICAgICAgICBmaWxsS2V5ID1cbiAgICAgICAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvbls1XTtcbiAgICAgICAgICB2YXIgbWF4QW5nbGUgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzZdO1xuICAgICAgICAgIHZhciBtZWFzdXJlUGl4ZWxSYXRpbyA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bN107XG4gICAgICAgICAgdmFyIG9mZnNldFkgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzhdO1xuICAgICAgICAgIHN0cm9rZUtleSA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bOV07XG4gICAgICAgICAgdmFyIHN0cm9rZVdpZHRoID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxMF07XG4gICAgICAgICAgdGV4dCA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bMTFdO1xuICAgICAgICAgIHRleHRLZXkgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzEyXTtcbiAgICAgICAgICB2YXIgcGl4ZWxSYXRpb1NjYWxlID0gW1xuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzEzXSxcbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxM11dO1xuICAgICAgICAgIHZhciB0ZXh0U3RhdGUgPSB0aGlzLnRleHRTdGF0ZXNbdGV4dEtleV07XG4gICAgICAgICAgdmFyIGZvbnQgPSB0ZXh0U3RhdGUuZm9udDtcbiAgICAgICAgICB2YXIgdGV4dFNjYWxlID0gW3RleHRTdGF0ZS5zY2FsZVswXSAqIG1lYXN1cmVQaXhlbFJhdGlvLCB0ZXh0U3RhdGUuc2NhbGVbMV0gKiBtZWFzdXJlUGl4ZWxSYXRpb107XG4gICAgICAgICAgdmFyIGNhY2hlZFdpZHRocyA9IHZvaWQgMDtcblxuICAgICAgICAgIGlmIChmb250IGluIHRoaXMud2lkdGhzXykge1xuICAgICAgICAgICAgY2FjaGVkV2lkdGhzID0gdGhpcy53aWR0aHNfW2ZvbnRdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRXaWR0aHMgPSB7fTtcbiAgICAgICAgICAgIHRoaXMud2lkdGhzX1tmb250XSA9IGNhY2hlZFdpZHRocztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgcGF0aExlbmd0aCA9IGxpbmVTdHJpbmdMZW5ndGgocGl4ZWxDb29yZGluYXRlcywgYmVnaW4sIGVuZCwgMik7XG4gICAgICAgICAgdmFyIHRleHRMZW5ndGggPSBNYXRoLmFicyh0ZXh0U2NhbGVbMF0pICogbWVhc3VyZUFuZENhY2hlVGV4dFdpZHRoKGZvbnQsIHRleHQsIGNhY2hlZFdpZHRocyk7XG5cbiAgICAgICAgICBpZiAob3ZlcmZsb3cgfHwgdGV4dExlbmd0aCA8PSBwYXRoTGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgdGV4dEFsaWduID0gdGhpcy50ZXh0U3RhdGVzW3RleHRLZXldLnRleHRBbGlnbjtcbiAgICAgICAgICAgIHZhciBzdGFydE0gPSAocGF0aExlbmd0aCAtIHRleHRMZW5ndGgpICogVEVYVF9BTElHTlt0ZXh0QWxpZ25dO1xuICAgICAgICAgICAgdmFyIHBhcnRzID0gZHJhd1RleHRPblBhdGgocGl4ZWxDb29yZGluYXRlcywgYmVnaW4sIGVuZCwgMiwgdGV4dCwgc3RhcnRNLCBtYXhBbmdsZSwgTWF0aC5hYnModGV4dFNjYWxlWzBdKSwgbWVhc3VyZUFuZENhY2hlVGV4dFdpZHRoLCBmb250LCBjYWNoZWRXaWR0aHMsIHZpZXdSb3RhdGlvbkZyb21UcmFuc2Zvcm0gPyAwIDogdGhpcy52aWV3Um90YXRpb25fKTtcblxuICAgICAgICAgICAgZHJhd0NoYXJzOiBpZiAocGFydHMpIHtcbiAgICAgICAgICAgICAgLyoqIEB0eXBlIHtBcnJheTxSZXBsYXlJbWFnZU9yTGFiZWxBcmdzPn0gKi9cbiAgICAgICAgICAgICAgdmFyIHJlcGxheUltYWdlT3JMYWJlbEFyZ3MgPSBbXTtcbiAgICAgICAgICAgICAgdmFyIGMgPSB2b2lkIDAsXG4gICAgICAgICAgICAgICAgICBjYyA9IHZvaWQgMCxcbiAgICAgICAgICAgICAgICAgIGNoYXJzID0gdm9pZCAwLFxuICAgICAgICAgICAgICAgICAgbGFiZWwgPSB2b2lkIDAsXG4gICAgICAgICAgICAgICAgICBwYXJ0ID0gdm9pZCAwO1xuXG4gICAgICAgICAgICAgIGlmIChzdHJva2VLZXkpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGMgPSAwLCBjYyA9IHBhcnRzLmxlbmd0aDsgYyA8IGNjOyArK2MpIHtcbiAgICAgICAgICAgICAgICAgIHBhcnQgPSBwYXJ0c1tjXTsgLy8geCwgeSwgYW5jaG9yWCwgcm90YXRpb24sIGNodW5rXG5cbiAgICAgICAgICAgICAgICAgIGNoYXJzID1cbiAgICAgICAgICAgICAgICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgICAgICAgICAgICAgICAgcGFydFs0XTtcbiAgICAgICAgICAgICAgICAgIGxhYmVsID0gdGhpcy5jcmVhdGVMYWJlbChjaGFycywgdGV4dEtleSwgJycsIHN0cm9rZUtleSk7XG4gICAgICAgICAgICAgICAgICBhbmNob3JYID1cbiAgICAgICAgICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgICAgICAgICAgcGFydFsyXSArICh0ZXh0U2NhbGVbMF0gPCAwID8gLXN0cm9rZVdpZHRoIDogc3Ryb2tlV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgYW5jaG9yWSA9IGJhc2VsaW5lICogbGFiZWwuaGVpZ2h0ICsgKDAuNSAtIGJhc2VsaW5lKSAqIDIgKiBzdHJva2VXaWR0aCAqIHRleHRTY2FsZVsxXSAvIHRleHRTY2FsZVswXSAtIG9mZnNldFk7XG4gICAgICAgICAgICAgICAgICB2YXIgZGltZW5zaW9ucyA9IHRoaXMuY2FsY3VsYXRlSW1hZ2VPckxhYmVsRGltZW5zaW9uc18obGFiZWwud2lkdGgsIGxhYmVsLmhlaWdodCwgcGFydFswXSwgcGFydFsxXSwgbGFiZWwud2lkdGgsIGxhYmVsLmhlaWdodCwgYW5jaG9yWCwgYW5jaG9yWSwgMCwgMCwgcGFydFszXSwgcGl4ZWxSYXRpb1NjYWxlLCBmYWxzZSwgZGVmYXVsdFBhZGRpbmcsIGZhbHNlLCBmZWF0dXJlKTtcblxuICAgICAgICAgICAgICAgICAgaWYgKG9wdF9kZWNsdXR0ZXJUcmVlICYmIG9wdF9kZWNsdXR0ZXJUcmVlLmNvbGxpZGVzKGRpbWVuc2lvbnMuZGVjbHV0dGVyQm94KSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhayBkcmF3Q2hhcnM7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIHJlcGxheUltYWdlT3JMYWJlbEFyZ3MucHVzaChbY29udGV4dCwgY29udGV4dFNjYWxlLCBsYWJlbCwgZGltZW5zaW9ucywgMSwgbnVsbCwgbnVsbF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChmaWxsS2V5KSB7XG4gICAgICAgICAgICAgICAgZm9yIChjID0gMCwgY2MgPSBwYXJ0cy5sZW5ndGg7IGMgPCBjYzsgKytjKSB7XG4gICAgICAgICAgICAgICAgICBwYXJ0ID0gcGFydHNbY107IC8vIHgsIHksIGFuY2hvclgsIHJvdGF0aW9uLCBjaHVua1xuXG4gICAgICAgICAgICAgICAgICBjaGFycyA9XG4gICAgICAgICAgICAgICAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICAgICAgICAgICAgICAgIHBhcnRbNF07XG4gICAgICAgICAgICAgICAgICBsYWJlbCA9IHRoaXMuY3JlYXRlTGFiZWwoY2hhcnMsIHRleHRLZXksIGZpbGxLZXksICcnKTtcbiAgICAgICAgICAgICAgICAgIGFuY2hvclggPVxuICAgICAgICAgICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgICAgICAgICBwYXJ0WzJdO1xuICAgICAgICAgICAgICAgICAgYW5jaG9yWSA9IGJhc2VsaW5lICogbGFiZWwuaGVpZ2h0IC0gb2Zmc2V0WTtcbiAgICAgICAgICAgICAgICAgIHZhciBkaW1lbnNpb25zID0gdGhpcy5jYWxjdWxhdGVJbWFnZU9yTGFiZWxEaW1lbnNpb25zXyhsYWJlbC53aWR0aCwgbGFiZWwuaGVpZ2h0LCBwYXJ0WzBdLCBwYXJ0WzFdLCBsYWJlbC53aWR0aCwgbGFiZWwuaGVpZ2h0LCBhbmNob3JYLCBhbmNob3JZLCAwLCAwLCBwYXJ0WzNdLCBwaXhlbFJhdGlvU2NhbGUsIGZhbHNlLCBkZWZhdWx0UGFkZGluZywgZmFsc2UsIGZlYXR1cmUpO1xuXG4gICAgICAgICAgICAgICAgICBpZiAob3B0X2RlY2x1dHRlclRyZWUgJiYgb3B0X2RlY2x1dHRlclRyZWUuY29sbGlkZXMoZGltZW5zaW9ucy5kZWNsdXR0ZXJCb3gpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrIGRyYXdDaGFycztcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgcmVwbGF5SW1hZ2VPckxhYmVsQXJncy5wdXNoKFtjb250ZXh0LCBjb250ZXh0U2NhbGUsIGxhYmVsLCBkaW1lbnNpb25zLCAxLCBudWxsLCBudWxsXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKG9wdF9kZWNsdXR0ZXJUcmVlKSB7XG4gICAgICAgICAgICAgICAgb3B0X2RlY2x1dHRlclRyZWUubG9hZChyZXBsYXlJbWFnZU9yTGFiZWxBcmdzLm1hcChnZXREZWNsdXR0ZXJCb3gpKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGZvciAodmFyIGlfMSA9IDAsIGlpXzEgPSByZXBsYXlJbWFnZU9yTGFiZWxBcmdzLmxlbmd0aDsgaV8xIDwgaWlfMTsgKytpXzEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlcGxheUltYWdlT3JMYWJlbF8uYXBwbHkodGhpcywgcmVwbGF5SW1hZ2VPckxhYmVsQXJnc1tpXzFdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgICsraTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIENhbnZhc0luc3RydWN0aW9uLkVORF9HRU9NRVRSWTpcbiAgICAgICAgICBpZiAob3B0X2ZlYXR1cmVDYWxsYmFjayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBmZWF0dXJlID1cbiAgICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gKi9cbiAgICAgICAgICAgIGluc3RydWN0aW9uWzFdO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IG9wdF9mZWF0dXJlQ2FsbGJhY2soZmVhdHVyZSwgY3VycmVudEdlb21ldHJ5KTtcblxuICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgICsraTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIENhbnZhc0luc3RydWN0aW9uLkZJTEw6XG4gICAgICAgICAgaWYgKGJhdGNoU2l6ZSkge1xuICAgICAgICAgICAgcGVuZGluZ0ZpbGwrKztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5maWxsXyhjb250ZXh0KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICArK2k7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5NT1ZFX1RPX0xJTkVfVE86XG4gICAgICAgICAgZCA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bMV07XG4gICAgICAgICAgZGQgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzJdO1xuICAgICAgICAgIHggPSBwaXhlbENvb3JkaW5hdGVzW2RdO1xuICAgICAgICAgIHkgPSBwaXhlbENvb3JkaW5hdGVzW2QgKyAxXTtcbiAgICAgICAgICByb3VuZFggPSB4ICsgMC41IHwgMDtcbiAgICAgICAgICByb3VuZFkgPSB5ICsgMC41IHwgMDtcblxuICAgICAgICAgIGlmIChyb3VuZFggIT09IHByZXZYIHx8IHJvdW5kWSAhPT0gcHJldlkpIHtcbiAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKHgsIHkpO1xuICAgICAgICAgICAgcHJldlggPSByb3VuZFg7XG4gICAgICAgICAgICBwcmV2WSA9IHJvdW5kWTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKGQgKz0gMjsgZCA8IGRkOyBkICs9IDIpIHtcbiAgICAgICAgICAgIHggPSBwaXhlbENvb3JkaW5hdGVzW2RdO1xuICAgICAgICAgICAgeSA9IHBpeGVsQ29vcmRpbmF0ZXNbZCArIDFdO1xuICAgICAgICAgICAgcm91bmRYID0geCArIDAuNSB8IDA7XG4gICAgICAgICAgICByb3VuZFkgPSB5ICsgMC41IHwgMDtcblxuICAgICAgICAgICAgaWYgKGQgPT0gZGQgLSAyIHx8IHJvdW5kWCAhPT0gcHJldlggfHwgcm91bmRZICE9PSBwcmV2WSkge1xuICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICAgICAgICAgICAgcHJldlggPSByb3VuZFg7XG4gICAgICAgICAgICAgIHByZXZZID0gcm91bmRZO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgICsraTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIENhbnZhc0luc3RydWN0aW9uLlNFVF9GSUxMX1NUWUxFOlxuICAgICAgICAgIGxhc3RGaWxsSW5zdHJ1Y3Rpb24gPSBpbnN0cnVjdGlvbjtcbiAgICAgICAgICB0aGlzLmFsaWduRmlsbF8gPSBpbnN0cnVjdGlvblsyXTtcblxuICAgICAgICAgIGlmIChwZW5kaW5nRmlsbCkge1xuICAgICAgICAgICAgdGhpcy5maWxsXyhjb250ZXh0KTtcbiAgICAgICAgICAgIHBlbmRpbmdGaWxsID0gMDtcblxuICAgICAgICAgICAgaWYgKHBlbmRpbmdTdHJva2UpIHtcbiAgICAgICAgICAgICAgY29udGV4dC5zdHJva2UoKTtcbiAgICAgICAgICAgICAgcGVuZGluZ1N0cm9rZSA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29udGV4dC5maWxsU3R5bGUgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxXTtcbiAgICAgICAgICArK2k7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5TRVRfU1RST0tFX1NUWUxFOlxuICAgICAgICAgIGxhc3RTdHJva2VJbnN0cnVjdGlvbiA9IGluc3RydWN0aW9uO1xuXG4gICAgICAgICAgaWYgKHBlbmRpbmdTdHJva2UpIHtcbiAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgICAgICAgICBwZW5kaW5nU3Ryb2tlID0gMDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLnNldFN0cm9rZVN0eWxlXyhjb250ZXh0LFxuICAgICAgICAgIC8qKiBAdHlwZSB7QXJyYXk8Kj59ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb24pO1xuICAgICAgICAgICsraTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIENhbnZhc0luc3RydWN0aW9uLlNUUk9LRTpcbiAgICAgICAgICBpZiAoYmF0Y2hTaXplKSB7XG4gICAgICAgICAgICBwZW5kaW5nU3Ryb2tlKys7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgKytpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgKytpOyAvLyBjb25zdW1lIHRoZSBpbnN0cnVjdGlvbiBhbnl3YXksIHRvIGF2b2lkIGFuIGluZmluaXRlIGxvb3BcblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwZW5kaW5nRmlsbCkge1xuICAgICAgdGhpcy5maWxsXyhjb250ZXh0KTtcbiAgICB9XG5cbiAgICBpZiAocGVuZGluZ1N0cm9rZSkge1xuICAgICAgY29udGV4dC5zdHJva2UoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvbnRleHRTY2FsZSBTY2FsZSBvZiB0aGUgY29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfSB0cmFuc2Zvcm0gVHJhbnNmb3JtLlxuICAgKiBAcGFyYW0ge251bWJlcn0gdmlld1JvdGF0aW9uIFZpZXcgcm90YXRpb24uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gc25hcFRvUGl4ZWwgU25hcCBwb2ludCBzeW1ib2xzIGFuZCB0ZXh0IHRvIGludGVnZXIgcGl4ZWxzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInJidXNoXCIpLmRlZmF1bHQ9fSBvcHRfZGVjbHV0dGVyVHJlZSBEZWNsdXR0ZXIgdHJlZS5cbiAgICovXG5cblxuICBFeGVjdXRvci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChjb250ZXh0LCBjb250ZXh0U2NhbGUsIHRyYW5zZm9ybSwgdmlld1JvdGF0aW9uLCBzbmFwVG9QaXhlbCwgb3B0X2RlY2x1dHRlclRyZWUpIHtcbiAgICB0aGlzLnZpZXdSb3RhdGlvbl8gPSB2aWV3Um90YXRpb247XG4gICAgdGhpcy5leGVjdXRlXyhjb250ZXh0LCBjb250ZXh0U2NhbGUsIHRyYW5zZm9ybSwgdGhpcy5pbnN0cnVjdGlvbnMsIHNuYXBUb1BpeGVsLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgb3B0X2RlY2x1dHRlclRyZWUpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfSB0cmFuc2Zvcm0gVHJhbnNmb3JtLlxuICAgKiBAcGFyYW0ge251bWJlcn0gdmlld1JvdGF0aW9uIFZpZXcgcm90YXRpb24uXG4gICAqIEBwYXJhbSB7RmVhdHVyZUNhbGxiYWNrPFQ+PX0gb3B0X2ZlYXR1cmVDYWxsYmFjayBGZWF0dXJlIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnQ9fSBvcHRfaGl0RXh0ZW50IE9ubHkgY2hlY2tcbiAgICogICAgIGZlYXR1cmVzIHRoYXQgaW50ZXJzZWN0IHRoaXMgZXh0ZW50LlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKi9cblxuXG4gIEV4ZWN1dG9yLnByb3RvdHlwZS5leGVjdXRlSGl0RGV0ZWN0aW9uID0gZnVuY3Rpb24gKGNvbnRleHQsIHRyYW5zZm9ybSwgdmlld1JvdGF0aW9uLCBvcHRfZmVhdHVyZUNhbGxiYWNrLCBvcHRfaGl0RXh0ZW50KSB7XG4gICAgdGhpcy52aWV3Um90YXRpb25fID0gdmlld1JvdGF0aW9uO1xuICAgIHJldHVybiB0aGlzLmV4ZWN1dGVfKGNvbnRleHQsIDEsIHRyYW5zZm9ybSwgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMsIHRydWUsIG9wdF9mZWF0dXJlQ2FsbGJhY2ssIG9wdF9oaXRFeHRlbnQpO1xuICB9O1xuXG4gIHJldHVybiBFeGVjdXRvcjtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgRXhlY3V0b3I7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9jYW52YXMvRXhlY3V0b3JHcm91cFxuICovXG5pbXBvcnQgQnVpbGRlclR5cGUgZnJvbSAnLi9CdWlsZGVyVHlwZS5qcyc7XG5pbXBvcnQgRXhlY3V0b3IgZnJvbSAnLi9FeGVjdXRvci5qcyc7XG5pbXBvcnQgeyBidWZmZXIsIGNyZWF0ZUVtcHR5LCBleHRlbmRDb29yZGluYXRlIH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGNvbXBvc2UgYXMgY29tcG9zZVRyYW5zZm9ybSwgY3JlYXRlIGFzIGNyZWF0ZVRyYW5zZm9ybSB9IGZyb20gJy4uLy4uL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVDYW52YXNDb250ZXh0MkQgfSBmcm9tICcuLi8uLi9kb20uanMnO1xuaW1wb3J0IHsgaXNFbXB0eSB9IGZyb20gJy4uLy4uL29iai5qcyc7XG5pbXBvcnQgeyBudW1iZXJTYWZlQ29tcGFyZUZ1bmN0aW9uIH0gZnJvbSAnLi4vLi4vYXJyYXkuanMnO1xuaW1wb3J0IHsgdHJhbnNmb3JtMkQgfSBmcm9tICcuLi8uLi9nZW9tL2ZsYXQvdHJhbnNmb3JtLmpzJztcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi9CdWlsZGVyVHlwZS5qc1wiKS5kZWZhdWx0Pn1cbiAqL1xuXG52YXIgT1JERVIgPSBbQnVpbGRlclR5cGUuUE9MWUdPTiwgQnVpbGRlclR5cGUuQ0lSQ0xFLCBCdWlsZGVyVHlwZS5MSU5FX1NUUklORywgQnVpbGRlclR5cGUuSU1BR0UsIEJ1aWxkZXJUeXBlLlRFWFQsIEJ1aWxkZXJUeXBlLkRFRkFVTFRdO1xuXG52YXIgRXhlY3V0b3JHcm91cCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IG1heEV4dGVudCBNYXggZXh0ZW50IGZvciBjbGlwcGluZy4gV2hlbiBhXG4gICAqIGBtYXhFeHRlbnRgIHdhcyBzZXQgb24gdGhlIEJ1aWxsZGVyIGZvciB0aGlzIGV4ZWN1dG9yIGdyb3VwLCB0aGUgc2FtZSBgbWF4RXh0ZW50YFxuICAgKiBzaG91bGQgYmUgc2V0IGhlcmUsIHVubGVzcyB0aGUgdGFyZ2V0IGNvbnRleHQgZG9lcyBub3QgZXhjZWV0IHRoYXQgZXh0ZW50ICh3aGljaFxuICAgKiBjYW4gYmUgdGhlIGNhc2Ugd2hlbiByZW5kZXJpbmcgdG8gdGlsZXMpLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtib29sZWFufSBvdmVybGFwcyBUaGUgZXhlY3V0b3IgZ3JvdXAgY2FuIGhhdmUgb3ZlcmxhcHBpbmcgZ2VvbWV0cmllcy5cbiAgICogQHBhcmFtIHshT2JqZWN0PHN0cmluZywgIU9iamVjdDxpbXBvcnQoXCIuL0J1aWxkZXJUeXBlLmpzXCIpLmRlZmF1bHQsIGltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5TZXJpYWxpemFibGVJbnN0cnVjdGlvbnM+Pn0gYWxsSW5zdHJ1Y3Rpb25zXG4gICAqIFRoZSBzZXJpYWxpemFibGUgaW5zdHJ1Y3Rpb25zLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9yZW5kZXJCdWZmZXIgT3B0aW9uYWwgcmVuZGVyaW5nIGJ1ZmZlci5cbiAgICovXG4gIGZ1bmN0aW9uIEV4ZWN1dG9yR3JvdXAobWF4RXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvLCBvdmVybGFwcywgYWxsSW5zdHJ1Y3Rpb25zLCBvcHRfcmVuZGVyQnVmZmVyKSB7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKi9cbiAgICB0aGlzLm1heEV4dGVudF8gPSBtYXhFeHRlbnQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIHRoaXMub3ZlcmxhcHNfID0gb3ZlcmxhcHM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5waXhlbFJhdGlvXyA9IHBpeGVsUmF0aW87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5yZXNvbHV0aW9uXyA9IHJlc29sdXRpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHRoaXMucmVuZGVyQnVmZmVyXyA9IG9wdF9yZW5kZXJCdWZmZXI7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsICFPYmplY3Q8aW1wb3J0KFwiLi9CdWlsZGVyVHlwZS5qc1wiKS5kZWZhdWx0LCBpbXBvcnQoXCIuL0V4ZWN1dG9yXCIpLmRlZmF1bHQ+Pn1cbiAgICAgKi9cblxuICAgIHRoaXMuZXhlY3V0b3JzQnlaSW5kZXhfID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfVxuICAgICAqL1xuXG4gICAgdGhpcy5oaXREZXRlY3Rpb25Db250ZXh0XyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX1cbiAgICAgKi9cblxuICAgIHRoaXMuaGl0RGV0ZWN0aW9uVHJhbnNmb3JtXyA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xuICAgIHRoaXMuY3JlYXRlRXhlY3V0b3JzXyhhbGxJbnN0cnVjdGlvbnMpO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gICAqL1xuXG5cbiAgRXhlY3V0b3JHcm91cC5wcm90b3R5cGUuY2xpcCA9IGZ1bmN0aW9uIChjb250ZXh0LCB0cmFuc2Zvcm0pIHtcbiAgICB2YXIgZmxhdENsaXBDb29yZHMgPSB0aGlzLmdldENsaXBDb29yZHModHJhbnNmb3JtKTtcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgIGNvbnRleHQubW92ZVRvKGZsYXRDbGlwQ29vcmRzWzBdLCBmbGF0Q2xpcENvb3Jkc1sxXSk7XG4gICAgY29udGV4dC5saW5lVG8oZmxhdENsaXBDb29yZHNbMl0sIGZsYXRDbGlwQ29vcmRzWzNdKTtcbiAgICBjb250ZXh0LmxpbmVUbyhmbGF0Q2xpcENvb3Jkc1s0XSwgZmxhdENsaXBDb29yZHNbNV0pO1xuICAgIGNvbnRleHQubGluZVRvKGZsYXRDbGlwQ29vcmRzWzZdLCBmbGF0Q2xpcENvb3Jkc1s3XSk7XG4gICAgY29udGV4dC5jbGlwKCk7XG4gIH07XG4gIC8qKlxuICAgKiBDcmVhdGUgZXhlY3V0b3JzIGFuZCBwb3B1bGF0ZSB0aGVtIHVzaW5nIHRoZSBwcm92aWRlZCBpbnN0cnVjdGlvbnMuXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7IU9iamVjdDxzdHJpbmcsICFPYmplY3Q8aW1wb3J0KFwiLi9CdWlsZGVyVHlwZS5qc1wiKS5kZWZhdWx0LCBpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU2VyaWFsaXphYmxlSW5zdHJ1Y3Rpb25zPj59IGFsbEluc3RydWN0aW9ucyBUaGUgc2VyaWFsaXphYmxlIGluc3RydWN0aW9uc1xuICAgKi9cblxuXG4gIEV4ZWN1dG9yR3JvdXAucHJvdG90eXBlLmNyZWF0ZUV4ZWN1dG9yc18gPSBmdW5jdGlvbiAoYWxsSW5zdHJ1Y3Rpb25zKSB7XG4gICAgZm9yICh2YXIgekluZGV4IGluIGFsbEluc3RydWN0aW9ucykge1xuICAgICAgdmFyIGV4ZWN1dG9ycyA9IHRoaXMuZXhlY3V0b3JzQnlaSW5kZXhfW3pJbmRleF07XG5cbiAgICAgIGlmIChleGVjdXRvcnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBleGVjdXRvcnMgPSB7fTtcbiAgICAgICAgdGhpcy5leGVjdXRvcnNCeVpJbmRleF9bekluZGV4XSA9IGV4ZWN1dG9ycztcbiAgICAgIH1cblxuICAgICAgdmFyIGluc3RydWN0aW9uQnlaaW5kZXggPSBhbGxJbnN0cnVjdGlvbnNbekluZGV4XTtcbiAgICAgIHZhciByZW5kZXJCdWZmZXIgPSBbdGhpcy5yZW5kZXJCdWZmZXJfIHx8IDAsIHRoaXMucmVuZGVyQnVmZmVyXyB8fCAwXTtcblxuICAgICAgZm9yICh2YXIgYnVpbGRlclR5cGUgaW4gaW5zdHJ1Y3Rpb25CeVppbmRleCkge1xuICAgICAgICB2YXIgaW5zdHJ1Y3Rpb25zID0gaW5zdHJ1Y3Rpb25CeVppbmRleFtidWlsZGVyVHlwZV07XG4gICAgICAgIGV4ZWN1dG9yc1tidWlsZGVyVHlwZV0gPSBuZXcgRXhlY3V0b3IodGhpcy5yZXNvbHV0aW9uXywgdGhpcy5waXhlbFJhdGlvXywgdGhpcy5vdmVybGFwc18sIGluc3RydWN0aW9ucywgcmVuZGVyQnVmZmVyKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vQnVpbGRlclR5cGUuanNcIikuZGVmYXVsdD59IGV4ZWN1dG9ycyBFeGVjdXRvcnMuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IEhhcyBleGVjdXRvcnMgb2YgdGhlIHByb3ZpZGVkIHR5cGVzLlxuICAgKi9cblxuXG4gIEV4ZWN1dG9yR3JvdXAucHJvdG90eXBlLmhhc0V4ZWN1dG9ycyA9IGZ1bmN0aW9uIChleGVjdXRvcnMpIHtcbiAgICBmb3IgKHZhciB6SW5kZXggaW4gdGhpcy5leGVjdXRvcnNCeVpJbmRleF8pIHtcbiAgICAgIHZhciBjYW5kaWRhdGVzID0gdGhpcy5leGVjdXRvcnNCeVpJbmRleF9bekluZGV4XTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZXhlY3V0b3JzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgaWYgKGV4ZWN1dG9yc1tpXSBpbiBjYW5kaWRhdGVzKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcm90YXRpb24gUm90YXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoaXRUb2xlcmFuY2UgSGl0IHRvbGVyYW5jZSBpbiBwaXhlbHMuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZSwgaW1wb3J0KFwiLi4vLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0LCBudW1iZXIpOiBUfSBjYWxsYmFjayBGZWF0dXJlIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2U+fSBkZWNsdXR0ZXJlZEZlYXR1cmVzIERlY2x1dHRlcmVkIGZlYXR1cmVzLlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKi9cblxuXG4gIEV4ZWN1dG9yR3JvdXAucHJvdG90eXBlLmZvckVhY2hGZWF0dXJlQXRDb29yZGluYXRlID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUsIHJlc29sdXRpb24sIHJvdGF0aW9uLCBoaXRUb2xlcmFuY2UsIGNhbGxiYWNrLCBkZWNsdXR0ZXJlZEZlYXR1cmVzKSB7XG4gICAgaGl0VG9sZXJhbmNlID0gTWF0aC5yb3VuZChoaXRUb2xlcmFuY2UpO1xuICAgIHZhciBjb250ZXh0U2l6ZSA9IGhpdFRvbGVyYW5jZSAqIDIgKyAxO1xuICAgIHZhciB0cmFuc2Zvcm0gPSBjb21wb3NlVHJhbnNmb3JtKHRoaXMuaGl0RGV0ZWN0aW9uVHJhbnNmb3JtXywgaGl0VG9sZXJhbmNlICsgMC41LCBoaXRUb2xlcmFuY2UgKyAwLjUsIDEgLyByZXNvbHV0aW9uLCAtMSAvIHJlc29sdXRpb24sIC1yb3RhdGlvbiwgLWNvb3JkaW5hdGVbMF0sIC1jb29yZGluYXRlWzFdKTtcbiAgICB2YXIgbmV3Q29udGV4dCA9ICF0aGlzLmhpdERldGVjdGlvbkNvbnRleHRfO1xuXG4gICAgaWYgKG5ld0NvbnRleHQpIHtcbiAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uQ29udGV4dF8gPSBjcmVhdGVDYW52YXNDb250ZXh0MkQoY29udGV4dFNpemUsIGNvbnRleHRTaXplKTtcbiAgICB9XG5cbiAgICB2YXIgY29udGV4dCA9IHRoaXMuaGl0RGV0ZWN0aW9uQ29udGV4dF87XG5cbiAgICBpZiAoY29udGV4dC5jYW52YXMud2lkdGggIT09IGNvbnRleHRTaXplIHx8IGNvbnRleHQuY2FudmFzLmhlaWdodCAhPT0gY29udGV4dFNpemUpIHtcbiAgICAgIGNvbnRleHQuY2FudmFzLndpZHRoID0gY29udGV4dFNpemU7XG4gICAgICBjb250ZXh0LmNhbnZhcy5oZWlnaHQgPSBjb250ZXh0U2l6ZTtcbiAgICB9IGVsc2UgaWYgKCFuZXdDb250ZXh0KSB7XG4gICAgICBjb250ZXh0LmNsZWFyUmVjdCgwLCAwLCBjb250ZXh0U2l6ZSwgY29udGV4dFNpemUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKi9cblxuXG4gICAgdmFyIGhpdEV4dGVudDtcblxuICAgIGlmICh0aGlzLnJlbmRlckJ1ZmZlcl8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgaGl0RXh0ZW50ID0gY3JlYXRlRW1wdHkoKTtcbiAgICAgIGV4dGVuZENvb3JkaW5hdGUoaGl0RXh0ZW50LCBjb29yZGluYXRlKTtcbiAgICAgIGJ1ZmZlcihoaXRFeHRlbnQsIHJlc29sdXRpb24gKiAodGhpcy5yZW5kZXJCdWZmZXJfICsgaGl0VG9sZXJhbmNlKSwgaGl0RXh0ZW50KTtcbiAgICB9XG5cbiAgICB2YXIgaW5kZXhlcyA9IGdldFBpeGVsSW5kZXhBcnJheShoaXRUb2xlcmFuY2UpO1xuICAgIHZhciBidWlsZGVyVHlwZTtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gICAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IENhbGxiYWNrIHJlc3VsdC5cbiAgICAgKi9cblxuICAgIGZ1bmN0aW9uIGZlYXR1cmVDYWxsYmFjayhmZWF0dXJlLCBnZW9tZXRyeSkge1xuICAgICAgdmFyIGltYWdlRGF0YSA9IGNvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIGNvbnRleHRTaXplLCBjb250ZXh0U2l6ZSkuZGF0YTtcblxuICAgICAgZm9yICh2YXIgaV8xID0gMCwgaWkgPSBpbmRleGVzLmxlbmd0aDsgaV8xIDwgaWk7IGlfMSsrKSB7XG4gICAgICAgIGlmIChpbWFnZURhdGFbaW5kZXhlc1tpXzFdXSA+IDApIHtcbiAgICAgICAgICBpZiAoIWRlY2x1dHRlcmVkRmVhdHVyZXMgfHwgYnVpbGRlclR5cGUgIT09IEJ1aWxkZXJUeXBlLklNQUdFICYmIGJ1aWxkZXJUeXBlICE9PSBCdWlsZGVyVHlwZS5URVhUIHx8IGRlY2x1dHRlcmVkRmVhdHVyZXMuaW5kZXhPZihmZWF0dXJlKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIHZhciBpZHggPSAoaW5kZXhlc1tpXzFdIC0gMykgLyA0O1xuICAgICAgICAgICAgdmFyIHggPSBoaXRUb2xlcmFuY2UgLSBpZHggJSBjb250ZXh0U2l6ZTtcbiAgICAgICAgICAgIHZhciB5ID0gaGl0VG9sZXJhbmNlIC0gKGlkeCAvIGNvbnRleHRTaXplIHwgMCk7XG4gICAgICAgICAgICB2YXIgcmVzdWx0XzEgPSBjYWxsYmFjayhmZWF0dXJlLCBnZW9tZXRyeSwgeCAqIHggKyB5ICogeSk7XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHRfMSkge1xuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0XzE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29udGV4dC5jbGVhclJlY3QoMCwgMCwgY29udGV4dFNpemUsIGNvbnRleHRTaXplKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG5cblxuICAgIHZhciB6cyA9IE9iamVjdC5rZXlzKHRoaXMuZXhlY3V0b3JzQnlaSW5kZXhfKS5tYXAoTnVtYmVyKTtcbiAgICB6cy5zb3J0KG51bWJlclNhZmVDb21wYXJlRnVuY3Rpb24pO1xuICAgIHZhciBpLCBqLCBleGVjdXRvcnMsIGV4ZWN1dG9yLCByZXN1bHQ7XG5cbiAgICBmb3IgKGkgPSB6cy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdmFyIHpJbmRleEtleSA9IHpzW2ldLnRvU3RyaW5nKCk7XG4gICAgICBleGVjdXRvcnMgPSB0aGlzLmV4ZWN1dG9yc0J5WkluZGV4X1t6SW5kZXhLZXldO1xuXG4gICAgICBmb3IgKGogPSBPUkRFUi5sZW5ndGggLSAxOyBqID49IDA7IC0taikge1xuICAgICAgICBidWlsZGVyVHlwZSA9IE9SREVSW2pdO1xuICAgICAgICBleGVjdXRvciA9IGV4ZWN1dG9yc1tidWlsZGVyVHlwZV07XG5cbiAgICAgICAgaWYgKGV4ZWN1dG9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXN1bHQgPSBleGVjdXRvci5leGVjdXRlSGl0RGV0ZWN0aW9uKGNvbnRleHQsIHRyYW5zZm9ybSwgcm90YXRpb24sIGZlYXR1cmVDYWxsYmFjaywgaGl0RXh0ZW50KTtcblxuICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gQ2xpcCBjb29yZGluYXRlcy5cbiAgICovXG5cblxuICBFeGVjdXRvckdyb3VwLnByb3RvdHlwZS5nZXRDbGlwQ29vcmRzID0gZnVuY3Rpb24gKHRyYW5zZm9ybSkge1xuICAgIHZhciBtYXhFeHRlbnQgPSB0aGlzLm1heEV4dGVudF87XG5cbiAgICBpZiAoIW1heEV4dGVudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIG1pblggPSBtYXhFeHRlbnRbMF07XG4gICAgdmFyIG1pblkgPSBtYXhFeHRlbnRbMV07XG4gICAgdmFyIG1heFggPSBtYXhFeHRlbnRbMl07XG4gICAgdmFyIG1heFkgPSBtYXhFeHRlbnRbM107XG4gICAgdmFyIGZsYXRDbGlwQ29vcmRzID0gW21pblgsIG1pblksIG1pblgsIG1heFksIG1heFgsIG1heFksIG1heFgsIG1pblldO1xuICAgIHRyYW5zZm9ybTJEKGZsYXRDbGlwQ29vcmRzLCAwLCA4LCAyLCB0cmFuc2Zvcm0sIGZsYXRDbGlwQ29vcmRzKTtcbiAgICByZXR1cm4gZmxhdENsaXBDb29yZHM7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJcyBlbXB0eS5cbiAgICovXG5cblxuICBFeGVjdXRvckdyb3VwLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBpc0VtcHR5KHRoaXMuZXhlY3V0b3JzQnlaSW5kZXhfKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IENvbnRleHQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjb250ZXh0U2NhbGUgU2NhbGUgb2YgdGhlIGNvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHZpZXdSb3RhdGlvbiBWaWV3IHJvdGF0aW9uLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNuYXBUb1BpeGVsIFNuYXAgcG9pbnQgc3ltYm9scyBhbmQgdGVzdCB0byBpbnRlZ2VyIHBpeGVsLlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vQnVpbGRlclR5cGUuanNcIikuZGVmYXVsdD49fSBvcHRfYnVpbGRlclR5cGVzIE9yZGVyZWQgcmVwbGF5IHR5cGVzIHRvIHJlcGxheS5cbiAgICogICAgIERlZmF1bHQgaXMge0BsaW5rIG1vZHVsZTpvbC9yZW5kZXIvcmVwbGF5fk9SREVSfVxuICAgKiBAcGFyYW0ge2ltcG9ydChcInJidXNoXCIpLmRlZmF1bHQ9fSBvcHRfZGVjbHV0dGVyVHJlZSBEZWNsdXR0ZXIgdHJlZS5cbiAgICovXG5cblxuICBFeGVjdXRvckdyb3VwLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKGNvbnRleHQsIGNvbnRleHRTY2FsZSwgdHJhbnNmb3JtLCB2aWV3Um90YXRpb24sIHNuYXBUb1BpeGVsLCBvcHRfYnVpbGRlclR5cGVzLCBvcHRfZGVjbHV0dGVyVHJlZSkge1xuICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICB2YXIgenMgPSBPYmplY3Qua2V5cyh0aGlzLmV4ZWN1dG9yc0J5WkluZGV4XykubWFwKE51bWJlcik7XG4gICAgenMuc29ydChudW1iZXJTYWZlQ29tcGFyZUZ1bmN0aW9uKTsgLy8gc2V0dXAgY2xpcHBpbmcgc28gdGhhdCB0aGUgcGFydHMgb2Ygb3Zlci1zaW1wbGlmaWVkIGdlb21ldHJpZXMgYXJlIG5vdFxuICAgIC8vIHZpc2libGUgb3V0c2lkZSB0aGUgY3VycmVudCBleHRlbnQgd2hlbiBwYW5uaW5nXG5cbiAgICBpZiAodGhpcy5tYXhFeHRlbnRfKSB7XG4gICAgICBjb250ZXh0LnNhdmUoKTtcbiAgICAgIHRoaXMuY2xpcChjb250ZXh0LCB0cmFuc2Zvcm0pO1xuICAgIH1cblxuICAgIHZhciBidWlsZGVyVHlwZXMgPSBvcHRfYnVpbGRlclR5cGVzID8gb3B0X2J1aWxkZXJUeXBlcyA6IE9SREVSO1xuICAgIHZhciBpLCBpaSwgaiwgamosIHJlcGxheXMsIHJlcGxheTtcblxuICAgIGlmIChvcHRfZGVjbHV0dGVyVHJlZSkge1xuICAgICAgenMucmV2ZXJzZSgpO1xuICAgIH1cblxuICAgIGZvciAoaSA9IDAsIGlpID0genMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdmFyIHpJbmRleEtleSA9IHpzW2ldLnRvU3RyaW5nKCk7XG4gICAgICByZXBsYXlzID0gdGhpcy5leGVjdXRvcnNCeVpJbmRleF9bekluZGV4S2V5XTtcblxuICAgICAgZm9yIChqID0gMCwgamogPSBidWlsZGVyVHlwZXMubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgICAgICB2YXIgYnVpbGRlclR5cGUgPSBidWlsZGVyVHlwZXNbal07XG4gICAgICAgIHJlcGxheSA9IHJlcGxheXNbYnVpbGRlclR5cGVdO1xuXG4gICAgICAgIGlmIChyZXBsYXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJlcGxheS5leGVjdXRlKGNvbnRleHQsIGNvbnRleHRTY2FsZSwgdHJhbnNmb3JtLCB2aWV3Um90YXRpb24sIHNuYXBUb1BpeGVsLCBvcHRfZGVjbHV0dGVyVHJlZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5tYXhFeHRlbnRfKSB7XG4gICAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIEV4ZWN1dG9yR3JvdXA7XG59KCk7XG4vKipcbiAqIFRoaXMgY2FjaGUgaXMgdXNlZCB0byBzdG9yZSBhcnJheXMgb2YgaW5kZXhlcyBmb3IgY2FsY3VsYXRlZCBwaXhlbCBjaXJjbGVzXG4gKiB0byBpbmNyZWFzZSBwZXJmb3JtYW5jZS5cbiAqIEl0IGlzIGEgc3RhdGljIHByb3BlcnR5IHRvIGFsbG93IGVhY2ggUmVwbGF5Z3JvdXAgdG8gYWNjZXNzIGl0LlxuICogQHR5cGUge09iamVjdDxudW1iZXIsIEFycmF5PG51bWJlcj4+fVxuICovXG5cblxudmFyIGNpcmNsZVBpeGVsSW5kZXhBcnJheUNhY2hlID0ge307XG4vKipcbiAqIFRoaXMgbWV0aG9kcyBjcmVhdGVzIGFuIGFycmF5IHdpdGggaW5kZXhlcyBvZiBhbGwgcGl4ZWxzIHdpdGhpbiBhIGNpcmNsZSxcbiAqIG9yZGVyZWQgYnkgaG93IGNsb3NlIHRoZXkgYXJlIHRvIHRoZSBjZW50ZXIuXG4gKiBBIGNhY2hlIGlzIHVzZWQgdG8gaW5jcmVhc2UgcGVyZm9ybWFuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkaXVzIFJhZGl1cy5cbiAqIEByZXR1cm5zIHtBcnJheTxudW1iZXI+fSBBbiBhcnJheSB3aXRoIGluZGV4ZXMgd2l0aGluIGEgY2lyY2xlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQaXhlbEluZGV4QXJyYXkocmFkaXVzKSB7XG4gIGlmIChjaXJjbGVQaXhlbEluZGV4QXJyYXlDYWNoZVtyYWRpdXNdICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gY2lyY2xlUGl4ZWxJbmRleEFycmF5Q2FjaGVbcmFkaXVzXTtcbiAgfVxuXG4gIHZhciBzaXplID0gcmFkaXVzICogMiArIDE7XG4gIHZhciBtYXhEaXN0YW5jZVNxID0gcmFkaXVzICogcmFkaXVzO1xuICB2YXIgZGlzdGFuY2VzID0gbmV3IEFycmF5KG1heERpc3RhbmNlU3EgKyAxKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8PSByYWRpdXM7ICsraSkge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDw9IHJhZGl1czsgKytqKSB7XG4gICAgICB2YXIgZGlzdGFuY2VTcSA9IGkgKiBpICsgaiAqIGo7XG5cbiAgICAgIGlmIChkaXN0YW5jZVNxID4gbWF4RGlzdGFuY2VTcSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgdmFyIGRpc3RhbmNlID0gZGlzdGFuY2VzW2Rpc3RhbmNlU3FdO1xuXG4gICAgICBpZiAoIWRpc3RhbmNlKSB7XG4gICAgICAgIGRpc3RhbmNlID0gW107XG4gICAgICAgIGRpc3RhbmNlc1tkaXN0YW5jZVNxXSA9IGRpc3RhbmNlO1xuICAgICAgfVxuXG4gICAgICBkaXN0YW5jZS5wdXNoKCgocmFkaXVzICsgaSkgKiBzaXplICsgKHJhZGl1cyArIGopKSAqIDQgKyAzKTtcblxuICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgIGRpc3RhbmNlLnB1c2goKChyYWRpdXMgLSBpKSAqIHNpemUgKyAocmFkaXVzICsgaikpICogNCArIDMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaiA+IDApIHtcbiAgICAgICAgZGlzdGFuY2UucHVzaCgoKHJhZGl1cyArIGkpICogc2l6ZSArIChyYWRpdXMgLSBqKSkgKiA0ICsgMyk7XG5cbiAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgZGlzdGFuY2UucHVzaCgoKHJhZGl1cyAtIGkpICogc2l6ZSArIChyYWRpdXMgLSBqKSkgKiA0ICsgMyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgcGl4ZWxJbmRleCA9IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGRpc3RhbmNlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgaWYgKGRpc3RhbmNlc1tpXSkge1xuICAgICAgcGl4ZWxJbmRleC5wdXNoLmFwcGx5KHBpeGVsSW5kZXgsIGRpc3RhbmNlc1tpXSk7XG4gICAgfVxuICB9XG5cbiAgY2lyY2xlUGl4ZWxJbmRleEFycmF5Q2FjaGVbcmFkaXVzXSA9IHBpeGVsSW5kZXg7XG4gIHJldHVybiBwaXhlbEluZGV4O1xufVxuZXhwb3J0IGRlZmF1bHQgRXhlY3V0b3JHcm91cDsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL2NhbnZhcy9JbW1lZGlhdGVcbiAqL1xuLy8gRklYTUUgdGVzdCwgZXNwZWNpYWxseSBwb2x5Z29ucyB3aXRoIGhvbGVzIGFuZCBtdWx0aXBvbHlnb25zXG4vLyBGSVhNRSBuZWVkIHRvIGhhbmRsZSBsYXJnZSB0aGljayBmZWF0dXJlcyAod2hlcmUgcGl4ZWwgc2l6ZSBtYXR0ZXJzKVxuLy8gRklYTUUgYWRkIG9mZnNldCBhbmQgZW5kIHRvIG9sL2dlb20vZmxhdC90cmFuc2Zvcm1+dHJhbnNmb3JtMkQ/XG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuXG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4uLy4uL2dlb20vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBWZWN0b3JDb250ZXh0IGZyb20gJy4uL1ZlY3RvckNvbnRleHQuanMnO1xuaW1wb3J0IHsgYXNDb2xvckxpa2UgfSBmcm9tICcuLi8uLi9jb2xvcmxpa2UuanMnO1xuaW1wb3J0IHsgY29tcG9zZSBhcyBjb21wb3NlVHJhbnNmb3JtLCBjcmVhdGUgYXMgY3JlYXRlVHJhbnNmb3JtIH0gZnJvbSAnLi4vLi4vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB7IGRlZmF1bHRGaWxsU3R5bGUsIGRlZmF1bHRGb250LCBkZWZhdWx0TGluZUNhcCwgZGVmYXVsdExpbmVEYXNoLCBkZWZhdWx0TGluZURhc2hPZmZzZXQsIGRlZmF1bHRMaW5lSm9pbiwgZGVmYXVsdExpbmVXaWR0aCwgZGVmYXVsdE1pdGVyTGltaXQsIGRlZmF1bHRTdHJva2VTdHlsZSwgZGVmYXVsdFRleHRBbGlnbiwgZGVmYXVsdFRleHRCYXNlbGluZSB9IGZyb20gJy4uL2NhbnZhcy5qcyc7XG5pbXBvcnQgeyBlcXVhbHMgfSBmcm9tICcuLi8uLi9hcnJheS5qcyc7XG5pbXBvcnQgeyBpbnRlcnNlY3RzIH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IHRyYW5zZm9ybTJEIH0gZnJvbSAnLi4vLi4vZ2VvbS9mbGF0L3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgeyB0cmFuc2Zvcm1HZW9tMkQgfSBmcm9tICcuLi8uLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQSBjb25jcmV0ZSBzdWJjbGFzcyBvZiB7QGxpbmsgbW9kdWxlOm9sL3JlbmRlci9WZWN0b3JDb250ZXh0fSB0aGF0IGltcGxlbWVudHNcbiAqIGRpcmVjdCByZW5kZXJpbmcgb2YgZmVhdHVyZXMgYW5kIGdlb21ldHJpZXMgdG8gYW4gSFRNTDUgQ2FudmFzIGNvbnRleHQuXG4gKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBhcmUgY3JlYXRlZCBpbnRlcm5hbGx5IGJ5IHRoZSBsaWJyYXJ5IGFuZFxuICogcHJvdmlkZWQgdG8gYXBwbGljYXRpb24gY29kZSBhcyB2ZWN0b3JDb250ZXh0IG1lbWJlciBvZiB0aGVcbiAqIHtAbGluayBtb2R1bGU6b2wvcmVuZGVyL0V2ZW50flJlbmRlckV2ZW50fSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHBvc3Rjb21wb3NlLCBwcmVjb21wb3NlIGFuZFxuICogcmVuZGVyIGV2ZW50cyBlbWl0dGVkIGJ5IGxheWVycyBhbmQgbWFwcy5cbiAqL1xuXG52YXIgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB2aWV3Um90YXRpb24gVmlldyByb3RhdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfc3F1YXJlZFRvbGVyYW5jZSBPcHRpb25hbCBzcXVhcmVkIHRvbGVyYW5jZSBmb3Igc2ltcGxpZmljYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbj19IG9wdF91c2VyVHJhbnNmb3JtIFRyYW5zZm9ybSBmcm9tIHVzZXIgdG8gdmlldyBwcm9qZWN0aW9uLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyKGNvbnRleHQsIHBpeGVsUmF0aW8sIGV4dGVudCwgdHJhbnNmb3JtLCB2aWV3Um90YXRpb24sIG9wdF9zcXVhcmVkVG9sZXJhbmNlLCBvcHRfdXNlclRyYW5zZm9ybSkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5jb250ZXh0XyA9IGNvbnRleHQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMucGl4ZWxSYXRpb18gPSBwaXhlbFJhdGlvO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5leHRlbnRfID0gZXh0ZW50O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gICAgICovXG5cbiAgICBfdGhpcy50cmFuc2Zvcm1fID0gdHJhbnNmb3JtO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnZpZXdSb3RhdGlvbl8gPSB2aWV3Um90YXRpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3F1YXJlZFRvbGVyYW5jZV8gPSBvcHRfc3F1YXJlZFRvbGVyYW5jZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufVxuICAgICAqL1xuXG4gICAgX3RoaXMudXNlclRyYW5zZm9ybV8gPSBvcHRfdXNlclRyYW5zZm9ybTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkZpbGxTdGF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbnRleHRGaWxsU3RhdGVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlN0cm9rZVN0YXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29udGV4dFN0cm9rZVN0YXRlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5UZXh0U3RhdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5jb250ZXh0VGV4dFN0YXRlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3RhdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5maWxsU3RhdGVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlN0cm9rZVN0YXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3Ryb2tlU3RhdGVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlQW5jaG9yWF8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlQW5jaG9yWV8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlSGVpZ2h0XyA9IDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW1hZ2VPcGFjaXR5XyA9IDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW1hZ2VPcmlnaW5YXyA9IDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW1hZ2VPcmlnaW5ZXyA9IDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlUm90YXRlV2l0aFZpZXdfID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW1hZ2VSb3RhdGlvbl8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlU2NhbGVfID0gWzAsIDBdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlV2lkdGhfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0XyA9ICcnO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRPZmZzZXRYXyA9IDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dE9mZnNldFlfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dFJvdGF0ZVdpdGhWaWV3XyA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRSb3RhdGlvbl8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRTY2FsZV8gPSBbMCwgMF07XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3RhdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0RmlsbFN0YXRlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5TdHJva2VTdGF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRTdHJva2VTdGF0ZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi9jYW52YXMuanNcIikuVGV4dFN0YXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dFN0YXRlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIF90aGlzLnBpeGVsQ29vcmRpbmF0ZXNfID0gW107XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRtcExvY2FsVHJhbnNmb3JtXyA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuZHJhd0ltYWdlc18gPSBmdW5jdGlvbiAoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKSB7XG4gICAgaWYgKCF0aGlzLmltYWdlXykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBwaXhlbENvb3JkaW5hdGVzID0gdHJhbnNmb3JtMkQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgMiwgdGhpcy50cmFuc2Zvcm1fLCB0aGlzLnBpeGVsQ29vcmRpbmF0ZXNfKTtcbiAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dF87XG4gICAgdmFyIGxvY2FsVHJhbnNmb3JtID0gdGhpcy50bXBMb2NhbFRyYW5zZm9ybV87XG4gICAgdmFyIGFscGhhID0gY29udGV4dC5nbG9iYWxBbHBoYTtcblxuICAgIGlmICh0aGlzLmltYWdlT3BhY2l0eV8gIT0gMSkge1xuICAgICAgY29udGV4dC5nbG9iYWxBbHBoYSA9IGFscGhhICogdGhpcy5pbWFnZU9wYWNpdHlfO1xuICAgIH1cblxuICAgIHZhciByb3RhdGlvbiA9IHRoaXMuaW1hZ2VSb3RhdGlvbl87XG5cbiAgICBpZiAodGhpcy5pbWFnZVJvdGF0ZVdpdGhWaWV3Xykge1xuICAgICAgcm90YXRpb24gKz0gdGhpcy52aWV3Um90YXRpb25fO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHBpeGVsQ29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgaWk7IGkgKz0gMikge1xuICAgICAgdmFyIHggPSBwaXhlbENvb3JkaW5hdGVzW2ldIC0gdGhpcy5pbWFnZUFuY2hvclhfO1xuICAgICAgdmFyIHkgPSBwaXhlbENvb3JkaW5hdGVzW2kgKyAxXSAtIHRoaXMuaW1hZ2VBbmNob3JZXztcblxuICAgICAgaWYgKHJvdGF0aW9uICE9PSAwIHx8IHRoaXMuaW1hZ2VTY2FsZV9bMF0gIT0gMSB8fCB0aGlzLmltYWdlU2NhbGVfWzFdICE9IDEpIHtcbiAgICAgICAgdmFyIGNlbnRlclggPSB4ICsgdGhpcy5pbWFnZUFuY2hvclhfO1xuICAgICAgICB2YXIgY2VudGVyWSA9IHkgKyB0aGlzLmltYWdlQW5jaG9yWV87XG4gICAgICAgIGNvbXBvc2VUcmFuc2Zvcm0obG9jYWxUcmFuc2Zvcm0sIGNlbnRlclgsIGNlbnRlclksIDEsIDEsIHJvdGF0aW9uLCAtY2VudGVyWCwgLWNlbnRlclkpO1xuICAgICAgICBjb250ZXh0LnNldFRyYW5zZm9ybS5hcHBseShjb250ZXh0LCBsb2NhbFRyYW5zZm9ybSk7XG4gICAgICAgIGNvbnRleHQudHJhbnNsYXRlKGNlbnRlclgsIGNlbnRlclkpO1xuICAgICAgICBjb250ZXh0LnNjYWxlKHRoaXMuaW1hZ2VTY2FsZV9bMF0sIHRoaXMuaW1hZ2VTY2FsZV9bMV0pO1xuICAgICAgICBjb250ZXh0LmRyYXdJbWFnZSh0aGlzLmltYWdlXywgdGhpcy5pbWFnZU9yaWdpblhfLCB0aGlzLmltYWdlT3JpZ2luWV8sIHRoaXMuaW1hZ2VXaWR0aF8sIHRoaXMuaW1hZ2VIZWlnaHRfLCAtdGhpcy5pbWFnZUFuY2hvclhfLCAtdGhpcy5pbWFnZUFuY2hvcllfLCB0aGlzLmltYWdlV2lkdGhfLCB0aGlzLmltYWdlSGVpZ2h0Xyk7XG4gICAgICAgIGNvbnRleHQuc2V0VHJhbnNmb3JtKDEsIDAsIDAsIDEsIDAsIDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGV4dC5kcmF3SW1hZ2UodGhpcy5pbWFnZV8sIHRoaXMuaW1hZ2VPcmlnaW5YXywgdGhpcy5pbWFnZU9yaWdpbllfLCB0aGlzLmltYWdlV2lkdGhfLCB0aGlzLmltYWdlSGVpZ2h0XywgeCwgeSwgdGhpcy5pbWFnZVdpZHRoXywgdGhpcy5pbWFnZUhlaWdodF8pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmltYWdlT3BhY2l0eV8gIT0gMSkge1xuICAgICAgY29udGV4dC5nbG9iYWxBbHBoYSA9IGFscGhhO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLmRyYXdUZXh0XyA9IGZ1bmN0aW9uIChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUpIHtcbiAgICBpZiAoIXRoaXMudGV4dFN0YXRlXyB8fCB0aGlzLnRleHRfID09PSAnJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRleHRGaWxsU3RhdGVfKSB7XG4gICAgICB0aGlzLnNldENvbnRleHRGaWxsU3RhdGVfKHRoaXMudGV4dEZpbGxTdGF0ZV8pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRleHRTdHJva2VTdGF0ZV8pIHtcbiAgICAgIHRoaXMuc2V0Q29udGV4dFN0cm9rZVN0YXRlXyh0aGlzLnRleHRTdHJva2VTdGF0ZV8pO1xuICAgIH1cblxuICAgIHRoaXMuc2V0Q29udGV4dFRleHRTdGF0ZV8odGhpcy50ZXh0U3RhdGVfKTtcbiAgICB2YXIgcGl4ZWxDb29yZGluYXRlcyA9IHRyYW5zZm9ybTJEKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgdGhpcy50cmFuc2Zvcm1fLCB0aGlzLnBpeGVsQ29vcmRpbmF0ZXNfKTtcbiAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dF87XG4gICAgdmFyIHJvdGF0aW9uID0gdGhpcy50ZXh0Um90YXRpb25fO1xuXG4gICAgaWYgKHRoaXMudGV4dFJvdGF0ZVdpdGhWaWV3Xykge1xuICAgICAgcm90YXRpb24gKz0gdGhpcy52aWV3Um90YXRpb25fO1xuICAgIH1cblxuICAgIGZvciAoOyBvZmZzZXQgPCBlbmQ7IG9mZnNldCArPSBzdHJpZGUpIHtcbiAgICAgIHZhciB4ID0gcGl4ZWxDb29yZGluYXRlc1tvZmZzZXRdICsgdGhpcy50ZXh0T2Zmc2V0WF87XG4gICAgICB2YXIgeSA9IHBpeGVsQ29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV0gKyB0aGlzLnRleHRPZmZzZXRZXztcblxuICAgICAgaWYgKHJvdGF0aW9uICE9PSAwIHx8IHRoaXMudGV4dFNjYWxlX1swXSAhPSAxIHx8IHRoaXMudGV4dFNjYWxlX1sxXSAhPSAxKSB7XG4gICAgICAgIHZhciBsb2NhbFRyYW5zZm9ybSA9IGNvbXBvc2VUcmFuc2Zvcm0odGhpcy50bXBMb2NhbFRyYW5zZm9ybV8sIHgsIHksIDEsIDEsIHJvdGF0aW9uLCAteCwgLXkpO1xuICAgICAgICBjb250ZXh0LnNldFRyYW5zZm9ybS5hcHBseShjb250ZXh0LCBsb2NhbFRyYW5zZm9ybSk7XG4gICAgICAgIGNvbnRleHQudHJhbnNsYXRlKHgsIHkpO1xuICAgICAgICBjb250ZXh0LnNjYWxlKHRoaXMudGV4dFNjYWxlX1swXSwgdGhpcy50ZXh0U2NhbGVfWzFdKTtcblxuICAgICAgICBpZiAodGhpcy50ZXh0U3Ryb2tlU3RhdGVfKSB7XG4gICAgICAgICAgY29udGV4dC5zdHJva2VUZXh0KHRoaXMudGV4dF8sIDAsIDApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMudGV4dEZpbGxTdGF0ZV8pIHtcbiAgICAgICAgICBjb250ZXh0LmZpbGxUZXh0KHRoaXMudGV4dF8sIDAsIDApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodGhpcy50ZXh0U3Ryb2tlU3RhdGVfKSB7XG4gICAgICAgICAgY29udGV4dC5zdHJva2VUZXh0KHRoaXMudGV4dF8sIHgsIHkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMudGV4dEZpbGxTdGF0ZV8pIHtcbiAgICAgICAgICBjb250ZXh0LmZpbGxUZXh0KHRoaXMudGV4dF8sIHgsIHkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBjbG9zZSBDbG9zZS5cbiAgICogQHByaXZhdGVcbiAgICogQHJldHVybiB7bnVtYmVyfSBlbmQgRW5kLlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5tb3ZlVG9MaW5lVG9fID0gZnVuY3Rpb24gKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgY2xvc2UpIHtcbiAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dF87XG4gICAgdmFyIHBpeGVsQ29vcmRpbmF0ZXMgPSB0cmFuc2Zvcm0yRChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIHRoaXMudHJhbnNmb3JtXywgdGhpcy5waXhlbENvb3JkaW5hdGVzXyk7XG4gICAgY29udGV4dC5tb3ZlVG8ocGl4ZWxDb29yZGluYXRlc1swXSwgcGl4ZWxDb29yZGluYXRlc1sxXSk7XG4gICAgdmFyIGxlbmd0aCA9IHBpeGVsQ29vcmRpbmF0ZXMubGVuZ3RoO1xuXG4gICAgaWYgKGNsb3NlKSB7XG4gICAgICBsZW5ndGggLT0gMjtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMjsgaSA8IGxlbmd0aDsgaSArPSAyKSB7XG4gICAgICBjb250ZXh0LmxpbmVUbyhwaXhlbENvb3JkaW5hdGVzW2ldLCBwaXhlbENvb3JkaW5hdGVzW2kgKyAxXSk7XG4gICAgfVxuXG4gICAgaWYgKGNsb3NlKSB7XG4gICAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIH1cblxuICAgIHJldHVybiBlbmQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBlbmRzIEVuZHMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEVuZC5cbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuZHJhd1JpbmdzXyA9IGZ1bmN0aW9uIChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBvZmZzZXQgPSB0aGlzLm1vdmVUb0xpbmVUb18oZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNbaV0sIHN0cmlkZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciBhIGNpcmNsZSBnZW9tZXRyeSBpbnRvIHRoZSBjYW52YXMuICBSZW5kZXJpbmcgaXMgaW1tZWRpYXRlIGFuZCB1c2VzXG4gICAqIHRoZSBjdXJyZW50IGZpbGwgYW5kIHN0cm9rZSBzdHlsZXMuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9DaXJjbGUuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgQ2lyY2xlIGdlb21ldHJ5LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLmRyYXdDaXJjbGUgPSBmdW5jdGlvbiAoZ2VvbWV0cnkpIHtcbiAgICBpZiAoIWludGVyc2VjdHModGhpcy5leHRlbnRfLCBnZW9tZXRyeS5nZXRFeHRlbnQoKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5maWxsU3RhdGVfIHx8IHRoaXMuc3Ryb2tlU3RhdGVfKSB7XG4gICAgICBpZiAodGhpcy5maWxsU3RhdGVfKSB7XG4gICAgICAgIHRoaXMuc2V0Q29udGV4dEZpbGxTdGF0ZV8odGhpcy5maWxsU3RhdGVfKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3Ryb2tlU3RhdGVfKSB7XG4gICAgICAgIHRoaXMuc2V0Q29udGV4dFN0cm9rZVN0YXRlXyh0aGlzLnN0cm9rZVN0YXRlXyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBwaXhlbENvb3JkaW5hdGVzID0gdHJhbnNmb3JtR2VvbTJEKGdlb21ldHJ5LCB0aGlzLnRyYW5zZm9ybV8sIHRoaXMucGl4ZWxDb29yZGluYXRlc18pO1xuICAgICAgdmFyIGR4ID0gcGl4ZWxDb29yZGluYXRlc1syXSAtIHBpeGVsQ29vcmRpbmF0ZXNbMF07XG4gICAgICB2YXIgZHkgPSBwaXhlbENvb3JkaW5hdGVzWzNdIC0gcGl4ZWxDb29yZGluYXRlc1sxXTtcbiAgICAgIHZhciByYWRpdXMgPSBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpO1xuICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHRfO1xuICAgICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICAgIGNvbnRleHQuYXJjKHBpeGVsQ29vcmRpbmF0ZXNbMF0sIHBpeGVsQ29vcmRpbmF0ZXNbMV0sIHJhZGl1cywgMCwgMiAqIE1hdGguUEkpO1xuXG4gICAgICBpZiAodGhpcy5maWxsU3RhdGVfKSB7XG4gICAgICAgIGNvbnRleHQuZmlsbCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdHJva2VTdGF0ZV8pIHtcbiAgICAgICAgY29udGV4dC5zdHJva2UoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy50ZXh0XyAhPT0gJycpIHtcbiAgICAgIHRoaXMuZHJhd1RleHRfKGdlb21ldHJ5LmdldENlbnRlcigpLCAwLCAyLCAyKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHJlbmRlcmluZyBzdHlsZS4gIE5vdGUgdGhhdCBzaW5jZSB0aGlzIGlzIGFuIGltbWVkaWF0ZSByZW5kZXJpbmcgQVBJLFxuICAgKiBhbnkgYHpJbmRleGAgb24gdGhlIHByb3ZpZGVkIHN0eWxlIHdpbGwgYmUgaWdub3JlZC5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBUaGUgcmVuZGVyaW5nIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLnNldFN0eWxlID0gZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgdGhpcy5zZXRGaWxsU3Ryb2tlU3R5bGUoc3R5bGUuZ2V0RmlsbCgpLCBzdHlsZS5nZXRTdHJva2UoKSk7XG4gICAgdGhpcy5zZXRJbWFnZVN0eWxlKHN0eWxlLmdldEltYWdlKCkpO1xuICAgIHRoaXMuc2V0VGV4dFN0eWxlKHN0eWxlLmdldFRleHQoKSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLnNldFRyYW5zZm9ybSA9IGZ1bmN0aW9uICh0cmFuc2Zvcm0pIHtcbiAgICB0aGlzLnRyYW5zZm9ybV8gPSB0cmFuc2Zvcm07XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgYSBnZW9tZXRyeSBpbnRvIHRoZSBjYW52YXMuICBDYWxsXG4gICAqIHtAbGluayBtb2R1bGU6b2wvcmVuZGVyL2NhbnZhcy9JbW1lZGlhdGUjc2V0U3R5bGV9IGZpcnN0IHRvIHNldCB0aGUgcmVuZGVyaW5nIHN0eWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IFRoZSBnZW9tZXRyeSB0byByZW5kZXIuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuZHJhd0dlb21ldHJ5ID0gZnVuY3Rpb24gKGdlb21ldHJ5KSB7XG4gICAgdmFyIHR5cGUgPSBnZW9tZXRyeS5nZXRUeXBlKCk7XG5cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgR2VvbWV0cnlUeXBlLlBPSU5UOlxuICAgICAgICB0aGlzLmRyYXdQb2ludChcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1BvaW50LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgR2VvbWV0cnlUeXBlLkxJTkVfU1RSSU5HOlxuICAgICAgICB0aGlzLmRyYXdMaW5lU3RyaW5nKFxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEdlb21ldHJ5VHlwZS5QT0xZR09OOlxuICAgICAgICB0aGlzLmRyYXdQb2x5Z29uKFxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9QT0lOVDpcbiAgICAgICAgdGhpcy5kcmF3TXVsdGlQb2ludChcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpUG9pbnQuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnkpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfTElORV9TVFJJTkc6XG4gICAgICAgIHRoaXMuZHJhd011bHRpTGluZVN0cmluZyhcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9QT0xZR09OOlxuICAgICAgICB0aGlzLmRyYXdNdWx0aVBvbHlnb24oXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aVBvbHlnb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnkpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBHZW9tZXRyeVR5cGUuR0VPTUVUUllfQ09MTEVDVElPTjpcbiAgICAgICAgdGhpcy5kcmF3R2VvbWV0cnlDb2xsZWN0aW9uKFxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vR2VvbWV0cnlDb2xsZWN0aW9uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgR2VvbWV0cnlUeXBlLkNJUkNMRTpcbiAgICAgICAgdGhpcy5kcmF3Q2lyY2xlKFxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vQ2lyY2xlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUmVuZGVyIGEgZmVhdHVyZSBpbnRvIHRoZSBjYW52YXMuICBOb3RlIHRoYXQgYW55IGB6SW5kZXhgIG9uIHRoZSBwcm92aWRlZFxuICAgKiBzdHlsZSB3aWxsIGJlIGlnbm9yZWQgLSBmZWF0dXJlcyBhcmUgcmVuZGVyZWQgaW1tZWRpYXRlbHkgaW4gdGhlIG9yZGVyIHRoYXRcbiAgICogdGhpcyBtZXRob2QgaXMgY2FsbGVkLiAgSWYgeW91IG5lZWQgYHpJbmRleGAgc3VwcG9ydCwgeW91IHNob3VsZCBiZSB1c2luZyBhblxuICAgKiB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL1ZlY3Rvcn5WZWN0b3JMYXllcn0gaW5zdGVhZC5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3RmVhdHVyZSA9IGZ1bmN0aW9uIChmZWF0dXJlLCBzdHlsZSkge1xuICAgIHZhciBnZW9tZXRyeSA9IHN0eWxlLmdldEdlb21ldHJ5RnVuY3Rpb24oKShmZWF0dXJlKTtcblxuICAgIGlmICghZ2VvbWV0cnkgfHwgIWludGVyc2VjdHModGhpcy5leHRlbnRfLCBnZW9tZXRyeS5nZXRFeHRlbnQoKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldFN0eWxlKHN0eWxlKTtcbiAgICB0aGlzLmRyYXdHZW9tZXRyeShnZW9tZXRyeSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgYSBHZW9tZXRyeUNvbGxlY3Rpb24gdG8gdGhlIGNhbnZhcy4gIFJlbmRlcmluZyBpcyBpbW1lZGlhdGUgYW5kXG4gICAqIHVzZXMgdGhlIGN1cnJlbnQgc3R5bGVzIGFwcHJvcHJpYXRlIGZvciBlYWNoIGdlb21ldHJ5IGluIHRoZSBjb2xsZWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vR2VvbWV0cnlDb2xsZWN0aW9uLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5IGNvbGxlY3Rpb24uXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLmRyYXdHZW9tZXRyeUNvbGxlY3Rpb24gPSBmdW5jdGlvbiAoZ2VvbWV0cnkpIHtcbiAgICB2YXIgZ2VvbWV0cmllcyA9IGdlb21ldHJ5LmdldEdlb21ldHJpZXNBcnJheSgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZ2VvbWV0cmllcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB0aGlzLmRyYXdHZW9tZXRyeShnZW9tZXRyaWVzW2ldKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgYSBQb2ludCBnZW9tZXRyeSBpbnRvIHRoZSBjYW52YXMuICBSZW5kZXJpbmcgaXMgaW1tZWRpYXRlIGFuZCB1c2VzXG4gICAqIHRoZSBjdXJyZW50IHN0eWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vUG9pbnQuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IFBvaW50IGdlb21ldHJ5LlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3UG9pbnQgPSBmdW5jdGlvbiAoZ2VvbWV0cnkpIHtcbiAgICBpZiAodGhpcy5zcXVhcmVkVG9sZXJhbmNlXykge1xuICAgICAgZ2VvbWV0cnkgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1BvaW50LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBnZW9tZXRyeS5zaW1wbGlmeVRyYW5zZm9ybWVkKHRoaXMuc3F1YXJlZFRvbGVyYW5jZV8sIHRoaXMudXNlclRyYW5zZm9ybV8pO1xuICAgIH1cblxuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBnZW9tZXRyeS5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcbiAgICB2YXIgc3RyaWRlID0gZ2VvbWV0cnkuZ2V0U3RyaWRlKCk7XG5cbiAgICBpZiAodGhpcy5pbWFnZV8pIHtcbiAgICAgIHRoaXMuZHJhd0ltYWdlc18oZmxhdENvb3JkaW5hdGVzLCAwLCBmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCBzdHJpZGUpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRleHRfICE9PSAnJykge1xuICAgICAgdGhpcy5kcmF3VGV4dF8oZmxhdENvb3JkaW5hdGVzLCAwLCBmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCBzdHJpZGUpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciBhIE11bHRpUG9pbnQgZ2VvbWV0cnkgIGludG8gdGhlIGNhbnZhcy4gIFJlbmRlcmluZyBpcyBpbW1lZGlhdGUgYW5kXG4gICAqIHVzZXMgdGhlIGN1cnJlbnQgc3R5bGUuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aVBvaW50LmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBNdWx0aVBvaW50IGdlb21ldHJ5LlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3TXVsdGlQb2ludCA9IGZ1bmN0aW9uIChnZW9tZXRyeSkge1xuICAgIGlmICh0aGlzLnNxdWFyZWRUb2xlcmFuY2VfKSB7XG4gICAgICBnZW9tZXRyeSA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2ludC5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZ2VvbWV0cnkuc2ltcGxpZnlUcmFuc2Zvcm1lZCh0aGlzLnNxdWFyZWRUb2xlcmFuY2VfLCB0aGlzLnVzZXJUcmFuc2Zvcm1fKTtcbiAgICB9XG5cbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gZ2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgdmFyIHN0cmlkZSA9IGdlb21ldHJ5LmdldFN0cmlkZSgpO1xuXG4gICAgaWYgKHRoaXMuaW1hZ2VfKSB7XG4gICAgICB0aGlzLmRyYXdJbWFnZXNfKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy50ZXh0XyAhPT0gJycpIHtcbiAgICAgIHRoaXMuZHJhd1RleHRfKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgYSBMaW5lU3RyaW5nIGludG8gdGhlIGNhbnZhcy4gIFJlbmRlcmluZyBpcyBpbW1lZGlhdGUgYW5kIHVzZXNcbiAgICogdGhlIGN1cnJlbnQgc3R5bGUuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9MaW5lU3RyaW5nLmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBMaW5lU3RyaW5nIGdlb21ldHJ5LlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3TGluZVN0cmluZyA9IGZ1bmN0aW9uIChnZW9tZXRyeSkge1xuICAgIGlmICh0aGlzLnNxdWFyZWRUb2xlcmFuY2VfKSB7XG4gICAgICBnZW9tZXRyeSA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZ2VvbWV0cnkuc2ltcGxpZnlUcmFuc2Zvcm1lZCh0aGlzLnNxdWFyZWRUb2xlcmFuY2VfLCB0aGlzLnVzZXJUcmFuc2Zvcm1fKTtcbiAgICB9XG5cbiAgICBpZiAoIWludGVyc2VjdHModGhpcy5leHRlbnRfLCBnZW9tZXRyeS5nZXRFeHRlbnQoKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdHJva2VTdGF0ZV8pIHtcbiAgICAgIHRoaXMuc2V0Q29udGV4dFN0cm9rZVN0YXRlXyh0aGlzLnN0cm9rZVN0YXRlXyk7XG4gICAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dF87XG4gICAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gZ2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgICAgdGhpcy5tb3ZlVG9MaW5lVG9fKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgZ2VvbWV0cnkuZ2V0U3RyaWRlKCksIGZhbHNlKTtcbiAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGV4dF8gIT09ICcnKSB7XG4gICAgICB2YXIgZmxhdE1pZHBvaW50ID0gZ2VvbWV0cnkuZ2V0RmxhdE1pZHBvaW50KCk7XG4gICAgICB0aGlzLmRyYXdUZXh0XyhmbGF0TWlkcG9pbnQsIDAsIDIsIDIpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciBhIE11bHRpTGluZVN0cmluZyBnZW9tZXRyeSBpbnRvIHRoZSBjYW52YXMuICBSZW5kZXJpbmcgaXMgaW1tZWRpYXRlXG4gICAqIGFuZCB1c2VzIHRoZSBjdXJyZW50IHN0eWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlMaW5lU3RyaW5nLmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBNdWx0aUxpbmVTdHJpbmcgZ2VvbWV0cnkuXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLmRyYXdNdWx0aUxpbmVTdHJpbmcgPSBmdW5jdGlvbiAoZ2VvbWV0cnkpIHtcbiAgICBpZiAodGhpcy5zcXVhcmVkVG9sZXJhbmNlXykge1xuICAgICAgZ2VvbWV0cnkgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZ2VvbWV0cnkuc2ltcGxpZnlUcmFuc2Zvcm1lZCh0aGlzLnNxdWFyZWRUb2xlcmFuY2VfLCB0aGlzLnVzZXJUcmFuc2Zvcm1fKTtcbiAgICB9XG5cbiAgICB2YXIgZ2VvbWV0cnlFeHRlbnQgPSBnZW9tZXRyeS5nZXRFeHRlbnQoKTtcblxuICAgIGlmICghaW50ZXJzZWN0cyh0aGlzLmV4dGVudF8sIGdlb21ldHJ5RXh0ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0cm9rZVN0YXRlXykge1xuICAgICAgdGhpcy5zZXRDb250ZXh0U3Ryb2tlU3RhdGVfKHRoaXMuc3Ryb2tlU3RhdGVfKTtcbiAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0XztcbiAgICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBnZW9tZXRyeS5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcbiAgICAgIHZhciBvZmZzZXQgPSAwO1xuICAgICAgdmFyIGVuZHMgPVxuICAgICAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuICAgICAgZ2VvbWV0cnkuZ2V0RW5kcygpO1xuICAgICAgdmFyIHN0cmlkZSA9IGdlb21ldHJ5LmdldFN0cmlkZSgpO1xuICAgICAgY29udGV4dC5iZWdpblBhdGgoKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIG9mZnNldCA9IHRoaXMubW92ZVRvTGluZVRvXyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc1tpXSwgc3RyaWRlLCBmYWxzZSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGV4dF8gIT09ICcnKSB7XG4gICAgICB2YXIgZmxhdE1pZHBvaW50cyA9IGdlb21ldHJ5LmdldEZsYXRNaWRwb2ludHMoKTtcbiAgICAgIHRoaXMuZHJhd1RleHRfKGZsYXRNaWRwb2ludHMsIDAsIGZsYXRNaWRwb2ludHMubGVuZ3RoLCAyKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgYSBQb2x5Z29uIGdlb21ldHJ5IGludG8gdGhlIGNhbnZhcy4gIFJlbmRlcmluZyBpcyBpbW1lZGlhdGUgYW5kIHVzZXNcbiAgICogdGhlIGN1cnJlbnQgc3R5bGUuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9Qb2x5Z29uLmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBQb2x5Z29uIGdlb21ldHJ5LlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3UG9seWdvbiA9IGZ1bmN0aW9uIChnZW9tZXRyeSkge1xuICAgIGlmICh0aGlzLnNxdWFyZWRUb2xlcmFuY2VfKSB7XG4gICAgICBnZW9tZXRyeSA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZ2VvbWV0cnkuc2ltcGxpZnlUcmFuc2Zvcm1lZCh0aGlzLnNxdWFyZWRUb2xlcmFuY2VfLCB0aGlzLnVzZXJUcmFuc2Zvcm1fKTtcbiAgICB9XG5cbiAgICBpZiAoIWludGVyc2VjdHModGhpcy5leHRlbnRfLCBnZW9tZXRyeS5nZXRFeHRlbnQoKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdHJva2VTdGF0ZV8gfHwgdGhpcy5maWxsU3RhdGVfKSB7XG4gICAgICBpZiAodGhpcy5maWxsU3RhdGVfKSB7XG4gICAgICAgIHRoaXMuc2V0Q29udGV4dEZpbGxTdGF0ZV8odGhpcy5maWxsU3RhdGVfKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3Ryb2tlU3RhdGVfKSB7XG4gICAgICAgIHRoaXMuc2V0Q29udGV4dFN0cm9rZVN0YXRlXyh0aGlzLnN0cm9rZVN0YXRlXyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0XztcbiAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgICB0aGlzLmRyYXdSaW5nc18oZ2VvbWV0cnkuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKSwgMCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIGdlb21ldHJ5LmdldEVuZHMoKSwgZ2VvbWV0cnkuZ2V0U3RyaWRlKCkpO1xuXG4gICAgICBpZiAodGhpcy5maWxsU3RhdGVfKSB7XG4gICAgICAgIGNvbnRleHQuZmlsbCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdHJva2VTdGF0ZV8pIHtcbiAgICAgICAgY29udGV4dC5zdHJva2UoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy50ZXh0XyAhPT0gJycpIHtcbiAgICAgIHZhciBmbGF0SW50ZXJpb3JQb2ludCA9IGdlb21ldHJ5LmdldEZsYXRJbnRlcmlvclBvaW50KCk7XG4gICAgICB0aGlzLmRyYXdUZXh0XyhmbGF0SW50ZXJpb3JQb2ludCwgMCwgMiwgMik7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUmVuZGVyIE11bHRpUG9seWdvbiBnZW9tZXRyeSBpbnRvIHRoZSBjYW52YXMuICBSZW5kZXJpbmcgaXMgaW1tZWRpYXRlIGFuZFxuICAgKiB1c2VzIHRoZSBjdXJyZW50IHN0eWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2x5Z29uLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IE11bHRpUG9seWdvbiBnZW9tZXRyeS5cbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuZHJhd011bHRpUG9seWdvbiA9IGZ1bmN0aW9uIChnZW9tZXRyeSkge1xuICAgIGlmICh0aGlzLnNxdWFyZWRUb2xlcmFuY2VfKSB7XG4gICAgICBnZW9tZXRyeSA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2x5Z29uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBnZW9tZXRyeS5zaW1wbGlmeVRyYW5zZm9ybWVkKHRoaXMuc3F1YXJlZFRvbGVyYW5jZV8sIHRoaXMudXNlclRyYW5zZm9ybV8pO1xuICAgIH1cblxuICAgIGlmICghaW50ZXJzZWN0cyh0aGlzLmV4dGVudF8sIGdlb21ldHJ5LmdldEV4dGVudCgpKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0cm9rZVN0YXRlXyB8fCB0aGlzLmZpbGxTdGF0ZV8pIHtcbiAgICAgIGlmICh0aGlzLmZpbGxTdGF0ZV8pIHtcbiAgICAgICAgdGhpcy5zZXRDb250ZXh0RmlsbFN0YXRlXyh0aGlzLmZpbGxTdGF0ZV8pO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdHJva2VTdGF0ZV8pIHtcbiAgICAgICAgdGhpcy5zZXRDb250ZXh0U3Ryb2tlU3RhdGVfKHRoaXMuc3Ryb2tlU3RhdGVfKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHRfO1xuICAgICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IGdlb21ldHJ5LmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzKCk7XG4gICAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICAgIHZhciBlbmRzcyA9IGdlb21ldHJ5LmdldEVuZHNzKCk7XG4gICAgICB2YXIgc3RyaWRlID0gZ2VvbWV0cnkuZ2V0U3RyaWRlKCk7XG4gICAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIHZhciBlbmRzID0gZW5kc3NbaV07XG4gICAgICAgIG9mZnNldCA9IHRoaXMuZHJhd1JpbmdzXyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuZmlsbFN0YXRlXykge1xuICAgICAgICBjb250ZXh0LmZpbGwoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3Ryb2tlU3RhdGVfKSB7XG4gICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGV4dF8gIT09ICcnKSB7XG4gICAgICB2YXIgZmxhdEludGVyaW9yUG9pbnRzID0gZ2VvbWV0cnkuZ2V0RmxhdEludGVyaW9yUG9pbnRzKCk7XG4gICAgICB0aGlzLmRyYXdUZXh0XyhmbGF0SW50ZXJpb3JQb2ludHMsIDAsIGZsYXRJbnRlcmlvclBvaW50cy5sZW5ndGgsIDIpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkZpbGxTdGF0ZX0gZmlsbFN0YXRlIEZpbGwgc3RhdGUuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLnNldENvbnRleHRGaWxsU3RhdGVfID0gZnVuY3Rpb24gKGZpbGxTdGF0ZSkge1xuICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0XztcbiAgICB2YXIgY29udGV4dEZpbGxTdGF0ZSA9IHRoaXMuY29udGV4dEZpbGxTdGF0ZV87XG5cbiAgICBpZiAoIWNvbnRleHRGaWxsU3RhdGUpIHtcbiAgICAgIGNvbnRleHQuZmlsbFN0eWxlID0gZmlsbFN0YXRlLmZpbGxTdHlsZTtcbiAgICAgIHRoaXMuY29udGV4dEZpbGxTdGF0ZV8gPSB7XG4gICAgICAgIGZpbGxTdHlsZTogZmlsbFN0YXRlLmZpbGxTdHlsZVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGNvbnRleHRGaWxsU3RhdGUuZmlsbFN0eWxlICE9IGZpbGxTdGF0ZS5maWxsU3R5bGUpIHtcbiAgICAgICAgY29udGV4dEZpbGxTdGF0ZS5maWxsU3R5bGUgPSBmaWxsU3RhdGUuZmlsbFN0eWxlO1xuICAgICAgICBjb250ZXh0LmZpbGxTdHlsZSA9IGZpbGxTdGF0ZS5maWxsU3R5bGU7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU3Ryb2tlU3RhdGV9IHN0cm9rZVN0YXRlIFN0cm9rZSBzdGF0ZS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuc2V0Q29udGV4dFN0cm9rZVN0YXRlXyA9IGZ1bmN0aW9uIChzdHJva2VTdGF0ZSkge1xuICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0XztcbiAgICB2YXIgY29udGV4dFN0cm9rZVN0YXRlID0gdGhpcy5jb250ZXh0U3Ryb2tlU3RhdGVfO1xuXG4gICAgaWYgKCFjb250ZXh0U3Ryb2tlU3RhdGUpIHtcbiAgICAgIGNvbnRleHQubGluZUNhcCA9IHN0cm9rZVN0YXRlLmxpbmVDYXA7XG5cbiAgICAgIGlmIChjb250ZXh0LnNldExpbmVEYXNoKSB7XG4gICAgICAgIGNvbnRleHQuc2V0TGluZURhc2goc3Ryb2tlU3RhdGUubGluZURhc2gpO1xuICAgICAgICBjb250ZXh0LmxpbmVEYXNoT2Zmc2V0ID0gc3Ryb2tlU3RhdGUubGluZURhc2hPZmZzZXQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnRleHQubGluZUpvaW4gPSBzdHJva2VTdGF0ZS5saW5lSm9pbjtcbiAgICAgIGNvbnRleHQubGluZVdpZHRoID0gc3Ryb2tlU3RhdGUubGluZVdpZHRoO1xuICAgICAgY29udGV4dC5taXRlckxpbWl0ID0gc3Ryb2tlU3RhdGUubWl0ZXJMaW1pdDtcbiAgICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBzdHJva2VTdGF0ZS5zdHJva2VTdHlsZTtcbiAgICAgIHRoaXMuY29udGV4dFN0cm9rZVN0YXRlXyA9IHtcbiAgICAgICAgbGluZUNhcDogc3Ryb2tlU3RhdGUubGluZUNhcCxcbiAgICAgICAgbGluZURhc2g6IHN0cm9rZVN0YXRlLmxpbmVEYXNoLFxuICAgICAgICBsaW5lRGFzaE9mZnNldDogc3Ryb2tlU3RhdGUubGluZURhc2hPZmZzZXQsXG4gICAgICAgIGxpbmVKb2luOiBzdHJva2VTdGF0ZS5saW5lSm9pbixcbiAgICAgICAgbGluZVdpZHRoOiBzdHJva2VTdGF0ZS5saW5lV2lkdGgsXG4gICAgICAgIG1pdGVyTGltaXQ6IHN0cm9rZVN0YXRlLm1pdGVyTGltaXQsXG4gICAgICAgIHN0cm9rZVN0eWxlOiBzdHJva2VTdGF0ZS5zdHJva2VTdHlsZVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGNvbnRleHRTdHJva2VTdGF0ZS5saW5lQ2FwICE9IHN0cm9rZVN0YXRlLmxpbmVDYXApIHtcbiAgICAgICAgY29udGV4dFN0cm9rZVN0YXRlLmxpbmVDYXAgPSBzdHJva2VTdGF0ZS5saW5lQ2FwO1xuICAgICAgICBjb250ZXh0LmxpbmVDYXAgPSBzdHJva2VTdGF0ZS5saW5lQ2FwO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29udGV4dC5zZXRMaW5lRGFzaCkge1xuICAgICAgICBpZiAoIWVxdWFscyhjb250ZXh0U3Ryb2tlU3RhdGUubGluZURhc2gsIHN0cm9rZVN0YXRlLmxpbmVEYXNoKSkge1xuICAgICAgICAgIGNvbnRleHQuc2V0TGluZURhc2goY29udGV4dFN0cm9rZVN0YXRlLmxpbmVEYXNoID0gc3Ryb2tlU3RhdGUubGluZURhc2gpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbnRleHRTdHJva2VTdGF0ZS5saW5lRGFzaE9mZnNldCAhPSBzdHJva2VTdGF0ZS5saW5lRGFzaE9mZnNldCkge1xuICAgICAgICAgIGNvbnRleHRTdHJva2VTdGF0ZS5saW5lRGFzaE9mZnNldCA9IHN0cm9rZVN0YXRlLmxpbmVEYXNoT2Zmc2V0O1xuICAgICAgICAgIGNvbnRleHQubGluZURhc2hPZmZzZXQgPSBzdHJva2VTdGF0ZS5saW5lRGFzaE9mZnNldDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY29udGV4dFN0cm9rZVN0YXRlLmxpbmVKb2luICE9IHN0cm9rZVN0YXRlLmxpbmVKb2luKSB7XG4gICAgICAgIGNvbnRleHRTdHJva2VTdGF0ZS5saW5lSm9pbiA9IHN0cm9rZVN0YXRlLmxpbmVKb2luO1xuICAgICAgICBjb250ZXh0LmxpbmVKb2luID0gc3Ryb2tlU3RhdGUubGluZUpvaW47XG4gICAgICB9XG5cbiAgICAgIGlmIChjb250ZXh0U3Ryb2tlU3RhdGUubGluZVdpZHRoICE9IHN0cm9rZVN0YXRlLmxpbmVXaWR0aCkge1xuICAgICAgICBjb250ZXh0U3Ryb2tlU3RhdGUubGluZVdpZHRoID0gc3Ryb2tlU3RhdGUubGluZVdpZHRoO1xuICAgICAgICBjb250ZXh0LmxpbmVXaWR0aCA9IHN0cm9rZVN0YXRlLmxpbmVXaWR0aDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbnRleHRTdHJva2VTdGF0ZS5taXRlckxpbWl0ICE9IHN0cm9rZVN0YXRlLm1pdGVyTGltaXQpIHtcbiAgICAgICAgY29udGV4dFN0cm9rZVN0YXRlLm1pdGVyTGltaXQgPSBzdHJva2VTdGF0ZS5taXRlckxpbWl0O1xuICAgICAgICBjb250ZXh0Lm1pdGVyTGltaXQgPSBzdHJva2VTdGF0ZS5taXRlckxpbWl0O1xuICAgICAgfVxuXG4gICAgICBpZiAoY29udGV4dFN0cm9rZVN0YXRlLnN0cm9rZVN0eWxlICE9IHN0cm9rZVN0YXRlLnN0cm9rZVN0eWxlKSB7XG4gICAgICAgIGNvbnRleHRTdHJva2VTdGF0ZS5zdHJva2VTdHlsZSA9IHN0cm9rZVN0YXRlLnN0cm9rZVN0eWxlO1xuICAgICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gc3Ryb2tlU3RhdGUuc3Ryb2tlU3R5bGU7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuVGV4dFN0YXRlfSB0ZXh0U3RhdGUgVGV4dCBzdGF0ZS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuc2V0Q29udGV4dFRleHRTdGF0ZV8gPSBmdW5jdGlvbiAodGV4dFN0YXRlKSB7XG4gICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHRfO1xuICAgIHZhciBjb250ZXh0VGV4dFN0YXRlID0gdGhpcy5jb250ZXh0VGV4dFN0YXRlXztcbiAgICB2YXIgdGV4dEFsaWduID0gdGV4dFN0YXRlLnRleHRBbGlnbiA/IHRleHRTdGF0ZS50ZXh0QWxpZ24gOiBkZWZhdWx0VGV4dEFsaWduO1xuXG4gICAgaWYgKCFjb250ZXh0VGV4dFN0YXRlKSB7XG4gICAgICBjb250ZXh0LmZvbnQgPSB0ZXh0U3RhdGUuZm9udDtcbiAgICAgIGNvbnRleHQudGV4dEFsaWduID1cbiAgICAgIC8qKiBAdHlwZSB7Q2FudmFzVGV4dEFsaWdufSAqL1xuICAgICAgdGV4dEFsaWduO1xuICAgICAgY29udGV4dC50ZXh0QmFzZWxpbmUgPVxuICAgICAgLyoqIEB0eXBlIHtDYW52YXNUZXh0QmFzZWxpbmV9ICovXG4gICAgICB0ZXh0U3RhdGUudGV4dEJhc2VsaW5lO1xuICAgICAgdGhpcy5jb250ZXh0VGV4dFN0YXRlXyA9IHtcbiAgICAgICAgZm9udDogdGV4dFN0YXRlLmZvbnQsXG4gICAgICAgIHRleHRBbGlnbjogdGV4dEFsaWduLFxuICAgICAgICB0ZXh0QmFzZWxpbmU6IHRleHRTdGF0ZS50ZXh0QmFzZWxpbmVcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChjb250ZXh0VGV4dFN0YXRlLmZvbnQgIT0gdGV4dFN0YXRlLmZvbnQpIHtcbiAgICAgICAgY29udGV4dFRleHRTdGF0ZS5mb250ID0gdGV4dFN0YXRlLmZvbnQ7XG4gICAgICAgIGNvbnRleHQuZm9udCA9IHRleHRTdGF0ZS5mb250O1xuICAgICAgfVxuXG4gICAgICBpZiAoY29udGV4dFRleHRTdGF0ZS50ZXh0QWxpZ24gIT0gdGV4dEFsaWduKSB7XG4gICAgICAgIGNvbnRleHRUZXh0U3RhdGUudGV4dEFsaWduID1cbiAgICAgICAgLyoqIEB0eXBlIHtDYW52YXNUZXh0QWxpZ259ICovXG4gICAgICAgIHRleHRBbGlnbjtcbiAgICAgICAgY29udGV4dC50ZXh0QWxpZ24gPVxuICAgICAgICAvKiogQHR5cGUge0NhbnZhc1RleHRBbGlnbn0gKi9cbiAgICAgICAgdGV4dEFsaWduO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29udGV4dFRleHRTdGF0ZS50ZXh0QmFzZWxpbmUgIT0gdGV4dFN0YXRlLnRleHRCYXNlbGluZSkge1xuICAgICAgICBjb250ZXh0VGV4dFN0YXRlLnRleHRCYXNlbGluZSA9XG4gICAgICAgIC8qKiBAdHlwZSB7Q2FudmFzVGV4dEJhc2VsaW5lfSAqL1xuICAgICAgICB0ZXh0U3RhdGUudGV4dEJhc2VsaW5lO1xuICAgICAgICBjb250ZXh0LnRleHRCYXNlbGluZSA9XG4gICAgICAgIC8qKiBAdHlwZSB7Q2FudmFzVGV4dEJhc2VsaW5lfSAqL1xuICAgICAgICB0ZXh0U3RhdGUudGV4dEJhc2VsaW5lO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgZmlsbCBhbmQgc3Ryb2tlIHN0eWxlIGZvciBzdWJzZXF1ZW50IGRyYXcgb3BlcmF0aW9ucy4gIFRvIGNsZWFyXG4gICAqIGVpdGhlciBmaWxsIG9yIHN0cm9rZSBzdHlsZXMsIHBhc3MgbnVsbCBmb3IgdGhlIGFwcHJvcHJpYXRlIHBhcmFtZXRlci5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zdHlsZS9GaWxsLmpzXCIpLmRlZmF1bHR9IGZpbGxTdHlsZSBGaWxsIHN0eWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3N0eWxlL1N0cm9rZS5qc1wiKS5kZWZhdWx0fSBzdHJva2VTdHlsZSBTdHJva2Ugc3R5bGUuXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLnNldEZpbGxTdHJva2VTdHlsZSA9IGZ1bmN0aW9uIChmaWxsU3R5bGUsIHN0cm9rZVN0eWxlKSB7XG4gICAgaWYgKCFmaWxsU3R5bGUpIHtcbiAgICAgIHRoaXMuZmlsbFN0YXRlXyA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBmaWxsU3R5bGVDb2xvciA9IGZpbGxTdHlsZS5nZXRDb2xvcigpO1xuICAgICAgdGhpcy5maWxsU3RhdGVfID0ge1xuICAgICAgICBmaWxsU3R5bGU6IGFzQ29sb3JMaWtlKGZpbGxTdHlsZUNvbG9yID8gZmlsbFN0eWxlQ29sb3IgOiBkZWZhdWx0RmlsbFN0eWxlKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoIXN0cm9rZVN0eWxlKSB7XG4gICAgICB0aGlzLnN0cm9rZVN0YXRlXyA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBzdHJva2VTdHlsZUNvbG9yID0gc3Ryb2tlU3R5bGUuZ2V0Q29sb3IoKTtcbiAgICAgIHZhciBzdHJva2VTdHlsZUxpbmVDYXAgPSBzdHJva2VTdHlsZS5nZXRMaW5lQ2FwKCk7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVMaW5lRGFzaCA9IHN0cm9rZVN0eWxlLmdldExpbmVEYXNoKCk7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVMaW5lRGFzaE9mZnNldCA9IHN0cm9rZVN0eWxlLmdldExpbmVEYXNoT2Zmc2V0KCk7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVMaW5lSm9pbiA9IHN0cm9rZVN0eWxlLmdldExpbmVKb2luKCk7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVXaWR0aCA9IHN0cm9rZVN0eWxlLmdldFdpZHRoKCk7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVNaXRlckxpbWl0ID0gc3Ryb2tlU3R5bGUuZ2V0TWl0ZXJMaW1pdCgpO1xuICAgICAgdGhpcy5zdHJva2VTdGF0ZV8gPSB7XG4gICAgICAgIGxpbmVDYXA6IHN0cm9rZVN0eWxlTGluZUNhcCAhPT0gdW5kZWZpbmVkID8gc3Ryb2tlU3R5bGVMaW5lQ2FwIDogZGVmYXVsdExpbmVDYXAsXG4gICAgICAgIGxpbmVEYXNoOiBzdHJva2VTdHlsZUxpbmVEYXNoID8gc3Ryb2tlU3R5bGVMaW5lRGFzaCA6IGRlZmF1bHRMaW5lRGFzaCxcbiAgICAgICAgbGluZURhc2hPZmZzZXQ6IHN0cm9rZVN0eWxlTGluZURhc2hPZmZzZXQgPyBzdHJva2VTdHlsZUxpbmVEYXNoT2Zmc2V0IDogZGVmYXVsdExpbmVEYXNoT2Zmc2V0LFxuICAgICAgICBsaW5lSm9pbjogc3Ryb2tlU3R5bGVMaW5lSm9pbiAhPT0gdW5kZWZpbmVkID8gc3Ryb2tlU3R5bGVMaW5lSm9pbiA6IGRlZmF1bHRMaW5lSm9pbixcbiAgICAgICAgbGluZVdpZHRoOiB0aGlzLnBpeGVsUmF0aW9fICogKHN0cm9rZVN0eWxlV2lkdGggIT09IHVuZGVmaW5lZCA/IHN0cm9rZVN0eWxlV2lkdGggOiBkZWZhdWx0TGluZVdpZHRoKSxcbiAgICAgICAgbWl0ZXJMaW1pdDogc3Ryb2tlU3R5bGVNaXRlckxpbWl0ICE9PSB1bmRlZmluZWQgPyBzdHJva2VTdHlsZU1pdGVyTGltaXQgOiBkZWZhdWx0TWl0ZXJMaW1pdCxcbiAgICAgICAgc3Ryb2tlU3R5bGU6IGFzQ29sb3JMaWtlKHN0cm9rZVN0eWxlQ29sb3IgPyBzdHJva2VTdHlsZUNvbG9yIDogZGVmYXVsdFN0cm9rZVN0eWxlKVxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGltYWdlIHN0eWxlIGZvciBzdWJzZXF1ZW50IGRyYXcgb3BlcmF0aW9ucy4gIFBhc3MgbnVsbCB0byByZW1vdmVcbiAgICogdGhlIGltYWdlIHN0eWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3N0eWxlL0ltYWdlLmpzXCIpLmRlZmF1bHR9IGltYWdlU3R5bGUgSW1hZ2Ugc3R5bGUuXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLnNldEltYWdlU3R5bGUgPSBmdW5jdGlvbiAoaW1hZ2VTdHlsZSkge1xuICAgIGlmICghaW1hZ2VTdHlsZSkge1xuICAgICAgdGhpcy5pbWFnZV8gPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgaW1hZ2VTaXplID0gaW1hZ2VTdHlsZS5nZXRTaXplKCk7XG5cbiAgICAgIGlmICghaW1hZ2VTaXplKSB7XG4gICAgICAgIHRoaXMuaW1hZ2VfID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBpbWFnZUFuY2hvciA9IGltYWdlU3R5bGUuZ2V0QW5jaG9yKCk7IC8vIEZJWE1FIHBpeGVsIHJhdGlvXG5cbiAgICAgICAgdmFyIGltYWdlSW1hZ2UgPSBpbWFnZVN0eWxlLmdldEltYWdlKDEpO1xuICAgICAgICB2YXIgaW1hZ2VPcmlnaW4gPSBpbWFnZVN0eWxlLmdldE9yaWdpbigpO1xuICAgICAgICB2YXIgaW1hZ2VTY2FsZSA9IGltYWdlU3R5bGUuZ2V0U2NhbGVBcnJheSgpO1xuICAgICAgICB0aGlzLmltYWdlQW5jaG9yWF8gPSBpbWFnZUFuY2hvclswXTtcbiAgICAgICAgdGhpcy5pbWFnZUFuY2hvcllfID0gaW1hZ2VBbmNob3JbMV07XG4gICAgICAgIHRoaXMuaW1hZ2VIZWlnaHRfID0gaW1hZ2VTaXplWzFdO1xuICAgICAgICB0aGlzLmltYWdlXyA9IGltYWdlSW1hZ2U7XG4gICAgICAgIHRoaXMuaW1hZ2VPcGFjaXR5XyA9IGltYWdlU3R5bGUuZ2V0T3BhY2l0eSgpO1xuICAgICAgICB0aGlzLmltYWdlT3JpZ2luWF8gPSBpbWFnZU9yaWdpblswXTtcbiAgICAgICAgdGhpcy5pbWFnZU9yaWdpbllfID0gaW1hZ2VPcmlnaW5bMV07XG4gICAgICAgIHRoaXMuaW1hZ2VSb3RhdGVXaXRoVmlld18gPSBpbWFnZVN0eWxlLmdldFJvdGF0ZVdpdGhWaWV3KCk7XG4gICAgICAgIHRoaXMuaW1hZ2VSb3RhdGlvbl8gPSBpbWFnZVN0eWxlLmdldFJvdGF0aW9uKCk7XG4gICAgICAgIHRoaXMuaW1hZ2VTY2FsZV8gPSBbdGhpcy5waXhlbFJhdGlvXyAqIGltYWdlU2NhbGVbMF0sIHRoaXMucGl4ZWxSYXRpb18gKiBpbWFnZVNjYWxlWzFdXTtcbiAgICAgICAgdGhpcy5pbWFnZVdpZHRoXyA9IGltYWdlU2l6ZVswXTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHRleHQgc3R5bGUgZm9yIHN1YnNlcXVlbnQgZHJhdyBvcGVyYXRpb25zLiAgUGFzcyBudWxsIHRvXG4gICAqIHJlbW92ZSB0aGUgdGV4dCBzdHlsZS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zdHlsZS9UZXh0LmpzXCIpLmRlZmF1bHR9IHRleHRTdHlsZSBUZXh0IHN0eWxlLlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5zZXRUZXh0U3R5bGUgPSBmdW5jdGlvbiAodGV4dFN0eWxlKSB7XG4gICAgaWYgKCF0ZXh0U3R5bGUpIHtcbiAgICAgIHRoaXMudGV4dF8gPSAnJztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHRleHRGaWxsU3R5bGUgPSB0ZXh0U3R5bGUuZ2V0RmlsbCgpO1xuXG4gICAgICBpZiAoIXRleHRGaWxsU3R5bGUpIHtcbiAgICAgICAgdGhpcy50ZXh0RmlsbFN0YXRlXyA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdGV4dEZpbGxTdHlsZUNvbG9yID0gdGV4dEZpbGxTdHlsZS5nZXRDb2xvcigpO1xuICAgICAgICB0aGlzLnRleHRGaWxsU3RhdGVfID0ge1xuICAgICAgICAgIGZpbGxTdHlsZTogYXNDb2xvckxpa2UodGV4dEZpbGxTdHlsZUNvbG9yID8gdGV4dEZpbGxTdHlsZUNvbG9yIDogZGVmYXVsdEZpbGxTdHlsZSlcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgdmFyIHRleHRTdHJva2VTdHlsZSA9IHRleHRTdHlsZS5nZXRTdHJva2UoKTtcblxuICAgICAgaWYgKCF0ZXh0U3Ryb2tlU3R5bGUpIHtcbiAgICAgICAgdGhpcy50ZXh0U3Ryb2tlU3RhdGVfID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciB0ZXh0U3Ryb2tlU3R5bGVDb2xvciA9IHRleHRTdHJva2VTdHlsZS5nZXRDb2xvcigpO1xuICAgICAgICB2YXIgdGV4dFN0cm9rZVN0eWxlTGluZUNhcCA9IHRleHRTdHJva2VTdHlsZS5nZXRMaW5lQ2FwKCk7XG4gICAgICAgIHZhciB0ZXh0U3Ryb2tlU3R5bGVMaW5lRGFzaCA9IHRleHRTdHJva2VTdHlsZS5nZXRMaW5lRGFzaCgpO1xuICAgICAgICB2YXIgdGV4dFN0cm9rZVN0eWxlTGluZURhc2hPZmZzZXQgPSB0ZXh0U3Ryb2tlU3R5bGUuZ2V0TGluZURhc2hPZmZzZXQoKTtcbiAgICAgICAgdmFyIHRleHRTdHJva2VTdHlsZUxpbmVKb2luID0gdGV4dFN0cm9rZVN0eWxlLmdldExpbmVKb2luKCk7XG4gICAgICAgIHZhciB0ZXh0U3Ryb2tlU3R5bGVXaWR0aCA9IHRleHRTdHJva2VTdHlsZS5nZXRXaWR0aCgpO1xuICAgICAgICB2YXIgdGV4dFN0cm9rZVN0eWxlTWl0ZXJMaW1pdCA9IHRleHRTdHJva2VTdHlsZS5nZXRNaXRlckxpbWl0KCk7XG4gICAgICAgIHRoaXMudGV4dFN0cm9rZVN0YXRlXyA9IHtcbiAgICAgICAgICBsaW5lQ2FwOiB0ZXh0U3Ryb2tlU3R5bGVMaW5lQ2FwICE9PSB1bmRlZmluZWQgPyB0ZXh0U3Ryb2tlU3R5bGVMaW5lQ2FwIDogZGVmYXVsdExpbmVDYXAsXG4gICAgICAgICAgbGluZURhc2g6IHRleHRTdHJva2VTdHlsZUxpbmVEYXNoID8gdGV4dFN0cm9rZVN0eWxlTGluZURhc2ggOiBkZWZhdWx0TGluZURhc2gsXG4gICAgICAgICAgbGluZURhc2hPZmZzZXQ6IHRleHRTdHJva2VTdHlsZUxpbmVEYXNoT2Zmc2V0ID8gdGV4dFN0cm9rZVN0eWxlTGluZURhc2hPZmZzZXQgOiBkZWZhdWx0TGluZURhc2hPZmZzZXQsXG4gICAgICAgICAgbGluZUpvaW46IHRleHRTdHJva2VTdHlsZUxpbmVKb2luICE9PSB1bmRlZmluZWQgPyB0ZXh0U3Ryb2tlU3R5bGVMaW5lSm9pbiA6IGRlZmF1bHRMaW5lSm9pbixcbiAgICAgICAgICBsaW5lV2lkdGg6IHRleHRTdHJva2VTdHlsZVdpZHRoICE9PSB1bmRlZmluZWQgPyB0ZXh0U3Ryb2tlU3R5bGVXaWR0aCA6IGRlZmF1bHRMaW5lV2lkdGgsXG4gICAgICAgICAgbWl0ZXJMaW1pdDogdGV4dFN0cm9rZVN0eWxlTWl0ZXJMaW1pdCAhPT0gdW5kZWZpbmVkID8gdGV4dFN0cm9rZVN0eWxlTWl0ZXJMaW1pdCA6IGRlZmF1bHRNaXRlckxpbWl0LFxuICAgICAgICAgIHN0cm9rZVN0eWxlOiBhc0NvbG9yTGlrZSh0ZXh0U3Ryb2tlU3R5bGVDb2xvciA/IHRleHRTdHJva2VTdHlsZUNvbG9yIDogZGVmYXVsdFN0cm9rZVN0eWxlKVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICB2YXIgdGV4dEZvbnQgPSB0ZXh0U3R5bGUuZ2V0Rm9udCgpO1xuICAgICAgdmFyIHRleHRPZmZzZXRYID0gdGV4dFN0eWxlLmdldE9mZnNldFgoKTtcbiAgICAgIHZhciB0ZXh0T2Zmc2V0WSA9IHRleHRTdHlsZS5nZXRPZmZzZXRZKCk7XG4gICAgICB2YXIgdGV4dFJvdGF0ZVdpdGhWaWV3ID0gdGV4dFN0eWxlLmdldFJvdGF0ZVdpdGhWaWV3KCk7XG4gICAgICB2YXIgdGV4dFJvdGF0aW9uID0gdGV4dFN0eWxlLmdldFJvdGF0aW9uKCk7XG4gICAgICB2YXIgdGV4dFNjYWxlID0gdGV4dFN0eWxlLmdldFNjYWxlQXJyYXkoKTtcbiAgICAgIHZhciB0ZXh0VGV4dCA9IHRleHRTdHlsZS5nZXRUZXh0KCk7XG4gICAgICB2YXIgdGV4dFRleHRBbGlnbiA9IHRleHRTdHlsZS5nZXRUZXh0QWxpZ24oKTtcbiAgICAgIHZhciB0ZXh0VGV4dEJhc2VsaW5lID0gdGV4dFN0eWxlLmdldFRleHRCYXNlbGluZSgpO1xuICAgICAgdGhpcy50ZXh0U3RhdGVfID0ge1xuICAgICAgICBmb250OiB0ZXh0Rm9udCAhPT0gdW5kZWZpbmVkID8gdGV4dEZvbnQgOiBkZWZhdWx0Rm9udCxcbiAgICAgICAgdGV4dEFsaWduOiB0ZXh0VGV4dEFsaWduICE9PSB1bmRlZmluZWQgPyB0ZXh0VGV4dEFsaWduIDogZGVmYXVsdFRleHRBbGlnbixcbiAgICAgICAgdGV4dEJhc2VsaW5lOiB0ZXh0VGV4dEJhc2VsaW5lICE9PSB1bmRlZmluZWQgPyB0ZXh0VGV4dEJhc2VsaW5lIDogZGVmYXVsdFRleHRCYXNlbGluZVxuICAgICAgfTtcbiAgICAgIHRoaXMudGV4dF8gPSB0ZXh0VGV4dCAhPT0gdW5kZWZpbmVkID8gdGV4dFRleHQgOiAnJztcbiAgICAgIHRoaXMudGV4dE9mZnNldFhfID0gdGV4dE9mZnNldFggIT09IHVuZGVmaW5lZCA/IHRoaXMucGl4ZWxSYXRpb18gKiB0ZXh0T2Zmc2V0WCA6IDA7XG4gICAgICB0aGlzLnRleHRPZmZzZXRZXyA9IHRleHRPZmZzZXRZICE9PSB1bmRlZmluZWQgPyB0aGlzLnBpeGVsUmF0aW9fICogdGV4dE9mZnNldFkgOiAwO1xuICAgICAgdGhpcy50ZXh0Um90YXRlV2l0aFZpZXdfID0gdGV4dFJvdGF0ZVdpdGhWaWV3ICE9PSB1bmRlZmluZWQgPyB0ZXh0Um90YXRlV2l0aFZpZXcgOiBmYWxzZTtcbiAgICAgIHRoaXMudGV4dFJvdGF0aW9uXyA9IHRleHRSb3RhdGlvbiAhPT0gdW5kZWZpbmVkID8gdGV4dFJvdGF0aW9uIDogMDtcbiAgICAgIHRoaXMudGV4dFNjYWxlXyA9IFt0aGlzLnBpeGVsUmF0aW9fICogdGV4dFNjYWxlWzBdLCB0aGlzLnBpeGVsUmF0aW9fICogdGV4dFNjYWxlWzFdXTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyO1xufShWZWN0b3JDb250ZXh0KTtcblxuZXhwb3J0IGRlZmF1bHQgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXI7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL0ljb25BbmNob3JVbml0c1xuICovXG5cbi8qKlxuICogSWNvbiBhbmNob3IgdW5pdHMuIE9uZSBvZiAnZnJhY3Rpb24nLCAncGl4ZWxzJy5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIEFuY2hvciBpcyBhIGZyYWN0aW9uXG4gICAqIEBhcGlcbiAgICovXG4gIEZSQUNUSU9OOiAnZnJhY3Rpb24nLFxuXG4gIC8qKlxuICAgKiBBbmNob3IgaXMgaW4gcGl4ZWxzXG4gICAqIEBhcGlcbiAgICovXG4gIFBJWEVMUzogJ3BpeGVscydcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL0ljb25PcmlnaW5cbiAqL1xuXG4vKipcbiAqIEljb24gb3JpZ2luLiBPbmUgb2YgJ2JvdHRvbS1sZWZ0JywgJ2JvdHRvbS1yaWdodCcsICd0b3AtbGVmdCcsICd0b3AtcmlnaHQnLlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogT3JpZ2luIGlzIGF0IGJvdHRvbSBsZWZ0XG4gICAqIEBhcGlcbiAgICovXG4gIEJPVFRPTV9MRUZUOiAnYm90dG9tLWxlZnQnLFxuXG4gIC8qKlxuICAgKiBPcmlnaW4gaXMgYXQgYm90dG9tIHJpZ2h0XG4gICAqIEBhcGlcbiAgICovXG4gIEJPVFRPTV9SSUdIVDogJ2JvdHRvbS1yaWdodCcsXG5cbiAgLyoqXG4gICAqIE9yaWdpbiBpcyBhdCB0b3AgbGVmdFxuICAgKiBAYXBpXG4gICAqL1xuICBUT1BfTEVGVDogJ3RvcC1sZWZ0JyxcblxuICAvKipcbiAgICogT3JpZ2luIGlzIGF0IHRvcCByaWdodFxuICAgKiBAYXBpXG4gICAqL1xuICBUT1BfUklHSFQ6ICd0b3AtcmlnaHQnXG59OyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvSW1hZ2VCYXNlXG4gKi9cblxuXG5pbXBvcnQgRXZlbnRUYXJnZXQgZnJvbSAnLi9ldmVudHMvVGFyZ2V0LmpzJztcbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCB7IGFic3RyYWN0IH0gZnJvbSAnLi91dGlsLmpzJztcbi8qKlxuICogQGFic3RyYWN0XG4gKi9cblxudmFyIEltYWdlQmFzZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhJbWFnZUJhc2UsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vSW1hZ2VTdGF0ZS5qc1wiKS5kZWZhdWx0fSBzdGF0ZSBTdGF0ZS5cbiAgICovXG5cblxuICBmdW5jdGlvbiBJbWFnZUJhc2UoZXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvLCBzdGF0ZSkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG5cblxuICAgIF90aGlzLmV4dGVudCA9IGV4dGVudDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5waXhlbFJhdGlvXyA9IHBpeGVsUmF0aW87XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVzb2x1dGlvbiA9IHJlc29sdXRpb247XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL0ltYWdlU3RhdGUuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnN0YXRlID0gc3RhdGU7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgSW1hZ2VCYXNlLnByb3RvdHlwZS5jaGFuZ2VkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChFdmVudFR5cGUuQ0hBTkdFKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICAgKi9cblxuXG4gIEltYWdlQmFzZS5wcm90b3R5cGUuZ2V0RXh0ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmV4dGVudDtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR9IEltYWdlLlxuICAgKi9cblxuXG4gIEltYWdlQmFzZS5wcm90b3R5cGUuZ2V0SW1hZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFBpeGVsUmF0aW8uXG4gICAqL1xuXG5cbiAgSW1hZ2VCYXNlLnByb3RvdHlwZS5nZXRQaXhlbFJhdGlvID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnBpeGVsUmF0aW9fO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBSZXNvbHV0aW9uLlxuICAgKi9cblxuXG4gIEltYWdlQmFzZS5wcm90b3R5cGUuZ2V0UmVzb2x1dGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICB0aGlzLnJlc29sdXRpb25cbiAgICApO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9JbWFnZVN0YXRlLmpzXCIpLmRlZmF1bHR9IFN0YXRlLlxuICAgKi9cblxuXG4gIEltYWdlQmFzZS5wcm90b3R5cGUuZ2V0U3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGU7XG4gIH07XG4gIC8qKlxuICAgKiBMb2FkIG5vdCB5ZXQgbG9hZGVkIFVSSS5cbiAgICogQGFic3RyYWN0XG4gICAqL1xuXG5cbiAgSW1hZ2VCYXNlLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgIGFic3RyYWN0KCk7XG4gIH07XG5cbiAgcmV0dXJuIEltYWdlQmFzZTtcbn0oRXZlbnRUYXJnZXQpO1xuXG5leHBvcnQgZGVmYXVsdCBJbWFnZUJhc2U7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9JbWFnZVxuICovXG5cblxuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IEltYWdlQmFzZSBmcm9tICcuL0ltYWdlQmFzZS5qcyc7XG5pbXBvcnQgSW1hZ2VTdGF0ZSBmcm9tICcuL0ltYWdlU3RhdGUuanMnO1xuaW1wb3J0IHsgSU1BR0VfREVDT0RFIH0gZnJvbSAnLi9oYXMuanMnO1xuaW1wb3J0IHsgZ2V0SGVpZ2h0IH0gZnJvbSAnLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgbGlzdGVuT25jZSwgdW5saXN0ZW5CeUtleSB9IGZyb20gJy4vZXZlbnRzLmpzJztcbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvSW1hZ2V+SW1hZ2V9IGZvciB0aGUgaW1hZ2UgYW5kIGFcbiAqIGB7c3RyaW5nfWAgZm9yIHRoZSBzcmMgYXMgYXJndW1lbnRzLiBJdCBpcyBzdXBwb3NlZCB0byBtYWtlIGl0IHNvIHRoZVxuICogdW5kZXJseWluZyBpbWFnZSB7QGxpbmsgbW9kdWxlOm9sL0ltYWdlfkltYWdlI2dldEltYWdlfSBpcyBhc3NpZ25lZCB0aGVcbiAqIGNvbnRlbnQgc3BlY2lmaWVkIGJ5IHRoZSBzcmMuIElmIG5vdCBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGlzXG4gKlxuICogICAgIGZ1bmN0aW9uKGltYWdlLCBzcmMpIHtcbiAqICAgICAgIGltYWdlLmdldEltYWdlKCkuc3JjID0gc3JjO1xuICogICAgIH1cbiAqXG4gKiBQcm92aWRpbmcgYSBjdXN0b20gYGltYWdlTG9hZEZ1bmN0aW9uYCBjYW4gYmUgdXNlZnVsIHRvIGxvYWQgaW1hZ2VzIHdpdGhcbiAqIHBvc3QgcmVxdWVzdHMgb3IgLSBpbiBnZW5lcmFsIC0gdGhyb3VnaCBYSFIgcmVxdWVzdHMsIHdoZXJlIHRoZSBzcmMgb2YgdGhlXG4gKiBpbWFnZSBlbGVtZW50IHdvdWxkIGJlIHNldCB0byBhIGRhdGEgVVJJIHdoZW4gdGhlIGNvbnRlbnQgaXMgbG9hZGVkLlxuICpcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihJbWFnZVdyYXBwZXIsIHN0cmluZyk6IHZvaWR9IExvYWRGdW5jdGlvblxuICogQGFwaVxuICovXG5cbnZhciBJbWFnZVdyYXBwZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoSW1hZ2VXcmFwcGVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfHVuZGVmaW5lZH0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNyYyBJbWFnZSBzb3VyY2UgVVJJLlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IGNyb3NzT3JpZ2luIENyb3NzIG9yaWdpbi5cbiAgICogQHBhcmFtIHtMb2FkRnVuY3Rpb259IGltYWdlTG9hZEZ1bmN0aW9uIEltYWdlIGxvYWQgZnVuY3Rpb24uXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gSW1hZ2VXcmFwcGVyKGV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbywgc3JjLCBjcm9zc09yaWdpbiwgaW1hZ2VMb2FkRnVuY3Rpb24pIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBleHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8sIEltYWdlU3RhdGUuSURMRSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cblxuICAgIF90aGlzLnNyY18gPSBzcmM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7SFRNTENhbnZhc0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW1hZ2VfID0gbmV3IEltYWdlKCk7XG5cbiAgICBpZiAoY3Jvc3NPcmlnaW4gIT09IG51bGwpIHtcbiAgICAgIF90aGlzLmltYWdlXy5jcm9zc09yaWdpbiA9IGNyb3NzT3JpZ2luO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/ZnVuY3Rpb24oKTp2b2lkfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy51bmxpc3Rlbl8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9JbWFnZVN0YXRlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5zdGF0ZSA9IEltYWdlU3RhdGUuSURMRTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtMb2FkRnVuY3Rpb259XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZUxvYWRGdW5jdGlvbl8gPSBpbWFnZUxvYWRGdW5jdGlvbjtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEByZXR1cm4ge0hUTUxDYW52YXNFbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR8SFRNTFZpZGVvRWxlbWVudH0gSW1hZ2UuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVdyYXBwZXIucHJvdG90eXBlLmdldEltYWdlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmltYWdlXztcbiAgfTtcbiAgLyoqXG4gICAqIFRyYWNrcyBsb2FkaW5nIG9yIHJlYWQgZXJyb3JzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIEltYWdlV3JhcHBlci5wcm90b3R5cGUuaGFuZGxlSW1hZ2VFcnJvcl8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zdGF0ZSA9IEltYWdlU3RhdGUuRVJST1I7XG4gICAgdGhpcy51bmxpc3RlbkltYWdlXygpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogVHJhY2tzIHN1Y2Nlc3NmdWwgaW1hZ2UgbG9hZC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBJbWFnZVdyYXBwZXIucHJvdG90eXBlLmhhbmRsZUltYWdlTG9hZF8gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMucmVzb2x1dGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnJlc29sdXRpb24gPSBnZXRIZWlnaHQodGhpcy5leHRlbnQpIC8gdGhpcy5pbWFnZV8uaGVpZ2h0O1xuICAgIH1cblxuICAgIHRoaXMuc3RhdGUgPSBJbWFnZVN0YXRlLkxPQURFRDtcbiAgICB0aGlzLnVubGlzdGVuSW1hZ2VfKCk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBMb2FkIHRoZSBpbWFnZSBvciByZXRyeSBpZiBsb2FkaW5nIHByZXZpb3VzbHkgZmFpbGVkLlxuICAgKiBMb2FkaW5nIGlzIHRha2VuIGNhcmUgb2YgYnkgdGhlIHRpbGUgcXVldWUsIGFuZCBjYWxsaW5nIHRoaXMgbWV0aG9kIGlzXG4gICAqIG9ubHkgbmVlZGVkIGZvciBwcmVsb2FkaW5nIG9yIGZvciByZWxvYWRpbmcgaW4gY2FzZSBvZiBhbiBlcnJvci5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEltYWdlV3JhcHBlci5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZSA9PSBJbWFnZVN0YXRlLklETEUgfHwgdGhpcy5zdGF0ZSA9PSBJbWFnZVN0YXRlLkVSUk9SKSB7XG4gICAgICB0aGlzLnN0YXRlID0gSW1hZ2VTdGF0ZS5MT0FESU5HO1xuICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICB0aGlzLmltYWdlTG9hZEZ1bmN0aW9uXyh0aGlzLCB0aGlzLnNyY18pO1xuICAgICAgdGhpcy51bmxpc3Rlbl8gPSBsaXN0ZW5JbWFnZSh0aGlzLmltYWdlXywgdGhpcy5oYW5kbGVJbWFnZUxvYWRfLmJpbmQodGhpcyksIHRoaXMuaGFuZGxlSW1hZ2VFcnJvcl8uYmluZCh0aGlzKSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR9IGltYWdlIEltYWdlLlxuICAgKi9cblxuXG4gIEltYWdlV3JhcHBlci5wcm90b3R5cGUuc2V0SW1hZ2UgPSBmdW5jdGlvbiAoaW1hZ2UpIHtcbiAgICB0aGlzLmltYWdlXyA9IGltYWdlO1xuICB9O1xuICAvKipcbiAgICogRGlzY2FyZHMgZXZlbnQgaGFuZGxlcnMgd2hpY2ggbGlzdGVuIGZvciBsb2FkIGNvbXBsZXRpb24gb3IgZXJyb3JzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIEltYWdlV3JhcHBlci5wcm90b3R5cGUudW5saXN0ZW5JbWFnZV8gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMudW5saXN0ZW5fKSB7XG4gICAgICB0aGlzLnVubGlzdGVuXygpO1xuICAgICAgdGhpcy51bmxpc3Rlbl8gPSBudWxsO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gSW1hZ2VXcmFwcGVyO1xufShJbWFnZUJhc2UpO1xuLyoqXG4gKiBAcGFyYW0ge0hUTUxDYW52YXNFbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR8SFRNTFZpZGVvRWxlbWVudH0gaW1hZ2UgSW1hZ2UgZWxlbWVudC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKTphbnl9IGxvYWRIYW5kbGVyIExvYWQgY2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCk6YW55fSBlcnJvckhhbmRsZXIgRXJyb3IgY2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAcmV0dXJuIHtmdW5jdGlvbigpOnZvaWR9IENhbGxiYWNrIHRvIHN0b3AgbGlzdGVuaW5nLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGxpc3RlbkltYWdlKGltYWdlLCBsb2FkSGFuZGxlciwgZXJyb3JIYW5kbGVyKSB7XG4gIHZhciBpbWcgPVxuICAvKiogQHR5cGUge0hUTUxJbWFnZUVsZW1lbnR9ICovXG4gIGltYWdlO1xuXG4gIGlmIChpbWcuc3JjICYmIElNQUdFX0RFQ09ERSkge1xuICAgIHZhciBwcm9taXNlID0gaW1nLmRlY29kZSgpO1xuICAgIHZhciBsaXN0ZW5pbmdfMSA9IHRydWU7XG5cbiAgICB2YXIgdW5saXN0ZW4gPSBmdW5jdGlvbiB1bmxpc3RlbigpIHtcbiAgICAgIGxpc3RlbmluZ18xID0gZmFsc2U7XG4gICAgfTtcblxuICAgIHByb21pc2UudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAobGlzdGVuaW5nXzEpIHtcbiAgICAgICAgbG9hZEhhbmRsZXIoKTtcbiAgICAgIH1cbiAgICB9KS5jYXRjaChmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmIChsaXN0ZW5pbmdfMSkge1xuICAgICAgICAvLyBGSVhNRTogVW5jb25kaXRpb25hbGx5IGNhbGwgZXJyb3JIYW5kbGVyKCkgd2hlbiB0aGlzIGJ1ZyBpcyBmaXhlZCB1cHN0cmVhbTpcbiAgICAgICAgLy8gICAgICAgIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xOTg1MjdcbiAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFbmNvZGluZ0Vycm9yJyAmJiBlcnJvci5tZXNzYWdlID09PSAnSW52YWxpZCBpbWFnZSB0eXBlLicpIHtcbiAgICAgICAgICBsb2FkSGFuZGxlcigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVycm9ySGFuZGxlcigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHVubGlzdGVuO1xuICB9XG5cbiAgdmFyIGxpc3RlbmVyS2V5cyA9IFtsaXN0ZW5PbmNlKGltZywgRXZlbnRUeXBlLkxPQUQsIGxvYWRIYW5kbGVyKSwgbGlzdGVuT25jZShpbWcsIEV2ZW50VHlwZS5FUlJPUiwgZXJyb3JIYW5kbGVyKV07XG4gIHJldHVybiBmdW5jdGlvbiB1bmxpc3RlbigpIHtcbiAgICBsaXN0ZW5lcktleXMuZm9yRWFjaCh1bmxpc3RlbkJ5S2V5KTtcbiAgfTtcbn1cbmV4cG9ydCBkZWZhdWx0IEltYWdlV3JhcHBlcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvc3R5bGUvSWNvbkltYWdlXG4gKi9cbnZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG5cbmltcG9ydCBFdmVudFRhcmdldCBmcm9tICcuLi9ldmVudHMvVGFyZ2V0LmpzJztcbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi4vZXZlbnRzL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgSW1hZ2VTdGF0ZSBmcm9tICcuLi9JbWFnZVN0YXRlLmpzJztcbmltcG9ydCB7IGFzU3RyaW5nIH0gZnJvbSAnLi4vY29sb3IuanMnO1xuaW1wb3J0IHsgY3JlYXRlQ2FudmFzQ29udGV4dDJEIH0gZnJvbSAnLi4vZG9tLmpzJztcbmltcG9ydCB7IHNoYXJlZCBhcyBpY29uSW1hZ2VDYWNoZSB9IGZyb20gJy4vSWNvbkltYWdlQ2FjaGUuanMnO1xuaW1wb3J0IHsgbGlzdGVuSW1hZ2UgfSBmcm9tICcuLi9JbWFnZS5qcyc7XG4vKipcbiAqIEB0eXBlIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9XG4gKi9cblxudmFyIHRhaW50ZWRUZXN0Q29udGV4dCA9IG51bGw7XG5cbnZhciBJY29uSW1hZ2UgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoSWNvbkltYWdlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtIVE1MSW1hZ2VFbGVtZW50fEhUTUxDYW52YXNFbGVtZW50fSBpbWFnZSBJbWFnZS5cbiAgICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBzcmMgU3JjLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBTaXplLlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IGNyb3NzT3JpZ2luIENyb3NzIG9yaWdpbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9JbWFnZVN0YXRlLmpzXCIpLmRlZmF1bHR9IGltYWdlU3RhdGUgSW1hZ2Ugc3RhdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J9IGNvbG9yIENvbG9yLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIEljb25JbWFnZShpbWFnZSwgc3JjLCBzaXplLCBjcm9zc09yaWdpbiwgaW1hZ2VTdGF0ZSwgY29sb3IpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0hUTUxJbWFnZUVsZW1lbnR8SFRNTENhbnZhc0VsZW1lbnR9XG4gICAgICovXG5cblxuICAgIF90aGlzLmhpdERldGVjdGlvbkltYWdlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7SFRNTEltYWdlRWxlbWVudHxIVE1MQ2FudmFzRWxlbWVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlXyA9ICFpbWFnZSA/IG5ldyBJbWFnZSgpIDogaW1hZ2U7XG5cbiAgICBpZiAoY3Jvc3NPcmlnaW4gIT09IG51bGwpIHtcbiAgICAgIC8qKiBAdHlwZSB7SFRNTEltYWdlRWxlbWVudH0gKi9cbiAgICAgIF90aGlzLmltYWdlXy5jcm9zc09yaWdpbiA9IGNyb3NzT3JpZ2luO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8bnVtYmVyLCBIVE1MQ2FudmFzRWxlbWVudD59XG4gICAgICovXG5cblxuICAgIF90aGlzLmNhbnZhc18gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9jb2xvci5qc1wiKS5Db2xvcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbG9yXyA9IGNvbG9yO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9mdW5jdGlvbigpOnZvaWR9XG4gICAgICovXG5cbiAgICBfdGhpcy51bmxpc3Rlbl8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL0ltYWdlU3RhdGUuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlU3RhdGVfID0gaW1hZ2VTdGF0ZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICBfdGhpcy5zaXplXyA9IHNpemU7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnNyY18gPSBzcmM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLnRhaW50ZWRfO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIGltYWdlIGNhbnZhcyBpcyB0YWludGVkLlxuICAgKi9cblxuXG4gIEljb25JbWFnZS5wcm90b3R5cGUuaXNUYWludGVkXyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy50YWludGVkXyA9PT0gdW5kZWZpbmVkICYmIHRoaXMuaW1hZ2VTdGF0ZV8gPT09IEltYWdlU3RhdGUuTE9BREVEKSB7XG4gICAgICBpZiAoIXRhaW50ZWRUZXN0Q29udGV4dCkge1xuICAgICAgICB0YWludGVkVGVzdENvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0MkQoMSwgMSk7XG4gICAgICB9XG5cbiAgICAgIHRhaW50ZWRUZXN0Q29udGV4dC5kcmF3SW1hZ2UodGhpcy5pbWFnZV8sIDAsIDApO1xuXG4gICAgICB0cnkge1xuICAgICAgICB0YWludGVkVGVzdENvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIDEsIDEpO1xuICAgICAgICB0aGlzLnRhaW50ZWRfID0gZmFsc2U7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRhaW50ZWRUZXN0Q29udGV4dCA9IG51bGw7XG4gICAgICAgIHRoaXMudGFpbnRlZF8gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnRhaW50ZWRfID09PSB0cnVlO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBJY29uSW1hZ2UucHJvdG90eXBlLmRpc3BhdGNoQ2hhbmdlRXZlbnRfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChFdmVudFR5cGUuQ0hBTkdFKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlLnByb3RvdHlwZS5oYW5kbGVJbWFnZUVycm9yXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmltYWdlU3RhdGVfID0gSW1hZ2VTdGF0ZS5FUlJPUjtcbiAgICB0aGlzLnVubGlzdGVuSW1hZ2VfKCk7XG4gICAgdGhpcy5kaXNwYXRjaENoYW5nZUV2ZW50XygpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBJY29uSW1hZ2UucHJvdG90eXBlLmhhbmRsZUltYWdlTG9hZF8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5pbWFnZVN0YXRlXyA9IEltYWdlU3RhdGUuTE9BREVEO1xuXG4gICAgaWYgKHRoaXMuc2l6ZV8pIHtcbiAgICAgIHRoaXMuaW1hZ2VfLndpZHRoID0gdGhpcy5zaXplX1swXTtcbiAgICAgIHRoaXMuaW1hZ2VfLmhlaWdodCA9IHRoaXMuc2l6ZV9bMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2l6ZV8gPSBbdGhpcy5pbWFnZV8ud2lkdGgsIHRoaXMuaW1hZ2VfLmhlaWdodF07XG4gICAgfVxuXG4gICAgdGhpcy51bmxpc3RlbkltYWdlXygpO1xuICAgIHRoaXMuZGlzcGF0Y2hDaGFuZ2VFdmVudF8oKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcmV0dXJuIHtIVE1MSW1hZ2VFbGVtZW50fEhUTUxDYW52YXNFbGVtZW50fSBJbWFnZSBvciBDYW52YXMgZWxlbWVudC5cbiAgICovXG5cblxuICBJY29uSW1hZ2UucHJvdG90eXBlLmdldEltYWdlID0gZnVuY3Rpb24gKHBpeGVsUmF0aW8pIHtcbiAgICB0aGlzLnJlcGxhY2VDb2xvcl8ocGl4ZWxSYXRpbyk7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzX1twaXhlbFJhdGlvXSA/IHRoaXMuY2FudmFzX1twaXhlbFJhdGlvXSA6IHRoaXMuaW1hZ2VfO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEByZXR1cm4ge251bWJlcn0gSW1hZ2Ugb3IgQ2FudmFzIGVsZW1lbnQuXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlLnByb3RvdHlwZS5nZXRQaXhlbFJhdGlvID0gZnVuY3Rpb24gKHBpeGVsUmF0aW8pIHtcbiAgICB0aGlzLnJlcGxhY2VDb2xvcl8ocGl4ZWxSYXRpbyk7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzX1twaXhlbFJhdGlvXSA/IHBpeGVsUmF0aW8gOiAxO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vSW1hZ2VTdGF0ZS5qc1wiKS5kZWZhdWx0fSBJbWFnZSBzdGF0ZS5cbiAgICovXG5cblxuICBJY29uSW1hZ2UucHJvdG90eXBlLmdldEltYWdlU3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VTdGF0ZV87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtIVE1MSW1hZ2VFbGVtZW50fEhUTUxDYW52YXNFbGVtZW50fSBJbWFnZSBlbGVtZW50LlxuICAgKi9cblxuXG4gIEljb25JbWFnZS5wcm90b3R5cGUuZ2V0SGl0RGV0ZWN0aW9uSW1hZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmhpdERldGVjdGlvbkltYWdlXykge1xuICAgICAgaWYgKHRoaXMuaXNUYWludGVkXygpKSB7XG4gICAgICAgIHZhciB3aWR0aCA9IHRoaXMuc2l6ZV9bMF07XG4gICAgICAgIHZhciBoZWlnaHQgPSB0aGlzLnNpemVfWzFdO1xuICAgICAgICB2YXIgY29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgY29udGV4dC5maWxsUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgdGhpcy5oaXREZXRlY3Rpb25JbWFnZV8gPSBjb250ZXh0LmNhbnZhcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VfID0gdGhpcy5pbWFnZV87XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzaXplIG9mIHRoZSBpY29uIChpbiBwaXhlbHMpLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IEltYWdlIHNpemUuXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlLnByb3RvdHlwZS5nZXRTaXplID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnNpemVfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH0gSW1hZ2Ugc3JjLlxuICAgKi9cblxuXG4gIEljb25JbWFnZS5wcm90b3R5cGUuZ2V0U3JjID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnNyY187XG4gIH07XG4gIC8qKlxuICAgKiBMb2FkIG5vdCB5ZXQgbG9hZGVkIFVSSS5cbiAgICovXG5cblxuICBJY29uSW1hZ2UucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuaW1hZ2VTdGF0ZV8gPT0gSW1hZ2VTdGF0ZS5JRExFKSB7XG4gICAgICB0aGlzLmltYWdlU3RhdGVfID0gSW1hZ2VTdGF0ZS5MT0FESU5HO1xuXG4gICAgICB0cnkge1xuICAgICAgICAvKiogQHR5cGUge0hUTUxJbWFnZUVsZW1lbnR9ICovXG4gICAgICAgIHRoaXMuaW1hZ2VfLnNyYyA9IHRoaXMuc3JjXztcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVJbWFnZUVycm9yXygpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnVubGlzdGVuXyA9IGxpc3RlbkltYWdlKHRoaXMuaW1hZ2VfLCB0aGlzLmhhbmRsZUltYWdlTG9hZF8uYmluZCh0aGlzKSwgdGhpcy5oYW5kbGVJbWFnZUVycm9yXy5iaW5kKHRoaXMpKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBJY29uSW1hZ2UucHJvdG90eXBlLnJlcGxhY2VDb2xvcl8gPSBmdW5jdGlvbiAocGl4ZWxSYXRpbykge1xuICAgIGlmICghdGhpcy5jb2xvcl8gfHwgdGhpcy5jYW52YXNfW3BpeGVsUmF0aW9dKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIHRoaXMuY2FudmFzX1twaXhlbFJhdGlvXSA9IGNhbnZhcztcbiAgICBjYW52YXMud2lkdGggPSBNYXRoLmNlaWwodGhpcy5pbWFnZV8ud2lkdGggKiBwaXhlbFJhdGlvKTtcbiAgICBjYW52YXMuaGVpZ2h0ID0gTWF0aC5jZWlsKHRoaXMuaW1hZ2VfLmhlaWdodCAqIHBpeGVsUmF0aW8pO1xuICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBjdHguc2NhbGUocGl4ZWxSYXRpbywgcGl4ZWxSYXRpbyk7XG4gICAgY3R4LmRyYXdJbWFnZSh0aGlzLmltYWdlXywgMCwgMCk7XG4gICAgY3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdtdWx0aXBseSc7IC8vIEludGVybmV0IEV4cGxvcmVyIDExIGRvZXMgbm90IHN1cHBvcnQgdGhlIG11bHRpcGx5IG9wZXJhdGlvbi5cbiAgICAvLyBJZiB0aGUgY2FudmFzIGlzIHRhaW50ZWQgaW4gSW50ZXJuZXQgRXhwbG9yZXIgdGhpcyBzdGlsbCBwcm9kdWNlc1xuICAgIC8vIGEgc29saWQgY29sb3IgaW1hZ2Ugd2l0aCB0aGUgc2hhcGUgb2YgdGhlIGljb24uXG5cbiAgICBpZiAoY3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9PT0gJ211bHRpcGx5JyB8fCB0aGlzLmlzVGFpbnRlZF8oKSkge1xuICAgICAgY3R4LmZpbGxTdHlsZSA9IGFzU3RyaW5nKHRoaXMuY29sb3JfKTtcbiAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuICAgICAgY3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdkZXN0aW5hdGlvbi1pbic7XG4gICAgICBjdHguZHJhd0ltYWdlKHRoaXMuaW1hZ2VfLCAwLCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGltZ0RhdGEgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG4gICAgICB2YXIgZGF0YSA9IGltZ0RhdGEuZGF0YTtcbiAgICAgIHZhciByID0gdGhpcy5jb2xvcl9bMF0gLyAyNTUuMDtcbiAgICAgIHZhciBnID0gdGhpcy5jb2xvcl9bMV0gLyAyNTUuMDtcbiAgICAgIHZhciBiID0gdGhpcy5jb2xvcl9bMl0gLyAyNTUuMDtcbiAgICAgIHZhciBhID0gdGhpcy5jb2xvcl9bM107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGRhdGEubGVuZ3RoOyBpIDwgaWk7IGkgKz0gNCkge1xuICAgICAgICBkYXRhW2ldICo9IHI7XG4gICAgICAgIGRhdGFbaSArIDFdICo9IGc7XG4gICAgICAgIGRhdGFbaSArIDJdICo9IGI7XG4gICAgICAgIGRhdGFbaSArIDNdICo9IGE7XG4gICAgICB9XG5cbiAgICAgIGN0eC5wdXRJbWFnZURhdGEoaW1nRGF0YSwgMCwgMCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogRGlzY2FyZHMgZXZlbnQgaGFuZGxlcnMgd2hpY2ggbGlzdGVuIGZvciBsb2FkIGNvbXBsZXRpb24gb3IgZXJyb3JzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIEljb25JbWFnZS5wcm90b3R5cGUudW5saXN0ZW5JbWFnZV8gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMudW5saXN0ZW5fKSB7XG4gICAgICB0aGlzLnVubGlzdGVuXygpO1xuICAgICAgdGhpcy51bmxpc3Rlbl8gPSBudWxsO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gSWNvbkltYWdlO1xufShFdmVudFRhcmdldCk7XG4vKipcbiAqIEBwYXJhbSB7SFRNTEltYWdlRWxlbWVudHxIVE1MQ2FudmFzRWxlbWVudH0gaW1hZ2UgSW1hZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3JjIFNyYy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIFNpemUuXG4gKiBAcGFyYW0gez9zdHJpbmd9IGNyb3NzT3JpZ2luIENyb3NzIG9yaWdpbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vSW1hZ2VTdGF0ZS5qc1wiKS5kZWZhdWx0fSBpbWFnZVN0YXRlIEltYWdlIHN0YXRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb2xvci5qc1wiKS5Db2xvcn0gY29sb3IgQ29sb3IuXG4gKiBAcmV0dXJuIHtJY29uSW1hZ2V9IEljb24gaW1hZ2UuXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0KGltYWdlLCBzcmMsIHNpemUsIGNyb3NzT3JpZ2luLCBpbWFnZVN0YXRlLCBjb2xvcikge1xuICB2YXIgaWNvbkltYWdlID0gaWNvbkltYWdlQ2FjaGUuZ2V0KHNyYywgY3Jvc3NPcmlnaW4sIGNvbG9yKTtcblxuICBpZiAoIWljb25JbWFnZSkge1xuICAgIGljb25JbWFnZSA9IG5ldyBJY29uSW1hZ2UoaW1hZ2UsIHNyYywgc2l6ZSwgY3Jvc3NPcmlnaW4sIGltYWdlU3RhdGUsIGNvbG9yKTtcbiAgICBpY29uSW1hZ2VDYWNoZS5zZXQoc3JjLCBjcm9zc09yaWdpbiwgY29sb3IsIGljb25JbWFnZSk7XG4gIH1cblxuICByZXR1cm4gaWNvbkltYWdlO1xufVxuZXhwb3J0IGRlZmF1bHQgSWNvbkltYWdlOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvc3R5bGUvSWNvblxuICovXG5cblxuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBJY29uQW5jaG9yVW5pdHMgZnJvbSAnLi9JY29uQW5jaG9yVW5pdHMuanMnO1xuaW1wb3J0IEljb25PcmlnaW4gZnJvbSAnLi9JY29uT3JpZ2luLmpzJztcbmltcG9ydCBJbWFnZVN0YXRlIGZyb20gJy4uL0ltYWdlU3RhdGUuanMnO1xuaW1wb3J0IEltYWdlU3R5bGUgZnJvbSAnLi9JbWFnZS5qcyc7XG5pbXBvcnQgeyBhc0FycmF5IH0gZnJvbSAnLi4vY29sb3IuanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vYXNzZXJ0cy5qcyc7XG5pbXBvcnQgeyBnZXQgYXMgZ2V0SWNvbkltYWdlIH0gZnJvbSAnLi9JY29uSW1hZ2UuanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi4vdXRpbC5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gW2FuY2hvcj1bMC41LCAwLjVdXSBBbmNob3IuIERlZmF1bHQgdmFsdWUgaXMgdGhlIGljb24gY2VudGVyLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL0ljb25PcmlnaW4uanNcIikuZGVmYXVsdH0gW2FuY2hvck9yaWdpbj0ndG9wLWxlZnQnXSBPcmlnaW4gb2YgdGhlIGFuY2hvcjogYGJvdHRvbS1sZWZ0YCwgYGJvdHRvbS1yaWdodGAsXG4gKiBgdG9wLWxlZnRgIG9yIGB0b3AtcmlnaHRgLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL0ljb25BbmNob3JVbml0cy5qc1wiKS5kZWZhdWx0fSBbYW5jaG9yWFVuaXRzPSdmcmFjdGlvbiddIFVuaXRzIGluIHdoaWNoIHRoZSBhbmNob3IgeCB2YWx1ZSBpc1xuICogc3BlY2lmaWVkLiBBIHZhbHVlIG9mIGAnZnJhY3Rpb24nYCBpbmRpY2F0ZXMgdGhlIHggdmFsdWUgaXMgYSBmcmFjdGlvbiBvZiB0aGUgaWNvbi4gQSB2YWx1ZSBvZiBgJ3BpeGVscydgIGluZGljYXRlc1xuICogdGhlIHggdmFsdWUgaW4gcGl4ZWxzLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL0ljb25BbmNob3JVbml0cy5qc1wiKS5kZWZhdWx0fSBbYW5jaG9yWVVuaXRzPSdmcmFjdGlvbiddIFVuaXRzIGluIHdoaWNoIHRoZSBhbmNob3IgeSB2YWx1ZSBpc1xuICogc3BlY2lmaWVkLiBBIHZhbHVlIG9mIGAnZnJhY3Rpb24nYCBpbmRpY2F0ZXMgdGhlIHkgdmFsdWUgaXMgYSBmcmFjdGlvbiBvZiB0aGUgaWNvbi4gQSB2YWx1ZSBvZiBgJ3BpeGVscydgIGluZGljYXRlc1xuICogdGhlIHkgdmFsdWUgaW4gcGl4ZWxzLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9jb2xvci5qc1wiKS5Db2xvcnxzdHJpbmd9IFtjb2xvcl0gQ29sb3IgdG8gdGludCB0aGUgaWNvbi4gSWYgbm90IHNwZWNpZmllZCxcbiAqIHRoZSBpY29uIHdpbGwgYmUgbGVmdCBhcyBpcy5cbiAqIEBwcm9wZXJ0eSB7bnVsbHxzdHJpbmd9IFtjcm9zc09yaWdpbl0gVGhlIGBjcm9zc09yaWdpbmAgYXR0cmlidXRlIGZvciBsb2FkZWQgaW1hZ2VzLiBOb3RlIHRoYXQgeW91IG11c3QgcHJvdmlkZSBhXG4gKiBgY3Jvc3NPcmlnaW5gIHZhbHVlIGlmIHlvdSB3YW50IHRvIGFjY2VzcyBwaXhlbCBkYXRhIHdpdGggdGhlIENhbnZhcyByZW5kZXJlci5cbiAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0NPUlNfZW5hYmxlZF9pbWFnZSBmb3IgbW9yZSBkZXRhaWwuXG4gKiBAcHJvcGVydHkge0hUTUxJbWFnZUVsZW1lbnR8SFRNTENhbnZhc0VsZW1lbnR9IFtpbWddIEltYWdlIG9iamVjdCBmb3IgdGhlIGljb24uIElmIHRoZSBgc3JjYCBvcHRpb24gaXMgbm90IHByb3ZpZGVkIHRoZW4gdGhlXG4gKiBwcm92aWRlZCBpbWFnZSBtdXN0IGFscmVhZHkgYmUgbG9hZGVkLiBBbmQgaW4gdGhhdCBjYXNlLCBpdCBpcyByZXF1aXJlZFxuICogdG8gcHJvdmlkZSB0aGUgc2l6ZSBvZiB0aGUgaW1hZ2UsIHdpdGggdGhlIGBpbWdTaXplYCBvcHRpb24uXG4gKiBAcHJvcGVydHkge0FycmF5PG51bWJlcj59IFtvZmZzZXQ9WzAsIDBdXSBPZmZzZXQsIHdoaWNoLCB0b2dldGhlciB3aXRoIHRoZSBzaXplIGFuZCB0aGUgb2Zmc2V0IG9yaWdpbiwgZGVmaW5lIHRoZVxuICogc3ViLXJlY3RhbmdsZSB0byB1c2UgZnJvbSB0aGUgb3JpZ2luYWwgaWNvbiBpbWFnZS5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gW2Rpc3BsYWNlbWVudD1bMCwwXV0gRGlzcGxhY2VtZW50IHRoZSBpY29uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vSWNvbk9yaWdpbi5qc1wiKS5kZWZhdWx0fSBbb2Zmc2V0T3JpZ2luPSd0b3AtbGVmdCddIE9yaWdpbiBvZiB0aGUgb2Zmc2V0OiBgYm90dG9tLWxlZnRgLCBgYm90dG9tLXJpZ2h0YCxcbiAqIGB0b3AtbGVmdGAgb3IgYHRvcC1yaWdodGAuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW29wYWNpdHk9MV0gT3BhY2l0eSBvZiB0aGUgaWNvbi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gW3NjYWxlPTFdIFNjYWxlLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbcm90YXRlV2l0aFZpZXc9ZmFsc2VdIFdoZXRoZXIgdG8gcm90YXRlIHRoZSBpY29uIHdpdGggdGhlIHZpZXcuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3JvdGF0aW9uPTBdIFJvdGF0aW9uIGluIHJhZGlhbnMgKHBvc2l0aXZlIHJvdGF0aW9uIGNsb2Nrd2lzZSkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gW3NpemVdIEljb24gc2l6ZSBpbiBwaXhlbC4gQ2FuIGJlIHVzZWQgdG9nZXRoZXIgd2l0aCBgb2Zmc2V0YCB0byBkZWZpbmUgdGhlXG4gKiBzdWItcmVjdGFuZ2xlIHRvIHVzZSBmcm9tIHRoZSBvcmlnaW4gKHNwcml0ZSkgaWNvbiBpbWFnZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBbaW1nU2l6ZV0gSW1hZ2Ugc2l6ZSBpbiBwaXhlbHMuIE9ubHkgcmVxdWlyZWQgaWYgYGltZ2AgaXMgc2V0IGFuZCBgc3JjYCBpcyBub3QsIGFuZFxuICogZm9yIFNWRyBpbWFnZXMgaW4gSW50ZXJuZXQgRXhwbG9yZXIgMTEuIFRoZSBwcm92aWRlZCBgaW1nU2l6ZWAgbmVlZHMgdG8gbWF0Y2ggdGhlIGFjdHVhbCBzaXplIG9mIHRoZSBpbWFnZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbc3JjXSBJbWFnZSBzb3VyY2UgVVJJLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogU2V0IGljb24gc3R5bGUgZm9yIHZlY3RvciBmZWF0dXJlcy5cbiAqIEBhcGlcbiAqL1xuXG52YXIgSWNvbiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhJY29uLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBJY29uKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgfHwge307XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHZhciBvcGFjaXR5ID0gb3B0aW9ucy5vcGFjaXR5ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm9wYWNpdHkgOiAxO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB2YXIgcm90YXRpb24gPSBvcHRpb25zLnJvdGF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnJvdGF0aW9uIDogMDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIHZhciBzY2FsZSA9IG9wdGlvbnMuc2NhbGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc2NhbGUgOiAxO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgdmFyIHJvdGF0ZVdpdGhWaWV3ID0gb3B0aW9ucy5yb3RhdGVXaXRoVmlldyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yb3RhdGVXaXRoVmlldyA6IGZhbHNlO1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgb3BhY2l0eTogb3BhY2l0eSxcbiAgICAgIHJvdGF0aW9uOiByb3RhdGlvbixcbiAgICAgIHNjYWxlOiBzY2FsZSxcbiAgICAgIGRpc3BsYWNlbWVudDogb3B0aW9ucy5kaXNwbGFjZW1lbnQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZGlzcGxhY2VtZW50IDogWzAsIDBdLFxuICAgICAgcm90YXRlV2l0aFZpZXc6IHJvdGF0ZVdpdGhWaWV3XG4gICAgfSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuYW5jaG9yXyA9IG9wdGlvbnMuYW5jaG9yICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmFuY2hvciA6IFswLjUsIDAuNV07XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIF90aGlzLm5vcm1hbGl6ZWRBbmNob3JfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL0ljb25PcmlnaW4uanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLmFuY2hvck9yaWdpbl8gPSBvcHRpb25zLmFuY2hvck9yaWdpbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5hbmNob3JPcmlnaW4gOiBJY29uT3JpZ2luLlRPUF9MRUZUO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vSWNvbkFuY2hvclVuaXRzLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5hbmNob3JYVW5pdHNfID0gb3B0aW9ucy5hbmNob3JYVW5pdHMgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuYW5jaG9yWFVuaXRzIDogSWNvbkFuY2hvclVuaXRzLkZSQUNUSU9OO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vSWNvbkFuY2hvclVuaXRzLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5hbmNob3JZVW5pdHNfID0gb3B0aW9ucy5hbmNob3JZVW5pdHMgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuYW5jaG9yWVVuaXRzIDogSWNvbkFuY2hvclVuaXRzLkZSQUNUSU9OO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9zdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy5jcm9zc09yaWdpbl8gPSBvcHRpb25zLmNyb3NzT3JpZ2luICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNyb3NzT3JpZ2luIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7SFRNTEltYWdlRWxlbWVudHxIVE1MQ2FudmFzRWxlbWVudH1cbiAgICAgKi9cblxuICAgIHZhciBpbWFnZSA9IG9wdGlvbnMuaW1nICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmltZyA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIHZhciBpbWdTaXplID0gb3B0aW9ucy5pbWdTaXplICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmltZ1NpemUgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtzdHJpbmd8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgdmFyIHNyYyA9IG9wdGlvbnMuc3JjO1xuICAgIGFzc2VydCghKHNyYyAhPT0gdW5kZWZpbmVkICYmIGltYWdlKSwgNCk7IC8vIGBpbWFnZWAgYW5kIGBzcmNgIGNhbm5vdCBiZSBwcm92aWRlZCBhdCB0aGUgc2FtZSB0aW1lXG5cbiAgICBhc3NlcnQoIWltYWdlIHx8IGltYWdlICYmIGltZ1NpemUsIDUpOyAvLyBgaW1nU2l6ZWAgbXVzdCBiZSBzZXQgd2hlbiBgaW1hZ2VgIGlzIHByb3ZpZGVkXG5cbiAgICBpZiAoKHNyYyA9PT0gdW5kZWZpbmVkIHx8IHNyYy5sZW5ndGggPT09IDApICYmIGltYWdlKSB7XG4gICAgICBzcmMgPVxuICAgICAgLyoqIEB0eXBlIHtIVE1MSW1hZ2VFbGVtZW50fSAqL1xuICAgICAgaW1hZ2Uuc3JjIHx8IGdldFVpZChpbWFnZSk7XG4gICAgfVxuXG4gICAgYXNzZXJ0KHNyYyAhPT0gdW5kZWZpbmVkICYmIHNyYy5sZW5ndGggPiAwLCA2KTsgLy8gQSBkZWZpbmVkIGFuZCBub24tZW1wdHkgYHNyY2Agb3IgYGltYWdlYCBtdXN0IGJlIHByb3ZpZGVkXG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vSW1hZ2VTdGF0ZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgdmFyIGltYWdlU3RhdGUgPSBvcHRpb25zLnNyYyAhPT0gdW5kZWZpbmVkID8gSW1hZ2VTdGF0ZS5JRExFIDogSW1hZ2VTdGF0ZS5MT0FERUQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J9XG4gICAgICovXG5cbiAgICBfdGhpcy5jb2xvcl8gPSBvcHRpb25zLmNvbG9yICE9PSB1bmRlZmluZWQgPyBhc0FycmF5KG9wdGlvbnMuY29sb3IpIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL0ljb25JbWFnZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMuaWNvbkltYWdlXyA9IGdldEljb25JbWFnZShpbWFnZSxcbiAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICBzcmMsIGltZ1NpemUsIF90aGlzLmNyb3NzT3JpZ2luXywgaW1hZ2VTdGF0ZSwgX3RoaXMuY29sb3JfKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgX3RoaXMub2Zmc2V0XyA9IG9wdGlvbnMub2Zmc2V0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm9mZnNldCA6IFswLCAwXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL0ljb25PcmlnaW4uanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLm9mZnNldE9yaWdpbl8gPSBvcHRpb25zLm9mZnNldE9yaWdpbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5vZmZzZXRPcmlnaW4gOiBJY29uT3JpZ2luLlRPUF9MRUZUO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5vcmlnaW5fID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICBfdGhpcy5zaXplXyA9IG9wdGlvbnMuc2l6ZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zaXplIDogbnVsbDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIENsb25lcyB0aGUgc3R5bGUuIFRoZSB1bmRlcmx5aW5nIEltYWdlL0hUTUxDYW52YXNFbGVtZW50IGlzIG5vdCBjbG9uZWQuXG4gICAqIEByZXR1cm4ge0ljb259IFRoZSBjbG9uZWQgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2NhbGUgPSB0aGlzLmdldFNjYWxlKCk7XG4gICAgcmV0dXJuIG5ldyBJY29uKHtcbiAgICAgIGFuY2hvcjogdGhpcy5hbmNob3JfLnNsaWNlKCksXG4gICAgICBhbmNob3JPcmlnaW46IHRoaXMuYW5jaG9yT3JpZ2luXyxcbiAgICAgIGFuY2hvclhVbml0czogdGhpcy5hbmNob3JYVW5pdHNfLFxuICAgICAgYW5jaG9yWVVuaXRzOiB0aGlzLmFuY2hvcllVbml0c18sXG4gICAgICBjcm9zc09yaWdpbjogdGhpcy5jcm9zc09yaWdpbl8sXG4gICAgICBjb2xvcjogdGhpcy5jb2xvcl8gJiYgdGhpcy5jb2xvcl8uc2xpY2UgPyB0aGlzLmNvbG9yXy5zbGljZSgpIDogdGhpcy5jb2xvcl8gfHwgdW5kZWZpbmVkLFxuICAgICAgc3JjOiB0aGlzLmdldFNyYygpLFxuICAgICAgb2Zmc2V0OiB0aGlzLm9mZnNldF8uc2xpY2UoKSxcbiAgICAgIG9mZnNldE9yaWdpbjogdGhpcy5vZmZzZXRPcmlnaW5fLFxuICAgICAgc2l6ZTogdGhpcy5zaXplXyAhPT0gbnVsbCA/IHRoaXMuc2l6ZV8uc2xpY2UoKSA6IHVuZGVmaW5lZCxcbiAgICAgIG9wYWNpdHk6IHRoaXMuZ2V0T3BhY2l0eSgpLFxuICAgICAgc2NhbGU6IEFycmF5LmlzQXJyYXkoc2NhbGUpID8gc2NhbGUuc2xpY2UoKSA6IHNjYWxlLFxuICAgICAgcm90YXRpb246IHRoaXMuZ2V0Um90YXRpb24oKSxcbiAgICAgIHJvdGF0ZVdpdGhWaWV3OiB0aGlzLmdldFJvdGF0ZVdpdGhWaWV3KClcbiAgICB9KTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgYW5jaG9yIHBvaW50IGluIHBpeGVscy4gVGhlIGFuY2hvciBkZXRlcm1pbmVzIHRoZSBjZW50ZXIgcG9pbnQgZm9yIHRoZVxuICAgKiBzeW1ib2xpemVyLlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBBbmNob3IuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS5nZXRBbmNob3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMubm9ybWFsaXplZEFuY2hvcl8pIHtcbiAgICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZWRBbmNob3JfO1xuICAgIH1cblxuICAgIHZhciBhbmNob3IgPSB0aGlzLmFuY2hvcl87XG4gICAgdmFyIHNpemUgPSB0aGlzLmdldFNpemUoKTtcblxuICAgIGlmICh0aGlzLmFuY2hvclhVbml0c18gPT0gSWNvbkFuY2hvclVuaXRzLkZSQUNUSU9OIHx8IHRoaXMuYW5jaG9yWVVuaXRzXyA9PSBJY29uQW5jaG9yVW5pdHMuRlJBQ1RJT04pIHtcbiAgICAgIGlmICghc2l6ZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgYW5jaG9yID0gdGhpcy5hbmNob3JfLnNsaWNlKCk7XG5cbiAgICAgIGlmICh0aGlzLmFuY2hvclhVbml0c18gPT0gSWNvbkFuY2hvclVuaXRzLkZSQUNUSU9OKSB7XG4gICAgICAgIGFuY2hvclswXSAqPSBzaXplWzBdO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hbmNob3JZVW5pdHNfID09IEljb25BbmNob3JVbml0cy5GUkFDVElPTikge1xuICAgICAgICBhbmNob3JbMV0gKj0gc2l6ZVsxXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5hbmNob3JPcmlnaW5fICE9IEljb25PcmlnaW4uVE9QX0xFRlQpIHtcbiAgICAgIGlmICghc2l6ZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYgKGFuY2hvciA9PT0gdGhpcy5hbmNob3JfKSB7XG4gICAgICAgIGFuY2hvciA9IHRoaXMuYW5jaG9yXy5zbGljZSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hbmNob3JPcmlnaW5fID09IEljb25PcmlnaW4uVE9QX1JJR0hUIHx8IHRoaXMuYW5jaG9yT3JpZ2luXyA9PSBJY29uT3JpZ2luLkJPVFRPTV9SSUdIVCkge1xuICAgICAgICBhbmNob3JbMF0gPSAtYW5jaG9yWzBdICsgc2l6ZVswXTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuYW5jaG9yT3JpZ2luXyA9PSBJY29uT3JpZ2luLkJPVFRPTV9MRUZUIHx8IHRoaXMuYW5jaG9yT3JpZ2luXyA9PSBJY29uT3JpZ2luLkJPVFRPTV9SSUdIVCkge1xuICAgICAgICBhbmNob3JbMV0gPSAtYW5jaG9yWzFdICsgc2l6ZVsxXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLm5vcm1hbGl6ZWRBbmNob3JfID0gYW5jaG9yO1xuICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZWRBbmNob3JfO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBhbmNob3IgcG9pbnQuIFRoZSBhbmNob3IgZGV0ZXJtaW5lcyB0aGUgY2VudGVyIHBvaW50IGZvciB0aGVcbiAgICogc3ltYm9saXplci5cbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBhbmNob3IgQW5jaG9yLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUuc2V0QW5jaG9yID0gZnVuY3Rpb24gKGFuY2hvcikge1xuICAgIHRoaXMuYW5jaG9yXyA9IGFuY2hvcjtcbiAgICB0aGlzLm5vcm1hbGl6ZWRBbmNob3JfID0gbnVsbDtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgaWNvbiBjb2xvci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J9IENvbG9yLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUuZ2V0Q29sb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29sb3JfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBpbWFnZSBpY29uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHJldHVybiB7SFRNTEltYWdlRWxlbWVudHxIVE1MQ2FudmFzRWxlbWVudH0gSW1hZ2Ugb3IgQ2FudmFzIGVsZW1lbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS5nZXRJbWFnZSA9IGZ1bmN0aW9uIChwaXhlbFJhdGlvKSB7XG4gICAgcmV0dXJuIHRoaXMuaWNvbkltYWdlXy5nZXRJbWFnZShwaXhlbFJhdGlvKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgcGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBwaXhlbCByYXRpb24gb2YgdGhlIGltYWdlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUuZ2V0UGl4ZWxSYXRpbyA9IGZ1bmN0aW9uIChwaXhlbFJhdGlvKSB7XG4gICAgcmV0dXJuIHRoaXMuaWNvbkltYWdlXy5nZXRQaXhlbFJhdGlvKHBpeGVsUmF0aW8pO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBJbWFnZSBzaXplLlxuICAgKi9cblxuXG4gIEljb24ucHJvdG90eXBlLmdldEltYWdlU2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pY29uSW1hZ2VfLmdldFNpemUoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gU2l6ZSBvZiB0aGUgaGl0LWRldGVjdGlvbiBpbWFnZS5cbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS5nZXRIaXREZXRlY3Rpb25JbWFnZVNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW1hZ2VTaXplKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9JbWFnZVN0YXRlLmpzXCIpLmRlZmF1bHR9IEltYWdlIHN0YXRlLlxuICAgKi9cblxuXG4gIEljb24ucHJvdG90eXBlLmdldEltYWdlU3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaWNvbkltYWdlXy5nZXRJbWFnZVN0YXRlKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtIVE1MSW1hZ2VFbGVtZW50fEhUTUxDYW52YXNFbGVtZW50fSBJbWFnZSBlbGVtZW50LlxuICAgKi9cblxuXG4gIEljb24ucHJvdG90eXBlLmdldEhpdERldGVjdGlvbkltYWdlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmljb25JbWFnZV8uZ2V0SGl0RGV0ZWN0aW9uSW1hZ2UoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgb3JpZ2luIG9mIHRoZSBzeW1ib2xpemVyLlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBPcmlnaW4uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS5nZXRPcmlnaW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMub3JpZ2luXykge1xuICAgICAgcmV0dXJuIHRoaXMub3JpZ2luXztcbiAgICB9XG5cbiAgICB2YXIgb2Zmc2V0ID0gdGhpcy5vZmZzZXRfO1xuICAgIHZhciBkaXNwbGFjZW1lbnQgPSB0aGlzLmdldERpc3BsYWNlbWVudCgpO1xuXG4gICAgaWYgKHRoaXMub2Zmc2V0T3JpZ2luXyAhPSBJY29uT3JpZ2luLlRPUF9MRUZUKSB7XG4gICAgICB2YXIgc2l6ZSA9IHRoaXMuZ2V0U2l6ZSgpO1xuICAgICAgdmFyIGljb25JbWFnZVNpemUgPSB0aGlzLmljb25JbWFnZV8uZ2V0U2l6ZSgpO1xuXG4gICAgICBpZiAoIXNpemUgfHwgIWljb25JbWFnZVNpemUpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIG9mZnNldCA9IG9mZnNldC5zbGljZSgpO1xuXG4gICAgICBpZiAodGhpcy5vZmZzZXRPcmlnaW5fID09IEljb25PcmlnaW4uVE9QX1JJR0hUIHx8IHRoaXMub2Zmc2V0T3JpZ2luXyA9PSBJY29uT3JpZ2luLkJPVFRPTV9SSUdIVCkge1xuICAgICAgICBvZmZzZXRbMF0gPSBpY29uSW1hZ2VTaXplWzBdIC0gc2l6ZVswXSAtIG9mZnNldFswXTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMub2Zmc2V0T3JpZ2luXyA9PSBJY29uT3JpZ2luLkJPVFRPTV9MRUZUIHx8IHRoaXMub2Zmc2V0T3JpZ2luXyA9PSBJY29uT3JpZ2luLkJPVFRPTV9SSUdIVCkge1xuICAgICAgICBvZmZzZXRbMV0gPSBpY29uSW1hZ2VTaXplWzFdIC0gc2l6ZVsxXSAtIG9mZnNldFsxXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBvZmZzZXRbMF0gKz0gZGlzcGxhY2VtZW50WzBdO1xuICAgIG9mZnNldFsxXSArPSBkaXNwbGFjZW1lbnRbMV07XG4gICAgdGhpcy5vcmlnaW5fID0gb2Zmc2V0O1xuICAgIHJldHVybiB0aGlzLm9yaWdpbl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGltYWdlIFVSTC5cbiAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH0gSW1hZ2Ugc3JjLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUuZ2V0U3JjID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmljb25JbWFnZV8uZ2V0U3JjKCk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHNpemUgb2YgdGhlIGljb24gKGluIHBpeGVscykuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gSW1hZ2Ugc2l6ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEljb24ucHJvdG90eXBlLmdldFNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICF0aGlzLnNpemVfID8gdGhpcy5pY29uSW1hZ2VfLmdldFNpemUoKSA6IHRoaXMuc2l6ZV87XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0KTogdm9pZH0gbGlzdGVuZXIgTGlzdGVuZXIgZnVuY3Rpb24uXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUubGlzdGVuSW1hZ2VDaGFuZ2UgPSBmdW5jdGlvbiAobGlzdGVuZXIpIHtcbiAgICB0aGlzLmljb25JbWFnZV8uYWRkRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuQ0hBTkdFLCBsaXN0ZW5lcik7XG4gIH07XG4gIC8qKlxuICAgKiBMb2FkIG5vdCB5ZXQgbG9hZGVkIFVSSS5cbiAgICogV2hlbiByZW5kZXJpbmcgYSBmZWF0dXJlIHdpdGggYW4gaWNvbiBzdHlsZSwgdGhlIHZlY3RvciByZW5kZXJlciB3aWxsXG4gICAqIGF1dG9tYXRpY2FsbHkgY2FsbCB0aGlzIG1ldGhvZC4gSG93ZXZlciwgeW91IG1pZ2h0IHdhbnQgdG8gY2FsbCB0aGlzXG4gICAqIG1ldGhvZCB5b3Vyc2VsZiBmb3IgcHJlbG9hZGluZyBvciBvdGhlciBwdXJwb3Nlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEljb24ucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5pY29uSW1hZ2VfLmxvYWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHQpOiB2b2lkfSBsaXN0ZW5lciBMaXN0ZW5lciBmdW5jdGlvbi5cbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS51bmxpc3RlbkltYWdlQ2hhbmdlID0gZnVuY3Rpb24gKGxpc3RlbmVyKSB7XG4gICAgdGhpcy5pY29uSW1hZ2VfLnJlbW92ZUV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNIQU5HRSwgbGlzdGVuZXIpO1xuICB9O1xuXG4gIHJldHVybiBJY29uO1xufShJbWFnZVN0eWxlKTtcblxuZXhwb3J0IGRlZmF1bHQgSWNvbjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL2NhbnZhcy9oaXRkZXRlY3RcbiAqL1xuaW1wb3J0IENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyIGZyb20gJy4vSW1tZWRpYXRlLmpzJztcbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi4vLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IEljb25BbmNob3JVbml0cyBmcm9tICcuLi8uLi9zdHlsZS9JY29uQW5jaG9yVW5pdHMuanMnO1xuaW1wb3J0IHsgSWNvbiB9IGZyb20gJy4uLy4uL3N0eWxlLmpzJztcbmltcG9ydCB7IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCB9IGZyb20gJy4uLy4uL2RvbS5qcyc7XG5pbXBvcnQgeyBpbnRlcnNlY3RzIH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IG51bWJlclNhZmVDb21wYXJlRnVuY3Rpb24gfSBmcm9tICcuLi8uLi9hcnJheS5qcyc7XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIENhbnZhcyBzaXplIGluIGNzcyBwaXhlbHMuXG4gKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm0+fSB0cmFuc2Zvcm1zIFRyYW5zZm9ybXNcbiAqIGZvciByZW5kZXJpbmcgZmVhdHVyZXMgdG8gYWxsIHdvcmxkcyBvZiB0aGUgdmlld3BvcnQsIGZyb20gY29vcmRpbmF0ZXMgdG8gY3NzXG4gKiBwaXhlbHMuXG4gKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2U+fSBmZWF0dXJlc1xuICogRmVhdHVyZXMgdG8gY29uc2lkZXIgZm9yIGhpdCBkZXRlY3Rpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlRnVuY3Rpb258dW5kZWZpbmVkfSBzdHlsZUZ1bmN0aW9uXG4gKiBMYXllciBzdHlsZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gcm90YXRpb24gUm90YXRpb24uXG4gKiBAcmV0dXJuIHtJbWFnZURhdGF9IEhpdCBkZXRlY3Rpb24gaW1hZ2UgZGF0YS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSGl0RGV0ZWN0aW9uSW1hZ2VEYXRhKHNpemUsIHRyYW5zZm9ybXMsIGZlYXR1cmVzLCBzdHlsZUZ1bmN0aW9uLCBleHRlbnQsIHJlc29sdXRpb24sIHJvdGF0aW9uKSB7XG4gIHZhciB3aWR0aCA9IHNpemVbMF0gLyAyO1xuICB2YXIgaGVpZ2h0ID0gc2l6ZVsxXSAvIDI7XG4gIHZhciBjb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKHdpZHRoLCBoZWlnaHQpO1xuICBjb250ZXh0LmltYWdlU21vb3RoaW5nRW5hYmxlZCA9IGZhbHNlO1xuICB2YXIgY2FudmFzID0gY29udGV4dC5jYW52YXM7XG4gIHZhciByZW5kZXJlciA9IG5ldyBDYW52YXNJbW1lZGlhdGVSZW5kZXJlcihjb250ZXh0LCAwLjUsIGV4dGVudCwgbnVsbCwgcm90YXRpb24pO1xuICB2YXIgZmVhdHVyZUNvdW50ID0gZmVhdHVyZXMubGVuZ3RoOyAvLyBTdHJldGNoIGhpdCBkZXRlY3Rpb24gaW5kZXggdG8gdXNlIHRoZSB3aG9sZSBhdmFpbGFibGUgY29sb3IgcmFuZ2VcblxuICB2YXIgaW5kZXhGYWN0b3IgPSBNYXRoLmZsb29yKCgyNTYgKiAyNTYgKiAyNTYgLSAxKSAvIGZlYXR1cmVDb3VudCk7XG4gIHZhciBmZWF0dXJlc0J5WkluZGV4ID0ge307XG5cbiAgZm9yICh2YXIgaSA9IDE7IGkgPD0gZmVhdHVyZUNvdW50OyArK2kpIHtcbiAgICB2YXIgZmVhdHVyZSA9IGZlYXR1cmVzW2kgLSAxXTtcbiAgICB2YXIgZmVhdHVyZVN0eWxlRnVuY3Rpb24gPSBmZWF0dXJlLmdldFN0eWxlRnVuY3Rpb24oKSB8fCBzdHlsZUZ1bmN0aW9uO1xuXG4gICAgaWYgKCFzdHlsZUZ1bmN0aW9uKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB2YXIgc3R5bGVzID0gZmVhdHVyZVN0eWxlRnVuY3Rpb24oZmVhdHVyZSwgcmVzb2x1dGlvbik7XG5cbiAgICBpZiAoIXN0eWxlcykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHN0eWxlcykpIHtcbiAgICAgIHN0eWxlcyA9IFtzdHlsZXNdO1xuICAgIH1cblxuICAgIHZhciBpbmRleCA9IGkgKiBpbmRleEZhY3RvcjtcbiAgICB2YXIgY29sb3IgPSAnIycgKyAoJzAwMDAwMCcgKyBpbmRleC50b1N0cmluZygxNikpLnNsaWNlKC02KTtcblxuICAgIGZvciAodmFyIGogPSAwLCBqaiA9IHN0eWxlcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgICB2YXIgb3JpZ2luYWxTdHlsZSA9IHN0eWxlc1tqXTtcbiAgICAgIHZhciBzdHlsZSA9IG9yaWdpbmFsU3R5bGUuY2xvbmUoKTtcbiAgICAgIHZhciBmaWxsID0gc3R5bGUuZ2V0RmlsbCgpO1xuXG4gICAgICBpZiAoZmlsbCkge1xuICAgICAgICBmaWxsLnNldENvbG9yKGNvbG9yKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHN0cm9rZSA9IHN0eWxlLmdldFN0cm9rZSgpO1xuXG4gICAgICBpZiAoc3Ryb2tlKSB7XG4gICAgICAgIHN0cm9rZS5zZXRDb2xvcihjb2xvcik7XG4gICAgICB9XG5cbiAgICAgIHN0eWxlLnNldFRleHQodW5kZWZpbmVkKTtcbiAgICAgIHZhciBpbWFnZSA9IG9yaWdpbmFsU3R5bGUuZ2V0SW1hZ2UoKTtcblxuICAgICAgaWYgKGltYWdlKSB7XG4gICAgICAgIHZhciBpbWdTaXplID0gaW1hZ2UuZ2V0SW1hZ2VTaXplKCk7XG5cbiAgICAgICAgaWYgKCFpbWdTaXplKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2FudmFzXzEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgICAgY2FudmFzXzEud2lkdGggPSBpbWdTaXplWzBdO1xuICAgICAgICBjYW52YXNfMS5oZWlnaHQgPSBpbWdTaXplWzFdO1xuICAgICAgICB2YXIgaW1nQ29udGV4dCA9IGNhbnZhc18xLmdldENvbnRleHQoJzJkJywge1xuICAgICAgICAgIGFscGhhOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgaW1nQ29udGV4dC5maWxsU3R5bGUgPSBjb2xvcjtcbiAgICAgICAgdmFyIGltZyA9IGltZ0NvbnRleHQuY2FudmFzO1xuICAgICAgICBpbWdDb250ZXh0LmZpbGxSZWN0KDAsIDAsIGltZy53aWR0aCwgaW1nLmhlaWdodCk7XG4gICAgICAgIHZhciB3aWR0aF8xID0gaW1nU2l6ZSA/IGltZ1NpemVbMF0gOiBpbWcud2lkdGg7XG4gICAgICAgIHZhciBoZWlnaHRfMSA9IGltZ1NpemUgPyBpbWdTaXplWzFdIDogaW1nLmhlaWdodDtcbiAgICAgICAgdmFyIGljb25Db250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKHdpZHRoXzEsIGhlaWdodF8xKTtcbiAgICAgICAgaWNvbkNvbnRleHQuZHJhd0ltYWdlKGltZywgMCwgMCk7XG4gICAgICAgIHN0eWxlLnNldEltYWdlKG5ldyBJY29uKHtcbiAgICAgICAgICBpbWc6IGltZyxcbiAgICAgICAgICBpbWdTaXplOiBpbWdTaXplLFxuICAgICAgICAgIGFuY2hvcjogaW1hZ2UuZ2V0QW5jaG9yKCksXG4gICAgICAgICAgYW5jaG9yWFVuaXRzOiBJY29uQW5jaG9yVW5pdHMuUElYRUxTLFxuICAgICAgICAgIGFuY2hvcllVbml0czogSWNvbkFuY2hvclVuaXRzLlBJWEVMUyxcbiAgICAgICAgICBvZmZzZXQ6IGltYWdlLmdldE9yaWdpbigpLFxuICAgICAgICAgIHNpemU6IGltYWdlLmdldFNpemUoKSxcbiAgICAgICAgICBvcGFjaXR5OiBpbWFnZS5nZXRPcGFjaXR5KCksXG4gICAgICAgICAgc2NhbGU6IGltYWdlLmdldFNjYWxlKCksXG4gICAgICAgICAgcm90YXRpb246IGltYWdlLmdldFJvdGF0aW9uKCksXG4gICAgICAgICAgcm90YXRlV2l0aFZpZXc6IGltYWdlLmdldFJvdGF0ZVdpdGhWaWV3KClcbiAgICAgICAgfSkpO1xuICAgICAgfVxuXG4gICAgICB2YXIgekluZGV4ID0gTnVtYmVyKHN0eWxlLmdldFpJbmRleCgpKTtcbiAgICAgIHZhciBieUdlb21ldHJ5VHlwZSA9IGZlYXR1cmVzQnlaSW5kZXhbekluZGV4XTtcblxuICAgICAgaWYgKCFieUdlb21ldHJ5VHlwZSkge1xuICAgICAgICBieUdlb21ldHJ5VHlwZSA9IHt9O1xuICAgICAgICBmZWF0dXJlc0J5WkluZGV4W3pJbmRleF0gPSBieUdlb21ldHJ5VHlwZTtcbiAgICAgICAgYnlHZW9tZXRyeVR5cGVbR2VvbWV0cnlUeXBlLlBPTFlHT05dID0gW107XG4gICAgICAgIGJ5R2VvbWV0cnlUeXBlW0dlb21ldHJ5VHlwZS5DSVJDTEVdID0gW107XG4gICAgICAgIGJ5R2VvbWV0cnlUeXBlW0dlb21ldHJ5VHlwZS5MSU5FX1NUUklOR10gPSBbXTtcbiAgICAgICAgYnlHZW9tZXRyeVR5cGVbR2VvbWV0cnlUeXBlLlBPSU5UXSA9IFtdO1xuICAgICAgfVxuXG4gICAgICB2YXIgZ2VvbWV0cnkgPSBzdHlsZS5nZXRHZW9tZXRyeUZ1bmN0aW9uKCkoZmVhdHVyZSk7XG5cbiAgICAgIGlmIChnZW9tZXRyeSAmJiBpbnRlcnNlY3RzKGV4dGVudCwgZ2VvbWV0cnkuZ2V0RXh0ZW50KCkpKSB7XG4gICAgICAgIGJ5R2VvbWV0cnlUeXBlW2dlb21ldHJ5LmdldFR5cGUoKS5yZXBsYWNlKCdNdWx0aScsICcnKV0ucHVzaChnZW9tZXRyeSwgc3R5bGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciB6SW5kZXhLZXlzID0gT2JqZWN0LmtleXMoZmVhdHVyZXNCeVpJbmRleCkubWFwKE51bWJlcikuc29ydChudW1iZXJTYWZlQ29tcGFyZUZ1bmN0aW9uKTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSB6SW5kZXhLZXlzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgYnlHZW9tZXRyeVR5cGUgPSBmZWF0dXJlc0J5WkluZGV4W3pJbmRleEtleXNbaV1dO1xuXG4gICAgZm9yICh2YXIgdHlwZSBpbiBieUdlb21ldHJ5VHlwZSkge1xuICAgICAgdmFyIGdlb21BbmRTdHlsZSA9IGJ5R2VvbWV0cnlUeXBlW3R5cGVdO1xuXG4gICAgICBmb3IgKHZhciBqID0gMCwgamogPSBnZW9tQW5kU3R5bGUubGVuZ3RoOyBqIDwgamo7IGogKz0gMikge1xuICAgICAgICByZW5kZXJlci5zZXRTdHlsZShnZW9tQW5kU3R5bGVbaiArIDFdKTtcblxuICAgICAgICBmb3IgKHZhciBrID0gMCwga2sgPSB0cmFuc2Zvcm1zLmxlbmd0aDsgayA8IGtrOyArK2spIHtcbiAgICAgICAgICByZW5kZXJlci5zZXRUcmFuc2Zvcm0odHJhbnNmb3Jtc1trXSk7XG4gICAgICAgICAgcmVuZGVyZXIuZHJhd0dlb21ldHJ5KGdlb21BbmRTdHlsZVtqXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29udGV4dC5nZXRJbWFnZURhdGEoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9waXhlbFwiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwgY29vcmRpbmF0ZSBvbiB0aGUgaGl0XG4gKiBkZXRlY3Rpb24gY2FudmFzIGluIGNzcyBwaXhlbHMuXG4gKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uLy4uL0ZlYXR1cmVcIikuRmVhdHVyZUxpa2U+fSBmZWF0dXJlcyBGZWF0dXJlcy4gSGFzIHRvXG4gKiBtYXRjaCB0aGUgYGZlYXR1cmVzYCBhcnJheSB0aGF0IHdhcyBwYXNzZWQgdG8gYGNyZWF0ZUhpdERldGVjdGlvbkltYWdlRGF0YSgpYC5cbiAqIEBwYXJhbSB7SW1hZ2VEYXRhfSBpbWFnZURhdGEgSGl0IGRldGVjdGlvbiBpbWFnZSBkYXRhIGdlbmVyYXRlZCBieVxuICogYGNyZWF0ZUhpdERldGVjdGlvbkltYWdlRGF0YSgpYC5cbiAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4uLy4uL0ZlYXR1cmVcIikuRmVhdHVyZUxpa2U+fSBmZWF0dXJlcyBGZWF0dXJlcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaGl0RGV0ZWN0KHBpeGVsLCBmZWF0dXJlcywgaW1hZ2VEYXRhKSB7XG4gIHZhciByZXN1bHRGZWF0dXJlcyA9IFtdO1xuXG4gIGlmIChpbWFnZURhdGEpIHtcbiAgICB2YXIgaW5kZXggPSAoTWF0aC5yb3VuZChwaXhlbFswXSAvIDIpICsgTWF0aC5yb3VuZChwaXhlbFsxXSAvIDIpICogaW1hZ2VEYXRhLndpZHRoKSAqIDQ7XG4gICAgdmFyIHIgPSBpbWFnZURhdGEuZGF0YVtpbmRleF07XG4gICAgdmFyIGcgPSBpbWFnZURhdGEuZGF0YVtpbmRleCArIDFdO1xuICAgIHZhciBiID0gaW1hZ2VEYXRhLmRhdGFbaW5kZXggKyAyXTtcbiAgICB2YXIgaSA9IGIgKyAyNTYgKiAoZyArIDI1NiAqIHIpO1xuICAgIHZhciBpbmRleEZhY3RvciA9IE1hdGguZmxvb3IoKDI1NiAqIDI1NiAqIDI1NiAtIDEpIC8gZmVhdHVyZXMubGVuZ3RoKTtcblxuICAgIGlmIChpICYmIGkgJSBpbmRleEZhY3RvciA9PT0gMCkge1xuICAgICAgcmVzdWx0RmVhdHVyZXMucHVzaChmZWF0dXJlc1tpIC8gaW5kZXhGYWN0b3IgLSAxXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdEZlYXR1cmVzO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXJlci92ZWN0b3JcbiAqL1xuaW1wb3J0IEJ1aWxkZXJUeXBlIGZyb20gJy4uL3JlbmRlci9jYW52YXMvQnVpbGRlclR5cGUuanMnO1xuaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICcuLi9nZW9tL0dlb21ldHJ5VHlwZS5qcyc7XG5pbXBvcnQgSW1hZ2VTdGF0ZSBmcm9tICcuLi9JbWFnZVN0YXRlLmpzJztcbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJy4uL3V0aWwuanMnO1xuLyoqXG4gKiBGZWF0dXJlIGNhbGxiYWNrLiBUaGUgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aHJlZSBhcmd1bWVudHMuIFRoZSBmaXJzdFxuICogYXJndW1lbnQgaXMgb25lIHtAbGluayBtb2R1bGU6b2wvRmVhdHVyZSBmZWF0dXJlfSBvciB7QGxpbmsgbW9kdWxlOm9sL3JlbmRlci9GZWF0dXJlIHJlbmRlciBmZWF0dXJlfVxuICogYXQgdGhlIHBpeGVsLCB0aGUgc2Vjb25kIGlzIHRoZSB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0xheWVyIGxheWVyfSBvZiB0aGUgZmVhdHVyZSBhbmQgd2lsbCBiZSBudWxsIGZvclxuICogdW5tYW5hZ2VkIGxheWVycy4gVGhlIHRoaXJkIGlzIHRoZSB7QGxpbmsgbW9kdWxlOm9sL2dlb20vU2ltcGxlR2VvbWV0cnl9IG9mIHRoZSBmZWF0dXJlLiBGb3IgZmVhdHVyZXNcbiAqIHdpdGggYSBHZW9tZXRyeUNvbGxlY3Rpb24gZ2VvbWV0cnksIGl0IHdpbGwgYmUgdGhlIGZpcnN0IGRldGVjdGVkIGdlb21ldHJ5IGZyb20gdGhlIGNvbGxlY3Rpb24uXG4gKiBAdGVtcGxhdGUgVFxuICogQHR5cGVkZWYge2Z1bmN0aW9uKGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2UsIGltcG9ydChcIi4uL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHQsIGltcG9ydChcIi4uL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdCk6IFR9IEZlYXR1cmVDYWxsYmFja1xuICovXG5cbi8qKlxuICogVG9sZXJhbmNlIGZvciBnZW9tZXRyeSBzaW1wbGlmaWNhdGlvbiBpbiBkZXZpY2UgcGl4ZWxzLlxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG52YXIgU0lNUExJRllfVE9MRVJBTkNFID0gMC41O1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtPYmplY3Q8aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdCxcbiAqICAgICAgICAgICAgICAgIGZ1bmN0aW9uKGltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHQsIGltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdCxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgIGltcG9ydChcIi4uL3N0eWxlL1N0eWxlLmpzXCIpLmRlZmF1bHQsIE9iamVjdCk6IHZvaWQ+fVxuICovXG5cbnZhciBHRU9NRVRSWV9SRU5ERVJFUlMgPSB7XG4gICdQb2ludCc6IHJlbmRlclBvaW50R2VvbWV0cnksXG4gICdMaW5lU3RyaW5nJzogcmVuZGVyTGluZVN0cmluZ0dlb21ldHJ5LFxuICAnUG9seWdvbic6IHJlbmRlclBvbHlnb25HZW9tZXRyeSxcbiAgJ011bHRpUG9pbnQnOiByZW5kZXJNdWx0aVBvaW50R2VvbWV0cnksXG4gICdNdWx0aUxpbmVTdHJpbmcnOiByZW5kZXJNdWx0aUxpbmVTdHJpbmdHZW9tZXRyeSxcbiAgJ011bHRpUG9seWdvbic6IHJlbmRlck11bHRpUG9seWdvbkdlb21ldHJ5LFxuICAnR2VvbWV0cnlDb2xsZWN0aW9uJzogcmVuZGVyR2VvbWV0cnlDb2xsZWN0aW9uR2VvbWV0cnksXG4gICdDaXJjbGUnOiByZW5kZXJDaXJjbGVHZW9tZXRyeVxufTtcbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlMSBGZWF0dXJlIDEuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUyIEZlYXR1cmUgMi5cbiAqIEByZXR1cm4ge251bWJlcn0gT3JkZXIuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRPcmRlcihmZWF0dXJlMSwgZmVhdHVyZTIpIHtcbiAgcmV0dXJuIHBhcnNlSW50KGdldFVpZChmZWF0dXJlMSksIDEwKSAtIHBhcnNlSW50KGdldFVpZChmZWF0dXJlMiksIDEwKTtcbn1cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICogQHJldHVybiB7bnVtYmVyfSBTcXVhcmVkIHBpeGVsIHRvbGVyYW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3F1YXJlZFRvbGVyYW5jZShyZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSB7XG4gIHZhciB0b2xlcmFuY2UgPSBnZXRUb2xlcmFuY2UocmVzb2x1dGlvbiwgcGl4ZWxSYXRpbyk7XG4gIHJldHVybiB0b2xlcmFuY2UgKiB0b2xlcmFuY2U7XG59XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAqIEByZXR1cm4ge251bWJlcn0gUGl4ZWwgdG9sZXJhbmNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUb2xlcmFuY2UocmVzb2x1dGlvbiwgcGl4ZWxSYXRpbykge1xuICByZXR1cm4gU0lNUExJRllfVE9MRVJBTkNFICogcmVzb2x1dGlvbiAvIHBpeGVsUmF0aW87XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdH0gYnVpbGRlckdyb3VwIEJ1aWxkZXIgZ3JvdXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vQ2lyY2xlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmZWF0dXJlIEZlYXR1cmUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHQ9fSBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIEJ1aWxkZXIgZm9yIGRlY2x1dHRlcmluZy5cbiAqL1xuXG5mdW5jdGlvbiByZW5kZXJDaXJjbGVHZW9tZXRyeShidWlsZGVyR3JvdXAsIGdlb21ldHJ5LCBzdHlsZSwgZmVhdHVyZSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkge1xuICB2YXIgZmlsbFN0eWxlID0gc3R5bGUuZ2V0RmlsbCgpO1xuICB2YXIgc3Ryb2tlU3R5bGUgPSBzdHlsZS5nZXRTdHJva2UoKTtcblxuICBpZiAoZmlsbFN0eWxlIHx8IHN0cm9rZVN0eWxlKSB7XG4gICAgdmFyIGNpcmNsZVJlcGxheSA9IGJ1aWxkZXJHcm91cC5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5DSVJDTEUpO1xuICAgIGNpcmNsZVJlcGxheS5zZXRGaWxsU3Ryb2tlU3R5bGUoZmlsbFN0eWxlLCBzdHJva2VTdHlsZSk7XG4gICAgY2lyY2xlUmVwbGF5LmRyYXdDaXJjbGUoZ2VvbWV0cnksIGZlYXR1cmUpO1xuICB9XG5cbiAgdmFyIHRleHRTdHlsZSA9IHN0eWxlLmdldFRleHQoKTtcblxuICBpZiAodGV4dFN0eWxlICYmIHRleHRTdHlsZS5nZXRUZXh0KCkpIHtcbiAgICB2YXIgdGV4dFJlcGxheSA9IChvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIHx8IGJ1aWxkZXJHcm91cCkuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuVEVYVCk7XG4gICAgdGV4dFJlcGxheS5zZXRUZXh0U3R5bGUodGV4dFN0eWxlKTtcbiAgICB0ZXh0UmVwbGF5LmRyYXdUZXh0KGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IHJlcGxheUdyb3VwIFJlcGxheSBncm91cC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzcXVhcmVkVG9sZXJhbmNlIFNxdWFyZWQgdG9sZXJhbmNlLlxuICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9ldmVudHMvRXZlbnQuanNcIikuZGVmYXVsdCk6IHZvaWR9IGxpc3RlbmVyIExpc3RlbmVyIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufSBbb3B0X3RyYW5zZm9ybV0gVHJhbnNmb3JtIGZyb20gdXNlciB0byB2aWV3IHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHQ9fSBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIEJ1aWxkZXIgZm9yIGRlY2x1dHRlcmluZy5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IGB0cnVlYCBpZiBzdHlsZSBpcyBsb2FkaW5nLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlckZlYXR1cmUocmVwbGF5R3JvdXAsIGZlYXR1cmUsIHN0eWxlLCBzcXVhcmVkVG9sZXJhbmNlLCBsaXN0ZW5lciwgb3B0X3RyYW5zZm9ybSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkge1xuICB2YXIgbG9hZGluZyA9IGZhbHNlO1xuICB2YXIgaW1hZ2VTdHlsZSA9IHN0eWxlLmdldEltYWdlKCk7XG5cbiAgaWYgKGltYWdlU3R5bGUpIHtcbiAgICB2YXIgaW1hZ2VTdGF0ZSA9IGltYWdlU3R5bGUuZ2V0SW1hZ2VTdGF0ZSgpO1xuXG4gICAgaWYgKGltYWdlU3RhdGUgPT0gSW1hZ2VTdGF0ZS5MT0FERUQgfHwgaW1hZ2VTdGF0ZSA9PSBJbWFnZVN0YXRlLkVSUk9SKSB7XG4gICAgICBpbWFnZVN0eWxlLnVubGlzdGVuSW1hZ2VDaGFuZ2UobGlzdGVuZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaW1hZ2VTdGF0ZSA9PSBJbWFnZVN0YXRlLklETEUpIHtcbiAgICAgICAgaW1hZ2VTdHlsZS5sb2FkKCk7XG4gICAgICB9XG5cbiAgICAgIGltYWdlU3RhdGUgPSBpbWFnZVN0eWxlLmdldEltYWdlU3RhdGUoKTtcbiAgICAgIGltYWdlU3R5bGUubGlzdGVuSW1hZ2VDaGFuZ2UobGlzdGVuZXIpO1xuICAgICAgbG9hZGluZyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmVuZGVyRmVhdHVyZUludGVybmFsKHJlcGxheUdyb3VwLCBmZWF0dXJlLCBzdHlsZSwgc3F1YXJlZFRvbGVyYW5jZSwgb3B0X3RyYW5zZm9ybSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCk7XG4gIHJldHVybiBsb2FkaW5nO1xufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IHJlcGxheUdyb3VwIFJlcGxheSBncm91cC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzcXVhcmVkVG9sZXJhbmNlIFNxdWFyZWQgdG9sZXJhbmNlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufSBbb3B0X3RyYW5zZm9ybV0gT3B0aW9uYWwgdHJhbnNmb3JtIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCBCdWlsZGVyIGZvciBkZWNsdXR0ZXJpbmcuXG4gKi9cblxuZnVuY3Rpb24gcmVuZGVyRmVhdHVyZUludGVybmFsKHJlcGxheUdyb3VwLCBmZWF0dXJlLCBzdHlsZSwgc3F1YXJlZFRvbGVyYW5jZSwgb3B0X3RyYW5zZm9ybSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkge1xuICB2YXIgZ2VvbWV0cnkgPSBzdHlsZS5nZXRHZW9tZXRyeUZ1bmN0aW9uKCkoZmVhdHVyZSk7XG5cbiAgaWYgKCFnZW9tZXRyeSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzaW1wbGlmaWVkR2VvbWV0cnkgPSBnZW9tZXRyeS5zaW1wbGlmeVRyYW5zZm9ybWVkKHNxdWFyZWRUb2xlcmFuY2UsIG9wdF90cmFuc2Zvcm0pO1xuICB2YXIgcmVuZGVyZXIgPSBzdHlsZS5nZXRSZW5kZXJlcigpO1xuXG4gIGlmIChyZW5kZXJlcikge1xuICAgIHJlbmRlckdlb21ldHJ5KHJlcGxheUdyb3VwLCBzaW1wbGlmaWVkR2VvbWV0cnksIHN0eWxlLCBmZWF0dXJlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZ2VvbWV0cnlSZW5kZXJlciA9IEdFT01FVFJZX1JFTkRFUkVSU1tzaW1wbGlmaWVkR2VvbWV0cnkuZ2V0VHlwZSgpXTtcbiAgICBnZW9tZXRyeVJlbmRlcmVyKHJlcGxheUdyb3VwLCBzaW1wbGlmaWVkR2VvbWV0cnksIHN0eWxlLCBmZWF0dXJlLCBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwKTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IHJlcGxheUdyb3VwIFJlcGxheSBncm91cC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL3JlbmRlci9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICovXG5cblxuZnVuY3Rpb24gcmVuZGVyR2VvbWV0cnkocmVwbGF5R3JvdXAsIGdlb21ldHJ5LCBzdHlsZSwgZmVhdHVyZSkge1xuICBpZiAoZ2VvbWV0cnkuZ2V0VHlwZSgpID09IEdlb21ldHJ5VHlwZS5HRU9NRVRSWV9DT0xMRUNUSU9OKSB7XG4gICAgdmFyIGdlb21ldHJpZXMgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeUNvbGxlY3Rpb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICBnZW9tZXRyeS5nZXRHZW9tZXRyaWVzKCk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBnZW9tZXRyaWVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHJlbmRlckdlb21ldHJ5KHJlcGxheUdyb3VwLCBnZW9tZXRyaWVzW2ldLCBzdHlsZSwgZmVhdHVyZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHJlcGxheSA9IHJlcGxheUdyb3VwLmdldEJ1aWxkZXIoc3R5bGUuZ2V0WkluZGV4KCksIEJ1aWxkZXJUeXBlLkRFRkFVTFQpO1xuICByZXBsYXkuZHJhd0N1c3RvbShcbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR9ICovXG4gIGdlb21ldHJ5LCBmZWF0dXJlLCBzdHlsZS5nZXRSZW5kZXJlcigpKTtcbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0fSByZXBsYXlHcm91cCBSZXBsYXkgZ3JvdXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnlDb2xsZWN0aW9uLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmZWF0dXJlIEZlYXR1cmUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHQ9fSBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIEJ1aWxkZXIgZm9yIGRlY2x1dHRlcmluZy5cbiAqL1xuXG5cbmZ1bmN0aW9uIHJlbmRlckdlb21ldHJ5Q29sbGVjdGlvbkdlb21ldHJ5KHJlcGxheUdyb3VwLCBnZW9tZXRyeSwgc3R5bGUsIGZlYXR1cmUsIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgdmFyIGdlb21ldHJpZXMgPSBnZW9tZXRyeS5nZXRHZW9tZXRyaWVzQXJyYXkoKTtcbiAgdmFyIGksIGlpO1xuXG4gIGZvciAoaSA9IDAsIGlpID0gZ2VvbWV0cmllcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGdlb21ldHJ5UmVuZGVyZXIgPSBHRU9NRVRSWV9SRU5ERVJFUlNbZ2VvbWV0cmllc1tpXS5nZXRUeXBlKCldO1xuICAgIGdlb21ldHJ5UmVuZGVyZXIocmVwbGF5R3JvdXAsIGdlb21ldHJpZXNbaV0sIHN0eWxlLCBmZWF0dXJlLCBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwKTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IGJ1aWxkZXJHcm91cCBSZXBsYXkgZ3JvdXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL3JlbmRlci9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCBCdWlsZGVyIGZvciBkZWNsdXR0ZXJpbmcuXG4gKi9cblxuXG5mdW5jdGlvbiByZW5kZXJMaW5lU3RyaW5nR2VvbWV0cnkoYnVpbGRlckdyb3VwLCBnZW9tZXRyeSwgc3R5bGUsIGZlYXR1cmUsIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgdmFyIHN0cm9rZVN0eWxlID0gc3R5bGUuZ2V0U3Ryb2tlKCk7XG5cbiAgaWYgKHN0cm9rZVN0eWxlKSB7XG4gICAgdmFyIGxpbmVTdHJpbmdSZXBsYXkgPSBidWlsZGVyR3JvdXAuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuTElORV9TVFJJTkcpO1xuICAgIGxpbmVTdHJpbmdSZXBsYXkuc2V0RmlsbFN0cm9rZVN0eWxlKG51bGwsIHN0cm9rZVN0eWxlKTtcbiAgICBsaW5lU3RyaW5nUmVwbGF5LmRyYXdMaW5lU3RyaW5nKGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgfVxuXG4gIHZhciB0ZXh0U3R5bGUgPSBzdHlsZS5nZXRUZXh0KCk7XG5cbiAgaWYgKHRleHRTdHlsZSAmJiB0ZXh0U3R5bGUuZ2V0VGV4dCgpKSB7XG4gICAgdmFyIHRleHRSZXBsYXkgPSAob3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCB8fCBidWlsZGVyR3JvdXApLmdldEJ1aWxkZXIoc3R5bGUuZ2V0WkluZGV4KCksIEJ1aWxkZXJUeXBlLlRFWFQpO1xuICAgIHRleHRSZXBsYXkuc2V0VGV4dFN0eWxlKHRleHRTdHlsZSk7XG4gICAgdGV4dFJlcGxheS5kcmF3VGV4dChnZW9tZXRyeSwgZmVhdHVyZSk7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0fSBidWlsZGVyR3JvdXAgUmVwbGF5IGdyb3VwLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL011bHRpTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL3JlbmRlci9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCBCdWlsZGVyIGZvciBkZWNsdXR0ZXJpbmcuXG4gKi9cblxuXG5mdW5jdGlvbiByZW5kZXJNdWx0aUxpbmVTdHJpbmdHZW9tZXRyeShidWlsZGVyR3JvdXAsIGdlb21ldHJ5LCBzdHlsZSwgZmVhdHVyZSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkge1xuICB2YXIgc3Ryb2tlU3R5bGUgPSBzdHlsZS5nZXRTdHJva2UoKTtcblxuICBpZiAoc3Ryb2tlU3R5bGUpIHtcbiAgICB2YXIgbGluZVN0cmluZ1JlcGxheSA9IGJ1aWxkZXJHcm91cC5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5MSU5FX1NUUklORyk7XG4gICAgbGluZVN0cmluZ1JlcGxheS5zZXRGaWxsU3Ryb2tlU3R5bGUobnVsbCwgc3Ryb2tlU3R5bGUpO1xuICAgIGxpbmVTdHJpbmdSZXBsYXkuZHJhd011bHRpTGluZVN0cmluZyhnZW9tZXRyeSwgZmVhdHVyZSk7XG4gIH1cblxuICB2YXIgdGV4dFN0eWxlID0gc3R5bGUuZ2V0VGV4dCgpO1xuXG4gIGlmICh0ZXh0U3R5bGUgJiYgdGV4dFN0eWxlLmdldFRleHQoKSkge1xuICAgIHZhciB0ZXh0UmVwbGF5ID0gKG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgfHwgYnVpbGRlckdyb3VwKS5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5URVhUKTtcbiAgICB0ZXh0UmVwbGF5LnNldFRleHRTdHlsZSh0ZXh0U3R5bGUpO1xuICAgIHRleHRSZXBsYXkuZHJhd1RleHQoZ2VvbWV0cnksIGZlYXR1cmUpO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdH0gYnVpbGRlckdyb3VwIFJlcGxheSBncm91cC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9NdWx0aVBvbHlnb24uanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3N0eWxlL1N0eWxlLmpzXCIpLmRlZmF1bHR9IHN0eWxlIFN0eWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGZlYXR1cmUgRmVhdHVyZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdD19IG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgQnVpbGRlciBmb3IgZGVjbHV0dGVyaW5nLlxuICovXG5cblxuZnVuY3Rpb24gcmVuZGVyTXVsdGlQb2x5Z29uR2VvbWV0cnkoYnVpbGRlckdyb3VwLCBnZW9tZXRyeSwgc3R5bGUsIGZlYXR1cmUsIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgdmFyIGZpbGxTdHlsZSA9IHN0eWxlLmdldEZpbGwoKTtcbiAgdmFyIHN0cm9rZVN0eWxlID0gc3R5bGUuZ2V0U3Ryb2tlKCk7XG5cbiAgaWYgKHN0cm9rZVN0eWxlIHx8IGZpbGxTdHlsZSkge1xuICAgIHZhciBwb2x5Z29uUmVwbGF5ID0gYnVpbGRlckdyb3VwLmdldEJ1aWxkZXIoc3R5bGUuZ2V0WkluZGV4KCksIEJ1aWxkZXJUeXBlLlBPTFlHT04pO1xuICAgIHBvbHlnb25SZXBsYXkuc2V0RmlsbFN0cm9rZVN0eWxlKGZpbGxTdHlsZSwgc3Ryb2tlU3R5bGUpO1xuICAgIHBvbHlnb25SZXBsYXkuZHJhd011bHRpUG9seWdvbihnZW9tZXRyeSwgZmVhdHVyZSk7XG4gIH1cblxuICB2YXIgdGV4dFN0eWxlID0gc3R5bGUuZ2V0VGV4dCgpO1xuXG4gIGlmICh0ZXh0U3R5bGUgJiYgdGV4dFN0eWxlLmdldFRleHQoKSkge1xuICAgIHZhciB0ZXh0UmVwbGF5ID0gKG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgfHwgYnVpbGRlckdyb3VwKS5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5URVhUKTtcbiAgICB0ZXh0UmVwbGF5LnNldFRleHRTdHlsZSh0ZXh0U3R5bGUpO1xuICAgIHRleHRSZXBsYXkuZHJhd1RleHQoZ2VvbWV0cnksIGZlYXR1cmUpO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdH0gYnVpbGRlckdyb3VwIFJlcGxheSBncm91cC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9Qb2ludC5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL3JlbmRlci9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCBCdWlsZGVyIGZvciBkZWNsdXR0ZXJpbmcuXG4gKi9cblxuXG5mdW5jdGlvbiByZW5kZXJQb2ludEdlb21ldHJ5KGJ1aWxkZXJHcm91cCwgZ2VvbWV0cnksIHN0eWxlLCBmZWF0dXJlLCBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwKSB7XG4gIHZhciBpbWFnZVN0eWxlID0gc3R5bGUuZ2V0SW1hZ2UoKTtcbiAgdmFyIHRleHRTdHlsZSA9IHN0eWxlLmdldFRleHQoKTtcbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzLmpzXCIpLkRlY2x1dHRlckltYWdlV2l0aFRleHR9ICovXG5cbiAgdmFyIGRlY2x1dHRlckltYWdlV2l0aFRleHQ7XG5cbiAgaWYgKG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgICBidWlsZGVyR3JvdXAgPSBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwO1xuICAgIGRlY2x1dHRlckltYWdlV2l0aFRleHQgPSBpbWFnZVN0eWxlICYmIHRleHRTdHlsZSAmJiB0ZXh0U3R5bGUuZ2V0VGV4dCgpID8ge30gOiB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoaW1hZ2VTdHlsZSkge1xuICAgIGlmIChpbWFnZVN0eWxlLmdldEltYWdlU3RhdGUoKSAhPSBJbWFnZVN0YXRlLkxPQURFRCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBpbWFnZVJlcGxheSA9IGJ1aWxkZXJHcm91cC5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5JTUFHRSk7XG4gICAgaW1hZ2VSZXBsYXkuc2V0SW1hZ2VTdHlsZShpbWFnZVN0eWxlLCBkZWNsdXR0ZXJJbWFnZVdpdGhUZXh0KTtcbiAgICBpbWFnZVJlcGxheS5kcmF3UG9pbnQoZ2VvbWV0cnksIGZlYXR1cmUpO1xuICB9XG5cbiAgaWYgKHRleHRTdHlsZSAmJiB0ZXh0U3R5bGUuZ2V0VGV4dCgpKSB7XG4gICAgdmFyIHRleHRSZXBsYXkgPSBidWlsZGVyR3JvdXAuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuVEVYVCk7XG4gICAgdGV4dFJlcGxheS5zZXRUZXh0U3R5bGUodGV4dFN0eWxlLCBkZWNsdXR0ZXJJbWFnZVdpdGhUZXh0KTtcbiAgICB0ZXh0UmVwbGF5LmRyYXdUZXh0KGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IGJ1aWxkZXJHcm91cCBSZXBsYXkgZ3JvdXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vTXVsdGlQb2ludC5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL3JlbmRlci9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCBCdWlsZGVyIGZvciBkZWNsdXR0ZXJpbmcuXG4gKi9cblxuXG5mdW5jdGlvbiByZW5kZXJNdWx0aVBvaW50R2VvbWV0cnkoYnVpbGRlckdyb3VwLCBnZW9tZXRyeSwgc3R5bGUsIGZlYXR1cmUsIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgdmFyIGltYWdlU3R5bGUgPSBzdHlsZS5nZXRJbWFnZSgpO1xuICB2YXIgdGV4dFN0eWxlID0gc3R5bGUuZ2V0VGV4dCgpO1xuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMuanNcIikuRGVjbHV0dGVySW1hZ2VXaXRoVGV4dH0gKi9cblxuICB2YXIgZGVjbHV0dGVySW1hZ2VXaXRoVGV4dDtcblxuICBpZiAob3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkge1xuICAgIGJ1aWxkZXJHcm91cCA9IG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXA7XG4gICAgZGVjbHV0dGVySW1hZ2VXaXRoVGV4dCA9IGltYWdlU3R5bGUgJiYgdGV4dFN0eWxlICYmIHRleHRTdHlsZS5nZXRUZXh0KCkgPyB7fSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmIChpbWFnZVN0eWxlKSB7XG4gICAgaWYgKGltYWdlU3R5bGUuZ2V0SW1hZ2VTdGF0ZSgpICE9IEltYWdlU3RhdGUuTE9BREVEKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGltYWdlUmVwbGF5ID0gYnVpbGRlckdyb3VwLmdldEJ1aWxkZXIoc3R5bGUuZ2V0WkluZGV4KCksIEJ1aWxkZXJUeXBlLklNQUdFKTtcbiAgICBpbWFnZVJlcGxheS5zZXRJbWFnZVN0eWxlKGltYWdlU3R5bGUsIGRlY2x1dHRlckltYWdlV2l0aFRleHQpO1xuICAgIGltYWdlUmVwbGF5LmRyYXdNdWx0aVBvaW50KGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgfVxuXG4gIGlmICh0ZXh0U3R5bGUgJiYgdGV4dFN0eWxlLmdldFRleHQoKSkge1xuICAgIHZhciB0ZXh0UmVwbGF5ID0gKG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgfHwgYnVpbGRlckdyb3VwKS5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5URVhUKTtcbiAgICB0ZXh0UmVwbGF5LnNldFRleHRTdHlsZSh0ZXh0U3R5bGUsIGRlY2x1dHRlckltYWdlV2l0aFRleHQpO1xuICAgIHRleHRSZXBsYXkuZHJhd1RleHQoZ2VvbWV0cnksIGZlYXR1cmUpO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdH0gYnVpbGRlckdyb3VwIFJlcGxheSBncm91cC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9Qb2x5Z29uLmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vcmVuZGVyL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3N0eWxlL1N0eWxlLmpzXCIpLmRlZmF1bHR9IHN0eWxlIFN0eWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHQ9fSBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIEJ1aWxkZXIgZm9yIGRlY2x1dHRlcmluZy5cbiAqL1xuXG5cbmZ1bmN0aW9uIHJlbmRlclBvbHlnb25HZW9tZXRyeShidWlsZGVyR3JvdXAsIGdlb21ldHJ5LCBzdHlsZSwgZmVhdHVyZSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkge1xuICB2YXIgZmlsbFN0eWxlID0gc3R5bGUuZ2V0RmlsbCgpO1xuICB2YXIgc3Ryb2tlU3R5bGUgPSBzdHlsZS5nZXRTdHJva2UoKTtcblxuICBpZiAoZmlsbFN0eWxlIHx8IHN0cm9rZVN0eWxlKSB7XG4gICAgdmFyIHBvbHlnb25SZXBsYXkgPSBidWlsZGVyR3JvdXAuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuUE9MWUdPTik7XG4gICAgcG9seWdvblJlcGxheS5zZXRGaWxsU3Ryb2tlU3R5bGUoZmlsbFN0eWxlLCBzdHJva2VTdHlsZSk7XG4gICAgcG9seWdvblJlcGxheS5kcmF3UG9seWdvbihnZW9tZXRyeSwgZmVhdHVyZSk7XG4gIH1cblxuICB2YXIgdGV4dFN0eWxlID0gc3R5bGUuZ2V0VGV4dCgpO1xuXG4gIGlmICh0ZXh0U3R5bGUgJiYgdGV4dFN0eWxlLmdldFRleHQoKSkge1xuICAgIHZhciB0ZXh0UmVwbGF5ID0gKG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgfHwgYnVpbGRlckdyb3VwKS5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5URVhUKTtcbiAgICB0ZXh0UmVwbGF5LnNldFRleHRTdHlsZSh0ZXh0U3R5bGUpO1xuICAgIHRleHRSZXBsYXkuZHJhd1RleHQoZ2VvbWV0cnksIGZlYXR1cmUpO1xuICB9XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXJlci9jYW52YXMvVmVjdG9yTGF5ZXJcbiAqL1xuXG5cbmltcG9ydCBDYW52YXNCdWlsZGVyR3JvdXAgZnJvbSAnLi4vLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanMnO1xuaW1wb3J0IENhbnZhc0xheWVyUmVuZGVyZXIgZnJvbSAnLi9MYXllci5qcyc7XG5pbXBvcnQgRXhlY3V0b3JHcm91cCBmcm9tICcuLi8uLi9yZW5kZXIvY2FudmFzL0V4ZWN1dG9yR3JvdXAuanMnO1xuaW1wb3J0IFZpZXdIaW50IGZyb20gJy4uLy4uL1ZpZXdIaW50LmpzJztcbmltcG9ydCB7IGFwcGx5LCBtYWtlSW52ZXJzZSwgbWFrZVNjYWxlLCB0b1N0cmluZyBhcyB0cmFuc2Zvcm1Ub1N0cmluZyB9IGZyb20gJy4uLy4uL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgeyBidWZmZXIsIGNvbnRhaW5zRXh0ZW50LCBjcmVhdGVFbXB0eSwgZ2V0V2lkdGgsIGludGVyc2VjdHMgYXMgaW50ZXJzZWN0c0V4dGVudCwgd3JhcFggYXMgd3JhcEV4dGVudFggfSBmcm9tICcuLi8uLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgY3JlYXRlSGl0RGV0ZWN0aW9uSW1hZ2VEYXRhLCBoaXREZXRlY3QgfSBmcm9tICcuLi8uLi9yZW5kZXIvY2FudmFzL2hpdGRldGVjdC5qcyc7XG5pbXBvcnQgeyBkZWZhdWx0T3JkZXIgYXMgZGVmYXVsdFJlbmRlck9yZGVyLCBnZXRUb2xlcmFuY2UgYXMgZ2V0UmVuZGVyVG9sZXJhbmNlLCBnZXRTcXVhcmVkVG9sZXJhbmNlIGFzIGdldFNxdWFyZWRSZW5kZXJUb2xlcmFuY2UsIHJlbmRlckZlYXR1cmUgfSBmcm9tICcuLi92ZWN0b3IuanMnO1xuaW1wb3J0IHsgZnJvbVVzZXJFeHRlbnQsIGdldFRyYW5zZm9ybUZyb21Qcm9qZWN0aW9ucywgZ2V0VXNlclByb2plY3Rpb24sIHRvVXNlckV4dGVudCB9IGZyb20gJy4uLy4uL3Byb2ouanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi4vLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyB3cmFwWCBhcyB3cmFwQ29vcmRpbmF0ZVggfSBmcm9tICcuLi8uLi9jb29yZGluYXRlLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQ2FudmFzIHJlbmRlcmVyIGZvciB2ZWN0b3IgbGF5ZXJzLlxuICogQGFwaVxuICovXG5cbnZhciBDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2xheWVyL1ZlY3Rvci5qc1wiKS5kZWZhdWx0fSB2ZWN0b3JMYXllciBWZWN0b3IgbGF5ZXIuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlcih2ZWN0b3JMYXllcikge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHZlY3RvckxheWVyKSB8fCB0aGlzO1xuICAgIC8qKiBAcHJpdmF0ZSAqL1xuXG5cbiAgICBfdGhpcy5ib3VuZEhhbmRsZVN0eWxlSW1hZ2VDaGFuZ2VfID0gX3RoaXMuaGFuZGxlU3R5bGVJbWFnZUNoYW5nZV8uYmluZChfdGhpcyk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5hbmltYXRpbmdPckludGVyYWN0aW5nXztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMuZGlydHlfID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0ltYWdlRGF0YX1cbiAgICAgKi9cblxuICAgIF90aGlzLmhpdERldGVjdGlvbkltYWdlRGF0YV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRGZWF0dXJlc18gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkUmV2aXNpb25fID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRSZXNvbHV0aW9uXyA9IE5hTjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRFeHRlbnRfID0gY3JlYXRlRW1wdHkoKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZFJvdGF0aW9uXztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlXCIpLkNvb3JkaW5hdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZENlbnRlcl8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3Byb2ovUHJvamVjdGlvblwiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRQcm9qZWN0aW9uXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0LCBpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQpOiBudW1iZXJ8bnVsbH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkUmVuZGVyT3JkZXJfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9yZW5kZXIvY2FudmFzL0V4ZWN1dG9yR3JvdXBcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlcGxheUdyb3VwXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQSBuZXcgcmVwbGF5IGdyb3VwIGhhZCB0byBiZSBjcmVhdGVkIGJ5IGBwcmVwYXJlRnJhbWUoKWBcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlcGxheUdyb3VwQ2hhbmdlZCA9IHRydWU7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3JlbmRlci9jYW52YXMvRXhlY3V0b3JHcm91cFwiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZGVjbHV0dGVyRXhlY3V0b3JHcm91cCA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQ2xpcHBpbmcgdG8gYmUgcGVyZm9ybWVkIGJ5IGByZW5kZXJGcmFtZSgpYFxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMuY2xpcHBpbmcgPSB0cnVlO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogR2V0IGEgcmVuZGVyaW5nIGNvbnRhaW5lciBmcm9tIGFuIGV4aXN0aW5nIHRhcmdldCwgaWYgY29tcGF0aWJsZS5cbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gdGFyZ2V0IFBvdGVudGlhbCByZW5kZXIgdGFyZ2V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHJhbnNmb3JtIENTUyBUcmFuc2Zvcm0uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcGFjaXR5IE9wYWNpdHkuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUudXNlQ29udGFpbmVyID0gZnVuY3Rpb24gKHRhcmdldCwgdHJhbnNmb3JtLCBvcGFjaXR5KSB7XG4gICAgaWYgKG9wYWNpdHkgPCAxKSB7XG4gICAgICB0YXJnZXQgPSBudWxsO1xuICAgIH1cblxuICAgIF9zdXBlci5wcm90b3R5cGUudXNlQ29udGFpbmVyLmNhbGwodGhpcywgdGFyZ2V0LCB0cmFuc2Zvcm0sIG9wYWNpdHkpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtFeGVjdXRvckdyb3VwfSBleGVjdXRvckdyb3VwIEV4ZWN1dG9yIGdyb3VwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcInJidXNoXCIpLmRlZmF1bHQ9fSBvcHRfZGVjbHV0dGVyVHJlZSBEZWNsdXR0ZXIgdHJlZS5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJXb3JsZHMgPSBmdW5jdGlvbiAoZXhlY3V0b3JHcm91cCwgZnJhbWVTdGF0ZSwgb3B0X2RlY2x1dHRlclRyZWUpIHtcbiAgICB2YXIgZXh0ZW50ID0gZnJhbWVTdGF0ZS5leHRlbnQ7XG4gICAgdmFyIHZpZXdTdGF0ZSA9IGZyYW1lU3RhdGUudmlld1N0YXRlO1xuICAgIHZhciBjZW50ZXIgPSB2aWV3U3RhdGUuY2VudGVyO1xuICAgIHZhciByZXNvbHV0aW9uID0gdmlld1N0YXRlLnJlc29sdXRpb247XG4gICAgdmFyIHByb2plY3Rpb24gPSB2aWV3U3RhdGUucHJvamVjdGlvbjtcbiAgICB2YXIgcm90YXRpb24gPSB2aWV3U3RhdGUucm90YXRpb247XG4gICAgdmFyIHByb2plY3Rpb25FeHRlbnQgPSBwcm9qZWN0aW9uLmdldEV4dGVudCgpO1xuICAgIHZhciB2ZWN0b3JTb3VyY2UgPSB0aGlzLmdldExheWVyKCkuZ2V0U291cmNlKCk7XG4gICAgdmFyIHBpeGVsUmF0aW8gPSBmcmFtZVN0YXRlLnBpeGVsUmF0aW87XG4gICAgdmFyIHZpZXdIaW50cyA9IGZyYW1lU3RhdGUudmlld0hpbnRzO1xuICAgIHZhciBzbmFwVG9QaXhlbCA9ICEodmlld0hpbnRzW1ZpZXdIaW50LkFOSU1BVElOR10gfHwgdmlld0hpbnRzW1ZpZXdIaW50LklOVEVSQUNUSU5HXSk7XG4gICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgdmFyIHdpZHRoID0gTWF0aC5yb3VuZChmcmFtZVN0YXRlLnNpemVbMF0gKiBwaXhlbFJhdGlvKTtcbiAgICB2YXIgaGVpZ2h0ID0gTWF0aC5yb3VuZChmcmFtZVN0YXRlLnNpemVbMV0gKiBwaXhlbFJhdGlvKTtcbiAgICB2YXIgbXVsdGlXb3JsZCA9IHZlY3RvclNvdXJjZS5nZXRXcmFwWCgpICYmIHByb2plY3Rpb24uY2FuV3JhcFgoKTtcbiAgICB2YXIgd29ybGRXaWR0aCA9IG11bHRpV29ybGQgPyBnZXRXaWR0aChwcm9qZWN0aW9uRXh0ZW50KSA6IG51bGw7XG4gICAgdmFyIGVuZFdvcmxkID0gbXVsdGlXb3JsZCA/IE1hdGguY2VpbCgoZXh0ZW50WzJdIC0gcHJvamVjdGlvbkV4dGVudFsyXSkgLyB3b3JsZFdpZHRoKSArIDEgOiAxO1xuICAgIHZhciB3b3JsZCA9IG11bHRpV29ybGQgPyBNYXRoLmZsb29yKChleHRlbnRbMF0gLSBwcm9qZWN0aW9uRXh0ZW50WzBdKSAvIHdvcmxkV2lkdGgpIDogMDtcblxuICAgIGRvIHtcbiAgICAgIHZhciB0cmFuc2Zvcm0gPSB0aGlzLmdldFJlbmRlclRyYW5zZm9ybShjZW50ZXIsIHJlc29sdXRpb24sIHJvdGF0aW9uLCBwaXhlbFJhdGlvLCB3aWR0aCwgaGVpZ2h0LCB3b3JsZCAqIHdvcmxkV2lkdGgpO1xuICAgICAgZXhlY3V0b3JHcm91cC5leGVjdXRlKGNvbnRleHQsIDEsIHRyYW5zZm9ybSwgcm90YXRpb24sIHNuYXBUb1BpeGVsLCB1bmRlZmluZWQsIG9wdF9kZWNsdXR0ZXJUcmVlKTtcbiAgICB9IHdoaWxlICgrK3dvcmxkIDwgZW5kV29ybGQpO1xuICB9O1xuICAvKipcbiAgICogUmVuZGVyIGRlY2x1dHRlciBpdGVtcyBmb3IgdGhpcyBsYXllclxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIucHJvdG90eXBlLnJlbmRlckRlY2x1dHRlciA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgaWYgKHRoaXMuZGVjbHV0dGVyRXhlY3V0b3JHcm91cCkge1xuICAgICAgdGhpcy5yZW5kZXJXb3JsZHModGhpcy5kZWNsdXR0ZXJFeGVjdXRvckdyb3VwLCBmcmFtZVN0YXRlLCBmcmFtZVN0YXRlLmRlY2x1dHRlclRyZWUpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgbGF5ZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRhcmdldCBUYXJnZXQgdGhhdCBtYXkgYmUgdXNlZCB0byByZW5kZXIgY29udGVudCB0by5cbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9IFRoZSByZW5kZXJlZCBlbGVtZW50LlxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIucHJvdG90eXBlLnJlbmRlckZyYW1lID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUsIHRhcmdldCkge1xuICAgIHZhciBwaXhlbFJhdGlvID0gZnJhbWVTdGF0ZS5waXhlbFJhdGlvO1xuICAgIHZhciBsYXllclN0YXRlID0gZnJhbWVTdGF0ZS5sYXllclN0YXRlc0FycmF5W2ZyYW1lU3RhdGUubGF5ZXJJbmRleF07IC8vIHNldCBmb3J3YXJkIGFuZCBpbnZlcnNlIHBpeGVsIHRyYW5zZm9ybXNcblxuICAgIG1ha2VTY2FsZSh0aGlzLnBpeGVsVHJhbnNmb3JtLCAxIC8gcGl4ZWxSYXRpbywgMSAvIHBpeGVsUmF0aW8pO1xuICAgIG1ha2VJbnZlcnNlKHRoaXMuaW52ZXJzZVBpeGVsVHJhbnNmb3JtLCB0aGlzLnBpeGVsVHJhbnNmb3JtKTtcbiAgICB2YXIgY2FudmFzVHJhbnNmb3JtID0gdHJhbnNmb3JtVG9TdHJpbmcodGhpcy5waXhlbFRyYW5zZm9ybSk7XG4gICAgdGhpcy51c2VDb250YWluZXIodGFyZ2V0LCBjYW52YXNUcmFuc2Zvcm0sIGxheWVyU3RhdGUub3BhY2l0eSk7XG4gICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgdmFyIGNhbnZhcyA9IGNvbnRleHQuY2FudmFzO1xuICAgIHZhciByZXBsYXlHcm91cCA9IHRoaXMucmVwbGF5R3JvdXBfO1xuICAgIHZhciBkZWNsdXR0ZXJFeGVjdXRvckdyb3VwID0gdGhpcy5kZWNsdXR0ZXJFeGVjdXRvckdyb3VwO1xuXG4gICAgaWYgKCghcmVwbGF5R3JvdXAgfHwgcmVwbGF5R3JvdXAuaXNFbXB0eSgpKSAmJiAoIWRlY2x1dHRlckV4ZWN1dG9yR3JvdXAgfHwgZGVjbHV0dGVyRXhlY3V0b3JHcm91cC5pc0VtcHR5KCkpKSB7XG4gICAgICBpZiAoIXRoaXMuY29udGFpbmVyUmV1c2VkICYmIGNhbnZhcy53aWR0aCA+IDApIHtcbiAgICAgICAgY2FudmFzLndpZHRoID0gMDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICAgIH0gLy8gcmVzaXplIGFuZCBjbGVhclxuXG5cbiAgICB2YXIgd2lkdGggPSBNYXRoLnJvdW5kKGZyYW1lU3RhdGUuc2l6ZVswXSAqIHBpeGVsUmF0aW8pO1xuICAgIHZhciBoZWlnaHQgPSBNYXRoLnJvdW5kKGZyYW1lU3RhdGUuc2l6ZVsxXSAqIHBpeGVsUmF0aW8pO1xuXG4gICAgaWYgKGNhbnZhcy53aWR0aCAhPSB3aWR0aCB8fCBjYW52YXMuaGVpZ2h0ICE9IGhlaWdodCkge1xuICAgICAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXG4gICAgICBpZiAoY2FudmFzLnN0eWxlLnRyYW5zZm9ybSAhPT0gY2FudmFzVHJhbnNmb3JtKSB7XG4gICAgICAgIGNhbnZhcy5zdHlsZS50cmFuc2Zvcm0gPSBjYW52YXNUcmFuc2Zvcm07XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghdGhpcy5jb250YWluZXJSZXVzZWQpIHtcbiAgICAgIGNvbnRleHQuY2xlYXJSZWN0KDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICAgIH1cblxuICAgIHRoaXMucHJlUmVuZGVyKGNvbnRleHQsIGZyYW1lU3RhdGUpO1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICB2YXIgcHJvamVjdGlvbiA9IHZpZXdTdGF0ZS5wcm9qZWN0aW9uOyAvLyBjbGlwcGVkIHJlbmRlcmluZyBpZiBsYXllciBleHRlbnQgaXMgc2V0XG5cbiAgICB2YXIgY2xpcHBlZCA9IGZhbHNlO1xuXG4gICAgaWYgKGxheWVyU3RhdGUuZXh0ZW50ICYmIHRoaXMuY2xpcHBpbmcpIHtcbiAgICAgIHZhciBsYXllckV4dGVudCA9IGZyb21Vc2VyRXh0ZW50KGxheWVyU3RhdGUuZXh0ZW50LCBwcm9qZWN0aW9uKTtcbiAgICAgIGNsaXBwZWQgPSAhY29udGFpbnNFeHRlbnQobGF5ZXJFeHRlbnQsIGZyYW1lU3RhdGUuZXh0ZW50KSAmJiBpbnRlcnNlY3RzRXh0ZW50KGxheWVyRXh0ZW50LCBmcmFtZVN0YXRlLmV4dGVudCk7XG5cbiAgICAgIGlmIChjbGlwcGVkKSB7XG4gICAgICAgIHRoaXMuY2xpcFVucm90YXRlZChjb250ZXh0LCBmcmFtZVN0YXRlLCBsYXllckV4dGVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5yZW5kZXJXb3JsZHMocmVwbGF5R3JvdXAsIGZyYW1lU3RhdGUpO1xuXG4gICAgaWYgKGNsaXBwZWQpIHtcbiAgICAgIGNvbnRleHQucmVzdG9yZSgpO1xuICAgIH1cblxuICAgIHRoaXMucG9zdFJlbmRlcihjb250ZXh0LCBmcmFtZVN0YXRlKTtcbiAgICB2YXIgb3BhY2l0eSA9IGxheWVyU3RhdGUub3BhY2l0eTtcbiAgICB2YXIgY29udGFpbmVyID0gdGhpcy5jb250YWluZXI7XG5cbiAgICBpZiAob3BhY2l0eSAhPT0gcGFyc2VGbG9hdChjb250YWluZXIuc3R5bGUub3BhY2l0eSkpIHtcbiAgICAgIGNvbnRhaW5lci5zdHlsZS5vcGFjaXR5ID0gb3BhY2l0eSA9PT0gMSA/ICcnIDogU3RyaW5nKG9wYWNpdHkpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnJlbmRlcmVkUm90YXRpb25fICE9PSB2aWV3U3RhdGUucm90YXRpb24pIHtcbiAgICAgIHRoaXMucmVuZGVyZWRSb3RhdGlvbl8gPSB2aWV3U3RhdGUucm90YXRpb247XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkltYWdlRGF0YV8gPSBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfTtcbiAgLyoqXG4gICAqIEFzeW5jaHJvbm91cyBsYXllciBsZXZlbCBoaXQgZGV0ZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3BpeGVsLmpzXCIpLlBpeGVsfSBwaXhlbCBQaXhlbC5cbiAgICogQHJldHVybiB7UHJvbWlzZTxBcnJheTxpbXBvcnQoXCIuLi8uLi9GZWF0dXJlXCIpLmRlZmF1bHQ+Pn0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYW4gYXJyYXkgb2YgZmVhdHVyZXMuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0RmVhdHVyZXMgPSBmdW5jdGlvbiAocGl4ZWwpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbihBcnJheTxpbXBvcnQoXCIuLi8uLi9GZWF0dXJlXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vLi4vcmVuZGVyL0ZlYXR1cmVcIikuZGVmYXVsdD4pOiB2b2lkfSByZXNvbHZlIFJlc29sdmVyIGZ1bmN0aW9uLlxuICAgICAqIEB0aGlzIHtDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICBpZiAoIXRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VEYXRhXyAmJiAhdGhpcy5hbmltYXRpbmdPckludGVyYWN0aW5nXykge1xuICAgICAgICB2YXIgc2l6ZSA9IFt0aGlzLmNvbnRleHQuY2FudmFzLndpZHRoLCB0aGlzLmNvbnRleHQuY2FudmFzLmhlaWdodF07XG4gICAgICAgIGFwcGx5KHRoaXMucGl4ZWxUcmFuc2Zvcm0sIHNpemUpO1xuICAgICAgICB2YXIgY2VudGVyID0gdGhpcy5yZW5kZXJlZENlbnRlcl87XG4gICAgICAgIHZhciByZXNvbHV0aW9uID0gdGhpcy5yZW5kZXJlZFJlc29sdXRpb25fO1xuICAgICAgICB2YXIgcm90YXRpb24gPSB0aGlzLnJlbmRlcmVkUm90YXRpb25fO1xuICAgICAgICB2YXIgcHJvamVjdGlvbiA9IHRoaXMucmVuZGVyZWRQcm9qZWN0aW9uXztcbiAgICAgICAgdmFyIGV4dGVudCA9IHRoaXMucmVuZGVyZWRFeHRlbnRfO1xuICAgICAgICB2YXIgbGF5ZXIgPSB0aGlzLmdldExheWVyKCk7XG4gICAgICAgIHZhciB0cmFuc2Zvcm1zID0gW107XG4gICAgICAgIHZhciB3aWR0aCA9IHNpemVbMF0gLyAyO1xuICAgICAgICB2YXIgaGVpZ2h0ID0gc2l6ZVsxXSAvIDI7XG4gICAgICAgIHRyYW5zZm9ybXMucHVzaCh0aGlzLmdldFJlbmRlclRyYW5zZm9ybShjZW50ZXIsIHJlc29sdXRpb24sIHJvdGF0aW9uLCAwLjUsIHdpZHRoLCBoZWlnaHQsIDApLnNsaWNlKCkpO1xuICAgICAgICB2YXIgc291cmNlID0gbGF5ZXIuZ2V0U291cmNlKCk7XG4gICAgICAgIHZhciBwcm9qZWN0aW9uRXh0ZW50ID0gcHJvamVjdGlvbi5nZXRFeHRlbnQoKTtcblxuICAgICAgICBpZiAoc291cmNlLmdldFdyYXBYKCkgJiYgcHJvamVjdGlvbi5jYW5XcmFwWCgpICYmICFjb250YWluc0V4dGVudChwcm9qZWN0aW9uRXh0ZW50LCBleHRlbnQpKSB7XG4gICAgICAgICAgdmFyIHN0YXJ0WCA9IGV4dGVudFswXTtcbiAgICAgICAgICB2YXIgd29ybGRXaWR0aCA9IGdldFdpZHRoKHByb2plY3Rpb25FeHRlbnQpO1xuICAgICAgICAgIHZhciB3b3JsZCA9IDA7XG4gICAgICAgICAgdmFyIG9mZnNldFggPSB2b2lkIDA7XG5cbiAgICAgICAgICB3aGlsZSAoc3RhcnRYIDwgcHJvamVjdGlvbkV4dGVudFswXSkge1xuICAgICAgICAgICAgLS13b3JsZDtcbiAgICAgICAgICAgIG9mZnNldFggPSB3b3JsZFdpZHRoICogd29ybGQ7XG4gICAgICAgICAgICB0cmFuc2Zvcm1zLnB1c2godGhpcy5nZXRSZW5kZXJUcmFuc2Zvcm0oY2VudGVyLCByZXNvbHV0aW9uLCByb3RhdGlvbiwgMC41LCB3aWR0aCwgaGVpZ2h0LCBvZmZzZXRYKS5zbGljZSgpKTtcbiAgICAgICAgICAgIHN0YXJ0WCArPSB3b3JsZFdpZHRoO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHdvcmxkID0gMDtcbiAgICAgICAgICBzdGFydFggPSBleHRlbnRbMl07XG5cbiAgICAgICAgICB3aGlsZSAoc3RhcnRYID4gcHJvamVjdGlvbkV4dGVudFsyXSkge1xuICAgICAgICAgICAgKyt3b3JsZDtcbiAgICAgICAgICAgIG9mZnNldFggPSB3b3JsZFdpZHRoICogd29ybGQ7XG4gICAgICAgICAgICB0cmFuc2Zvcm1zLnB1c2godGhpcy5nZXRSZW5kZXJUcmFuc2Zvcm0oY2VudGVyLCByZXNvbHV0aW9uLCByb3RhdGlvbiwgMC41LCB3aWR0aCwgaGVpZ2h0LCBvZmZzZXRYKS5zbGljZSgpKTtcbiAgICAgICAgICAgIHN0YXJ0WCAtPSB3b3JsZFdpZHRoO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VEYXRhXyA9IGNyZWF0ZUhpdERldGVjdGlvbkltYWdlRGF0YShzaXplLCB0cmFuc2Zvcm1zLCB0aGlzLnJlbmRlcmVkRmVhdHVyZXNfLCBsYXllci5nZXRTdHlsZUZ1bmN0aW9uKCksIGV4dGVudCwgcmVzb2x1dGlvbiwgcm90YXRpb24pO1xuICAgICAgfVxuXG4gICAgICByZXNvbHZlKGhpdERldGVjdChwaXhlbCwgdGhpcy5yZW5kZXJlZEZlYXR1cmVzXywgdGhpcy5oaXREZXRlY3Rpb25JbWFnZURhdGFfKSk7XG4gICAgfS5iaW5kKHRoaXMpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoaXRUb2xlcmFuY2UgSGl0IHRvbGVyYW5jZSBpbiBwaXhlbHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdmVjdG9yLmpzXCIpLkZlYXR1cmVDYWxsYmFjazxUPn0gY2FsbGJhY2sgRmVhdHVyZSBjYWxsYmFjay5cbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi9NYXAuanNcIikuSGl0TWF0Y2g8VD4+fSBtYXRjaGVzIFRoZSBoaXQgZGV0ZWN0ZWQgbWF0Y2hlcyB3aXRoIHRvbGVyYW5jZS5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IENhbGxiYWNrIHJlc3VsdC5cbiAgICogQHRlbXBsYXRlIFRcbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyLnByb3RvdHlwZS5mb3JFYWNoRmVhdHVyZUF0Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uIChjb29yZGluYXRlLCBmcmFtZVN0YXRlLCBoaXRUb2xlcmFuY2UsIGNhbGxiYWNrLCBtYXRjaGVzKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIGlmICghdGhpcy5yZXBsYXlHcm91cF8pIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdmFyIHJlc29sdXRpb24gPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZS5yZXNvbHV0aW9uO1xuICAgIHZhciByb3RhdGlvbiA9IGZyYW1lU3RhdGUudmlld1N0YXRlLnJvdGF0aW9uO1xuICAgIHZhciBsYXllciA9IHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICAvKiogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi9NYXAuanNcIikuSGl0TWF0Y2g8VD58dHJ1ZT59ICovXG5cbiAgICB2YXIgZmVhdHVyZXMgPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGRpc3RhbmNlU3EgVGhlIHNxdWFyZWQgZGlzdGFuY2UgdG8gdGhlIGNsaWNrIHBvc2l0aW9uXG4gICAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IENhbGxiYWNrIHJlc3VsdC5cbiAgICAgKi9cblxuICAgIHZhciBmZWF0dXJlQ2FsbGJhY2sgPSBmdW5jdGlvbiBmZWF0dXJlQ2FsbGJhY2soZmVhdHVyZSwgZ2VvbWV0cnksIGRpc3RhbmNlU3EpIHtcbiAgICAgIHZhciBrZXkgPSBnZXRVaWQoZmVhdHVyZSk7XG4gICAgICB2YXIgbWF0Y2ggPSBmZWF0dXJlc1trZXldO1xuXG4gICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgIGlmIChkaXN0YW5jZVNxID09PSAwKSB7XG4gICAgICAgICAgZmVhdHVyZXNba2V5XSA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGZlYXR1cmUsIGxheWVyLCBnZW9tZXRyeSk7XG4gICAgICAgIH1cblxuICAgICAgICBtYXRjaGVzLnB1c2goZmVhdHVyZXNba2V5XSA9IHtcbiAgICAgICAgICBmZWF0dXJlOiBmZWF0dXJlLFxuICAgICAgICAgIGxheWVyOiBsYXllcixcbiAgICAgICAgICBnZW9tZXRyeTogZ2VvbWV0cnksXG4gICAgICAgICAgZGlzdGFuY2VTcTogZGlzdGFuY2VTcSxcbiAgICAgICAgICBjYWxsYmFjazogY2FsbGJhY2tcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKG1hdGNoICE9PSB0cnVlICYmIGRpc3RhbmNlU3EgPCBtYXRjaC5kaXN0YW5jZVNxKSB7XG4gICAgICAgIGlmIChkaXN0YW5jZVNxID09PSAwKSB7XG4gICAgICAgICAgZmVhdHVyZXNba2V5XSA9IHRydWU7XG4gICAgICAgICAgbWF0Y2hlcy5zcGxpY2UobWF0Y2hlcy5sYXN0SW5kZXhPZihtYXRjaCksIDEpO1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhmZWF0dXJlLCBsYXllciwgZ2VvbWV0cnkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbWF0Y2guZ2VvbWV0cnkgPSBnZW9tZXRyeTtcbiAgICAgICAgbWF0Y2guZGlzdGFuY2VTcSA9IGRpc3RhbmNlU3E7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfTtcblxuICAgIHZhciByZXN1bHQ7XG4gICAgdmFyIGV4ZWN1dG9yR3JvdXBzID0gW3RoaXMucmVwbGF5R3JvdXBfXTtcblxuICAgIGlmICh0aGlzLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXApIHtcbiAgICAgIGV4ZWN1dG9yR3JvdXBzLnB1c2godGhpcy5kZWNsdXR0ZXJFeGVjdXRvckdyb3VwKTtcbiAgICB9XG5cbiAgICBleGVjdXRvckdyb3Vwcy5zb21lKGZ1bmN0aW9uIChleGVjdXRvckdyb3VwKSB7XG4gICAgICByZXR1cm4gcmVzdWx0ID0gZXhlY3V0b3JHcm91cC5mb3JFYWNoRmVhdHVyZUF0Q29vcmRpbmF0ZShjb29yZGluYXRlLCByZXNvbHV0aW9uLCByb3RhdGlvbiwgaGl0VG9sZXJhbmNlLCBmZWF0dXJlQ2FsbGJhY2ssIGV4ZWN1dG9yR3JvdXAgPT09IF90aGlzLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXAgPyBmcmFtZVN0YXRlLmRlY2x1dHRlclRyZWUuYWxsKCkubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIHJldHVybiBpdGVtLnZhbHVlO1xuICAgICAgfSkgOiBudWxsKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuICAvKipcbiAgICogUGVyZm9ybSBhY3Rpb24gbmVjZXNzYXJ5IHRvIGdldCB0aGUgbGF5ZXIgcmVuZGVyZWQgYWZ0ZXIgbmV3IGZvbnRzIGhhdmUgbG9hZGVkXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuaGFuZGxlRm9udHNDaGFuZ2VkID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBsYXllciA9IHRoaXMuZ2V0TGF5ZXIoKTtcblxuICAgIGlmIChsYXllci5nZXRWaXNpYmxlKCkgJiYgdGhpcy5yZXBsYXlHcm91cF8pIHtcbiAgICAgIGxheWVyLmNoYW5nZWQoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGUgY2hhbmdlcyBpbiBpbWFnZSBzdHlsZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9ldmVudHMvRXZlbnQuanNcIikuZGVmYXVsdH0gZXZlbnQgSW1hZ2Ugc3R5bGUgY2hhbmdlIGV2ZW50LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIucHJvdG90eXBlLmhhbmRsZVN0eWxlSW1hZ2VDaGFuZ2VfID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdGhpcy5yZW5kZXJJZlJlYWR5QW5kVmlzaWJsZSgpO1xuICB9O1xuICAvKipcbiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgcmVuZGVyIHNob3VsZCBiZSBjYWxsZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IExheWVyIGlzIHJlYWR5IHRvIGJlIHJlbmRlcmVkLlxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIucHJvdG90eXBlLnByZXBhcmVGcmFtZSA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgdmFyIHZlY3RvckxheWVyID0gdGhpcy5nZXRMYXllcigpO1xuICAgIHZhciB2ZWN0b3JTb3VyY2UgPSB2ZWN0b3JMYXllci5nZXRTb3VyY2UoKTtcblxuICAgIGlmICghdmVjdG9yU291cmNlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGFuaW1hdGluZyA9IGZyYW1lU3RhdGUudmlld0hpbnRzW1ZpZXdIaW50LkFOSU1BVElOR107XG4gICAgdmFyIGludGVyYWN0aW5nID0gZnJhbWVTdGF0ZS52aWV3SGludHNbVmlld0hpbnQuSU5URVJBQ1RJTkddO1xuICAgIHZhciB1cGRhdGVXaGlsZUFuaW1hdGluZyA9IHZlY3RvckxheWVyLmdldFVwZGF0ZVdoaWxlQW5pbWF0aW5nKCk7XG4gICAgdmFyIHVwZGF0ZVdoaWxlSW50ZXJhY3RpbmcgPSB2ZWN0b3JMYXllci5nZXRVcGRhdGVXaGlsZUludGVyYWN0aW5nKCk7XG5cbiAgICBpZiAoIXRoaXMuZGlydHlfICYmICF1cGRhdGVXaGlsZUFuaW1hdGluZyAmJiBhbmltYXRpbmcgfHwgIXVwZGF0ZVdoaWxlSW50ZXJhY3RpbmcgJiYgaW50ZXJhY3RpbmcpIHtcbiAgICAgIHRoaXMuYW5pbWF0aW5nT3JJbnRlcmFjdGluZ18gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy5hbmltYXRpbmdPckludGVyYWN0aW5nXyA9IGZhbHNlO1xuICAgIHZhciBmcmFtZVN0YXRlRXh0ZW50ID0gZnJhbWVTdGF0ZS5leHRlbnQ7XG4gICAgdmFyIHZpZXdTdGF0ZSA9IGZyYW1lU3RhdGUudmlld1N0YXRlO1xuICAgIHZhciBwcm9qZWN0aW9uID0gdmlld1N0YXRlLnByb2plY3Rpb247XG4gICAgdmFyIHJlc29sdXRpb24gPSB2aWV3U3RhdGUucmVzb2x1dGlvbjtcbiAgICB2YXIgcGl4ZWxSYXRpbyA9IGZyYW1lU3RhdGUucGl4ZWxSYXRpbztcbiAgICB2YXIgdmVjdG9yTGF5ZXJSZXZpc2lvbiA9IHZlY3RvckxheWVyLmdldFJldmlzaW9uKCk7XG4gICAgdmFyIHZlY3RvckxheWVyUmVuZGVyQnVmZmVyID0gdmVjdG9yTGF5ZXIuZ2V0UmVuZGVyQnVmZmVyKCk7XG4gICAgdmFyIHZlY3RvckxheWVyUmVuZGVyT3JkZXIgPSB2ZWN0b3JMYXllci5nZXRSZW5kZXJPcmRlcigpO1xuXG4gICAgaWYgKHZlY3RvckxheWVyUmVuZGVyT3JkZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdmVjdG9yTGF5ZXJSZW5kZXJPcmRlciA9IGRlZmF1bHRSZW5kZXJPcmRlcjtcbiAgICB9XG5cbiAgICB2YXIgY2VudGVyID0gdmlld1N0YXRlLmNlbnRlci5zbGljZSgpO1xuICAgIHZhciBleHRlbnQgPSBidWZmZXIoZnJhbWVTdGF0ZUV4dGVudCwgdmVjdG9yTGF5ZXJSZW5kZXJCdWZmZXIgKiByZXNvbHV0aW9uKTtcbiAgICB2YXIgbG9hZEV4dGVudHMgPSBbZXh0ZW50LnNsaWNlKCldO1xuICAgIHZhciBwcm9qZWN0aW9uRXh0ZW50ID0gcHJvamVjdGlvbi5nZXRFeHRlbnQoKTtcblxuICAgIGlmICh2ZWN0b3JTb3VyY2UuZ2V0V3JhcFgoKSAmJiBwcm9qZWN0aW9uLmNhbldyYXBYKCkgJiYgIWNvbnRhaW5zRXh0ZW50KHByb2plY3Rpb25FeHRlbnQsIGZyYW1lU3RhdGUuZXh0ZW50KSkge1xuICAgICAgLy8gRm9yIHRoZSByZXBsYXkgZ3JvdXAsIHdlIG5lZWQgYW4gZXh0ZW50IHRoYXQgaW50ZXJzZWN0cyB0aGUgcmVhbCB3b3JsZFxuICAgICAgLy8gKC0xODDCsCB0byArMTgwwrApLiBUbyBzdXBwb3J0IGdlb21ldHJpZXMgaW4gYSBjb29yZGluYXRlIHJhbmdlIGZyb20gLTU0MMKwXG4gICAgICAvLyB0byArNTQwwrAsIHdlIGFkZCBhdCBsZWFzdCAxIHdvcmxkIHdpZHRoIG9uIGVhY2ggc2lkZSBvZiB0aGUgcHJvamVjdGlvblxuICAgICAgLy8gZXh0ZW50LiBJZiB0aGUgdmlld3BvcnQgaXMgd2lkZXIgdGhhbiB0aGUgd29ybGQsIHdlIG5lZWQgdG8gYWRkIGhhbGYgb2ZcbiAgICAgIC8vIHRoZSB2aWV3cG9ydCB3aWR0aCB0byBtYWtlIHN1cmUgd2UgY292ZXIgdGhlIHdob2xlIHZpZXdwb3J0LlxuICAgICAgdmFyIHdvcmxkV2lkdGggPSBnZXRXaWR0aChwcm9qZWN0aW9uRXh0ZW50KTtcbiAgICAgIHZhciBndXR0ZXIgPSBNYXRoLm1heChnZXRXaWR0aChleHRlbnQpIC8gMiwgd29ybGRXaWR0aCk7XG4gICAgICBleHRlbnRbMF0gPSBwcm9qZWN0aW9uRXh0ZW50WzBdIC0gZ3V0dGVyO1xuICAgICAgZXh0ZW50WzJdID0gcHJvamVjdGlvbkV4dGVudFsyXSArIGd1dHRlcjtcbiAgICAgIHdyYXBDb29yZGluYXRlWChjZW50ZXIsIHByb2plY3Rpb24pO1xuICAgICAgdmFyIGxvYWRFeHRlbnQgPSB3cmFwRXh0ZW50WChsb2FkRXh0ZW50c1swXSwgcHJvamVjdGlvbik7IC8vIElmIHRoZSBleHRlbnQgY3Jvc3NlcyB0aGUgZGF0ZSBsaW5lLCB3ZSBsb2FkIGRhdGEgZm9yIGJvdGggZWRnZXMgb2YgdGhlIHdvcmxkc1xuXG4gICAgICBpZiAobG9hZEV4dGVudFswXSA8IHByb2plY3Rpb25FeHRlbnRbMF0gJiYgbG9hZEV4dGVudFsyXSA8IHByb2plY3Rpb25FeHRlbnRbMl0pIHtcbiAgICAgICAgbG9hZEV4dGVudHMucHVzaChbbG9hZEV4dGVudFswXSArIHdvcmxkV2lkdGgsIGxvYWRFeHRlbnRbMV0sIGxvYWRFeHRlbnRbMl0gKyB3b3JsZFdpZHRoLCBsb2FkRXh0ZW50WzNdXSk7XG4gICAgICB9IGVsc2UgaWYgKGxvYWRFeHRlbnRbMF0gPiBwcm9qZWN0aW9uRXh0ZW50WzBdICYmIGxvYWRFeHRlbnRbMl0gPiBwcm9qZWN0aW9uRXh0ZW50WzJdKSB7XG4gICAgICAgIGxvYWRFeHRlbnRzLnB1c2goW2xvYWRFeHRlbnRbMF0gLSB3b3JsZFdpZHRoLCBsb2FkRXh0ZW50WzFdLCBsb2FkRXh0ZW50WzJdIC0gd29ybGRXaWR0aCwgbG9hZEV4dGVudFszXV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGhpcy5kaXJ0eV8gJiYgdGhpcy5yZW5kZXJlZFJlc29sdXRpb25fID09IHJlc29sdXRpb24gJiYgdGhpcy5yZW5kZXJlZFJldmlzaW9uXyA9PSB2ZWN0b3JMYXllclJldmlzaW9uICYmIHRoaXMucmVuZGVyZWRSZW5kZXJPcmRlcl8gPT0gdmVjdG9yTGF5ZXJSZW5kZXJPcmRlciAmJiBjb250YWluc0V4dGVudCh0aGlzLnJlbmRlcmVkRXh0ZW50XywgZXh0ZW50KSkge1xuICAgICAgdGhpcy5yZXBsYXlHcm91cENoYW5nZWQgPSBmYWxzZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMucmVwbGF5R3JvdXBfID0gbnVsbDtcbiAgICB0aGlzLmRpcnR5XyA9IGZhbHNlO1xuICAgIHZhciByZXBsYXlHcm91cCA9IG5ldyBDYW52YXNCdWlsZGVyR3JvdXAoZ2V0UmVuZGVyVG9sZXJhbmNlKHJlc29sdXRpb24sIHBpeGVsUmF0aW8pLCBleHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8pO1xuICAgIHZhciBkZWNsdXR0ZXJCdWlsZGVyR3JvdXA7XG5cbiAgICBpZiAodGhpcy5nZXRMYXllcigpLmdldERlY2x1dHRlcigpKSB7XG4gICAgICBkZWNsdXR0ZXJCdWlsZGVyR3JvdXAgPSBuZXcgQ2FudmFzQnVpbGRlckdyb3VwKGdldFJlbmRlclRvbGVyYW5jZShyZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSwgZXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKTtcbiAgICB9XG5cbiAgICB2YXIgdXNlclByb2plY3Rpb24gPSBnZXRVc2VyUHJvamVjdGlvbigpO1xuICAgIHZhciB1c2VyVHJhbnNmb3JtO1xuXG4gICAgaWYgKHVzZXJQcm9qZWN0aW9uKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBsb2FkRXh0ZW50cy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIHZlY3RvclNvdXJjZS5sb2FkRmVhdHVyZXModG9Vc2VyRXh0ZW50KGxvYWRFeHRlbnRzW2ldLCBwcm9qZWN0aW9uKSwgcmVzb2x1dGlvbiwgdXNlclByb2plY3Rpb24pO1xuICAgICAgfVxuXG4gICAgICB1c2VyVHJhbnNmb3JtID0gZ2V0VHJhbnNmb3JtRnJvbVByb2plY3Rpb25zKHVzZXJQcm9qZWN0aW9uLCBwcm9qZWN0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbG9hZEV4dGVudHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICB2ZWN0b3JTb3VyY2UubG9hZEZlYXR1cmVzKGxvYWRFeHRlbnRzW2ldLCByZXNvbHV0aW9uLCBwcm9qZWN0aW9uKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc3F1YXJlZFRvbGVyYW5jZSA9IGdldFNxdWFyZWRSZW5kZXJUb2xlcmFuY2UocmVzb2x1dGlvbiwgcGl4ZWxSYXRpbyk7XG5cbiAgICB2YXIgcmVuZGVyID1cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZmVhdHVyZSBGZWF0dXJlLlxuICAgICAqIEB0aGlzIHtDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChmZWF0dXJlKSB7XG4gICAgICB2YXIgc3R5bGVzO1xuICAgICAgdmFyIHN0eWxlRnVuY3Rpb24gPSBmZWF0dXJlLmdldFN0eWxlRnVuY3Rpb24oKSB8fCB2ZWN0b3JMYXllci5nZXRTdHlsZUZ1bmN0aW9uKCk7XG5cbiAgICAgIGlmIChzdHlsZUZ1bmN0aW9uKSB7XG4gICAgICAgIHN0eWxlcyA9IHN0eWxlRnVuY3Rpb24oZmVhdHVyZSwgcmVzb2x1dGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdHlsZXMpIHtcbiAgICAgICAgdmFyIGRpcnR5ID0gdGhpcy5yZW5kZXJGZWF0dXJlKGZlYXR1cmUsIHNxdWFyZWRUb2xlcmFuY2UsIHN0eWxlcywgcmVwbGF5R3JvdXAsIHVzZXJUcmFuc2Zvcm0sIGRlY2x1dHRlckJ1aWxkZXJHcm91cCk7XG4gICAgICAgIHRoaXMuZGlydHlfID0gdGhpcy5kaXJ0eV8gfHwgZGlydHk7XG4gICAgICB9XG4gICAgfS5iaW5kKHRoaXMpO1xuXG4gICAgdmFyIHVzZXJFeHRlbnQgPSB0b1VzZXJFeHRlbnQoZXh0ZW50LCBwcm9qZWN0aW9uKTtcbiAgICAvKiogQHR5cGUge0FycmF5PGltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdD59ICovXG5cbiAgICB2YXIgZmVhdHVyZXMgPSB2ZWN0b3JTb3VyY2UuZ2V0RmVhdHVyZXNJbkV4dGVudCh1c2VyRXh0ZW50KTtcblxuICAgIGlmICh2ZWN0b3JMYXllclJlbmRlck9yZGVyKSB7XG4gICAgICBmZWF0dXJlcy5zb3J0KHZlY3RvckxheWVyUmVuZGVyT3JkZXIpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZlYXR1cmVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHJlbmRlcihmZWF0dXJlc1tpXSk7XG4gICAgfVxuXG4gICAgdGhpcy5yZW5kZXJlZEZlYXR1cmVzXyA9IGZlYXR1cmVzO1xuICAgIHZhciByZXBsYXlHcm91cEluc3RydWN0aW9ucyA9IHJlcGxheUdyb3VwLmZpbmlzaCgpO1xuICAgIHZhciBleGVjdXRvckdyb3VwID0gbmV3IEV4ZWN1dG9yR3JvdXAoZXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvLCB2ZWN0b3JTb3VyY2UuZ2V0T3ZlcmxhcHMoKSwgcmVwbGF5R3JvdXBJbnN0cnVjdGlvbnMsIHZlY3RvckxheWVyLmdldFJlbmRlckJ1ZmZlcigpKTtcblxuICAgIGlmIChkZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgICAgIHRoaXMuZGVjbHV0dGVyRXhlY3V0b3JHcm91cCA9IG5ldyBFeGVjdXRvckdyb3VwKGV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbywgdmVjdG9yU291cmNlLmdldE92ZXJsYXBzKCksIGRlY2x1dHRlckJ1aWxkZXJHcm91cC5maW5pc2goKSwgdmVjdG9yTGF5ZXIuZ2V0UmVuZGVyQnVmZmVyKCkpO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyZWRSZXNvbHV0aW9uXyA9IHJlc29sdXRpb247XG4gICAgdGhpcy5yZW5kZXJlZFJldmlzaW9uXyA9IHZlY3RvckxheWVyUmV2aXNpb247XG4gICAgdGhpcy5yZW5kZXJlZFJlbmRlck9yZGVyXyA9IHZlY3RvckxheWVyUmVuZGVyT3JkZXI7XG4gICAgdGhpcy5yZW5kZXJlZEV4dGVudF8gPSBleHRlbnQ7XG4gICAgdGhpcy5yZW5kZXJlZENlbnRlcl8gPSBjZW50ZXI7XG4gICAgdGhpcy5yZW5kZXJlZFByb2plY3Rpb25fID0gcHJvamVjdGlvbjtcbiAgICB0aGlzLnJlcGxheUdyb3VwXyA9IGV4ZWN1dG9yR3JvdXA7XG4gICAgdGhpcy5oaXREZXRlY3Rpb25JbWFnZURhdGFfID0gbnVsbDtcbiAgICB0aGlzLnJlcGxheUdyb3VwQ2hhbmdlZCA9IHRydWU7XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHJlbmRlciB0b2xlcmFuY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdHxBcnJheTxpbXBvcnQoXCIuLi8uLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0Pn0gc3R5bGVzIFRoZSBzdHlsZSBvciBhcnJheSBvZiBzdHlsZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdH0gYnVpbGRlckdyb3VwIEJ1aWxkZXIgZ3JvdXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbj19IG9wdF90cmFuc2Zvcm0gVHJhbnNmb3JtIGZyb20gdXNlciB0byB2aWV3IHByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdD19IG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgQnVpbGRlciBmb3IgZGVjbHV0dGVyaW5nLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgYW4gaW1hZ2UgaXMgbG9hZGluZy5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJGZWF0dXJlID0gZnVuY3Rpb24gKGZlYXR1cmUsIHNxdWFyZWRUb2xlcmFuY2UsIHN0eWxlcywgYnVpbGRlckdyb3VwLCBvcHRfdHJhbnNmb3JtLCBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwKSB7XG4gICAgaWYgKCFzdHlsZXMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgbG9hZGluZyA9IGZhbHNlO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc3R5bGVzKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gc3R5bGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgbG9hZGluZyA9IHJlbmRlckZlYXR1cmUoYnVpbGRlckdyb3VwLCBmZWF0dXJlLCBzdHlsZXNbaV0sIHNxdWFyZWRUb2xlcmFuY2UsIHRoaXMuYm91bmRIYW5kbGVTdHlsZUltYWdlQ2hhbmdlXywgb3B0X3RyYW5zZm9ybSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkgfHwgbG9hZGluZztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbG9hZGluZyA9IHJlbmRlckZlYXR1cmUoYnVpbGRlckdyb3VwLCBmZWF0dXJlLCBzdHlsZXMsIHNxdWFyZWRUb2xlcmFuY2UsIHRoaXMuYm91bmRIYW5kbGVTdHlsZUltYWdlQ2hhbmdlXywgb3B0X3RyYW5zZm9ybSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxvYWRpbmc7XG4gIH07XG5cbiAgcmV0dXJuIENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXI7XG59KENhbnZhc0xheWVyUmVuZGVyZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvbGF5ZXIvVmVjdG9yXG4gKi9cblxuXG5pbXBvcnQgQmFzZVZlY3RvckxheWVyIGZyb20gJy4vQmFzZVZlY3Rvci5qcyc7XG5pbXBvcnQgQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlciBmcm9tICcuLi9yZW5kZXJlci9jYW52YXMvVmVjdG9yTGF5ZXIuanMnO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBWZWN0b3IgZGF0YSB0aGF0IGlzIHJlbmRlcmVkIGNsaWVudC1zaWRlLlxuICogTm90ZSB0aGF0IGFueSBwcm9wZXJ0eSBzZXQgaW4gdGhlIG9wdGlvbnMgaXMgc2V0IGFzIGEge0BsaW5rIG1vZHVsZTpvbC9PYmplY3R+QmFzZU9iamVjdH1cbiAqIHByb3BlcnR5IG9uIHRoZSBsYXllciBvYmplY3Q7IGZvciBleGFtcGxlLCBzZXR0aW5nIGB0aXRsZTogJ015IFRpdGxlJ2AgaW4gdGhlXG4gKiBvcHRpb25zIG1lYW5zIHRoYXQgYHRpdGxlYCBpcyBvYnNlcnZhYmxlLCBhbmQgaGFzIGdldC9zZXQgYWNjZXNzb3JzLlxuICpcbiAqIEBleHRlbmRzIHtCYXNlVmVjdG9yTGF5ZXI8aW1wb3J0KFwiLi4vc291cmNlL1ZlY3Rvci5qc1wiKS5kZWZhdWx0Pn1cbiAqIEBhcGlcbiAqL1xuXG52YXIgVmVjdG9yTGF5ZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVmVjdG9yTGF5ZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vQmFzZVZlY3Rvci5qc1wiKS5PcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBWZWN0b3JMYXllcihvcHRfb3B0aW9ucykge1xuICAgIHJldHVybiBfc3VwZXIuY2FsbCh0aGlzLCBvcHRfb3B0aW9ucykgfHwgdGhpcztcbiAgfVxuICAvKipcbiAgICogQ3JlYXRlIGEgcmVuZGVyZXIgZm9yIHRoaXMgbGF5ZXIuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3JlbmRlcmVyL0xheWVyLmpzXCIpLmRlZmF1bHR9IEEgbGF5ZXIgcmVuZGVyZXIuXG4gICAqL1xuXG5cbiAgVmVjdG9yTGF5ZXIucHJvdG90eXBlLmNyZWF0ZVJlbmRlcmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBuZXcgQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlcih0aGlzKTtcbiAgfTtcblxuICByZXR1cm4gVmVjdG9yTGF5ZXI7XG59KEJhc2VWZWN0b3JMYXllcik7XG5cbmV4cG9ydCBkZWZhdWx0IFZlY3RvckxheWVyOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHJ1Y3RzL1JCdXNoXG4gKi9cbmltcG9ydCBSQnVzaF8gZnJvbSAncmJ1c2gnO1xuaW1wb3J0IHsgY3JlYXRlT3JVcGRhdGUsIGVxdWFscyB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBnZXRVaWQgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IGlzRW1wdHkgfSBmcm9tICcuLi9vYmouanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBFbnRyeVxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1pblhcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtaW5ZXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWF4WFxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1heFlcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBbdmFsdWVdXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgUkJ1c2ggYnkgVmxhZGltaXIgQWdhZm9ua2luLlxuICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9tb3VybmVyL3JidXNoLlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKi9cblxudmFyIFJCdXNoID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X21heEVudHJpZXMgTWF4IGVudHJpZXMuXG4gICAqL1xuICBmdW5jdGlvbiBSQnVzaChvcHRfbWF4RW50cmllcykge1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgdGhpcy5yYnVzaF8gPSBuZXcgUkJ1c2hfKG9wdF9tYXhFbnRyaWVzKTtcbiAgICAvKipcbiAgICAgKiBBIG1hcHBpbmcgYmV0d2VlbiB0aGUgb2JqZWN0cyBhZGRlZCB0byB0aGlzIHJidXNoIHdyYXBwZXJcbiAgICAgKiBhbmQgdGhlIG9iamVjdHMgdGhhdCBhcmUgYWN0dWFsbHkgYWRkZWQgdG8gdGhlIGludGVybmFsIHJidXNoLlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsIEVudHJ5Pn1cbiAgICAgKi9cblxuICAgIHRoaXMuaXRlbXNfID0ge307XG4gIH1cbiAgLyoqXG4gICAqIEluc2VydCBhIHZhbHVlIGludG8gdGhlIFJCdXNoLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7VH0gdmFsdWUgVmFsdWUuXG4gICAqL1xuXG5cbiAgUkJ1c2gucHJvdG90eXBlLmluc2VydCA9IGZ1bmN0aW9uIChleHRlbnQsIHZhbHVlKSB7XG4gICAgLyoqIEB0eXBlIHtFbnRyeX0gKi9cbiAgICB2YXIgaXRlbSA9IHtcbiAgICAgIG1pblg6IGV4dGVudFswXSxcbiAgICAgIG1pblk6IGV4dGVudFsxXSxcbiAgICAgIG1heFg6IGV4dGVudFsyXSxcbiAgICAgIG1heFk6IGV4dGVudFszXSxcbiAgICAgIHZhbHVlOiB2YWx1ZVxuICAgIH07XG4gICAgdGhpcy5yYnVzaF8uaW5zZXJ0KGl0ZW0pO1xuICAgIHRoaXMuaXRlbXNfW2dldFVpZCh2YWx1ZSldID0gaXRlbTtcbiAgfTtcbiAgLyoqXG4gICAqIEJ1bGstaW5zZXJ0IHZhbHVlcyBpbnRvIHRoZSBSQnVzaC5cbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50Pn0gZXh0ZW50cyBFeHRlbnRzLlxuICAgKiBAcGFyYW0ge0FycmF5PFQ+fSB2YWx1ZXMgVmFsdWVzLlxuICAgKi9cblxuXG4gIFJCdXNoLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKGV4dGVudHMsIHZhbHVlcykge1xuICAgIHZhciBpdGVtcyA9IG5ldyBBcnJheSh2YWx1ZXMubGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdmFyIGV4dGVudCA9IGV4dGVudHNbaV07XG4gICAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbaV07XG4gICAgICAvKiogQHR5cGUge0VudHJ5fSAqL1xuXG4gICAgICB2YXIgaXRlbSA9IHtcbiAgICAgICAgbWluWDogZXh0ZW50WzBdLFxuICAgICAgICBtaW5ZOiBleHRlbnRbMV0sXG4gICAgICAgIG1heFg6IGV4dGVudFsyXSxcbiAgICAgICAgbWF4WTogZXh0ZW50WzNdLFxuICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICAgIH07XG4gICAgICBpdGVtc1tpXSA9IGl0ZW07XG4gICAgICB0aGlzLml0ZW1zX1tnZXRVaWQodmFsdWUpXSA9IGl0ZW07XG4gICAgfVxuXG4gICAgdGhpcy5yYnVzaF8ubG9hZChpdGVtcyk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgYSB2YWx1ZSBmcm9tIHRoZSBSQnVzaC5cbiAgICogQHBhcmFtIHtUfSB2YWx1ZSBWYWx1ZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gUmVtb3ZlZC5cbiAgICovXG5cblxuICBSQnVzaC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdmFyIHVpZCA9IGdldFVpZCh2YWx1ZSk7IC8vIGdldCB0aGUgb2JqZWN0IGluIHdoaWNoIHRoZSB2YWx1ZSB3YXMgd3JhcHBlZCB3aGVuIGFkZGluZyB0byB0aGVcbiAgICAvLyBpbnRlcm5hbCByYnVzaC4gdGhlbiB1c2UgdGhhdCBvYmplY3QgdG8gZG8gdGhlIHJlbW92YWwuXG5cbiAgICB2YXIgaXRlbSA9IHRoaXMuaXRlbXNfW3VpZF07XG4gICAgZGVsZXRlIHRoaXMuaXRlbXNfW3VpZF07XG4gICAgcmV0dXJuIHRoaXMucmJ1c2hfLnJlbW92ZShpdGVtKSAhPT0gbnVsbDtcbiAgfTtcbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgZXh0ZW50IG9mIGEgdmFsdWUgaW4gdGhlIFJCdXNoLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7VH0gdmFsdWUgVmFsdWUuXG4gICAqL1xuXG5cbiAgUkJ1c2gucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChleHRlbnQsIHZhbHVlKSB7XG4gICAgdmFyIGl0ZW0gPSB0aGlzLml0ZW1zX1tnZXRVaWQodmFsdWUpXTtcbiAgICB2YXIgYmJveCA9IFtpdGVtLm1pblgsIGl0ZW0ubWluWSwgaXRlbS5tYXhYLCBpdGVtLm1heFldO1xuXG4gICAgaWYgKCFlcXVhbHMoYmJveCwgZXh0ZW50KSkge1xuICAgICAgdGhpcy5yZW1vdmUodmFsdWUpO1xuICAgICAgdGhpcy5pbnNlcnQoZXh0ZW50LCB2YWx1ZSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUmV0dXJuIGFsbCB2YWx1ZXMgaW4gdGhlIFJCdXNoLlxuICAgKiBAcmV0dXJuIHtBcnJheTxUPn0gQWxsLlxuICAgKi9cblxuXG4gIFJCdXNoLnByb3RvdHlwZS5nZXRBbGwgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGl0ZW1zID0gdGhpcy5yYnVzaF8uYWxsKCk7XG4gICAgcmV0dXJuIGl0ZW1zLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgcmV0dXJuIGl0ZW0udmFsdWU7XG4gICAgfSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gYWxsIHZhbHVlcyBpbiB0aGUgZ2l2ZW4gZXh0ZW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEByZXR1cm4ge0FycmF5PFQ+fSBBbGwgaW4gZXh0ZW50LlxuICAgKi9cblxuXG4gIFJCdXNoLnByb3RvdHlwZS5nZXRJbkV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICAvKiogQHR5cGUge0VudHJ5fSAqL1xuICAgIHZhciBiYm94ID0ge1xuICAgICAgbWluWDogZXh0ZW50WzBdLFxuICAgICAgbWluWTogZXh0ZW50WzFdLFxuICAgICAgbWF4WDogZXh0ZW50WzJdLFxuICAgICAgbWF4WTogZXh0ZW50WzNdXG4gICAgfTtcbiAgICB2YXIgaXRlbXMgPSB0aGlzLnJidXNoXy5zZWFyY2goYmJveCk7XG4gICAgcmV0dXJuIGl0ZW1zLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgcmV0dXJuIGl0ZW0udmFsdWU7XG4gICAgfSk7XG4gIH07XG4gIC8qKlxuICAgKiBDYWxscyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHdpdGggZWFjaCB2YWx1ZSBpbiB0aGUgdHJlZS5cbiAgICogSWYgdGhlIGNhbGxiYWNrIHJldHVybnMgYSB0cnV0aHkgdmFsdWUsIHRoaXMgdmFsdWUgaXMgcmV0dXJuZWQgd2l0aG91dFxuICAgKiBjaGVja2luZyB0aGUgcmVzdCBvZiB0aGUgdHJlZS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihUKTogKn0gY2FsbGJhY2sgQ2FsbGJhY2suXG4gICAqIEByZXR1cm4geyp9IENhbGxiYWNrIHJldHVybiB2YWx1ZS5cbiAgICovXG5cblxuICBSQnVzaC5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIHJldHVybiB0aGlzLmZvckVhY2hfKHRoaXMuZ2V0QWxsKCksIGNhbGxiYWNrKTtcbiAgfTtcbiAgLyoqXG4gICAqIENhbGxzIGEgY2FsbGJhY2sgZnVuY3Rpb24gd2l0aCBlYWNoIHZhbHVlIGluIHRoZSBwcm92aWRlZCBleHRlbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihUKTogKn0gY2FsbGJhY2sgQ2FsbGJhY2suXG4gICAqIEByZXR1cm4geyp9IENhbGxiYWNrIHJldHVybiB2YWx1ZS5cbiAgICovXG5cblxuICBSQnVzaC5wcm90b3R5cGUuZm9yRWFjaEluRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5mb3JFYWNoXyh0aGlzLmdldEluRXh0ZW50KGV4dGVudCksIGNhbGxiYWNrKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8VD59IHZhbHVlcyBWYWx1ZXMuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oVCk6ICp9IGNhbGxiYWNrIENhbGxiYWNrLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcmV0dXJuIHsqfSBDYWxsYmFjayByZXR1cm4gdmFsdWUuXG4gICAqL1xuXG5cbiAgUkJ1c2gucHJvdG90eXBlLmZvckVhY2hfID0gZnVuY3Rpb24gKHZhbHVlcywgY2FsbGJhY2spIHtcbiAgICB2YXIgcmVzdWx0O1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICByZXN1bHQgPSBjYWxsYmFjayh2YWx1ZXNbaV0pO1xuXG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElzIGVtcHR5LlxuICAgKi9cblxuXG4gIFJCdXNoLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBpc0VtcHR5KHRoaXMuaXRlbXNfKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSBhbGwgdmFsdWVzIGZyb20gdGhlIFJCdXNoLlxuICAgKi9cblxuXG4gIFJCdXNoLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJidXNoXy5jbGVhcigpO1xuICAgIHRoaXMuaXRlbXNfID0ge307XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnQ9fSBvcHRfZXh0ZW50IEV4dGVudC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICAgKi9cblxuXG4gIFJCdXNoLnByb3RvdHlwZS5nZXRFeHRlbnQgPSBmdW5jdGlvbiAob3B0X2V4dGVudCkge1xuICAgIHZhciBkYXRhID0gdGhpcy5yYnVzaF8udG9KU09OKCk7XG4gICAgcmV0dXJuIGNyZWF0ZU9yVXBkYXRlKGRhdGEubWluWCwgZGF0YS5taW5ZLCBkYXRhLm1heFgsIGRhdGEubWF4WSwgb3B0X2V4dGVudCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge1JCdXNofSByYnVzaCBSLVRyZWUuXG4gICAqL1xuXG5cbiAgUkJ1c2gucHJvdG90eXBlLmNvbmNhdCA9IGZ1bmN0aW9uIChyYnVzaCkge1xuICAgIHRoaXMucmJ1c2hfLmxvYWQocmJ1c2gucmJ1c2hfLmFsbCgpKTtcblxuICAgIGZvciAodmFyIGkgaW4gcmJ1c2guaXRlbXNfKSB7XG4gICAgICB0aGlzLml0ZW1zX1tpXSA9IHJidXNoLml0ZW1zX1tpXTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIFJCdXNoO1xufSgpO1xuXG5leHBvcnQgZGVmYXVsdCBSQnVzaDsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3NvdXJjZS9Tb3VyY2VcbiAqL1xuXG5cbmltcG9ydCBCYXNlT2JqZWN0IGZyb20gJy4uL09iamVjdC5qcyc7XG5pbXBvcnQgU291cmNlU3RhdGUgZnJvbSAnLi9TdGF0ZS5qcyc7XG5pbXBvcnQgeyBhYnN0cmFjdCB9IGZyb20gJy4uL3V0aWwuanMnO1xuaW1wb3J0IHsgZ2V0IGFzIGdldFByb2plY3Rpb24gfSBmcm9tICcuLi9wcm9qLmpzJztcbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBzdHJpbmcgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncyByZXByZXNlbnRpbmcgc291cmNlXG4gKiBhdHRyaWJ1dGlvbnMuXG4gKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKGltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlKTogKHN0cmluZ3xBcnJheTxzdHJpbmc+KX0gQXR0cmlidXRpb25cbiAqL1xuXG4vKipcbiAqIEEgdHlwZSB0aGF0IGNhbiBiZSB1c2VkIHRvIHByb3ZpZGUgYXR0cmlidXRpb24gaW5mb3JtYXRpb24gZm9yIGRhdGEgc291cmNlcy5cbiAqXG4gKiBJdCByZXByZXNlbnRzIGVpdGhlclxuICogKiBhIHNpbXBsZSBzdHJpbmcgKGUuZy4gYCfCqSBBY21lIEluYy4nYClcbiAqICogYW4gYXJyYXkgb2Ygc2ltcGxlIHN0cmluZ3MgKGUuZy4gYFsnwqkgQWNtZSBJbmMuJywgJ8KpIEJhY21lIEluYy4nXWApXG4gKiAqIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgc3RyaW5nIG9yIGFycmF5IG9mIHN0cmluZ3MgKHtAbGluayBtb2R1bGU6b2wvc291cmNlL1NvdXJjZX5BdHRyaWJ1dGlvbn0pXG4gKlxuICogQHR5cGVkZWYge3N0cmluZ3xBcnJheTxzdHJpbmc+fEF0dHJpYnV0aW9ufSBBdHRyaWJ1dGlvbkxpa2VcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7QXR0cmlidXRpb25MaWtlfSBbYXR0cmlidXRpb25zXVxuICogQHByb3BlcnR5IHtib29sZWFufSBbYXR0cmlidXRpb25zQ29sbGFwc2libGU9dHJ1ZV0gQXR0cmlidXRpb25zIGFyZSBjb2xsYXBzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gW3Byb2plY3Rpb25dIFByb2plY3Rpb24uIERlZmF1bHQgaXMgdGhlIHZpZXcgcHJvamVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9TdGF0ZS5qc1wiKS5kZWZhdWx0fSBbc3RhdGU9J3JlYWR5J11cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3dyYXBYPWZhbHNlXVxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWJzdHJhY3QgYmFzZSBjbGFzczsgbm9ybWFsbHkgb25seSB1c2VkIGZvciBjcmVhdGluZyBzdWJjbGFzc2VzIGFuZCBub3RcbiAqIGluc3RhbnRpYXRlZCBpbiBhcHBzLlxuICogQmFzZSBjbGFzcyBmb3Ige0BsaW5rIG1vZHVsZTpvbC9sYXllci9MYXllcn5MYXllcn0gc291cmNlcy5cbiAqXG4gKiBBIGdlbmVyaWMgYGNoYW5nZWAgZXZlbnQgaXMgdHJpZ2dlcmVkIHdoZW4gdGhlIHN0YXRlIG9mIHRoZSBzb3VyY2UgY2hhbmdlcy5cbiAqIEBhYnN0cmFjdFxuICogQGFwaVxuICovXG5cbnZhciBTb3VyY2UgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoU291cmNlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIFNvdXJjZSBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFNvdXJjZShvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMucHJvamVjdGlvbl8gPSBnZXRQcm9qZWN0aW9uKG9wdGlvbnMucHJvamVjdGlvbik7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P0F0dHJpYnV0aW9ufVxuICAgICAqL1xuXG4gICAgX3RoaXMuYXR0cmlidXRpb25zXyA9IGFkYXB0QXR0cmlidXRpb25zKG9wdGlvbnMuYXR0cmlidXRpb25zKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMuYXR0cmlidXRpb25zQ29sbGFwc2libGVfID0gb3B0aW9ucy5hdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5hdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZSA6IHRydWU7XG4gICAgLyoqXG4gICAgICogVGhpcyBzb3VyY2UgaXMgY3VycmVudGx5IGxvYWRpbmcgZGF0YS4gU291cmNlcyB0aGF0IGRlZmVyIGxvYWRpbmcgdG8gdGhlXG4gICAgICogbWFwJ3MgdGlsZSBxdWV1ZSBuZXZlciBzZXQgdGhpcyB0byBgdHJ1ZWAuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9TdGF0ZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3RhdGVfID0gb3B0aW9ucy5zdGF0ZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zdGF0ZSA6IFNvdXJjZVN0YXRlLlJFQURZO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy53cmFwWF8gPSBvcHRpb25zLndyYXBYICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLndyYXBYIDogZmFsc2U7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIGF0dHJpYnV0aW9uIGZ1bmN0aW9uIGZvciB0aGUgc291cmNlLlxuICAgKiBAcmV0dXJuIHs/QXR0cmlidXRpb259IEF0dHJpYnV0aW9uIGZ1bmN0aW9uLlxuICAgKi9cblxuXG4gIFNvdXJjZS5wcm90b3R5cGUuZ2V0QXR0cmlidXRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmF0dHJpYnV0aW9uc187XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBBdHRyaWJ1dGlvbnMgYXJlIGNvbGxhcHNpYmxlLlxuICAgKi9cblxuXG4gIFNvdXJjZS5wcm90b3R5cGUuZ2V0QXR0cmlidXRpb25zQ29sbGFwc2libGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuYXR0cmlidXRpb25zQ29sbGFwc2libGVfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBwcm9qZWN0aW9uIG9mIHRoZSBzb3VyY2UuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBQcm9qZWN0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU291cmNlLnByb3RvdHlwZS5nZXRQcm9qZWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnByb2plY3Rpb25fO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj58dW5kZWZpbmVkfSBSZXNvbHV0aW9ucy5cbiAgICovXG5cblxuICBTb3VyY2UucHJvdG90eXBlLmdldFJlc29sdXRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzdGF0ZSBvZiB0aGUgc291cmNlLCBzZWUge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvU3RhdGV+U3RhdGV9IGZvciBwb3NzaWJsZSBzdGF0ZXMuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vU3RhdGUuanNcIikuZGVmYXVsdH0gU3RhdGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTb3VyY2UucHJvdG90eXBlLmdldFN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW58dW5kZWZpbmVkfSBXcmFwIFguXG4gICAqL1xuXG5cbiAgU291cmNlLnByb3RvdHlwZS5nZXRXcmFwWCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy53cmFwWF87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSBDb250ZXh0IG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgU291cmNlLnByb3RvdHlwZS5nZXRDb250ZXh0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogUmVmcmVzaGVzIHRoZSBzb3VyY2UuIFRoZSBzb3VyY2Ugd2lsbCBiZSBjbGVhcmVkLCBhbmQgZGF0YSBmcm9tIHRoZSBzZXJ2ZXIgd2lsbCBiZSByZWxvYWRlZC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFNvdXJjZS5wcm90b3R5cGUucmVmcmVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgYXR0cmlidXRpb25zIG9mIHRoZSBzb3VyY2UuXG4gICAqIEBwYXJhbSB7QXR0cmlidXRpb25MaWtlfHVuZGVmaW5lZH0gYXR0cmlidXRpb25zIEF0dHJpYnV0aW9ucy5cbiAgICogICAgIENhbiBiZSBwYXNzZWQgYXMgYHN0cmluZ2AsIGBBcnJheTxzdHJpbmc+YCwge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvU291cmNlfkF0dHJpYnV0aW9ufSxcbiAgICogICAgIG9yIGB1bmRlZmluZWRgLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU291cmNlLnByb3RvdHlwZS5zZXRBdHRyaWJ1dGlvbnMgPSBmdW5jdGlvbiAoYXR0cmlidXRpb25zKSB7XG4gICAgdGhpcy5hdHRyaWJ1dGlvbnNfID0gYWRhcHRBdHRyaWJ1dGlvbnMoYXR0cmlidXRpb25zKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgc3RhdGUgb2YgdGhlIHNvdXJjZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1N0YXRlLmpzXCIpLmRlZmF1bHR9IHN0YXRlIFN0YXRlLlxuICAgKi9cblxuXG4gIFNvdXJjZS5wcm90b3R5cGUuc2V0U3RhdGUgPSBmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICB0aGlzLnN0YXRlXyA9IHN0YXRlO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuXG4gIHJldHVybiBTb3VyY2U7XG59KEJhc2VPYmplY3QpO1xuLyoqXG4gKiBUdXJucyB0aGUgYXR0cmlidXRpb25zIG9wdGlvbiBpbnRvIGFuIGF0dHJpYnV0aW9ucyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7QXR0cmlidXRpb25MaWtlfHVuZGVmaW5lZH0gYXR0cmlidXRpb25MaWtlIFRoZSBhdHRyaWJ1dGlvbiBvcHRpb24uXG4gKiBAcmV0dXJuIHs/QXR0cmlidXRpb259IEFuIGF0dHJpYnV0aW9uIGZ1bmN0aW9uIChvciBudWxsKS5cbiAqL1xuXG5cbmZ1bmN0aW9uIGFkYXB0QXR0cmlidXRpb25zKGF0dHJpYnV0aW9uTGlrZSkge1xuICBpZiAoIWF0dHJpYnV0aW9uTGlrZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoYXR0cmlidXRpb25MaWtlKSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgICAgcmV0dXJuIGF0dHJpYnV0aW9uTGlrZTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBhdHRyaWJ1dGlvbkxpa2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gYXR0cmlidXRpb25MaWtlO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgcmV0dXJuIFthdHRyaWJ1dGlvbkxpa2VdO1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBTb3VyY2U7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3NvdXJjZS9WZWN0b3JFdmVudFR5cGVcbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFRyaWdnZXJlZCB3aGVuIGEgZmVhdHVyZSBpcyBhZGRlZCB0byB0aGUgc291cmNlLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3IuVmVjdG9yU291cmNlRXZlbnQjYWRkZmVhdHVyZVxuICAgKiBAYXBpXG4gICAqL1xuICBBRERGRUFUVVJFOiAnYWRkZmVhdHVyZScsXG5cbiAgLyoqXG4gICAqIFRyaWdnZXJlZCB3aGVuIGEgZmVhdHVyZSBpcyB1cGRhdGVkLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3IuVmVjdG9yU291cmNlRXZlbnQjY2hhbmdlZmVhdHVyZVxuICAgKiBAYXBpXG4gICAqL1xuICBDSEFOR0VGRUFUVVJFOiAnY2hhbmdlZmVhdHVyZScsXG5cbiAgLyoqXG4gICAqIFRyaWdnZXJlZCB3aGVuIHRoZSBjbGVhciBtZXRob2QgaXMgY2FsbGVkIG9uIHRoZSBzb3VyY2UuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvci5WZWN0b3JTb3VyY2VFdmVudCNjbGVhclxuICAgKiBAYXBpXG4gICAqL1xuICBDTEVBUjogJ2NsZWFyJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIHdoZW4gYSBmZWF0dXJlIGlzIHJlbW92ZWQgZnJvbSB0aGUgc291cmNlLlxuICAgKiBTZWUge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yI2NsZWFyIHNvdXJjZS5jbGVhcigpfSBmb3IgZXhjZXB0aW9ucy5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yLlZlY3RvclNvdXJjZUV2ZW50I3JlbW92ZWZlYXR1cmVcbiAgICogQGFwaVxuICAgKi9cbiAgUkVNT1ZFRkVBVFVSRTogJ3JlbW92ZWZlYXR1cmUnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBmZWF0dXJlcyBzdGFydHMgbG9hZGluZy5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yLlZlY3RvclNvdXJjZUV2ZW50I2ZlYXR1cmVzbG9hZHN0YXJ0XG4gICAqIEBhcGlcbiAgICovXG4gIEZFQVRVUkVTTE9BRFNUQVJUOiAnZmVhdHVyZXNsb2Fkc3RhcnQnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBmZWF0dXJlcyBmaW5pc2hlcyBsb2FkaW5nLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3IuVmVjdG9yU291cmNlRXZlbnQjZmVhdHVyZXNsb2FkZW5kXG4gICAqIEBhcGlcbiAgICovXG4gIEZFQVRVUkVTTE9BREVORDogJ2ZlYXR1cmVzbG9hZGVuZCcsXG5cbiAgLyoqXG4gICAqIFRyaWdnZXJlZCBpZiBmZWF0dXJlIGxvYWRpbmcgcmVzdWx0cyBpbiBhbiBlcnJvci5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yLlZlY3RvclNvdXJjZUV2ZW50I2ZlYXR1cmVzbG9hZGVycm9yXG4gICAqIEBhcGlcbiAgICovXG4gIEZFQVRVUkVTTE9BREVSUk9SOiAnZmVhdHVyZXNsb2FkZXJyb3InXG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC9sb2FkaW5nc3RyYXRlZ3lcbiAqL1xuXG4vKipcbiAqIFN0cmF0ZWd5IGZ1bmN0aW9uIGZvciBsb2FkaW5nIGFsbCBmZWF0dXJlcyB3aXRoIGEgc2luZ2xlIHJlcXVlc3QuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnQ+fSBFeHRlbnRzLlxuICogQGFwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gYWxsKGV4dGVudCwgcmVzb2x1dGlvbikge1xuICByZXR1cm4gW1stSW5maW5pdHksIC1JbmZpbml0eSwgSW5maW5pdHksIEluZmluaXR5XV07XG59XG4vKipcbiAqIFN0cmF0ZWd5IGZ1bmN0aW9uIGZvciBsb2FkaW5nIGZlYXR1cmVzIGJhc2VkIG9uIHRoZSB2aWV3J3MgZXh0ZW50IGFuZFxuICogcmVzb2x1dGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudD59IEV4dGVudHMuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGJib3goZXh0ZW50LCByZXNvbHV0aW9uKSB7XG4gIHJldHVybiBbZXh0ZW50XTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIHN0cmF0ZWd5IGZ1bmN0aW9uIGZvciBsb2FkaW5nIGZlYXR1cmVzIGJhc2VkIG9uIGEgdGlsZSBncmlkLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IHRpbGVHcmlkIFRpbGUgZ3JpZC5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudCwgbnVtYmVyKTogQXJyYXk8aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50Pn0gTG9hZGluZyBzdHJhdGVneS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdGlsZSh0aWxlR3JpZCkge1xuICByZXR1cm4gKFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50Pn0gRXh0ZW50cy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXh0ZW50LCByZXNvbHV0aW9uKSB7XG4gICAgICB2YXIgeiA9IHRpbGVHcmlkLmdldFpGb3JSZXNvbHV0aW9uKHJlc29sdXRpb24pO1xuICAgICAgdmFyIHRpbGVSYW5nZSA9IHRpbGVHcmlkLmdldFRpbGVSYW5nZUZvckV4dGVudEFuZFooZXh0ZW50LCB6KTtcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50Pn0gKi9cblxuICAgICAgdmFyIGV4dGVudHMgPSBbXTtcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSAqL1xuXG4gICAgICB2YXIgdGlsZUNvb3JkID0gW3osIDAsIDBdO1xuXG4gICAgICBmb3IgKHRpbGVDb29yZFsxXSA9IHRpbGVSYW5nZS5taW5YOyB0aWxlQ29vcmRbMV0gPD0gdGlsZVJhbmdlLm1heFg7ICsrdGlsZUNvb3JkWzFdKSB7XG4gICAgICAgIGZvciAodGlsZUNvb3JkWzJdID0gdGlsZVJhbmdlLm1pblk7IHRpbGVDb29yZFsyXSA8PSB0aWxlUmFuZ2UubWF4WTsgKyt0aWxlQ29vcmRbMl0pIHtcbiAgICAgICAgICBleHRlbnRzLnB1c2godGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHRpbGVDb29yZCkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBleHRlbnRzO1xuICAgIH1cbiAgKTtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZm9ybWF0L0Zvcm1hdFR5cGVcbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgQVJSQVlfQlVGRkVSOiAnYXJyYXlidWZmZXInLFxuICBKU09OOiAnanNvbicsXG4gIFRFWFQ6ICd0ZXh0JyxcbiAgWE1MOiAneG1sJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZmVhdHVyZWxvYWRlclxuICovXG5pbXBvcnQgRm9ybWF0VHlwZSBmcm9tICcuL2Zvcm1hdC9Gb3JtYXRUeXBlLmpzJztcbmltcG9ydCB7IFZPSUQgfSBmcm9tICcuL2Z1bmN0aW9ucy5qcyc7XG4vKipcbiAqXG4gKiBAdHlwZSB7Ym9vbGVhbn1cbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIHdpdGhDcmVkZW50aWFscyA9IGZhbHNlO1xuLyoqXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3J9IHNvdXJjZXMgdXNlIGEgZnVuY3Rpb24gb2YgdGhpcyB0eXBlIHRvXG4gKiBsb2FkIGZlYXR1cmVzLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gdGFrZXMgYW4ge0BsaW5rIG1vZHVsZTpvbC9leHRlbnR+RXh0ZW50fSByZXByZXNlbnRpbmcgdGhlIGFyZWEgdG8gYmUgbG9hZGVkLFxuICogYSBge251bWJlcn1gIHJlcHJlc2VudGluZyB0aGUgcmVzb2x1dGlvbiAobWFwIHVuaXRzIHBlciBwaXhlbCksIGFuXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn0gZm9yIHRoZSBwcm9qZWN0aW9uIGFuZCBzdWNjZXNzIGFuZCBmYWlsdXJlIGNhbGxiYWNrcyBhc1xuICogYXJndW1lbnRzLiBgdGhpc2Agd2l0aGluIHRoZSBmdW5jdGlvbiBpcyBib3VuZCB0byB0aGVcbiAqIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn0gaXQncyBjYWxsZWQgZnJvbS5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gaXMgcmVzcG9uc2libGUgZm9yIGxvYWRpbmcgdGhlIGZlYXR1cmVzIGFuZCBhZGRpbmcgdGhlbSB0byB0aGVcbiAqIHNvdXJjZS5cbiAqIEB0eXBlZGVmIHtmdW5jdGlvbih0aGlzOihpbXBvcnQoXCIuL3NvdXJjZS9WZWN0b3JcIikuZGVmYXVsdHxpbXBvcnQoXCIuL1ZlY3RvclRpbGUuanNcIikuZGVmYXVsdCksXG4gKiAgICAgICAgICAgaW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50LFxuICogICAgICAgICAgIG51bWJlcixcbiAqICAgICAgICAgICBpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0LFxuICogICAgICAgICAgIGZ1bmN0aW9uKEFycmF5PGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0Pik6IHZvaWQ9LFxuICogICAgICAgICAgIGZ1bmN0aW9uKCk6IHZvaWQ9KTogdm9pZH0gRmVhdHVyZUxvYWRlclxuICogQGFwaVxuICovXG5cbi8qKlxuICoge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yfSBzb3VyY2VzIHVzZSBhIGZ1bmN0aW9uIG9mIHRoaXMgdHlwZSB0b1xuICogZ2V0IHRoZSB1cmwgdG8gbG9hZCBmZWF0dXJlcyBmcm9tLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gdGFrZXMgYW4ge0BsaW5rIG1vZHVsZTpvbC9leHRlbnR+RXh0ZW50fSByZXByZXNlbnRpbmcgdGhlIGFyZWFcbiAqIHRvIGJlIGxvYWRlZCwgYSBge251bWJlcn1gIHJlcHJlc2VudGluZyB0aGUgcmVzb2x1dGlvbiAobWFwIHVuaXRzIHBlciBwaXhlbClcbiAqIGFuZCBhbiB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn0gZm9yIHRoZSBwcm9qZWN0aW9uICBhc1xuICogYXJndW1lbnRzIGFuZCByZXR1cm5zIGEgYHtzdHJpbmd9YCByZXByZXNlbnRpbmcgdGhlIFVSTC5cbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnQsIG51bWJlciwgaW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdCk6IHN0cmluZ30gRmVhdHVyZVVybEZ1bmN0aW9uXG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ3xGZWF0dXJlVXJsRnVuY3Rpb259IHVybCBGZWF0dXJlIFVSTCBzZXJ2aWNlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Zvcm1hdC9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGZvcm1hdCBGZWF0dXJlIGZvcm1hdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICogQHBhcmFtIHtmdW5jdGlvbihBcnJheTxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuZGVmYXVsdD4sIGltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHQpOiB2b2lkfSBzdWNjZXNzIFN1Y2Nlc3NcbiAqICAgICAgRnVuY3Rpb24gY2FsbGVkIHdpdGggdGhlIGxvYWRlZCBmZWF0dXJlcyBhbmQgb3B0aW9uYWxseSB3aXRoIHRoZSBkYXRhIHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCk6IHZvaWR9IGZhaWx1cmUgRmFpbHVyZVxuICogICAgICBGdW5jdGlvbiBjYWxsZWQgd2hlbiBsb2FkaW5nIGZhaWxlZC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbG9hZEZlYXR1cmVzWGhyKHVybCwgZm9ybWF0LCBleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24sIHN1Y2Nlc3MsIGZhaWx1cmUpIHtcbiAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICB4aHIub3BlbignR0VUJywgdHlwZW9mIHVybCA9PT0gJ2Z1bmN0aW9uJyA/IHVybChleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24pIDogdXJsLCB0cnVlKTtcblxuICBpZiAoZm9ybWF0LmdldFR5cGUoKSA9PSBGb3JtYXRUeXBlLkFSUkFZX0JVRkZFUikge1xuICAgIHhoci5yZXNwb25zZVR5cGUgPSAnYXJyYXlidWZmZXInO1xuICB9XG5cbiAgeGhyLndpdGhDcmVkZW50aWFscyA9IHdpdGhDcmVkZW50aWFscztcbiAgLyoqXG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IEV2ZW50LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuICB4aHIub25sb2FkID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgLy8gc3RhdHVzIHdpbGwgYmUgMCBmb3IgZmlsZTovLyB1cmxzXG4gICAgaWYgKCF4aHIuc3RhdHVzIHx8IHhoci5zdGF0dXMgPj0gMjAwICYmIHhoci5zdGF0dXMgPCAzMDApIHtcbiAgICAgIHZhciB0eXBlID0gZm9ybWF0LmdldFR5cGUoKTtcbiAgICAgIC8qKiBAdHlwZSB7RG9jdW1lbnR8Tm9kZXxPYmplY3R8c3RyaW5nfHVuZGVmaW5lZH0gKi9cblxuICAgICAgdmFyIHNvdXJjZSA9IHZvaWQgMDtcblxuICAgICAgaWYgKHR5cGUgPT0gRm9ybWF0VHlwZS5KU09OIHx8IHR5cGUgPT0gRm9ybWF0VHlwZS5URVhUKSB7XG4gICAgICAgIHNvdXJjZSA9IHhoci5yZXNwb25zZVRleHQ7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gRm9ybWF0VHlwZS5YTUwpIHtcbiAgICAgICAgc291cmNlID0geGhyLnJlc3BvbnNlWE1MO1xuXG4gICAgICAgIGlmICghc291cmNlKSB7XG4gICAgICAgICAgc291cmNlID0gbmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZyh4aHIucmVzcG9uc2VUZXh0LCAnYXBwbGljYXRpb24veG1sJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBGb3JtYXRUeXBlLkFSUkFZX0JVRkZFUikge1xuICAgICAgICBzb3VyY2UgPVxuICAgICAgICAvKiogQHR5cGUge0FycmF5QnVmZmVyfSAqL1xuICAgICAgICB4aHIucmVzcG9uc2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgc3VjY2VzcyhcbiAgICAgICAgLyoqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuZGVmYXVsdD59ICovXG4gICAgICAgIGZvcm1hdC5yZWFkRmVhdHVyZXMoc291cmNlLCB7XG4gICAgICAgICAgZXh0ZW50OiBleHRlbnQsXG4gICAgICAgICAgZmVhdHVyZVByb2plY3Rpb246IHByb2plY3Rpb25cbiAgICAgICAgfSksIGZvcm1hdC5yZWFkUHJvamVjdGlvbihzb3VyY2UpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZhaWx1cmUoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZmFpbHVyZSgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgeGhyLm9uZXJyb3IgPSBmYWlsdXJlO1xuICB4aHIuc2VuZCgpO1xufVxuLyoqXG4gKiBDcmVhdGUgYW4gWEhSIGZlYXR1cmUgbG9hZGVyIGZvciBhIGB1cmxgIGFuZCBgZm9ybWF0YC4gVGhlIGZlYXR1cmUgbG9hZGVyXG4gKiBsb2FkcyBmZWF0dXJlcyAod2l0aCBYSFIpLCBwYXJzZXMgdGhlIGZlYXR1cmVzLCBhbmQgYWRkcyB0aGVtIHRvIHRoZVxuICogdmVjdG9yIHNvdXJjZS5cbiAqIEBwYXJhbSB7c3RyaW5nfEZlYXR1cmVVcmxGdW5jdGlvbn0gdXJsIEZlYXR1cmUgVVJMIHNlcnZpY2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZm9ybWF0L0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZm9ybWF0IEZlYXR1cmUgZm9ybWF0LlxuICogQHJldHVybiB7RmVhdHVyZUxvYWRlcn0gVGhlIGZlYXR1cmUgbG9hZGVyLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB4aHIodXJsLCBmb3JtYXQpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtmdW5jdGlvbigpOiB2b2lkPX0gc3VjY2VzcyBTdWNjZXNzXG4gICAqICAgICAgRnVuY3Rpb24gY2FsbGVkIHdoZW4gbG9hZGluZyBzdWNjZWVkZWQuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oKTogdm9pZD19IGZhaWx1cmUgRmFpbHVyZVxuICAgKiAgICAgIEZ1bmN0aW9uIGNhbGxlZCB3aGVuIGxvYWRpbmcgZmFpbGVkLlxuICAgKiBAdGhpcyB7aW1wb3J0KFwiLi9zb3VyY2UvVmVjdG9yXCIpLmRlZmF1bHR9XG4gICAqL1xuICByZXR1cm4gZnVuY3Rpb24gKGV4dGVudCwgcmVzb2x1dGlvbiwgcHJvamVjdGlvbiwgc3VjY2VzcywgZmFpbHVyZSkge1xuICAgIHZhciBzb3VyY2UgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9zb3VyY2UvVmVjdG9yXCIpLmRlZmF1bHR9ICovXG4gICAgdGhpcztcbiAgICBsb2FkRmVhdHVyZXNYaHIodXJsLCBmb3JtYXQsIGV4dGVudCwgcmVzb2x1dGlvbiwgcHJvamVjdGlvbixcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0Pn0gZmVhdHVyZXMgVGhlIGxvYWRlZCBmZWF0dXJlcy5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IGRhdGFQcm9qZWN0aW9uIERhdGFcbiAgICAgKiBwcm9qZWN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChmZWF0dXJlcywgZGF0YVByb2plY3Rpb24pIHtcbiAgICAgIGlmIChzdWNjZXNzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3VjY2VzcyhmZWF0dXJlcyk7XG4gICAgICB9XG5cbiAgICAgIHNvdXJjZS5hZGRGZWF0dXJlcyhmZWF0dXJlcyk7XG4gICAgfSxcbiAgICAvKiBGSVhNRSBoYW5kbGUgZXJyb3IgKi9cbiAgICBmYWlsdXJlID8gZmFpbHVyZSA6IFZPSUQpO1xuICB9O1xufVxuLyoqXG4gKiBTZXR0ZXIgZm9yIHRoZSB3aXRoQ3JlZGVudGlhbHMgY29uZmlndXJhdGlvbiBmb3IgdGhlIFhIUi5cbiAqXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHhocldpdGhDcmVkZW50aWFscyBUaGUgdmFsdWUgb2Ygd2l0aENyZWRlbnRpYWxzIHRvIHNldC5cbiAqIENvbXBhcmUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1hNTEh0dHBSZXF1ZXN0L1xuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRXaXRoQ3JlZGVudGlhbHMoeGhyV2l0aENyZWRlbnRpYWxzKSB7XG4gIHdpdGhDcmVkZW50aWFscyA9IHhocldpdGhDcmVkZW50aWFscztcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvc291cmNlL1ZlY3RvclxuICovXG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuXG5pbXBvcnQgQ29sbGVjdGlvbiBmcm9tICcuLi9Db2xsZWN0aW9uLmpzJztcbmltcG9ydCBDb2xsZWN0aW9uRXZlbnRUeXBlIGZyb20gJy4uL0NvbGxlY3Rpb25FdmVudFR5cGUuanMnO1xuaW1wb3J0IEV2ZW50IGZyb20gJy4uL2V2ZW50cy9FdmVudC5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IE9iamVjdEV2ZW50VHlwZSBmcm9tICcuLi9PYmplY3RFdmVudFR5cGUuanMnO1xuaW1wb3J0IFJCdXNoIGZyb20gJy4uL3N0cnVjdHMvUkJ1c2guanMnO1xuaW1wb3J0IFNvdXJjZSBmcm9tICcuL1NvdXJjZS5qcyc7XG5pbXBvcnQgU291cmNlU3RhdGUgZnJvbSAnLi9TdGF0ZS5qcyc7XG5pbXBvcnQgVmVjdG9yRXZlbnRUeXBlIGZyb20gJy4vVmVjdG9yRXZlbnRUeXBlLmpzJztcbmltcG9ydCB7IFRSVUUsIFZPSUQgfSBmcm9tICcuLi9mdW5jdGlvbnMuanMnO1xuaW1wb3J0IHsgYWxsIGFzIGFsbFN0cmF0ZWd5IH0gZnJvbSAnLi4vbG9hZGluZ3N0cmF0ZWd5LmpzJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uL2Fzc2VydHMuanMnO1xuaW1wb3J0IHsgY29udGFpbnNFeHRlbnQsIGVxdWFscyB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tICcuLi9hcnJheS5qcyc7XG5pbXBvcnQgeyBnZXRVaWQgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IGdldFZhbHVlcywgaXNFbXB0eSB9IGZyb20gJy4uL29iai5qcyc7XG5pbXBvcnQgeyBsaXN0ZW4sIHVubGlzdGVuQnlLZXkgfSBmcm9tICcuLi9ldmVudHMuanMnO1xuaW1wb3J0IHsgeGhyIH0gZnJvbSAnLi4vZmVhdHVyZWxvYWRlci5qcyc7XG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhbiB7QGxpbmsgbW9kdWxlOm9sL2V4dGVudH5FeHRlbnR9IGFuZCBhIHJlc29sdXRpb24gYXMgYXJndW1lbnRzLCBhbmRcbiAqIHJldHVybnMgYW4gYXJyYXkgb2Yge0BsaW5rIG1vZHVsZTpvbC9leHRlbnR+RXh0ZW50fSB3aXRoIHRoZSBleHRlbnRzIHRvIGxvYWQuIFVzdWFsbHkgdGhpc1xuICogaXMgb25lIG9mIHRoZSBzdGFuZGFyZCB7QGxpbmsgbW9kdWxlOm9sL2xvYWRpbmdzdHJhdGVneX0gc3RyYXRlZ2llcy5cbiAqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudCwgbnVtYmVyKTogQXJyYXk8aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudD59IExvYWRpbmdTdHJhdGVneVxuICogQGFwaVxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogRXZlbnRzIGVtaXR0ZWQgYnkge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yfSBpbnN0YW5jZXMgYXJlIGluc3RhbmNlcyBvZiB0aGlzXG4gKiB0eXBlLlxuICogQHRlbXBsYXRlIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IEdlb21ldHJ5XG4gKi9cblxudmFyIFZlY3RvclNvdXJjZUV2ZW50ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFZlY3RvclNvdXJjZUV2ZW50LCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVHlwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+PX0gb3B0X2ZlYXR1cmUgRmVhdHVyZS5cbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pj19IG9wdF9mZWF0dXJlcyBGZWF0dXJlcy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBWZWN0b3JTb3VyY2VFdmVudCh0eXBlLCBvcHRfZmVhdHVyZSwgb3B0X2ZlYXR1cmVzKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdHlwZSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBUaGUgYWRkZWQgb3IgcmVtb3ZlZCBmZWF0dXJlIGZvciB0aGUgYEFEREZFQVRVUkVgIGFuZCBgUkVNT1ZFRkVBVFVSRWAgZXZlbnRzLCBgdW5kZWZpbmVkYCBvdGhlcndpc2UuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT58dW5kZWZpbmVkfVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuXG4gICAgX3RoaXMuZmVhdHVyZSA9IG9wdF9mZWF0dXJlO1xuICAgIC8qKlxuICAgICAqIFRoZSBsb2FkZWQgZmVhdHVyZXMgZm9yIHRoZSBgRkVBVFVSRVNMT0FERURgIGV2ZW50LCBgdW5kZWZpbmVkYCBvdGhlcndpc2UuXG4gICAgICogQHR5cGUge0FycmF5PGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fHVuZGVmaW5lZH1cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgICBfdGhpcy5mZWF0dXJlcyA9IG9wdF9mZWF0dXJlcztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICByZXR1cm4gVmVjdG9yU291cmNlRXZlbnQ7XG59KEV2ZW50KTtcblxuZXhwb3J0IHsgVmVjdG9yU291cmNlRXZlbnQgfTtcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1NvdXJjZS5qc1wiKS5BdHRyaWJ1dGlvbkxpa2V9IFthdHRyaWJ1dGlvbnNdIEF0dHJpYnV0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PnxDb2xsZWN0aW9uPGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdD59IFtmZWF0dXJlc11cbiAqIEZlYXR1cmVzLiBJZiBwcm92aWRlZCBhcyB7QGxpbmsgbW9kdWxlOm9sL0NvbGxlY3Rpb259LCB0aGUgZmVhdHVyZXMgaW4gdGhlIHNvdXJjZVxuICogYW5kIHRoZSBjb2xsZWN0aW9uIHdpbGwgc3RheSBpbiBzeW5jLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9mb3JtYXQvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBbZm9ybWF0XSBUaGUgZmVhdHVyZSBmb3JtYXQgdXNlZCBieSB0aGUgWEhSXG4gKiBmZWF0dXJlIGxvYWRlciB3aGVuIGB1cmxgIGlzIHNldC4gUmVxdWlyZWQgaWYgYHVybGAgaXMgc2V0LCBvdGhlcndpc2UgaWdub3JlZC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZmVhdHVyZWxvYWRlci5qc1wiKS5GZWF0dXJlTG9hZGVyfSBbbG9hZGVyXVxuICogVGhlIGxvYWRlciBmdW5jdGlvbiB1c2VkIHRvIGxvYWQgZmVhdHVyZXMsIGZyb20gYSByZW1vdGUgc291cmNlIGZvciBleGFtcGxlLlxuICogSWYgdGhpcyBpcyBub3Qgc2V0IGFuZCBgdXJsYCBpcyBzZXQsIHRoZSBzb3VyY2Ugd2lsbCBjcmVhdGUgYW5kIHVzZSBhbiBYSFJcbiAqIGZlYXR1cmUgbG9hZGVyLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogYGBganNcbiAqIGltcG9ydCB7VmVjdG9yfSBmcm9tICdvbC9zb3VyY2UnO1xuICogaW1wb3J0IHtHZW9KU09OfSBmcm9tICdvbC9mb3JtYXQnO1xuICogaW1wb3J0IHtiYm94fSBmcm9tICdvbC9sb2FkaW5nc3RyYXRlZ3knO1xuICpcbiAqIHZhciB2ZWN0b3JTb3VyY2UgPSBuZXcgVmVjdG9yKHtcbiAqICAgZm9ybWF0OiBuZXcgR2VvSlNPTigpLFxuICogICBsb2FkZXI6IGZ1bmN0aW9uKGV4dGVudCwgcmVzb2x1dGlvbiwgcHJvamVjdGlvbikge1xuICogICAgICB2YXIgcHJvaiA9IHByb2plY3Rpb24uZ2V0Q29kZSgpO1xuICogICAgICB2YXIgdXJsID0gJ2h0dHBzOi8vYWhvY2V2YXIuY29tL2dlb3NlcnZlci93ZnM/c2VydmljZT1XRlMmJyArXG4gKiAgICAgICAgICAndmVyc2lvbj0xLjEuMCZyZXF1ZXN0PUdldEZlYXR1cmUmdHlwZW5hbWU9b3NtOndhdGVyX2FyZWFzJicgK1xuICogICAgICAgICAgJ291dHB1dEZvcm1hdD1hcHBsaWNhdGlvbi9qc29uJnNyc25hbWU9JyArIHByb2ogKyAnJicgK1xuICogICAgICAgICAgJ2Jib3g9JyArIGV4dGVudC5qb2luKCcsJykgKyAnLCcgKyBwcm9qO1xuICogICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gKiAgICAgIHhoci5vcGVuKCdHRVQnLCB1cmwpO1xuICogICAgICB2YXIgb25FcnJvciA9IGZ1bmN0aW9uKCkge1xuICogICAgICAgIHZlY3RvclNvdXJjZS5yZW1vdmVMb2FkZWRFeHRlbnQoZXh0ZW50KTtcbiAqICAgICAgfVxuICogICAgICB4aHIub25lcnJvciA9IG9uRXJyb3I7XG4gKiAgICAgIHhoci5vbmxvYWQgPSBmdW5jdGlvbigpIHtcbiAqICAgICAgICBpZiAoeGhyLnN0YXR1cyA9PSAyMDApIHtcbiAqICAgICAgICAgIHZlY3RvclNvdXJjZS5hZGRGZWF0dXJlcyhcbiAqICAgICAgICAgICAgICB2ZWN0b3JTb3VyY2UuZ2V0Rm9ybWF0KCkucmVhZEZlYXR1cmVzKHhoci5yZXNwb25zZVRleHQpKTtcbiAqICAgICAgICB9IGVsc2Uge1xuICogICAgICAgICAgb25FcnJvcigpO1xuICogICAgICAgIH1cbiAqICAgICAgfVxuICogICAgICB4aHIuc2VuZCgpO1xuICogICAgfSxcbiAqICAgIHN0cmF0ZWd5OiBiYm94XG4gKiAgfSk7XG4gKiBgYGBcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW292ZXJsYXBzPXRydWVdIFRoaXMgc291cmNlIG1heSBoYXZlIG92ZXJsYXBwaW5nIGdlb21ldHJpZXMuXG4gKiBTZXR0aW5nIHRoaXMgdG8gYGZhbHNlYCAoZS5nLiBmb3Igc291cmNlcyB3aXRoIHBvbHlnb25zIHRoYXQgcmVwcmVzZW50IGFkbWluaXN0cmF0aXZlXG4gKiBib3VuZGFyaWVzIG9yIFRvcG9KU09OIHNvdXJjZXMpIGFsbG93cyB0aGUgcmVuZGVyZXIgdG8gb3B0aW1pc2UgZmlsbCBhbmRcbiAqIHN0cm9rZSBvcGVyYXRpb25zLlxuICogQHByb3BlcnR5IHtMb2FkaW5nU3RyYXRlZ3l9IFtzdHJhdGVneV0gVGhlIGxvYWRpbmcgc3RyYXRlZ3kgdG8gdXNlLlxuICogQnkgZGVmYXVsdCBhbiB7QGxpbmsgbW9kdWxlOm9sL2xvYWRpbmdzdHJhdGVneX5hbGx9XG4gKiBzdHJhdGVneSBpcyB1c2VkLCBhIG9uZS1vZmYgc3RyYXRlZ3kgd2hpY2ggbG9hZHMgYWxsIGZlYXR1cmVzIGF0IG9uY2UuXG4gKiBAcHJvcGVydHkge3N0cmluZ3xpbXBvcnQoXCIuLi9mZWF0dXJlbG9hZGVyLmpzXCIpLkZlYXR1cmVVcmxGdW5jdGlvbn0gW3VybF1cbiAqIFNldHRpbmcgdGhpcyBvcHRpb24gaW5zdHJ1Y3RzIHRoZSBzb3VyY2UgdG8gbG9hZCBmZWF0dXJlcyB1c2luZyBhbiBYSFIgbG9hZGVyXG4gKiAoc2VlIHtAbGluayBtb2R1bGU6b2wvZmVhdHVyZWxvYWRlcn54aHJ9KS4gVXNlIGEgYHN0cmluZ2AgYW5kIGFuXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2xvYWRpbmdzdHJhdGVneX5hbGx9IGZvciBhIG9uZS1vZmYgZG93bmxvYWQgb2YgYWxsIGZlYXR1cmVzIGZyb21cbiAqIHRoZSBnaXZlbiBVUkwuIFVzZSBhIHtAbGluayBtb2R1bGU6b2wvZmVhdHVyZWxvYWRlcn5GZWF0dXJlVXJsRnVuY3Rpb259IHRvIGdlbmVyYXRlIHRoZSB1cmwgd2l0aFxuICogb3RoZXIgbG9hZGluZyBzdHJhdGVnaWVzLlxuICogUmVxdWlyZXMgYGZvcm1hdGAgdG8gYmUgc2V0IGFzIHdlbGwuXG4gKiBXaGVuIGRlZmF1bHQgWEhSIGZlYXR1cmUgbG9hZGVyIGlzIHByb3ZpZGVkLCB0aGUgZmVhdHVyZXMgd2lsbFxuICogYmUgdHJhbnNmb3JtZWQgZnJvbSB0aGUgZGF0YSBwcm9qZWN0aW9uIHRvIHRoZSB2aWV3IHByb2plY3Rpb25cbiAqIGR1cmluZyBwYXJzaW5nLiBJZiB5b3VyIHJlbW90ZSBkYXRhIHNvdXJjZSBkb2VzIG5vdCBhZHZlcnRpc2UgaXRzIHByb2plY3Rpb25cbiAqIHByb3Blcmx5LCB0aGlzIHRyYW5zZm9ybWF0aW9uIHdpbGwgYmUgaW5jb3JyZWN0LiBGb3Igc29tZSBmb3JtYXRzLCB0aGVcbiAqIGRlZmF1bHQgcHJvamVjdGlvbiAodXN1YWxseSBFUFNHOjQzMjYpIGNhbiBiZSBvdmVycmlkZGVuIGJ5IHNldHRpbmcgdGhlXG4gKiBkYXRhUHJvamVjdGlvbiBjb25zdHJ1Y3RvciBvcHRpb24gb24gdGhlIGZvcm1hdC5cbiAqIE5vdGUgdGhhdCBpZiBhIHNvdXJjZSBjb250YWlucyBub24tZmVhdHVyZSBkYXRhLCBzdWNoIGFzIGEgR2VvSlNPTiBnZW9tZXRyeVxuICogb3IgYSBLTUwgTmV0d29ya0xpbmssIHRoZXNlIHdpbGwgYmUgaWdub3JlZC4gVXNlIGEgY3VzdG9tIGxvYWRlciB0byBsb2FkIHRoZXNlLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbdXNlU3BhdGlhbEluZGV4PXRydWVdXG4gKiBCeSBkZWZhdWx0LCBhbiBSVHJlZSBpcyB1c2VkIGFzIHNwYXRpYWwgaW5kZXguIFdoZW4gZmVhdHVyZXMgYXJlIHJlbW92ZWQgYW5kXG4gKiBhZGRlZCBmcmVxdWVudGx5LCBhbmQgdGhlIHRvdGFsIG51bWJlciBvZiBmZWF0dXJlcyBpcyBsb3csIHNldHRpbmcgdGhpcyB0b1xuICogYGZhbHNlYCBtYXkgaW1wcm92ZSBwZXJmb3JtYW5jZS5cbiAqXG4gKiBOb3RlIHRoYXRcbiAqIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn5WZWN0b3JTb3VyY2UjZ2V0RmVhdHVyZXNJbkV4dGVudH0sXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3J+VmVjdG9yU291cmNlI2dldENsb3Nlc3RGZWF0dXJlVG9Db29yZGluYXRlfSBhbmRcbiAqIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn5WZWN0b3JTb3VyY2UjZ2V0RXh0ZW50fSBjYW5ub3QgYmUgdXNlZCB3aGVuIGB1c2VTcGF0aWFsSW5kZXhgIGlzXG4gKiBzZXQgdG8gYGZhbHNlYCwgYW5kIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn5WZWN0b3JTb3VyY2UjZm9yRWFjaEZlYXR1cmVJbkV4dGVudH0gd2lsbCBsb29wXG4gKiB0aHJvdWdoIGFsbCBmZWF0dXJlcy5cbiAqXG4gKiBXaGVuIHNldCB0byBgZmFsc2VgLCB0aGUgZmVhdHVyZXMgd2lsbCBiZSBtYWludGFpbmVkIGluIGFuXG4gKiB7QGxpbmsgbW9kdWxlOm9sL0NvbGxlY3Rpb259LCB3aGljaCBjYW4gYmUgcmV0cmlldmVkIHRocm91Z2hcbiAqIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn5WZWN0b3JTb3VyY2UjZ2V0RmVhdHVyZXNDb2xsZWN0aW9ufS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3dyYXBYPXRydWVdIFdyYXAgdGhlIHdvcmxkIGhvcml6b250YWxseS4gRm9yIHZlY3RvciBlZGl0aW5nIGFjcm9zcyB0aGVcbiAqIC0xODDCsCBhbmQgMTgwwrAgbWVyaWRpYW5zIHRvIHdvcmsgcHJvcGVybHksIHRoaXMgc2hvdWxkIGJlIHNldCB0byBgZmFsc2VgLiBUaGVcbiAqIHJlc3VsdGluZyBnZW9tZXRyeSBjb29yZGluYXRlcyB3aWxsIHRoZW4gZXhjZWVkIHRoZSB3b3JsZCBib3VuZHMuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBQcm92aWRlcyBhIHNvdXJjZSBvZiBmZWF0dXJlcyBmb3IgdmVjdG9yIGxheWVycy4gVmVjdG9yIGZlYXR1cmVzIHByb3ZpZGVkXG4gKiBieSB0aGlzIHNvdXJjZSBhcmUgc3VpdGFibGUgZm9yIGVkaXRpbmcuIFNlZSB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3JUaWxlflZlY3RvclRpbGV9IGZvclxuICogdmVjdG9yIGRhdGEgdGhhdCBpcyBvcHRpbWl6ZWQgZm9yIHJlbmRlcmluZy5cbiAqXG4gKiBAZmlyZXMgVmVjdG9yU291cmNlRXZlbnRcbiAqIEBhcGlcbiAqIEB0ZW1wbGF0ZSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeVxuICovXG5cbnZhciBWZWN0b3JTb3VyY2UgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVmVjdG9yU291cmNlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgVmVjdG9yIHNvdXJjZSBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFZlY3RvclNvdXJjZShvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zIHx8IHt9O1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgYXR0cmlidXRpb25zOiBvcHRpb25zLmF0dHJpYnV0aW9ucyxcbiAgICAgIHByb2plY3Rpb246IHVuZGVmaW5lZCxcbiAgICAgIHN0YXRlOiBTb3VyY2VTdGF0ZS5SRUFEWSxcbiAgICAgIHdyYXBYOiBvcHRpb25zLndyYXBYICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLndyYXBYIDogdHJ1ZVxuICAgIH0pIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZmVhdHVyZWxvYWRlci5qc1wiKS5GZWF0dXJlTG9hZGVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubG9hZGVyXyA9IFZPSUQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZm9ybWF0L0ZlYXR1cmUuanNcIikuZGVmYXVsdHx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5mb3JtYXRfID0gb3B0aW9ucy5mb3JtYXQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLm92ZXJsYXBzXyA9IG9wdGlvbnMub3ZlcmxhcHMgPT09IHVuZGVmaW5lZCA/IHRydWUgOiBvcHRpb25zLm92ZXJsYXBzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ3xpbXBvcnQoXCIuLi9mZWF0dXJlbG9hZGVyLmpzXCIpLkZlYXR1cmVVcmxGdW5jdGlvbnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy51cmxfID0gb3B0aW9ucy51cmw7XG5cbiAgICBpZiAob3B0aW9ucy5sb2FkZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgX3RoaXMubG9hZGVyXyA9IG9wdGlvbnMubG9hZGVyO1xuICAgIH0gZWxzZSBpZiAoX3RoaXMudXJsXyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhc3NlcnQoX3RoaXMuZm9ybWF0XywgNyk7IC8vIGBmb3JtYXRgIG11c3QgYmUgc2V0IHdoZW4gYHVybGAgaXMgc2V0XG4gICAgICAvLyBjcmVhdGUgYSBYSFIgZmVhdHVyZSBsb2FkZXIgZm9yIFwidXJsXCIgYW5kIFwiZm9ybWF0XCJcblxuICAgICAgX3RoaXMubG9hZGVyXyA9IHhocihfdGhpcy51cmxfLFxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9mb3JtYXQvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgX3RoaXMuZm9ybWF0Xyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0xvYWRpbmdTdHJhdGVneX1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuc3RyYXRlZ3lfID0gb3B0aW9ucy5zdHJhdGVneSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zdHJhdGVneSA6IGFsbFN0cmF0ZWd5O1xuICAgIHZhciB1c2VTcGF0aWFsSW5kZXggPSBvcHRpb25zLnVzZVNwYXRpYWxJbmRleCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy51c2VTcGF0aWFsSW5kZXggOiB0cnVlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge1JCdXNoPGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmVhdHVyZXNSdHJlZV8gPSB1c2VTcGF0aWFsSW5kZXggPyBuZXcgUkJ1c2goKSA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7UkJ1c2g8e2V4dGVudDogaW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0+fVxuICAgICAqL1xuXG4gICAgX3RoaXMubG9hZGVkRXh0ZW50c1J0cmVlXyA9IG5ldyBSQnVzaCgpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLm51bGxHZW9tZXRyeUZlYXR1cmVzXyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEEgbG9va3VwIG9mIGZlYXR1cmVzIGJ5IGlkICh0aGUgcmV0dXJuIGZyb20gZmVhdHVyZS5nZXRJZCgpKS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pj59XG4gICAgICovXG5cbiAgICBfdGhpcy5pZEluZGV4XyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEEgbG9va3VwIG9mIGZlYXR1cmVzIGJ5IHVpZCAodXNpbmcgZ2V0VWlkKGZlYXR1cmUpKS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pj59XG4gICAgICovXG5cbiAgICBfdGhpcy51aWRJbmRleF8gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBBcnJheTxpbXBvcnQoXCIuLi9ldmVudHMuanNcIikuRXZlbnRzS2V5Pj59XG4gICAgICovXG5cbiAgICBfdGhpcy5mZWF0dXJlQ2hhbmdlS2V5c18gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtDb2xsZWN0aW9uPGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXyA9IG51bGw7XG4gICAgdmFyIGNvbGxlY3Rpb24sIGZlYXR1cmVzO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkob3B0aW9ucy5mZWF0dXJlcykpIHtcbiAgICAgIGZlYXR1cmVzID0gb3B0aW9ucy5mZWF0dXJlcztcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMuZmVhdHVyZXMpIHtcbiAgICAgIGNvbGxlY3Rpb24gPSBvcHRpb25zLmZlYXR1cmVzO1xuICAgICAgZmVhdHVyZXMgPSBjb2xsZWN0aW9uLmdldEFycmF5KCk7XG4gICAgfVxuXG4gICAgaWYgKCF1c2VTcGF0aWFsSW5kZXggJiYgY29sbGVjdGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb2xsZWN0aW9uID0gbmV3IENvbGxlY3Rpb24oZmVhdHVyZXMpO1xuICAgIH1cblxuICAgIGlmIChmZWF0dXJlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBfdGhpcy5hZGRGZWF0dXJlc0ludGVybmFsKGZlYXR1cmVzKTtcbiAgICB9XG5cbiAgICBpZiAoY29sbGVjdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBfdGhpcy5iaW5kRmVhdHVyZXNDb2xsZWN0aW9uXyhjb2xsZWN0aW9uKTtcbiAgICB9XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEFkZCBhIHNpbmdsZSBmZWF0dXJlIHRvIHRoZSBzb3VyY2UuICBJZiB5b3Ugd2FudCB0byBhZGQgYSBiYXRjaCBvZiBmZWF0dXJlc1xuICAgKiBhdCBvbmNlLCBjYWxsIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn5WZWN0b3JTb3VyY2UjYWRkRmVhdHVyZXMgI2FkZEZlYXR1cmVzKCl9XG4gICAqIGluc3RlYWQuIEEgZmVhdHVyZSB3aWxsIG5vdCBiZSBhZGRlZCB0byB0aGUgc291cmNlIGlmIGZlYXR1cmUgd2l0aFxuICAgKiB0aGUgc2FtZSBpZCBpcyBhbHJlYWR5IHRoZXJlLiBUaGUgcmVhc29uIGZvciB0aGlzIGJlaGF2aW9yIGlzIHRvIGF2b2lkXG4gICAqIGZlYXR1cmUgZHVwbGljYXRpb24gd2hlbiB1c2luZyBiYm94IG9yIHRpbGUgbG9hZGluZyBzdHJhdGVnaWVzLlxuICAgKiBOb3RlOiB0aGlzIGFsc28gYXBwbGllcyBpZiBhbiB7QGxpbmsgbW9kdWxlOm9sL0NvbGxlY3Rpb259IGlzIHVzZWQgZm9yIGZlYXR1cmVzLFxuICAgKiBtZWFuaW5nIHRoYXQgaWYgYSBmZWF0dXJlIHdpdGggYSBkdXBsaWNhdGUgaWQgaXMgYWRkZWQgaW4gdGhlIGNvbGxlY3Rpb24sIGl0IHdpbGxcbiAgICogYmUgcmVtb3ZlZCBmcm9tIGl0IHJpZ2h0IGF3YXkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pn0gZmVhdHVyZSBGZWF0dXJlIHRvIGFkZC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuYWRkRmVhdHVyZSA9IGZ1bmN0aW9uIChmZWF0dXJlKSB7XG4gICAgdGhpcy5hZGRGZWF0dXJlSW50ZXJuYWwoZmVhdHVyZSk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBBZGQgYSBmZWF0dXJlIHdpdGhvdXQgZmlyaW5nIGEgYGNoYW5nZWAgZXZlbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pn0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5hZGRGZWF0dXJlSW50ZXJuYWwgPSBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgIHZhciBmZWF0dXJlS2V5ID0gZ2V0VWlkKGZlYXR1cmUpO1xuXG4gICAgaWYgKCF0aGlzLmFkZFRvSW5kZXhfKGZlYXR1cmVLZXksIGZlYXR1cmUpKSB7XG4gICAgICBpZiAodGhpcy5mZWF0dXJlc0NvbGxlY3Rpb25fKSB7XG4gICAgICAgIHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXy5yZW1vdmUoZmVhdHVyZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldHVwQ2hhbmdlRXZlbnRzXyhmZWF0dXJlS2V5LCBmZWF0dXJlKTtcbiAgICB2YXIgZ2VvbWV0cnkgPSBmZWF0dXJlLmdldEdlb21ldHJ5KCk7XG5cbiAgICBpZiAoZ2VvbWV0cnkpIHtcbiAgICAgIHZhciBleHRlbnQgPSBnZW9tZXRyeS5nZXRFeHRlbnQoKTtcblxuICAgICAgaWYgKHRoaXMuZmVhdHVyZXNSdHJlZV8pIHtcbiAgICAgICAgdGhpcy5mZWF0dXJlc1J0cmVlXy5pbnNlcnQoZXh0ZW50LCBmZWF0dXJlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc19bZmVhdHVyZUtleV0gPSBmZWF0dXJlO1xuICAgIH1cblxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgVmVjdG9yU291cmNlRXZlbnQoVmVjdG9yRXZlbnRUeXBlLkFEREZFQVRVUkUsIGZlYXR1cmUpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmZWF0dXJlS2V5IFVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgZmVhdHVyZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSBmZWF0dXJlIFRoZSBmZWF0dXJlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuc2V0dXBDaGFuZ2VFdmVudHNfID0gZnVuY3Rpb24gKGZlYXR1cmVLZXksIGZlYXR1cmUpIHtcbiAgICB0aGlzLmZlYXR1cmVDaGFuZ2VLZXlzX1tmZWF0dXJlS2V5XSA9IFtsaXN0ZW4oZmVhdHVyZSwgRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5oYW5kbGVGZWF0dXJlQ2hhbmdlXywgdGhpcyksIGxpc3RlbihmZWF0dXJlLCBPYmplY3RFdmVudFR5cGUuUFJPUEVSVFlDSEFOR0UsIHRoaXMuaGFuZGxlRmVhdHVyZUNoYW5nZV8sIHRoaXMpXTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmZWF0dXJlS2V5IFVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgZmVhdHVyZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSBmZWF0dXJlIFRoZSBmZWF0dXJlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaGUgZmVhdHVyZSBpcyBcInZhbGlkXCIsIGluIHRoZSBzZW5zZSB0aGF0IGl0IGlzIGFsc28gYVxuICAgKiAgICAgY2FuZGlkYXRlIGZvciBpbnNlcnRpb24gaW50byB0aGUgUnRyZWUuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5hZGRUb0luZGV4XyA9IGZ1bmN0aW9uIChmZWF0dXJlS2V5LCBmZWF0dXJlKSB7XG4gICAgdmFyIHZhbGlkID0gdHJ1ZTtcbiAgICB2YXIgaWQgPSBmZWF0dXJlLmdldElkKCk7XG5cbiAgICBpZiAoaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKCEoaWQudG9TdHJpbmcoKSBpbiB0aGlzLmlkSW5kZXhfKSkge1xuICAgICAgICB0aGlzLmlkSW5kZXhfW2lkLnRvU3RyaW5nKCldID0gZmVhdHVyZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbGlkID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHZhbGlkKSB7XG4gICAgICBhc3NlcnQoIShmZWF0dXJlS2V5IGluIHRoaXMudWlkSW5kZXhfKSwgMzApOyAvLyBUaGUgcGFzc2VkIGBmZWF0dXJlYCB3YXMgYWxyZWFkeSBhZGRlZCB0byB0aGUgc291cmNlXG5cbiAgICAgIHRoaXMudWlkSW5kZXhfW2ZlYXR1cmVLZXldID0gZmVhdHVyZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsaWQ7XG4gIH07XG4gIC8qKlxuICAgKiBBZGQgYSBiYXRjaCBvZiBmZWF0dXJlcyB0byB0aGUgc291cmNlLlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fSBmZWF0dXJlcyBGZWF0dXJlcyB0byBhZGQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmFkZEZlYXR1cmVzID0gZnVuY3Rpb24gKGZlYXR1cmVzKSB7XG4gICAgdGhpcy5hZGRGZWF0dXJlc0ludGVybmFsKGZlYXR1cmVzKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEFkZCBmZWF0dXJlcyB3aXRob3V0IGZpcmluZyBhIGBjaGFuZ2VgIGV2ZW50LlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fSBmZWF0dXJlcyBGZWF0dXJlcy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuYWRkRmVhdHVyZXNJbnRlcm5hbCA9IGZ1bmN0aW9uIChmZWF0dXJlcykge1xuICAgIHZhciBleHRlbnRzID0gW107XG4gICAgdmFyIG5ld0ZlYXR1cmVzID0gW107XG4gICAgdmFyIGdlb21ldHJ5RmVhdHVyZXMgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGhfMSA9IGZlYXR1cmVzLmxlbmd0aDsgaSA8IGxlbmd0aF8xOyBpKyspIHtcbiAgICAgIHZhciBmZWF0dXJlID0gZmVhdHVyZXNbaV07XG4gICAgICB2YXIgZmVhdHVyZUtleSA9IGdldFVpZChmZWF0dXJlKTtcblxuICAgICAgaWYgKHRoaXMuYWRkVG9JbmRleF8oZmVhdHVyZUtleSwgZmVhdHVyZSkpIHtcbiAgICAgICAgbmV3RmVhdHVyZXMucHVzaChmZWF0dXJlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoXzIgPSBuZXdGZWF0dXJlcy5sZW5ndGg7IGkgPCBsZW5ndGhfMjsgaSsrKSB7XG4gICAgICB2YXIgZmVhdHVyZSA9IG5ld0ZlYXR1cmVzW2ldO1xuICAgICAgdmFyIGZlYXR1cmVLZXkgPSBnZXRVaWQoZmVhdHVyZSk7XG4gICAgICB0aGlzLnNldHVwQ2hhbmdlRXZlbnRzXyhmZWF0dXJlS2V5LCBmZWF0dXJlKTtcbiAgICAgIHZhciBnZW9tZXRyeSA9IGZlYXR1cmUuZ2V0R2VvbWV0cnkoKTtcblxuICAgICAgaWYgKGdlb21ldHJ5KSB7XG4gICAgICAgIHZhciBleHRlbnQgPSBnZW9tZXRyeS5nZXRFeHRlbnQoKTtcbiAgICAgICAgZXh0ZW50cy5wdXNoKGV4dGVudCk7XG4gICAgICAgIGdlb21ldHJ5RmVhdHVyZXMucHVzaChmZWF0dXJlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfW2ZlYXR1cmVLZXldID0gZmVhdHVyZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5mZWF0dXJlc1J0cmVlXykge1xuICAgICAgdGhpcy5mZWF0dXJlc1J0cmVlXy5sb2FkKGV4dGVudHMsIGdlb21ldHJ5RmVhdHVyZXMpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGhfMyA9IG5ld0ZlYXR1cmVzLmxlbmd0aDsgaSA8IGxlbmd0aF8zOyBpKyspIHtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgVmVjdG9yU291cmNlRXZlbnQoVmVjdG9yRXZlbnRUeXBlLkFEREZFQVRVUkUsIG5ld0ZlYXR1cmVzW2ldKSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHshQ29sbGVjdGlvbjxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pn0gY29sbGVjdGlvbiBDb2xsZWN0aW9uLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuYmluZEZlYXR1cmVzQ29sbGVjdGlvbl8gPSBmdW5jdGlvbiAoY29sbGVjdGlvbikge1xuICAgIHZhciBtb2RpZnlpbmdDb2xsZWN0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKFZlY3RvckV2ZW50VHlwZS5BRERGRUFUVVJFLFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVjdG9yU291cmNlRXZlbnQ8R2VvbWV0cnk+fSBldnQgVGhlIHZlY3RvciBzb3VyY2UgZXZlbnRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBpZiAoIW1vZGlmeWluZ0NvbGxlY3Rpb24pIHtcbiAgICAgICAgbW9kaWZ5aW5nQ29sbGVjdGlvbiA9IHRydWU7XG4gICAgICAgIGNvbGxlY3Rpb24ucHVzaChldnQuZmVhdHVyZSk7XG4gICAgICAgIG1vZGlmeWluZ0NvbGxlY3Rpb24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoVmVjdG9yRXZlbnRUeXBlLlJFTU9WRUZFQVRVUkUsXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtWZWN0b3JTb3VyY2VFdmVudDxHZW9tZXRyeT59IGV2dCBUaGUgdmVjdG9yIHNvdXJjZSBldmVudFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChldnQpIHtcbiAgICAgIGlmICghbW9kaWZ5aW5nQ29sbGVjdGlvbikge1xuICAgICAgICBtb2RpZnlpbmdDb2xsZWN0aW9uID0gdHJ1ZTtcbiAgICAgICAgY29sbGVjdGlvbi5yZW1vdmUoZXZ0LmZlYXR1cmUpO1xuICAgICAgICBtb2RpZnlpbmdDb2xsZWN0aW9uID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29sbGVjdGlvbi5hZGRFdmVudExpc3RlbmVyKENvbGxlY3Rpb25FdmVudFR5cGUuQURELFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uRXZlbnR9IGV2dCBUaGUgY29sbGVjdGlvbiBldmVudFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChldnQpIHtcbiAgICAgIGlmICghbW9kaWZ5aW5nQ29sbGVjdGlvbikge1xuICAgICAgICBtb2RpZnlpbmdDb2xsZWN0aW9uID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5hZGRGZWF0dXJlKFxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT59ICovXG4gICAgICAgIGV2dC5lbGVtZW50KTtcbiAgICAgICAgbW9kaWZ5aW5nQ29sbGVjdGlvbiA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0uYmluZCh0aGlzKSk7XG4gICAgY29sbGVjdGlvbi5hZGRFdmVudExpc3RlbmVyKENvbGxlY3Rpb25FdmVudFR5cGUuUkVNT1ZFLFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uRXZlbnR9IGV2dCBUaGUgY29sbGVjdGlvbiBldmVudFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChldnQpIHtcbiAgICAgIGlmICghbW9kaWZ5aW5nQ29sbGVjdGlvbikge1xuICAgICAgICBtb2RpZnlpbmdDb2xsZWN0aW9uID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5yZW1vdmVGZWF0dXJlKFxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT59ICovXG4gICAgICAgIGV2dC5lbGVtZW50KTtcbiAgICAgICAgbW9kaWZ5aW5nQ29sbGVjdGlvbiA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0uYmluZCh0aGlzKSk7XG4gICAgdGhpcy5mZWF0dXJlc0NvbGxlY3Rpb25fID0gY29sbGVjdGlvbjtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSBhbGwgZmVhdHVyZXMgZnJvbSB0aGUgc291cmNlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfZmFzdCBTa2lwIGRpc3BhdGNoaW5nIG9mIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvci5WZWN0b3JTb3VyY2VFdmVudCNyZW1vdmVmZWF0dXJlfSBldmVudHMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKG9wdF9mYXN0KSB7XG4gICAgaWYgKG9wdF9mYXN0KSB7XG4gICAgICBmb3IgKHZhciBmZWF0dXJlSWQgaW4gdGhpcy5mZWF0dXJlQ2hhbmdlS2V5c18pIHtcbiAgICAgICAgdmFyIGtleXMgPSB0aGlzLmZlYXR1cmVDaGFuZ2VLZXlzX1tmZWF0dXJlSWRdO1xuICAgICAgICBrZXlzLmZvckVhY2godW5saXN0ZW5CeUtleSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5mZWF0dXJlc0NvbGxlY3Rpb25fKSB7XG4gICAgICAgIHRoaXMuZmVhdHVyZUNoYW5nZUtleXNfID0ge307XG4gICAgICAgIHRoaXMuaWRJbmRleF8gPSB7fTtcbiAgICAgICAgdGhpcy51aWRJbmRleF8gPSB7fTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuZmVhdHVyZXNSdHJlZV8pIHtcbiAgICAgICAgdGhpcy5mZWF0dXJlc1J0cmVlXy5mb3JFYWNoKHRoaXMucmVtb3ZlRmVhdHVyZUludGVybmFsLmJpbmQodGhpcykpO1xuXG4gICAgICAgIGZvciAodmFyIGlkIGluIHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVGZWF0dXJlSW50ZXJuYWwodGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc19baWRdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl8pIHtcbiAgICAgIHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXy5jbGVhcigpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmZlYXR1cmVzUnRyZWVfKSB7XG4gICAgICB0aGlzLmZlYXR1cmVzUnRyZWVfLmNsZWFyKCk7XG4gICAgfVxuXG4gICAgdGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc18gPSB7fTtcbiAgICB2YXIgY2xlYXJFdmVudCA9IG5ldyBWZWN0b3JTb3VyY2VFdmVudChWZWN0b3JFdmVudFR5cGUuQ0xFQVIpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChjbGVhckV2ZW50KTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEl0ZXJhdGUgdGhyb3VnaCBhbGwgZmVhdHVyZXMgb24gdGhlIHNvdXJjZSwgY2FsbGluZyB0aGUgcHJvdmlkZWQgY2FsbGJhY2tcbiAgICogd2l0aCBlYWNoIG9uZS4gIElmIHRoZSBjYWxsYmFjayByZXR1cm5zIGFueSBcInRydXRoeVwiIHZhbHVlLCBpdGVyYXRpb24gd2lsbFxuICAgKiBzdG9wIGFuZCB0aGUgZnVuY3Rpb24gd2lsbCByZXR1cm4gdGhlIHNhbWUgdmFsdWUuXG4gICAqIE5vdGU6IHRoaXMgZnVuY3Rpb24gb25seSBpdGVyYXRlIHRocm91Z2ggdGhlIGZlYXR1cmUgdGhhdCBoYXZlIGEgZGVmaW5lZCBnZW9tZXRyeS5cbiAgICpcbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+KTogVH0gY2FsbGJhY2sgQ2FsbGVkIHdpdGggZWFjaCBmZWF0dXJlXG4gICAqICAgICBvbiB0aGUgc291cmNlLiAgUmV0dXJuIGEgdHJ1dGh5IHZhbHVlIHRvIHN0b3AgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gVGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBsYXN0IGNhbGwgdG8gdGhlIGNhbGxiYWNrLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5mb3JFYWNoRmVhdHVyZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLmZlYXR1cmVzUnRyZWVfKSB7XG4gICAgICByZXR1cm4gdGhpcy5mZWF0dXJlc1J0cmVlXy5mb3JFYWNoKGNhbGxiYWNrKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXykge1xuICAgICAgdGhpcy5mZWF0dXJlc0NvbGxlY3Rpb25fLmZvckVhY2goY2FsbGJhY2spO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEl0ZXJhdGUgdGhyb3VnaCBhbGwgZmVhdHVyZXMgd2hvc2UgZ2VvbWV0cmllcyBjb250YWluIHRoZSBwcm92aWRlZFxuICAgKiBjb29yZGluYXRlLCBjYWxsaW5nIHRoZSBjYWxsYmFjayB3aXRoIGVhY2ggZmVhdHVyZS4gIElmIHRoZSBjYWxsYmFjayByZXR1cm5zXG4gICAqIGEgXCJ0cnV0aHlcIiB2YWx1ZSwgaXRlcmF0aW9uIHdpbGwgc3RvcCBhbmQgdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHRoZSBzYW1lXG4gICAqIHZhbHVlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4pOiBUfSBjYWxsYmFjayBDYWxsZWQgd2l0aCBlYWNoIGZlYXR1cmVcbiAgICogICAgIHdob3NlIGdvZW1ldHJ5IGNvbnRhaW5zIHRoZSBwcm92aWRlZCBjb29yZGluYXRlLlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gVGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBsYXN0IGNhbGwgdG8gdGhlIGNhbGxiYWNrLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGVEaXJlY3QgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgZXh0ZW50ID0gW2Nvb3JkaW5hdGVbMF0sIGNvb3JkaW5hdGVbMV0sIGNvb3JkaW5hdGVbMF0sIGNvb3JkaW5hdGVbMV1dO1xuICAgIHJldHVybiB0aGlzLmZvckVhY2hGZWF0dXJlSW5FeHRlbnQoZXh0ZW50LCBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgICAgdmFyIGdlb21ldHJ5ID0gZmVhdHVyZS5nZXRHZW9tZXRyeSgpO1xuXG4gICAgICBpZiAoZ2VvbWV0cnkuaW50ZXJzZWN0c0Nvb3JkaW5hdGUoY29vcmRpbmF0ZSkpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGZlYXR1cmUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbiAgLyoqXG4gICAqIEl0ZXJhdGUgdGhyb3VnaCBhbGwgZmVhdHVyZXMgd2hvc2UgYm91bmRpbmcgYm94IGludGVyc2VjdHMgdGhlIHByb3ZpZGVkXG4gICAqIGV4dGVudCAobm90ZSB0aGF0IHRoZSBmZWF0dXJlJ3MgZ2VvbWV0cnkgbWF5IG5vdCBpbnRlcnNlY3QgdGhlIGV4dGVudCksXG4gICAqIGNhbGxpbmcgdGhlIGNhbGxiYWNrIHdpdGggZWFjaCBmZWF0dXJlLiAgSWYgdGhlIGNhbGxiYWNrIHJldHVybnMgYSBcInRydXRoeVwiXG4gICAqIHZhbHVlLCBpdGVyYXRpb24gd2lsbCBzdG9wIGFuZCB0aGUgZnVuY3Rpb24gd2lsbCByZXR1cm4gdGhlIHNhbWUgdmFsdWUuXG4gICAqXG4gICAqIElmIHlvdSBhcmUgaW50ZXJlc3RlZCBpbiBmZWF0dXJlcyB3aG9zZSBnZW9tZXRyeSBpbnRlcnNlY3RzIGFuIGV4dGVudCwgY2FsbFxuICAgKiB0aGUge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yflZlY3RvclNvdXJjZSNmb3JFYWNoRmVhdHVyZUludGVyc2VjdGluZ0V4dGVudCAjZm9yRWFjaEZlYXR1cmVJbnRlcnNlY3RpbmdFeHRlbnQoKX0gbWV0aG9kIGluc3RlYWQuXG4gICAqXG4gICAqIFdoZW4gYHVzZVNwYXRpYWxJbmRleGAgaXMgc2V0IHRvIGZhbHNlLCB0aGlzIG1ldGhvZCB3aWxsIGxvb3AgdGhyb3VnaCBhbGxcbiAgICogZmVhdHVyZXMsIGVxdWl2YWxlbnQgdG8ge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yflZlY3RvclNvdXJjZSNmb3JFYWNoRmVhdHVyZSAjZm9yRWFjaEZlYXR1cmUoKX0uXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+KTogVH0gY2FsbGJhY2sgQ2FsbGVkIHdpdGggZWFjaCBmZWF0dXJlXG4gICAqICAgICB3aG9zZSBib3VuZGluZyBib3ggaW50ZXJzZWN0cyB0aGUgcHJvdmlkZWQgZXh0ZW50LlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gVGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBsYXN0IGNhbGwgdG8gdGhlIGNhbGxiYWNrLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5mb3JFYWNoRmVhdHVyZUluRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCwgY2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy5mZWF0dXJlc1J0cmVlXykge1xuICAgICAgcmV0dXJuIHRoaXMuZmVhdHVyZXNSdHJlZV8uZm9yRWFjaEluRXh0ZW50KGV4dGVudCwgY2FsbGJhY2spO1xuICAgIH0gZWxzZSBpZiAodGhpcy5mZWF0dXJlc0NvbGxlY3Rpb25fKSB7XG4gICAgICB0aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl8uZm9yRWFjaChjYWxsYmFjayk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogSXRlcmF0ZSB0aHJvdWdoIGFsbCBmZWF0dXJlcyB3aG9zZSBnZW9tZXRyeSBpbnRlcnNlY3RzIHRoZSBwcm92aWRlZCBleHRlbnQsXG4gICAqIGNhbGxpbmcgdGhlIGNhbGxiYWNrIHdpdGggZWFjaCBmZWF0dXJlLiAgSWYgdGhlIGNhbGxiYWNrIHJldHVybnMgYSBcInRydXRoeVwiXG4gICAqIHZhbHVlLCBpdGVyYXRpb24gd2lsbCBzdG9wIGFuZCB0aGUgZnVuY3Rpb24gd2lsbCByZXR1cm4gdGhlIHNhbWUgdmFsdWUuXG4gICAqXG4gICAqIElmIHlvdSBvbmx5IHdhbnQgdG8gdGVzdCBmb3IgYm91bmRpbmcgYm94IGludGVyc2VjdGlvbiwgY2FsbCB0aGVcbiAgICoge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yflZlY3RvclNvdXJjZSNmb3JFYWNoRmVhdHVyZUluRXh0ZW50ICNmb3JFYWNoRmVhdHVyZUluRXh0ZW50KCl9IG1ldGhvZCBpbnN0ZWFkLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pik6IFR9IGNhbGxiYWNrIENhbGxlZCB3aXRoIGVhY2ggZmVhdHVyZVxuICAgKiAgICAgd2hvc2UgZ2VvbWV0cnkgaW50ZXJzZWN0cyB0aGUgcHJvdmlkZWQgZXh0ZW50LlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gVGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBsYXN0IGNhbGwgdG8gdGhlIGNhbGxiYWNrLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5mb3JFYWNoRmVhdHVyZUludGVyc2VjdGluZ0V4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHRoaXMuZm9yRWFjaEZlYXR1cmVJbkV4dGVudChleHRlbnQsXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbGFzdCBjYWxsIHRvIHRoZSBjYWxsYmFjay5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgICAgdmFyIGdlb21ldHJ5ID0gZmVhdHVyZS5nZXRHZW9tZXRyeSgpO1xuXG4gICAgICBpZiAoZ2VvbWV0cnkuaW50ZXJzZWN0c0V4dGVudChleHRlbnQpKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjYWxsYmFjayhmZWF0dXJlKTtcblxuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBmZWF0dXJlcyBjb2xsZWN0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNvdXJjZS4gV2lsbCBiZSBgbnVsbGBcbiAgICogdW5sZXNzIHRoZSBzb3VyY2Ugd2FzIGNvbmZpZ3VyZWQgd2l0aCBgdXNlU3BhdGlhbEluZGV4YCBzZXQgdG8gYGZhbHNlYCwgb3JcbiAgICogd2l0aCBhbiB7QGxpbmsgbW9kdWxlOm9sL0NvbGxlY3Rpb259IGFzIGBmZWF0dXJlc2AuXG4gICAqIEByZXR1cm4ge0NvbGxlY3Rpb248aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pj59IFRoZSBjb2xsZWN0aW9uIG9mIGZlYXR1cmVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5nZXRGZWF0dXJlc0NvbGxlY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhbGwgZmVhdHVyZXMgb24gdGhlIHNvdXJjZSBpbiByYW5kb20gb3JkZXIuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fSBGZWF0dXJlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZ2V0RmVhdHVyZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGZlYXR1cmVzO1xuXG4gICAgaWYgKHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXykge1xuICAgICAgZmVhdHVyZXMgPSB0aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl8uZ2V0QXJyYXkoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZmVhdHVyZXNSdHJlZV8pIHtcbiAgICAgIGZlYXR1cmVzID0gdGhpcy5mZWF0dXJlc1J0cmVlXy5nZXRBbGwoKTtcblxuICAgICAgaWYgKCFpc0VtcHR5KHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfKSkge1xuICAgICAgICBleHRlbmQoZmVhdHVyZXMsIGdldFZhbHVlcyh0aGlzLm51bGxHZW9tZXRyeUZlYXR1cmVzXykpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge0FycmF5PGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fSAqL1xuICAgICAgZmVhdHVyZXNcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogR2V0IGFsbCBmZWF0dXJlcyB3aG9zZSBnZW9tZXRyeSBpbnRlcnNlY3RzIHRoZSBwcm92aWRlZCBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pn0gRmVhdHVyZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmdldEZlYXR1cmVzQXRDb29yZGluYXRlID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUpIHtcbiAgICB2YXIgZmVhdHVyZXMgPSBbXTtcbiAgICB0aGlzLmZvckVhY2hGZWF0dXJlQXRDb29yZGluYXRlRGlyZWN0KGNvb3JkaW5hdGUsIGZ1bmN0aW9uIChmZWF0dXJlKSB7XG4gICAgICBmZWF0dXJlcy5wdXNoKGZlYXR1cmUpO1xuICAgIH0pO1xuICAgIHJldHVybiBmZWF0dXJlcztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhbGwgZmVhdHVyZXMgd2hvc2UgYm91bmRpbmcgYm94IGludGVyc2VjdHMgdGhlIHByb3ZpZGVkIGV4dGVudC4gIE5vdGUgdGhhdCB0aGlzIHJldHVybnMgYW4gYXJyYXkgb2ZcbiAgICogYWxsIGZlYXR1cmVzIGludGVyc2VjdGluZyB0aGUgZ2l2ZW4gZXh0ZW50IGluIHJhbmRvbSBvcmRlciAoc28gaXQgbWF5IGluY2x1ZGVcbiAgICogZmVhdHVyZXMgd2hvc2UgZ2VvbWV0cmllcyBkbyBub3QgaW50ZXJzZWN0IHRoZSBleHRlbnQpLlxuICAgKlxuICAgKiBXaGVuIGB1c2VTcGF0aWFsSW5kZXhgIGlzIHNldCB0byBmYWxzZSwgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gYWxsXG4gICAqIGZlYXR1cmVzLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fSBGZWF0dXJlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZ2V0RmVhdHVyZXNJbkV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICBpZiAodGhpcy5mZWF0dXJlc1J0cmVlXykge1xuICAgICAgcmV0dXJuIHRoaXMuZmVhdHVyZXNSdHJlZV8uZ2V0SW5FeHRlbnQoZXh0ZW50KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXykge1xuICAgICAgcmV0dXJuIHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXy5nZXRBcnJheSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBjbG9zZXN0IGZlYXR1cmUgdG8gdGhlIHByb3ZpZGVkIGNvb3JkaW5hdGUuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGlzIG5vdCBhdmFpbGFibGUgd2hlbiB0aGUgc291cmNlIGlzIGNvbmZpZ3VyZWQgd2l0aFxuICAgKiBgdXNlU3BhdGlhbEluZGV4YCBzZXQgdG8gYGZhbHNlYC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+KTpib29sZWFuPX0gb3B0X2ZpbHRlciBGZWF0dXJlIGZpbHRlciBmdW5jdGlvbi5cbiAgICogICAgIFRoZSBmaWx0ZXIgZnVuY3Rpb24gd2lsbCByZWNlaXZlIG9uZSBhcmd1bWVudCwgdGhlIHtAbGluayBtb2R1bGU6b2wvRmVhdHVyZSBmZWF0dXJlfVxuICAgKiAgICAgYW5kIGl0IHNob3VsZCByZXR1cm4gYSBib29sZWFuIHZhbHVlLiBCeSBkZWZhdWx0LCBubyBmaWx0ZXJpbmcgaXMgbWFkZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pn0gQ2xvc2VzdCBmZWF0dXJlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5nZXRDbG9zZXN0RmVhdHVyZVRvQ29vcmRpbmF0ZSA9IGZ1bmN0aW9uIChjb29yZGluYXRlLCBvcHRfZmlsdGVyKSB7XG4gICAgLy8gRmluZCB0aGUgY2xvc2VzdCBmZWF0dXJlIHVzaW5nIGJyYW5jaCBhbmQgYm91bmQuICBXZSBzdGFydCBzZWFyY2hpbmcgYW5cbiAgICAvLyBpbmZpbml0ZSBleHRlbnQsIGFuZCBmaW5kIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBmaXJzdCBmZWF0dXJlIGZvdW5kLiAgVGhpc1xuICAgIC8vIGJlY29tZXMgdGhlIGNsb3Nlc3QgZmVhdHVyZS4gIFdlIHRoZW4gY29tcHV0ZSBhIHNtYWxsZXIgZXh0ZW50IHdoaWNoIGFueVxuICAgIC8vIGNsb3NlciBmZWF0dXJlIG11c3QgaW50ZXJzZWN0LiAgV2UgY29udGludWUgc2VhcmNoaW5nIHdpdGggdGhpcyBzbWFsbGVyXG4gICAgLy8gZXh0ZW50LCB0cnlpbmcgdG8gZmluZCBhIGNsb3NlciBmZWF0dXJlLiAgRXZlcnkgdGltZSB3ZSBmaW5kIGEgY2xvc2VyXG4gICAgLy8gZmVhdHVyZSwgd2UgdXBkYXRlIHRoZSBleHRlbnQgYmVpbmcgc2VhcmNoZWQgc28gdGhhdCBhbnkgZXZlbiBjbG9zZXJcbiAgICAvLyBmZWF0dXJlIG11c3QgaW50ZXJzZWN0IGl0LiAgV2UgY29udGludWUgdW50aWwgd2UgcnVuIG91dCBvZiBmZWF0dXJlcy5cbiAgICB2YXIgeCA9IGNvb3JkaW5hdGVbMF07XG4gICAgdmFyIHkgPSBjb29yZGluYXRlWzFdO1xuICAgIHZhciBjbG9zZXN0RmVhdHVyZSA9IG51bGw7XG4gICAgdmFyIGNsb3Nlc3RQb2ludCA9IFtOYU4sIE5hTl07XG4gICAgdmFyIG1pblNxdWFyZWREaXN0YW5jZSA9IEluZmluaXR5O1xuICAgIHZhciBleHRlbnQgPSBbLUluZmluaXR5LCAtSW5maW5pdHksIEluZmluaXR5LCBJbmZpbml0eV07XG4gICAgdmFyIGZpbHRlciA9IG9wdF9maWx0ZXIgPyBvcHRfZmlsdGVyIDogVFJVRTtcbiAgICB0aGlzLmZlYXR1cmVzUnRyZWVfLmZvckVhY2hJbkV4dGVudChleHRlbnQsXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gKGZlYXR1cmUpIHtcbiAgICAgIGlmIChmaWx0ZXIoZmVhdHVyZSkpIHtcbiAgICAgICAgdmFyIGdlb21ldHJ5ID0gZmVhdHVyZS5nZXRHZW9tZXRyeSgpO1xuICAgICAgICB2YXIgcHJldmlvdXNNaW5TcXVhcmVkRGlzdGFuY2UgPSBtaW5TcXVhcmVkRGlzdGFuY2U7XG4gICAgICAgIG1pblNxdWFyZWREaXN0YW5jZSA9IGdlb21ldHJ5LmNsb3Nlc3RQb2ludFhZKHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKTtcblxuICAgICAgICBpZiAobWluU3F1YXJlZERpc3RhbmNlIDwgcHJldmlvdXNNaW5TcXVhcmVkRGlzdGFuY2UpIHtcbiAgICAgICAgICBjbG9zZXN0RmVhdHVyZSA9IGZlYXR1cmU7IC8vIFRoaXMgaXMgc25lYWt5LiAgUmVkdWNlIHRoZSBleHRlbnQgdGhhdCBpdCBpcyBjdXJyZW50bHkgYmVpbmdcbiAgICAgICAgICAvLyBzZWFyY2hlZCB3aGlsZSB0aGUgUi1UcmVlIHRyYXZlcnNhbCB1c2luZyB0aGlzIHNhbWUgZXh0ZW50IG9iamVjdFxuICAgICAgICAgIC8vIGlzIHN0aWxsIGluIHByb2dyZXNzLiAgVGhpcyBpcyBzYWZlIGJlY2F1c2UgdGhlIG5ldyBleHRlbnQgaXNcbiAgICAgICAgICAvLyBzdHJpY3RseSBjb250YWluZWQgYnkgdGhlIG9sZCBleHRlbnQuXG5cbiAgICAgICAgICB2YXIgbWluRGlzdGFuY2UgPSBNYXRoLnNxcnQobWluU3F1YXJlZERpc3RhbmNlKTtcbiAgICAgICAgICBleHRlbnRbMF0gPSB4IC0gbWluRGlzdGFuY2U7XG4gICAgICAgICAgZXh0ZW50WzFdID0geSAtIG1pbkRpc3RhbmNlO1xuICAgICAgICAgIGV4dGVudFsyXSA9IHggKyBtaW5EaXN0YW5jZTtcbiAgICAgICAgICBleHRlbnRbM10gPSB5ICsgbWluRGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvc2VzdEZlYXR1cmU7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGV4dGVudCBvZiB0aGUgZmVhdHVyZXMgY3VycmVudGx5IGluIHRoZSBzb3VyY2UuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGlzIG5vdCBhdmFpbGFibGUgd2hlbiB0aGUgc291cmNlIGlzIGNvbmZpZ3VyZWQgd2l0aFxuICAgKiBgdXNlU3BhdGlhbEluZGV4YCBzZXQgdG8gYGZhbHNlYC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50PX0gb3B0X2V4dGVudCBEZXN0aW5hdGlvbiBleHRlbnQuIElmIHByb3ZpZGVkLCBubyBuZXcgZXh0ZW50XG4gICAqICAgICB3aWxsIGJlIGNyZWF0ZWQuIEluc3RlYWQsIHRoYXQgZXh0ZW50J3MgY29vcmRpbmF0ZXMgd2lsbCBiZSBvdmVyd3JpdHRlbi5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5nZXRFeHRlbnQgPSBmdW5jdGlvbiAob3B0X2V4dGVudCkge1xuICAgIHJldHVybiB0aGlzLmZlYXR1cmVzUnRyZWVfLmdldEV4dGVudChvcHRfZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhIGZlYXR1cmUgYnkgaXRzIGlkZW50aWZpZXIgKHRoZSB2YWx1ZSByZXR1cm5lZCBieSBmZWF0dXJlLmdldElkKCkpLlxuICAgKiBOb3RlIHRoYXQgdGhlIGluZGV4IHRyZWF0cyBzdHJpbmcgYW5kIG51bWVyaWMgaWRlbnRpZmllcnMgYXMgdGhlIHNhbWUuICBTb1xuICAgKiBgc291cmNlLmdldEZlYXR1cmVCeUlkKDIpYCB3aWxsIHJldHVybiBhIGZlYXR1cmUgd2l0aCBpZCBgJzInYCBvciBgMmAuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgRmVhdHVyZSBpZGVudGlmaWVyLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSBUaGUgZmVhdHVyZSAob3IgYG51bGxgIGlmIG5vdCBmb3VuZCkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmdldEZlYXR1cmVCeUlkID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgdmFyIGZlYXR1cmUgPSB0aGlzLmlkSW5kZXhfW2lkLnRvU3RyaW5nKCldO1xuICAgIHJldHVybiBmZWF0dXJlICE9PSB1bmRlZmluZWQgPyBmZWF0dXJlIDogbnVsbDtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhIGZlYXR1cmUgYnkgaXRzIGludGVybmFsIHVuaXF1ZSBpZGVudGlmaWVyICh1c2luZyBgZ2V0VWlkYCkuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1aWQgRmVhdHVyZSBpZGVudGlmaWVyLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSBUaGUgZmVhdHVyZSAob3IgYG51bGxgIGlmIG5vdCBmb3VuZCkuXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5nZXRGZWF0dXJlQnlVaWQgPSBmdW5jdGlvbiAodWlkKSB7XG4gICAgdmFyIGZlYXR1cmUgPSB0aGlzLnVpZEluZGV4X1t1aWRdO1xuICAgIHJldHVybiBmZWF0dXJlICE9PSB1bmRlZmluZWQgPyBmZWF0dXJlIDogbnVsbDtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZm9ybWF0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNvdXJjZS5cbiAgICpcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZm9ybWF0L0ZlYXR1cmUuanNcIikuZGVmYXVsdHx1bmRlZmluZWR9IFRoZSBmZWF0dXJlIGZvcm1hdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZ2V0Rm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZvcm1hdF87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaGUgc291cmNlIGNhbiBoYXZlIG92ZXJsYXBwaW5nIGdlb21ldHJpZXMuXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5nZXRPdmVybGFwcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5vdmVybGFwc187XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHVybCBhc3NvY2lhdGVkIHdpdGggdGhpcyBzb3VyY2UuXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZ3xpbXBvcnQoXCIuLi9mZWF0dXJlbG9hZGVyLmpzXCIpLkZlYXR1cmVVcmxGdW5jdGlvbnx1bmRlZmluZWR9IFRoZSB1cmwuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmdldFVybCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy51cmxfO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtFdmVudH0gZXZlbnQgRXZlbnQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5oYW5kbGVGZWF0dXJlQ2hhbmdlXyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHZhciBmZWF0dXJlID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT59ICovXG4gICAgZXZlbnQudGFyZ2V0O1xuICAgIHZhciBmZWF0dXJlS2V5ID0gZ2V0VWlkKGZlYXR1cmUpO1xuICAgIHZhciBnZW9tZXRyeSA9IGZlYXR1cmUuZ2V0R2VvbWV0cnkoKTtcblxuICAgIGlmICghZ2VvbWV0cnkpIHtcbiAgICAgIGlmICghKGZlYXR1cmVLZXkgaW4gdGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc18pKSB7XG4gICAgICAgIGlmICh0aGlzLmZlYXR1cmVzUnRyZWVfKSB7XG4gICAgICAgICAgdGhpcy5mZWF0dXJlc1J0cmVlXy5yZW1vdmUoZmVhdHVyZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm51bGxHZW9tZXRyeUZlYXR1cmVzX1tmZWF0dXJlS2V5XSA9IGZlYXR1cmU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBleHRlbnQgPSBnZW9tZXRyeS5nZXRFeHRlbnQoKTtcblxuICAgICAgaWYgKGZlYXR1cmVLZXkgaW4gdGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc18pIHtcbiAgICAgICAgZGVsZXRlIHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfW2ZlYXR1cmVLZXldO1xuXG4gICAgICAgIGlmICh0aGlzLmZlYXR1cmVzUnRyZWVfKSB7XG4gICAgICAgICAgdGhpcy5mZWF0dXJlc1J0cmVlXy5pbnNlcnQoZXh0ZW50LCBmZWF0dXJlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuZmVhdHVyZXNSdHJlZV8pIHtcbiAgICAgICAgICB0aGlzLmZlYXR1cmVzUnRyZWVfLnVwZGF0ZShleHRlbnQsIGZlYXR1cmUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGlkID0gZmVhdHVyZS5nZXRJZCgpO1xuXG4gICAgaWYgKGlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciBzaWQgPSBpZC50b1N0cmluZygpO1xuXG4gICAgICBpZiAodGhpcy5pZEluZGV4X1tzaWRdICE9PSBmZWF0dXJlKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlRnJvbUlkSW5kZXhfKGZlYXR1cmUpO1xuICAgICAgICB0aGlzLmlkSW5kZXhfW3NpZF0gPSBmZWF0dXJlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbW92ZUZyb21JZEluZGV4XyhmZWF0dXJlKTtcbiAgICAgIHRoaXMudWlkSW5kZXhfW2ZlYXR1cmVLZXldID0gZmVhdHVyZTtcbiAgICB9XG5cbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IFZlY3RvclNvdXJjZUV2ZW50KFZlY3RvckV2ZW50VHlwZS5DSEFOR0VGRUFUVVJFLCBmZWF0dXJlKSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZlYXR1cmUgaXMgY29udGFpbmVkIHdpdGhpbiB0aGUgc291cmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT59IGZlYXR1cmUgRmVhdHVyZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSGFzIGZlYXR1cmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmhhc0ZlYXR1cmUgPSBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgIHZhciBpZCA9IGZlYXR1cmUuZ2V0SWQoKTtcblxuICAgIGlmIChpZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gaWQgaW4gdGhpcy5pZEluZGV4XztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGdldFVpZChmZWF0dXJlKSBpbiB0aGlzLnVpZEluZGV4XztcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJcyBlbXB0eS5cbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmVhdHVyZXNSdHJlZV8uaXNFbXB0eSgpICYmIGlzRW1wdHkodGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc18pO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5sb2FkRmVhdHVyZXMgPSBmdW5jdGlvbiAoZXh0ZW50LCByZXNvbHV0aW9uLCBwcm9qZWN0aW9uKSB7XG4gICAgdmFyIGxvYWRlZEV4dGVudHNSdHJlZSA9IHRoaXMubG9hZGVkRXh0ZW50c1J0cmVlXztcbiAgICB2YXIgZXh0ZW50c1RvTG9hZCA9IHRoaXMuc3RyYXRlZ3lfKGV4dGVudCwgcmVzb2x1dGlvbik7XG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG5cbiAgICB2YXIgX2xvb3BfMSA9IGZ1bmN0aW9uIF9sb29wXzEoaSwgaWkpIHtcbiAgICAgIHZhciBleHRlbnRUb0xvYWQgPSBleHRlbnRzVG9Mb2FkW2ldO1xuICAgICAgdmFyIGFscmVhZHlMb2FkZWQgPSBsb2FkZWRFeHRlbnRzUnRyZWUuZm9yRWFjaEluRXh0ZW50KGV4dGVudFRvTG9hZCxcbiAgICAgIC8qKlxuICAgICAgICogQHBhcmFtIHt7ZXh0ZW50OiBpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fX0gb2JqZWN0IE9iamVjdC5cbiAgICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IENvbnRhaW5zLlxuICAgICAgICovXG4gICAgICBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBjb250YWluc0V4dGVudChvYmplY3QuZXh0ZW50LCBleHRlbnRUb0xvYWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGlmICghYWxyZWFkeUxvYWRlZCkge1xuICAgICAgICB0aGlzXzEuZGlzcGF0Y2hFdmVudChuZXcgVmVjdG9yU291cmNlRXZlbnQoVmVjdG9yRXZlbnRUeXBlLkZFQVRVUkVTTE9BRFNUQVJUKSk7XG4gICAgICAgIHRoaXNfMS5sb2FkZXJfLmNhbGwodGhpc18xLCBleHRlbnRUb0xvYWQsIHJlc29sdXRpb24sIHByb2plY3Rpb24sIGZ1bmN0aW9uIChmZWF0dXJlcykge1xuICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgVmVjdG9yU291cmNlRXZlbnQoVmVjdG9yRXZlbnRUeXBlLkZFQVRVUkVTTE9BREVORCwgdW5kZWZpbmVkLCBmZWF0dXJlcykpO1xuICAgICAgICB9LmJpbmQodGhpc18xKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgVmVjdG9yU291cmNlRXZlbnQoVmVjdG9yRXZlbnRUeXBlLkZFQVRVUkVTTE9BREVSUk9SKSk7XG4gICAgICAgIH0uYmluZCh0aGlzXzEpKTtcbiAgICAgICAgbG9hZGVkRXh0ZW50c1J0cmVlLmluc2VydChleHRlbnRUb0xvYWQsIHtcbiAgICAgICAgICBleHRlbnQ6IGV4dGVudFRvTG9hZC5zbGljZSgpXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzXzEubG9hZGluZyA9IHRoaXNfMS5sb2FkZXJfICE9PSBWT0lEO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgdGhpc18xID0gdGhpcztcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGV4dGVudHNUb0xvYWQubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgX2xvb3BfMShpLCBpaSk7XG4gICAgfVxuICB9O1xuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUucmVmcmVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmNsZWFyKHRydWUpO1xuICAgIHRoaXMubG9hZGVkRXh0ZW50c1J0cmVlXy5jbGVhcigpO1xuXG4gICAgX3N1cGVyLnByb3RvdHlwZS5yZWZyZXNoLmNhbGwodGhpcyk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgYW4gZXh0ZW50IGZyb20gdGhlIGxpc3Qgb2YgbG9hZGVkIGV4dGVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUucmVtb3ZlTG9hZGVkRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCkge1xuICAgIHZhciBsb2FkZWRFeHRlbnRzUnRyZWUgPSB0aGlzLmxvYWRlZEV4dGVudHNSdHJlZV87XG4gICAgdmFyIG9iajtcbiAgICBsb2FkZWRFeHRlbnRzUnRyZWUuZm9yRWFjaEluRXh0ZW50KGV4dGVudCwgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgICAgaWYgKGVxdWFscyhvYmplY3QuZXh0ZW50LCBleHRlbnQpKSB7XG4gICAgICAgIG9iaiA9IG9iamVjdDtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAob2JqKSB7XG4gICAgICBsb2FkZWRFeHRlbnRzUnRyZWUucmVtb3ZlKG9iaik7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIGEgc2luZ2xlIGZlYXR1cmUgZnJvbSB0aGUgc291cmNlLiAgSWYgeW91IHdhbnQgdG8gcmVtb3ZlIGFsbCBmZWF0dXJlc1xuICAgKiBhdCBvbmNlLCB1c2UgdGhlIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn5WZWN0b3JTb3VyY2UjY2xlYXIgI2NsZWFyKCl9IG1ldGhvZFxuICAgKiBpbnN0ZWFkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT59IGZlYXR1cmUgRmVhdHVyZSB0byByZW1vdmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLnJlbW92ZUZlYXR1cmUgPSBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgIHZhciBmZWF0dXJlS2V5ID0gZ2V0VWlkKGZlYXR1cmUpO1xuXG4gICAgaWYgKGZlYXR1cmVLZXkgaW4gdGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc18pIHtcbiAgICAgIGRlbGV0ZSB0aGlzLm51bGxHZW9tZXRyeUZlYXR1cmVzX1tmZWF0dXJlS2V5XTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuZmVhdHVyZXNSdHJlZV8pIHtcbiAgICAgICAgdGhpcy5mZWF0dXJlc1J0cmVlXy5yZW1vdmUoZmVhdHVyZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5yZW1vdmVGZWF0dXJlSW50ZXJuYWwoZmVhdHVyZSk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgZmVhdHVyZSB3aXRob3V0IGZpcmluZyBhIGBjaGFuZ2VgIGV2ZW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT59IGZlYXR1cmUgRmVhdHVyZS5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUucmVtb3ZlRmVhdHVyZUludGVybmFsID0gZnVuY3Rpb24gKGZlYXR1cmUpIHtcbiAgICB2YXIgZmVhdHVyZUtleSA9IGdldFVpZChmZWF0dXJlKTtcbiAgICB0aGlzLmZlYXR1cmVDaGFuZ2VLZXlzX1tmZWF0dXJlS2V5XS5mb3JFYWNoKHVubGlzdGVuQnlLZXkpO1xuICAgIGRlbGV0ZSB0aGlzLmZlYXR1cmVDaGFuZ2VLZXlzX1tmZWF0dXJlS2V5XTtcbiAgICB2YXIgaWQgPSBmZWF0dXJlLmdldElkKCk7XG5cbiAgICBpZiAoaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZGVsZXRlIHRoaXMuaWRJbmRleF9baWQudG9TdHJpbmcoKV07XG4gICAgfVxuXG4gICAgZGVsZXRlIHRoaXMudWlkSW5kZXhfW2ZlYXR1cmVLZXldO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgVmVjdG9yU291cmNlRXZlbnQoVmVjdG9yRXZlbnRUeXBlLlJFTU9WRUZFQVRVUkUsIGZlYXR1cmUpKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSBhIGZlYXR1cmUgZnJvbSB0aGUgaWQgaW5kZXguICBDYWxsZWQgaW50ZXJuYWxseSB3aGVuIHRoZSBmZWF0dXJlIGlkXG4gICAqIG1heSBoYXZlIGNoYW5nZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pn0gZmVhdHVyZSBUaGUgZmVhdHVyZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gUmVtb3ZlZCB0aGUgZmVhdHVyZSBmcm9tIHRoZSBpbmRleC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLnJlbW92ZUZyb21JZEluZGV4XyA9IGZ1bmN0aW9uIChmZWF0dXJlKSB7XG4gICAgdmFyIHJlbW92ZWQgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGlkIGluIHRoaXMuaWRJbmRleF8pIHtcbiAgICAgIGlmICh0aGlzLmlkSW5kZXhfW2lkXSA9PT0gZmVhdHVyZSkge1xuICAgICAgICBkZWxldGUgdGhpcy5pZEluZGV4X1tpZF07XG4gICAgICAgIHJlbW92ZWQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVtb3ZlZDtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgbmV3IGxvYWRlciBvZiB0aGUgc291cmNlLiBUaGUgbmV4dCByZW5kZXIgY3ljbGUgd2lsbCB1c2UgdGhlXG4gICAqIG5ldyBsb2FkZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZmVhdHVyZWxvYWRlci5qc1wiKS5GZWF0dXJlTG9hZGVyfSBsb2FkZXIgVGhlIGxvYWRlciB0byBzZXQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLnNldExvYWRlciA9IGZ1bmN0aW9uIChsb2FkZXIpIHtcbiAgICB0aGlzLmxvYWRlcl8gPSBsb2FkZXI7XG4gIH07XG4gIC8qKlxuICAgKiBQb2ludHMgdGhlIHNvdXJjZSB0byBhIG5ldyB1cmwuIFRoZSBuZXh0IHJlbmRlciBjeWNsZSB3aWxsIHVzZSB0aGUgbmV3IHVybC5cbiAgICogQHBhcmFtIHtzdHJpbmd8aW1wb3J0KFwiLi4vZmVhdHVyZWxvYWRlci5qc1wiKS5GZWF0dXJlVXJsRnVuY3Rpb259IHVybCBVcmwuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLnNldFVybCA9IGZ1bmN0aW9uICh1cmwpIHtcbiAgICBhc3NlcnQodGhpcy5mb3JtYXRfLCA3KTsgLy8gYGZvcm1hdGAgbXVzdCBiZSBzZXQgd2hlbiBgdXJsYCBpcyBzZXRcblxuICAgIHRoaXMuc2V0TG9hZGVyKHhocih1cmwsIHRoaXMuZm9ybWF0XykpO1xuICB9O1xuXG4gIHJldHVybiBWZWN0b3JTb3VyY2U7XG59KFNvdXJjZSk7XG5cbmV4cG9ydCBkZWZhdWx0IFZlY3RvclNvdXJjZTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB2YXIgbWFwQ29udGFpbmVyID0gXCJtYXAtbW9kdWxlLS1tYXBDb250YWluZXItLTN6Qml1XCI7XG5leHBvcnQgdmFyIHBvcHVwQ29udGFpbmVyID0gXCJtYXAtbW9kdWxlLS1wb3B1cENvbnRhaW5lci0tMktFOGhcIjtcbmV4cG9ydCB2YXIgcG9wdXBDbG9zZXIgPSBcIm1hcC1tb2R1bGUtLXBvcHVwQ2xvc2VyLS01WHdVWFwiOyIsIi8qKlxuICogQG1vZHVsZSBvbC9sYXllci9UaWxlUHJvcGVydHlcbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgUFJFTE9BRDogJ3ByZWxvYWQnLFxuICBVU0VfSU5URVJJTV9USUxFU19PTl9FUlJPUjogJ3VzZUludGVyaW1UaWxlc09uRXJyb3InXG59OyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvbGF5ZXIvQmFzZVRpbGVcbiAqL1xuXG5cbmltcG9ydCBMYXllciBmcm9tICcuL0xheWVyLmpzJztcbmltcG9ydCBUaWxlUHJvcGVydHkgZnJvbSAnLi9UaWxlUHJvcGVydHkuanMnO1xuaW1wb3J0IHsgYXNzaWduIH0gZnJvbSAnLi4vb2JqLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjbGFzc05hbWU9J29sLWxheWVyJ10gQSBDU1MgY2xhc3MgbmFtZSB0byBzZXQgdG8gdGhlIGxheWVyIGVsZW1lbnQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW29wYWNpdHk9MV0gT3BhY2l0eSAoMCwgMSkuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt2aXNpYmxlPXRydWVdIFZpc2liaWxpdHkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IFtleHRlbnRdIFRoZSBib3VuZGluZyBleHRlbnQgZm9yIGxheWVyIHJlbmRlcmluZy4gIFRoZSBsYXllciB3aWxsIG5vdCBiZVxuICogcmVuZGVyZWQgb3V0c2lkZSBvZiB0aGlzIGV4dGVudC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbekluZGV4XSBUaGUgei1pbmRleCBmb3IgbGF5ZXIgcmVuZGVyaW5nLiAgQXQgcmVuZGVyaW5nIHRpbWUsIHRoZSBsYXllcnNcbiAqIHdpbGwgYmUgb3JkZXJlZCwgZmlyc3QgYnkgWi1pbmRleCBhbmQgdGhlbiBieSBwb3NpdGlvbi4gV2hlbiBgdW5kZWZpbmVkYCwgYSBgekluZGV4YCBvZiAwIGlzIGFzc3VtZWRcbiAqIGZvciBsYXllcnMgdGhhdCBhcmUgYWRkZWQgdG8gdGhlIG1hcCdzIGBsYXllcnNgIGNvbGxlY3Rpb24sIG9yIGBJbmZpbml0eWAgd2hlbiB0aGUgbGF5ZXIncyBgc2V0TWFwKClgXG4gKiBtZXRob2Qgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblJlc29sdXRpb25dIFRoZSBtaW5pbXVtIHJlc29sdXRpb24gKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhSZXNvbHV0aW9uXSBUaGUgbWF4aW11bSByZXNvbHV0aW9uIChleGNsdXNpdmUpIGJlbG93IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluWm9vbV0gVGhlIG1pbmltdW0gdmlldyB6b29tIGxldmVsIChleGNsdXNpdmUpIGFib3ZlIHdoaWNoIHRoaXMgbGF5ZXIgd2lsbCBiZVxuICogdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4Wm9vbV0gVGhlIG1heGltdW0gdmlldyB6b29tIGxldmVsIChpbmNsdXNpdmUpIGF0IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcHJlbG9hZD0wXSBQcmVsb2FkLiBMb2FkIGxvdy1yZXNvbHV0aW9uIHRpbGVzIHVwIHRvIGBwcmVsb2FkYCBsZXZlbHMuIGAwYFxuICogbWVhbnMgbm8gcHJlbG9hZGluZy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc291cmNlL1RpbGUuanNcIikuZGVmYXVsdH0gW3NvdXJjZV0gU291cmNlIGZvciB0aGlzIGxheWVyLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gW21hcF0gU2V0cyB0aGUgbGF5ZXIgYXMgb3ZlcmxheSBvbiBhIG1hcC4gVGhlIG1hcCB3aWxsIG5vdCBtYW5hZ2VcbiAqIHRoaXMgbGF5ZXIgaW4gaXRzIGxheWVycyBjb2xsZWN0aW9uLCBhbmQgdGhlIGxheWVyIHdpbGwgYmUgcmVuZGVyZWQgb24gdG9wLiBUaGlzIGlzIHVzZWZ1bCBmb3JcbiAqIHRlbXBvcmFyeSBsYXllcnMuIFRoZSBzdGFuZGFyZCB3YXkgdG8gYWRkIGEgbGF5ZXIgdG8gYSBtYXAgYW5kIGhhdmUgaXQgbWFuYWdlZCBieSB0aGUgbWFwIGlzIHRvXG4gKiB1c2Uge0BsaW5rIG1vZHVsZTpvbC9NYXAjYWRkTGF5ZXJ9LlxuICogQHByb3BlcnR5IHtib29sZWFufSBbdXNlSW50ZXJpbVRpbGVzT25FcnJvcj10cnVlXSBVc2UgaW50ZXJpbSB0aWxlcyBvbiBlcnJvci5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEZvciBsYXllciBzb3VyY2VzIHRoYXQgcHJvdmlkZSBwcmUtcmVuZGVyZWQsIHRpbGVkIGltYWdlcyBpbiBncmlkcyB0aGF0IGFyZVxuICogb3JnYW5pemVkIGJ5IHpvb20gbGV2ZWxzIGZvciBzcGVjaWZpYyByZXNvbHV0aW9ucy5cbiAqIE5vdGUgdGhhdCBhbnkgcHJvcGVydHkgc2V0IGluIHRoZSBvcHRpb25zIGlzIHNldCBhcyBhIHtAbGluayBtb2R1bGU6b2wvT2JqZWN0fkJhc2VPYmplY3R9XG4gKiBwcm9wZXJ0eSBvbiB0aGUgbGF5ZXIgb2JqZWN0OyBmb3IgZXhhbXBsZSwgc2V0dGluZyBgdGl0bGU6ICdNeSBUaXRsZSdgIGluIHRoZVxuICogb3B0aW9ucyBtZWFucyB0aGF0IGB0aXRsZWAgaXMgb2JzZXJ2YWJsZSwgYW5kIGhhcyBnZXQvc2V0IGFjY2Vzc29ycy5cbiAqXG4gKiBAZXh0ZW5kcyB7TGF5ZXI8aW1wb3J0KFwiLi4vc291cmNlL1RpbGUuanNcIikuZGVmYXVsdD59XG4gKiBAYXBpXG4gKi9cblxudmFyIEJhc2VUaWxlTGF5ZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQmFzZVRpbGVMYXllciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIFRpbGUgbGF5ZXIgb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBCYXNlVGlsZUxheWVyKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIHZhciBiYXNlT3B0aW9ucyA9IGFzc2lnbih7fSwgb3B0aW9ucyk7XG4gICAgZGVsZXRlIGJhc2VPcHRpb25zLnByZWxvYWQ7XG4gICAgZGVsZXRlIGJhc2VPcHRpb25zLnVzZUludGVyaW1UaWxlc09uRXJyb3I7XG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBiYXNlT3B0aW9ucykgfHwgdGhpcztcblxuICAgIF90aGlzLnNldFByZWxvYWQob3B0aW9ucy5wcmVsb2FkICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnByZWxvYWQgOiAwKTtcblxuICAgIF90aGlzLnNldFVzZUludGVyaW1UaWxlc09uRXJyb3Iob3B0aW9ucy51c2VJbnRlcmltVGlsZXNPbkVycm9yICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnVzZUludGVyaW1UaWxlc09uRXJyb3IgOiB0cnVlKTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogUmV0dXJuIHRoZSBsZXZlbCBhcyBudW1iZXIgdG8gd2hpY2ggd2Ugd2lsbCBwcmVsb2FkIHRpbGVzIHVwIHRvLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBsZXZlbCB0byBwcmVsb2FkIHRpbGVzIHVwIHRvLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZVRpbGVMYXllci5wcm90b3R5cGUuZ2V0UHJlbG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICB0aGlzLmdldChUaWxlUHJvcGVydHkuUFJFTE9BRClcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBsZXZlbCBhcyBudW1iZXIgdG8gd2hpY2ggd2Ugd2lsbCBwcmVsb2FkIHRpbGVzIHVwIHRvLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcHJlbG9hZCBUaGUgbGV2ZWwgdG8gcHJlbG9hZCB0aWxlcyB1cCB0by5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VUaWxlTGF5ZXIucHJvdG90eXBlLnNldFByZWxvYWQgPSBmdW5jdGlvbiAocHJlbG9hZCkge1xuICAgIHRoaXMuc2V0KFRpbGVQcm9wZXJ0eS5QUkVMT0FELCBwcmVsb2FkKTtcbiAgfTtcbiAgLyoqXG4gICAqIFdoZXRoZXIgd2UgdXNlIGludGVyaW0gdGlsZXMgb24gZXJyb3IuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFVzZSBpbnRlcmltIHRpbGVzIG9uIGVycm9yLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZVRpbGVMYXllci5wcm90b3R5cGUuZ2V0VXNlSW50ZXJpbVRpbGVzT25FcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtib29sZWFufSAqL1xuICAgICAgdGhpcy5nZXQoVGlsZVByb3BlcnR5LlVTRV9JTlRFUklNX1RJTEVTX09OX0VSUk9SKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgd2hldGhlciB3ZSB1c2UgaW50ZXJpbSB0aWxlcyBvbiBlcnJvci5cbiAgICogQHBhcmFtIHtib29sZWFufSB1c2VJbnRlcmltVGlsZXNPbkVycm9yIFVzZSBpbnRlcmltIHRpbGVzIG9uIGVycm9yLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZVRpbGVMYXllci5wcm90b3R5cGUuc2V0VXNlSW50ZXJpbVRpbGVzT25FcnJvciA9IGZ1bmN0aW9uICh1c2VJbnRlcmltVGlsZXNPbkVycm9yKSB7XG4gICAgdGhpcy5zZXQoVGlsZVByb3BlcnR5LlVTRV9JTlRFUklNX1RJTEVTX09OX0VSUk9SLCB1c2VJbnRlcmltVGlsZXNPbkVycm9yKTtcbiAgfTtcblxuICByZXR1cm4gQmFzZVRpbGVMYXllcjtcbn0oTGF5ZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBCYXNlVGlsZUxheWVyOyIsIi8qKlxuICogQG1vZHVsZSBvbC9UaWxlUmFuZ2VcbiAqL1xuXG4vKipcbiAqIEEgcmVwcmVzZW50YXRpb24gb2YgYSBjb250aWd1b3VzIGJsb2NrIG9mIHRpbGVzLiAgQSB0aWxlIHJhbmdlIGlzIHNwZWNpZmllZFxuICogYnkgaXRzIG1pbi9tYXggdGlsZSBjb29yZGluYXRlcyBhbmQgaXMgaW5jbHVzaXZlIG9mIGNvb3JkaW5hdGVzLlxuICovXG52YXIgVGlsZVJhbmdlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtaW5YIE1pbmltdW0gWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1heFggTWF4aW11bSBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWluWSBNaW5pbXVtIFkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhZIE1heGltdW0gWS5cbiAgICovXG4gIGZ1bmN0aW9uIFRpbGVSYW5nZShtaW5YLCBtYXhYLCBtaW5ZLCBtYXhZKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLm1pblggPSBtaW5YO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLm1heFggPSBtYXhYO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLm1pblkgPSBtaW5ZO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLm1heFkgPSBtYXhZO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMgdGlsZSBjb29yZGluYXRlLlxuICAgKi9cblxuXG4gIFRpbGVSYW5nZS5wcm90b3R5cGUuY29udGFpbnMgPSBmdW5jdGlvbiAodGlsZUNvb3JkKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbnNYWSh0aWxlQ29vcmRbMV0sIHRpbGVDb29yZFsyXSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge1RpbGVSYW5nZX0gdGlsZVJhbmdlIFRpbGUgcmFuZ2UuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IENvbnRhaW5zLlxuICAgKi9cblxuXG4gIFRpbGVSYW5nZS5wcm90b3R5cGUuY29udGFpbnNUaWxlUmFuZ2UgPSBmdW5jdGlvbiAodGlsZVJhbmdlKSB7XG4gICAgcmV0dXJuIHRoaXMubWluWCA8PSB0aWxlUmFuZ2UubWluWCAmJiB0aWxlUmFuZ2UubWF4WCA8PSB0aGlzLm1heFggJiYgdGhpcy5taW5ZIDw9IHRpbGVSYW5nZS5taW5ZICYmIHRpbGVSYW5nZS5tYXhZIDw9IHRoaXMubWF4WTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFRpbGUgY29vcmRpbmF0ZSB4LlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBUaWxlIGNvb3JkaW5hdGUgeS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMgY29vcmRpbmF0ZS5cbiAgICovXG5cblxuICBUaWxlUmFuZ2UucHJvdG90eXBlLmNvbnRhaW5zWFkgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIHJldHVybiB0aGlzLm1pblggPD0geCAmJiB4IDw9IHRoaXMubWF4WCAmJiB0aGlzLm1pblkgPD0geSAmJiB5IDw9IHRoaXMubWF4WTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7VGlsZVJhbmdlfSB0aWxlUmFuZ2UgVGlsZSByYW5nZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gRXF1YWxzLlxuICAgKi9cblxuXG4gIFRpbGVSYW5nZS5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKHRpbGVSYW5nZSkge1xuICAgIHJldHVybiB0aGlzLm1pblggPT0gdGlsZVJhbmdlLm1pblggJiYgdGhpcy5taW5ZID09IHRpbGVSYW5nZS5taW5ZICYmIHRoaXMubWF4WCA9PSB0aWxlUmFuZ2UubWF4WCAmJiB0aGlzLm1heFkgPT0gdGlsZVJhbmdlLm1heFk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge1RpbGVSYW5nZX0gdGlsZVJhbmdlIFRpbGUgcmFuZ2UuXG4gICAqL1xuXG5cbiAgVGlsZVJhbmdlLnByb3RvdHlwZS5leHRlbmQgPSBmdW5jdGlvbiAodGlsZVJhbmdlKSB7XG4gICAgaWYgKHRpbGVSYW5nZS5taW5YIDwgdGhpcy5taW5YKSB7XG4gICAgICB0aGlzLm1pblggPSB0aWxlUmFuZ2UubWluWDtcbiAgICB9XG5cbiAgICBpZiAodGlsZVJhbmdlLm1heFggPiB0aGlzLm1heFgpIHtcbiAgICAgIHRoaXMubWF4WCA9IHRpbGVSYW5nZS5tYXhYO1xuICAgIH1cblxuICAgIGlmICh0aWxlUmFuZ2UubWluWSA8IHRoaXMubWluWSkge1xuICAgICAgdGhpcy5taW5ZID0gdGlsZVJhbmdlLm1pblk7XG4gICAgfVxuXG4gICAgaWYgKHRpbGVSYW5nZS5tYXhZID4gdGhpcy5tYXhZKSB7XG4gICAgICB0aGlzLm1heFkgPSB0aWxlUmFuZ2UubWF4WTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEhlaWdodC5cbiAgICovXG5cblxuICBUaWxlUmFuZ2UucHJvdG90eXBlLmdldEhlaWdodCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5tYXhZIC0gdGhpcy5taW5ZICsgMTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBTaXplLlxuICAgKi9cblxuXG4gIFRpbGVSYW5nZS5wcm90b3R5cGUuZ2V0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gW3RoaXMuZ2V0V2lkdGgoKSwgdGhpcy5nZXRIZWlnaHQoKV07XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFdpZHRoLlxuICAgKi9cblxuXG4gIFRpbGVSYW5nZS5wcm90b3R5cGUuZ2V0V2lkdGggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubWF4WCAtIHRoaXMubWluWCArIDE7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge1RpbGVSYW5nZX0gdGlsZVJhbmdlIFRpbGUgcmFuZ2UuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IEludGVyc2VjdHMuXG4gICAqL1xuXG5cbiAgVGlsZVJhbmdlLnByb3RvdHlwZS5pbnRlcnNlY3RzID0gZnVuY3Rpb24gKHRpbGVSYW5nZSkge1xuICAgIHJldHVybiB0aGlzLm1pblggPD0gdGlsZVJhbmdlLm1heFggJiYgdGhpcy5tYXhYID49IHRpbGVSYW5nZS5taW5YICYmIHRoaXMubWluWSA8PSB0aWxlUmFuZ2UubWF4WSAmJiB0aGlzLm1heFkgPj0gdGlsZVJhbmdlLm1pblk7XG4gIH07XG5cbiAgcmV0dXJuIFRpbGVSYW5nZTtcbn0oKTtcbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG1pblggTWluaW11bSBYLlxuICogQHBhcmFtIHtudW1iZXJ9IG1heFggTWF4aW11bSBYLlxuICogQHBhcmFtIHtudW1iZXJ9IG1pblkgTWluaW11bSBZLlxuICogQHBhcmFtIHtudW1iZXJ9IG1heFkgTWF4aW11bSBZLlxuICogQHBhcmFtIHtUaWxlUmFuZ2U9fSB0aWxlUmFuZ2UgVGlsZVJhbmdlLlxuICogQHJldHVybiB7VGlsZVJhbmdlfSBUaWxlIHJhbmdlLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlKG1pblgsIG1heFgsIG1pblksIG1heFksIHRpbGVSYW5nZSkge1xuICBpZiAodGlsZVJhbmdlICE9PSB1bmRlZmluZWQpIHtcbiAgICB0aWxlUmFuZ2UubWluWCA9IG1pblg7XG4gICAgdGlsZVJhbmdlLm1heFggPSBtYXhYO1xuICAgIHRpbGVSYW5nZS5taW5ZID0gbWluWTtcbiAgICB0aWxlUmFuZ2UubWF4WSA9IG1heFk7XG4gICAgcmV0dXJuIHRpbGVSYW5nZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IFRpbGVSYW5nZShtaW5YLCBtYXhYLCBtaW5ZLCBtYXhZKTtcbiAgfVxufVxuZXhwb3J0IGRlZmF1bHQgVGlsZVJhbmdlOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyZXIvY2FudmFzL1RpbGVMYXllclxuICovXG5cblxuaW1wb3J0IENhbnZhc0xheWVyUmVuZGVyZXIgZnJvbSAnLi9MYXllci5qcyc7XG5pbXBvcnQgVGlsZVJhbmdlIGZyb20gJy4uLy4uL1RpbGVSYW5nZS5qcyc7XG5pbXBvcnQgVGlsZVN0YXRlIGZyb20gJy4uLy4uL1RpbGVTdGF0ZS5qcyc7XG5pbXBvcnQgeyBhcHBseSBhcyBhcHBseVRyYW5zZm9ybSwgY29tcG9zZSBhcyBjb21wb3NlVHJhbnNmb3JtLCBtYWtlSW52ZXJzZSB9IGZyb20gJy4uLy4uL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICcuLi8uLi9vYmouanMnO1xuaW1wb3J0IHsgY3JlYXRlRW1wdHksIGVxdWFscywgZ2V0SW50ZXJzZWN0aW9uLCBnZXRUb3BMZWZ0IH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGNyZWF0ZVRyYW5zZm9ybVN0cmluZyB9IGZyb20gJy4uLy4uL3JlbmRlci9jYW52YXMuanMnO1xuaW1wb3J0IHsgZnJvbVVzZXJFeHRlbnQgfSBmcm9tICcuLi8uLi9wcm9qLmpzJztcbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJy4uLy4uL3V0aWwuanMnO1xuaW1wb3J0IHsgbnVtYmVyU2FmZUNvbXBhcmVGdW5jdGlvbiB9IGZyb20gJy4uLy4uL2FycmF5LmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQ2FudmFzIHJlbmRlcmVyIGZvciB0aWxlIGxheWVycy5cbiAqIEBhcGlcbiAqL1xuXG52YXIgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2xheWVyL1RpbGUuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi8uLi9sYXllci9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGVMYXllciBUaWxlIGxheWVyLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIENhbnZhc1RpbGVMYXllclJlbmRlcmVyKHRpbGVMYXllcikge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHRpbGVMYXllcikgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBSZW5kZXJlZCBleHRlbnQgaGFzIGNoYW5nZWQgc2luY2UgdGhlIHByZXZpb3VzIGByZW5kZXJGcmFtZSgpYCBjYWxsXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cblxuICAgIF90aGlzLmV4dGVudENoYW5nZWQgPSB0cnVlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRFeHRlbnRfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkUGl4ZWxSYXRpbztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRQcm9qZWN0aW9uID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkUmV2aXNpb247XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHshQXJyYXk8aW1wb3J0KFwiLi4vLi4vVGlsZS5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkVGlsZXMgPSBbXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMubmV3VGlsZXNfID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMudG1wRXh0ZW50ID0gY3JlYXRlRW1wdHkoKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnRtcFRpbGVSYW5nZV8gPSBuZXcgVGlsZVJhbmdlKDAsIDAsIDAsIDApO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1RpbGUuanNcIikuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaWxlIGlzIGRyYXdhYmxlLlxuICAgKi9cblxuXG4gIENhbnZhc1RpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5pc0RyYXdhYmxlVGlsZSA9IGZ1bmN0aW9uICh0aWxlKSB7XG4gICAgdmFyIHRpbGVMYXllciA9IHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICB2YXIgdGlsZVN0YXRlID0gdGlsZS5nZXRTdGF0ZSgpO1xuICAgIHZhciB1c2VJbnRlcmltVGlsZXNPbkVycm9yID0gdGlsZUxheWVyLmdldFVzZUludGVyaW1UaWxlc09uRXJyb3IoKTtcbiAgICByZXR1cm4gdGlsZVN0YXRlID09IFRpbGVTdGF0ZS5MT0FERUQgfHwgdGlsZVN0YXRlID09IFRpbGVTdGF0ZS5FTVBUWSB8fCB0aWxlU3RhdGUgPT0gVGlsZVN0YXRlLkVSUk9SICYmICF1c2VJbnRlcmltVGlsZXNPbkVycm9yO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHogVGlsZSBjb29yZGluYXRlIHouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFRpbGUgY29vcmRpbmF0ZSB4LlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBUaWxlIGNvb3JkaW5hdGUgeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uLy4uL1RpbGUuanNcIikuZGVmYXVsdH0gVGlsZS5cbiAgICovXG5cblxuICBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0VGlsZSA9IGZ1bmN0aW9uICh6LCB4LCB5LCBmcmFtZVN0YXRlKSB7XG4gICAgdmFyIHBpeGVsUmF0aW8gPSBmcmFtZVN0YXRlLnBpeGVsUmF0aW87XG4gICAgdmFyIHByb2plY3Rpb24gPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZS5wcm9qZWN0aW9uO1xuICAgIHZhciB0aWxlTGF5ZXIgPSB0aGlzLmdldExheWVyKCk7XG4gICAgdmFyIHRpbGVTb3VyY2UgPSB0aWxlTGF5ZXIuZ2V0U291cmNlKCk7XG4gICAgdmFyIHRpbGUgPSB0aWxlU291cmNlLmdldFRpbGUoeiwgeCwgeSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbik7XG5cbiAgICBpZiAodGlsZS5nZXRTdGF0ZSgpID09IFRpbGVTdGF0ZS5FUlJPUikge1xuICAgICAgaWYgKCF0aWxlTGF5ZXIuZ2V0VXNlSW50ZXJpbVRpbGVzT25FcnJvcigpKSB7XG4gICAgICAgIC8vIFdoZW4gdXNlSW50ZXJpbVRpbGVzT25FcnJvciBpcyBmYWxzZSwgd2UgY29uc2lkZXIgdGhlIGVycm9yIHRpbGUgYXMgbG9hZGVkLlxuICAgICAgICB0aWxlLnNldFN0YXRlKFRpbGVTdGF0ZS5MT0FERUQpO1xuICAgICAgfSBlbHNlIGlmICh0aWxlTGF5ZXIuZ2V0UHJlbG9hZCgpID4gMCkge1xuICAgICAgICAvLyBQcmVsb2FkZWQgdGlsZXMgZm9yIGxvd2VyIHJlc29sdXRpb25zIG1pZ2h0IGhhdmUgZmluaXNoZWQgbG9hZGluZy5cbiAgICAgICAgdGhpcy5uZXdUaWxlc18gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGhpcy5pc0RyYXdhYmxlVGlsZSh0aWxlKSkge1xuICAgICAgdGlsZSA9IHRpbGUuZ2V0SW50ZXJpbVRpbGUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGlsZTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0PG51bWJlciwgT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vLi4vVGlsZS5qc1wiKS5kZWZhdWx0Pj59IHRpbGVzIExvb2t1cCBvZiBsb2FkZWQgdGlsZXMgYnkgem9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHpvb20gWm9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9UaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVGlsZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbnx2b2lkfSBJZiBgZmFsc2VgLCB0aGUgdGlsZSB3aWxsIG5vdCBiZSBjb25zaWRlcmVkIGxvYWRlZC5cbiAgICovXG5cblxuICBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUubG9hZGVkVGlsZUNhbGxiYWNrID0gZnVuY3Rpb24gKHRpbGVzLCB6b29tLCB0aWxlKSB7XG4gICAgaWYgKHRoaXMuaXNEcmF3YWJsZVRpbGUodGlsZSkpIHtcbiAgICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLmxvYWRlZFRpbGVDYWxsYmFjay5jYWxsKHRoaXMsIHRpbGVzLCB6b29tLCB0aWxlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgd2hldGhlciByZW5kZXIgc2hvdWxkIGJlIGNhbGxlZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gTGF5ZXIgaXMgcmVhZHkgdG8gYmUgcmVuZGVyZWQuXG4gICAqL1xuXG5cbiAgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLnByZXBhcmVGcmFtZSA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgcmV0dXJuICEhdGhpcy5nZXRMYXllcigpLmdldFNvdXJjZSgpO1xuICB9O1xuICAvKipcbiAgICogUmVuZGVyIHRoZSBsYXllci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gdGFyZ2V0IFRhcmdldCB0aGF0IG1heSBiZSB1c2VkIHRvIHJlbmRlciBjb250ZW50IHRvLlxuICAgKiBAcmV0dXJuIHtIVE1MRWxlbWVudH0gVGhlIHJlbmRlcmVkIGVsZW1lbnQuXG4gICAqL1xuXG5cbiAgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLnJlbmRlckZyYW1lID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUsIHRhcmdldCkge1xuICAgIHZhciBsYXllclN0YXRlID0gZnJhbWVTdGF0ZS5sYXllclN0YXRlc0FycmF5W2ZyYW1lU3RhdGUubGF5ZXJJbmRleF07XG4gICAgdmFyIHZpZXdTdGF0ZSA9IGZyYW1lU3RhdGUudmlld1N0YXRlO1xuICAgIHZhciBwcm9qZWN0aW9uID0gdmlld1N0YXRlLnByb2plY3Rpb247XG4gICAgdmFyIHZpZXdSZXNvbHV0aW9uID0gdmlld1N0YXRlLnJlc29sdXRpb247XG4gICAgdmFyIHZpZXdDZW50ZXIgPSB2aWV3U3RhdGUuY2VudGVyO1xuICAgIHZhciByb3RhdGlvbiA9IHZpZXdTdGF0ZS5yb3RhdGlvbjtcbiAgICB2YXIgcGl4ZWxSYXRpbyA9IGZyYW1lU3RhdGUucGl4ZWxSYXRpbztcbiAgICB2YXIgdGlsZUxheWVyID0gdGhpcy5nZXRMYXllcigpO1xuICAgIHZhciB0aWxlU291cmNlID0gdGlsZUxheWVyLmdldFNvdXJjZSgpO1xuICAgIHZhciBzb3VyY2VSZXZpc2lvbiA9IHRpbGVTb3VyY2UuZ2V0UmV2aXNpb24oKTtcbiAgICB2YXIgdGlsZUdyaWQgPSB0aWxlU291cmNlLmdldFRpbGVHcmlkRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgICB2YXIgeiA9IHRpbGVHcmlkLmdldFpGb3JSZXNvbHV0aW9uKHZpZXdSZXNvbHV0aW9uLCB0aWxlU291cmNlLnpEaXJlY3Rpb24pO1xuICAgIHZhciB0aWxlUmVzb2x1dGlvbiA9IHRpbGVHcmlkLmdldFJlc29sdXRpb24oeik7XG4gICAgdmFyIGV4dGVudCA9IGZyYW1lU3RhdGUuZXh0ZW50O1xuICAgIHZhciBsYXllckV4dGVudCA9IGxheWVyU3RhdGUuZXh0ZW50ICYmIGZyb21Vc2VyRXh0ZW50KGxheWVyU3RhdGUuZXh0ZW50LCBwcm9qZWN0aW9uKTtcblxuICAgIGlmIChsYXllckV4dGVudCkge1xuICAgICAgZXh0ZW50ID0gZ2V0SW50ZXJzZWN0aW9uKGV4dGVudCwgZnJvbVVzZXJFeHRlbnQobGF5ZXJTdGF0ZS5leHRlbnQsIHByb2plY3Rpb24pKTtcbiAgICB9XG5cbiAgICB2YXIgdGlsZVBpeGVsUmF0aW8gPSB0aWxlU291cmNlLmdldFRpbGVQaXhlbFJhdGlvKHBpeGVsUmF0aW8pOyAvLyBkZXNpcmVkIGRpbWVuc2lvbnMgb2YgdGhlIGNhbnZhcyBpbiBwaXhlbHNcblxuICAgIHZhciB3aWR0aCA9IE1hdGgucm91bmQoZnJhbWVTdGF0ZS5zaXplWzBdICogdGlsZVBpeGVsUmF0aW8pO1xuICAgIHZhciBoZWlnaHQgPSBNYXRoLnJvdW5kKGZyYW1lU3RhdGUuc2l6ZVsxXSAqIHRpbGVQaXhlbFJhdGlvKTtcblxuICAgIGlmIChyb3RhdGlvbikge1xuICAgICAgdmFyIHNpemUgPSBNYXRoLnJvdW5kKE1hdGguc3FydCh3aWR0aCAqIHdpZHRoICsgaGVpZ2h0ICogaGVpZ2h0KSk7XG4gICAgICB3aWR0aCA9IHNpemU7XG4gICAgICBoZWlnaHQgPSBzaXplO1xuICAgIH1cblxuICAgIHZhciBkeCA9IHRpbGVSZXNvbHV0aW9uICogd2lkdGggLyAyIC8gdGlsZVBpeGVsUmF0aW87XG4gICAgdmFyIGR5ID0gdGlsZVJlc29sdXRpb24gKiBoZWlnaHQgLyAyIC8gdGlsZVBpeGVsUmF0aW87XG4gICAgdmFyIGNhbnZhc0V4dGVudCA9IFt2aWV3Q2VudGVyWzBdIC0gZHgsIHZpZXdDZW50ZXJbMV0gLSBkeSwgdmlld0NlbnRlclswXSArIGR4LCB2aWV3Q2VudGVyWzFdICsgZHldO1xuICAgIHZhciB0aWxlUmFuZ2UgPSB0aWxlR3JpZC5nZXRUaWxlUmFuZ2VGb3JFeHRlbnRBbmRaKGV4dGVudCwgeik7XG4gICAgLyoqXG4gICAgICogQHR5cGUge09iamVjdDxudW1iZXIsIE9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uLy4uL1RpbGUuanNcIikuZGVmYXVsdD4+fVxuICAgICAqL1xuXG4gICAgdmFyIHRpbGVzVG9EcmF3QnlaID0ge307XG4gICAgdGlsZXNUb0RyYXdCeVpbel0gPSB7fTtcbiAgICB2YXIgZmluZExvYWRlZFRpbGVzID0gdGhpcy5jcmVhdGVMb2FkZWRUaWxlRmluZGVyKHRpbGVTb3VyY2UsIHByb2plY3Rpb24sIHRpbGVzVG9EcmF3QnlaKTtcbiAgICB2YXIgdG1wRXh0ZW50ID0gdGhpcy50bXBFeHRlbnQ7XG4gICAgdmFyIHRtcFRpbGVSYW5nZSA9IHRoaXMudG1wVGlsZVJhbmdlXztcbiAgICB0aGlzLm5ld1RpbGVzXyA9IGZhbHNlO1xuXG4gICAgZm9yICh2YXIgeCA9IHRpbGVSYW5nZS5taW5YOyB4IDw9IHRpbGVSYW5nZS5tYXhYOyArK3gpIHtcbiAgICAgIGZvciAodmFyIHkgPSB0aWxlUmFuZ2UubWluWTsgeSA8PSB0aWxlUmFuZ2UubWF4WTsgKyt5KSB7XG4gICAgICAgIHZhciB0aWxlID0gdGhpcy5nZXRUaWxlKHosIHgsIHksIGZyYW1lU3RhdGUpO1xuXG4gICAgICAgIGlmICh0aGlzLmlzRHJhd2FibGVUaWxlKHRpbGUpKSB7XG4gICAgICAgICAgdmFyIHVpZCA9IGdldFVpZCh0aGlzKTtcblxuICAgICAgICAgIGlmICh0aWxlLmdldFN0YXRlKCkgPT0gVGlsZVN0YXRlLkxPQURFRCkge1xuICAgICAgICAgICAgdGlsZXNUb0RyYXdCeVpbel1bdGlsZS50aWxlQ29vcmQudG9TdHJpbmcoKV0gPSB0aWxlO1xuICAgICAgICAgICAgdmFyIGluVHJhbnNpdGlvbiA9IHRpbGUuaW5UcmFuc2l0aW9uKHVpZCk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5uZXdUaWxlc18gJiYgKGluVHJhbnNpdGlvbiB8fCB0aGlzLnJlbmRlcmVkVGlsZXMuaW5kZXhPZih0aWxlKSA9PT0gLTEpKSB7XG4gICAgICAgICAgICAgIHRoaXMubmV3VGlsZXNfID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGlsZS5nZXRBbHBoYSh1aWQsIGZyYW1lU3RhdGUudGltZSkgPT09IDEpIHtcbiAgICAgICAgICAgIC8vIGRvbid0IGxvb2sgZm9yIGFsdCB0aWxlcyBpZiBhbHBoYSBpcyAxXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2hpbGRUaWxlUmFuZ2UgPSB0aWxlR3JpZC5nZXRUaWxlQ29vcmRDaGlsZFRpbGVSYW5nZSh0aWxlLnRpbGVDb29yZCwgdG1wVGlsZVJhbmdlLCB0bXBFeHRlbnQpO1xuICAgICAgICB2YXIgY292ZXJlZCA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChjaGlsZFRpbGVSYW5nZSkge1xuICAgICAgICAgIGNvdmVyZWQgPSBmaW5kTG9hZGVkVGlsZXMoeiArIDEsIGNoaWxkVGlsZVJhbmdlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghY292ZXJlZCkge1xuICAgICAgICAgIHRpbGVHcmlkLmZvckVhY2hUaWxlQ29vcmRQYXJlbnRUaWxlUmFuZ2UodGlsZS50aWxlQ29vcmQsIGZpbmRMb2FkZWRUaWxlcywgdG1wVGlsZVJhbmdlLCB0bXBFeHRlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGNhbnZhc1NjYWxlID0gdGlsZVJlc29sdXRpb24gLyB2aWV3UmVzb2x1dGlvbjsgLy8gc2V0IGZvcndhcmQgYW5kIGludmVyc2UgcGl4ZWwgdHJhbnNmb3Jtc1xuXG4gICAgY29tcG9zZVRyYW5zZm9ybSh0aGlzLnBpeGVsVHJhbnNmb3JtLCBmcmFtZVN0YXRlLnNpemVbMF0gLyAyLCBmcmFtZVN0YXRlLnNpemVbMV0gLyAyLCAxIC8gdGlsZVBpeGVsUmF0aW8sIDEgLyB0aWxlUGl4ZWxSYXRpbywgcm90YXRpb24sIC13aWR0aCAvIDIsIC1oZWlnaHQgLyAyKTtcbiAgICB2YXIgY2FudmFzVHJhbnNmb3JtID0gY3JlYXRlVHJhbnNmb3JtU3RyaW5nKHRoaXMucGl4ZWxUcmFuc2Zvcm0pO1xuICAgIHRoaXMudXNlQ29udGFpbmVyKHRhcmdldCwgY2FudmFzVHJhbnNmb3JtLCBsYXllclN0YXRlLm9wYWNpdHkpO1xuICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0O1xuICAgIHZhciBjYW52YXMgPSBjb250ZXh0LmNhbnZhcztcbiAgICBtYWtlSW52ZXJzZSh0aGlzLmludmVyc2VQaXhlbFRyYW5zZm9ybSwgdGhpcy5waXhlbFRyYW5zZm9ybSk7IC8vIHNldCBzY2FsZSB0cmFuc2Zvcm0gZm9yIGNhbGN1bGF0aW5nIHRpbGUgcG9zaXRpb25zIG9uIHRoZSBjYW52YXNcblxuICAgIGNvbXBvc2VUcmFuc2Zvcm0odGhpcy50ZW1wVHJhbnNmb3JtLCB3aWR0aCAvIDIsIGhlaWdodCAvIDIsIGNhbnZhc1NjYWxlLCBjYW52YXNTY2FsZSwgMCwgLXdpZHRoIC8gMiwgLWhlaWdodCAvIDIpO1xuXG4gICAgaWYgKGNhbnZhcy53aWR0aCAhPSB3aWR0aCB8fCBjYW52YXMuaGVpZ2h0ICE9IGhlaWdodCkge1xuICAgICAgY2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIH0gZWxzZSBpZiAoIXRoaXMuY29udGFpbmVyUmV1c2VkKSB7XG4gICAgICBjb250ZXh0LmNsZWFyUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICB9XG5cbiAgICBpZiAobGF5ZXJFeHRlbnQpIHtcbiAgICAgIHRoaXMuY2xpcFVucm90YXRlZChjb250ZXh0LCBmcmFtZVN0YXRlLCBsYXllckV4dGVudCk7XG4gICAgfVxuXG4gICAgYXNzaWduKGNvbnRleHQsIHRpbGVTb3VyY2UuZ2V0Q29udGV4dE9wdGlvbnMoKSk7XG4gICAgdGhpcy5wcmVSZW5kZXIoY29udGV4dCwgZnJhbWVTdGF0ZSk7XG4gICAgdGhpcy5yZW5kZXJlZFRpbGVzLmxlbmd0aCA9IDA7XG4gICAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuXG4gICAgdmFyIHpzID0gT2JqZWN0LmtleXModGlsZXNUb0RyYXdCeVopLm1hcChOdW1iZXIpO1xuICAgIHpzLnNvcnQobnVtYmVyU2FmZUNvbXBhcmVGdW5jdGlvbik7XG4gICAgdmFyIGNsaXBzLCBjbGlwWnMsIGN1cnJlbnRDbGlwO1xuXG4gICAgaWYgKGxheWVyU3RhdGUub3BhY2l0eSA9PT0gMSAmJiAoIXRoaXMuY29udGFpbmVyUmV1c2VkIHx8IHRpbGVTb3VyY2UuZ2V0T3BhcXVlKGZyYW1lU3RhdGUudmlld1N0YXRlLnByb2plY3Rpb24pKSkge1xuICAgICAgenMgPSB6cy5yZXZlcnNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNsaXBzID0gW107XG4gICAgICBjbGlwWnMgPSBbXTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0genMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHZhciBjdXJyZW50WiA9IHpzW2ldO1xuICAgICAgdmFyIGN1cnJlbnRUaWxlUGl4ZWxTaXplID0gdGlsZVNvdXJjZS5nZXRUaWxlUGl4ZWxTaXplKGN1cnJlbnRaLCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKTtcbiAgICAgIHZhciBjdXJyZW50UmVzb2x1dGlvbiA9IHRpbGVHcmlkLmdldFJlc29sdXRpb24oY3VycmVudFopO1xuICAgICAgdmFyIGN1cnJlbnRTY2FsZSA9IGN1cnJlbnRSZXNvbHV0aW9uIC8gdGlsZVJlc29sdXRpb247XG4gICAgICB2YXIgZHhfMSA9IGN1cnJlbnRUaWxlUGl4ZWxTaXplWzBdICogY3VycmVudFNjYWxlICogY2FudmFzU2NhbGU7XG4gICAgICB2YXIgZHlfMSA9IGN1cnJlbnRUaWxlUGl4ZWxTaXplWzFdICogY3VycmVudFNjYWxlICogY2FudmFzU2NhbGU7XG4gICAgICB2YXIgb3JpZ2luVGlsZUNvb3JkID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRm9yQ29vcmRBbmRaKGdldFRvcExlZnQoY2FudmFzRXh0ZW50KSwgY3VycmVudFopO1xuICAgICAgdmFyIG9yaWdpblRpbGVFeHRlbnQgPSB0aWxlR3JpZC5nZXRUaWxlQ29vcmRFeHRlbnQob3JpZ2luVGlsZUNvb3JkKTtcbiAgICAgIHZhciBvcmlnaW5fMSA9IGFwcGx5VHJhbnNmb3JtKHRoaXMudGVtcFRyYW5zZm9ybSwgW3RpbGVQaXhlbFJhdGlvICogKG9yaWdpblRpbGVFeHRlbnRbMF0gLSBjYW52YXNFeHRlbnRbMF0pIC8gdGlsZVJlc29sdXRpb24sIHRpbGVQaXhlbFJhdGlvICogKGNhbnZhc0V4dGVudFszXSAtIG9yaWdpblRpbGVFeHRlbnRbM10pIC8gdGlsZVJlc29sdXRpb25dKTtcbiAgICAgIHZhciB0aWxlR3V0dGVyID0gdGlsZVBpeGVsUmF0aW8gKiB0aWxlU291cmNlLmdldEd1dHRlckZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgICB2YXIgdGlsZXNUb0RyYXcgPSB0aWxlc1RvRHJhd0J5WltjdXJyZW50Wl07XG5cbiAgICAgIGZvciAodmFyIHRpbGVDb29yZEtleSBpbiB0aWxlc1RvRHJhdykge1xuICAgICAgICB2YXIgdGlsZSA9XG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vSW1hZ2VUaWxlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIHRpbGVzVG9EcmF3W3RpbGVDb29yZEtleV07XG4gICAgICAgIHZhciB0aWxlQ29vcmQgPSB0aWxlLnRpbGVDb29yZDsgLy8gQ2FsY3VsYXRlIGludGVnZXIgcG9zaXRpb25zIGFuZCBzaXplcyBzbyB0aGF0IHRpbGVzIGFsaWduXG5cbiAgICAgICAgdmFyIGZsb2F0WCA9IG9yaWdpbl8xWzBdIC0gKG9yaWdpblRpbGVDb29yZFsxXSAtIHRpbGVDb29yZFsxXSkgKiBkeF8xO1xuICAgICAgICB2YXIgbmV4dFggPSBNYXRoLnJvdW5kKGZsb2F0WCArIGR4XzEpO1xuICAgICAgICB2YXIgZmxvYXRZID0gb3JpZ2luXzFbMV0gLSAob3JpZ2luVGlsZUNvb3JkWzJdIC0gdGlsZUNvb3JkWzJdKSAqIGR5XzE7XG4gICAgICAgIHZhciBuZXh0WSA9IE1hdGgucm91bmQoZmxvYXRZICsgZHlfMSk7XG4gICAgICAgIHZhciB4ID0gTWF0aC5yb3VuZChmbG9hdFgpO1xuICAgICAgICB2YXIgeSA9IE1hdGgucm91bmQoZmxvYXRZKTtcbiAgICAgICAgdmFyIHcgPSBuZXh0WCAtIHg7XG4gICAgICAgIHZhciBoID0gbmV4dFkgLSB5O1xuICAgICAgICB2YXIgdHJhbnNpdGlvbiA9IHogPT09IGN1cnJlbnRaO1xuICAgICAgICB2YXIgaW5UcmFuc2l0aW9uID0gdHJhbnNpdGlvbiAmJiB0aWxlLmdldEFscGhhKGdldFVpZCh0aGlzKSwgZnJhbWVTdGF0ZS50aW1lKSAhPT0gMTtcblxuICAgICAgICBpZiAoIWluVHJhbnNpdGlvbikge1xuICAgICAgICAgIGlmIChjbGlwcykge1xuICAgICAgICAgICAgLy8gQ2xpcCBtYXNrIGZvciByZWdpb25zIGluIHRoaXMgdGlsZSB0aGF0IGFscmVhZHkgZmlsbGVkIGJ5IGEgaGlnaGVyIHogdGlsZVxuICAgICAgICAgICAgY29udGV4dC5zYXZlKCk7XG4gICAgICAgICAgICBjdXJyZW50Q2xpcCA9IFt4LCB5LCB4ICsgdywgeSwgeCArIHcsIHkgKyBoLCB4LCB5ICsgaF07XG5cbiAgICAgICAgICAgIGZvciAodmFyIGlfMSA9IDAsIGlpID0gY2xpcHMubGVuZ3RoOyBpXzEgPCBpaTsgKytpXzEpIHtcbiAgICAgICAgICAgICAgaWYgKHogIT09IGN1cnJlbnRaICYmIGN1cnJlbnRaIDwgY2xpcFpzW2lfMV0pIHtcbiAgICAgICAgICAgICAgICB2YXIgY2xpcCA9IGNsaXBzW2lfMV07XG4gICAgICAgICAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTsgLy8gY291bnRlci1jbG9ja3dpc2UgKG91dGVyIHJpbmcpIGZvciBjdXJyZW50IHRpbGVcblxuICAgICAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKGN1cnJlbnRDbGlwWzBdLCBjdXJyZW50Q2xpcFsxXSk7XG4gICAgICAgICAgICAgICAgY29udGV4dC5saW5lVG8oY3VycmVudENsaXBbMl0sIGN1cnJlbnRDbGlwWzNdKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhjdXJyZW50Q2xpcFs0XSwgY3VycmVudENsaXBbNV0pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGN1cnJlbnRDbGlwWzZdLCBjdXJyZW50Q2xpcFs3XSk7IC8vIGNsb2Nrd2lzZSAoaW5uZXIgcmluZykgZm9yIGhpZ2hlciB6IHRpbGVcblxuICAgICAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKGNsaXBbNl0sIGNsaXBbN10pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGNsaXBbNF0sIGNsaXBbNV0pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGNsaXBbMl0sIGNsaXBbM10pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGNsaXBbMF0sIGNsaXBbMV0pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQuY2xpcCgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNsaXBzLnB1c2goY3VycmVudENsaXApO1xuICAgICAgICAgICAgY2xpcFpzLnB1c2goY3VycmVudFopO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb250ZXh0LmNsZWFyUmVjdCh4LCB5LCB3LCBoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRyYXdUaWxlSW1hZ2UodGlsZSwgZnJhbWVTdGF0ZSwgeCwgeSwgdywgaCwgdGlsZUd1dHRlciwgdHJhbnNpdGlvbiwgbGF5ZXJTdGF0ZS5vcGFjaXR5KTtcblxuICAgICAgICBpZiAoY2xpcHMgJiYgIWluVHJhbnNpdGlvbikge1xuICAgICAgICAgIGNvbnRleHQucmVzdG9yZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlZFRpbGVzLnB1c2godGlsZSk7XG4gICAgICAgIHRoaXMudXBkYXRlVXNlZFRpbGVzKGZyYW1lU3RhdGUudXNlZFRpbGVzLCB0aWxlU291cmNlLCB0aWxlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnJlbmRlcmVkUmV2aXNpb24gPSBzb3VyY2VSZXZpc2lvbjtcbiAgICB0aGlzLnJlbmRlcmVkUmVzb2x1dGlvbiA9IHRpbGVSZXNvbHV0aW9uO1xuICAgIHRoaXMuZXh0ZW50Q2hhbmdlZCA9ICF0aGlzLnJlbmRlcmVkRXh0ZW50XyB8fCAhZXF1YWxzKHRoaXMucmVuZGVyZWRFeHRlbnRfLCBjYW52YXNFeHRlbnQpO1xuICAgIHRoaXMucmVuZGVyZWRFeHRlbnRfID0gY2FudmFzRXh0ZW50O1xuICAgIHRoaXMucmVuZGVyZWRQaXhlbFJhdGlvID0gcGl4ZWxSYXRpbztcbiAgICB0aGlzLnJlbmRlcmVkUHJvamVjdGlvbiA9IHByb2plY3Rpb247XG4gICAgdGhpcy5tYW5hZ2VUaWxlUHlyYW1pZChmcmFtZVN0YXRlLCB0aWxlU291cmNlLCB0aWxlR3JpZCwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbiwgZXh0ZW50LCB6LCB0aWxlTGF5ZXIuZ2V0UHJlbG9hZCgpKTtcbiAgICB0aGlzLnNjaGVkdWxlRXhwaXJlQ2FjaGUoZnJhbWVTdGF0ZSwgdGlsZVNvdXJjZSk7XG4gICAgdGhpcy5wb3N0UmVuZGVyKGNvbnRleHQsIGZyYW1lU3RhdGUpO1xuXG4gICAgaWYgKGxheWVyU3RhdGUuZXh0ZW50KSB7XG4gICAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgICB9XG5cbiAgICBpZiAoY2FudmFzVHJhbnNmb3JtICE9PSBjYW52YXMuc3R5bGUudHJhbnNmb3JtKSB7XG4gICAgICBjYW52YXMuc3R5bGUudHJhbnNmb3JtID0gY2FudmFzVHJhbnNmb3JtO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vSW1hZ2VUaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVGlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHggTGVmdCBvZiB0aGUgdGlsZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgVG9wIG9mIHRoZSB0aWxlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gdyBXaWR0aCBvZiB0aGUgdGlsZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGggSGVpZ2h0IG9mIHRoZSB0aWxlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZ3V0dGVyIFRpbGUgZ3V0dGVyLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHRyYW5zaXRpb24gQXBwbHkgYW4gYWxwaGEgdHJhbnNpdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9wYWNpdHkgT3BhY2l0eS5cbiAgICovXG5cblxuICBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZHJhd1RpbGVJbWFnZSA9IGZ1bmN0aW9uICh0aWxlLCBmcmFtZVN0YXRlLCB4LCB5LCB3LCBoLCBndXR0ZXIsIHRyYW5zaXRpb24sIG9wYWNpdHkpIHtcbiAgICB2YXIgaW1hZ2UgPSB0aGlzLmdldFRpbGVJbWFnZSh0aWxlKTtcblxuICAgIGlmICghaW1hZ2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgdWlkID0gZ2V0VWlkKHRoaXMpO1xuICAgIHZhciB0aWxlQWxwaGEgPSB0cmFuc2l0aW9uID8gdGlsZS5nZXRBbHBoYSh1aWQsIGZyYW1lU3RhdGUudGltZSkgOiAxO1xuICAgIHZhciBhbHBoYSA9IG9wYWNpdHkgKiB0aWxlQWxwaGE7XG4gICAgdmFyIGFscGhhQ2hhbmdlZCA9IGFscGhhICE9PSB0aGlzLmNvbnRleHQuZ2xvYmFsQWxwaGE7XG5cbiAgICBpZiAoYWxwaGFDaGFuZ2VkKSB7XG4gICAgICB0aGlzLmNvbnRleHQuc2F2ZSgpO1xuICAgICAgdGhpcy5jb250ZXh0Lmdsb2JhbEFscGhhID0gYWxwaGE7XG4gICAgfVxuXG4gICAgdGhpcy5jb250ZXh0LmRyYXdJbWFnZShpbWFnZSwgZ3V0dGVyLCBndXR0ZXIsIGltYWdlLndpZHRoIC0gMiAqIGd1dHRlciwgaW1hZ2UuaGVpZ2h0IC0gMiAqIGd1dHRlciwgeCwgeSwgdywgaCk7XG5cbiAgICBpZiAoYWxwaGFDaGFuZ2VkKSB7XG4gICAgICB0aGlzLmNvbnRleHQucmVzdG9yZSgpO1xuICAgIH1cblxuICAgIGlmICh0aWxlQWxwaGEgIT09IDEpIHtcbiAgICAgIGZyYW1lU3RhdGUuYW5pbWF0ZSA9IHRydWU7XG4gICAgfSBlbHNlIGlmICh0cmFuc2l0aW9uKSB7XG4gICAgICB0aWxlLmVuZFRyYW5zaXRpb24odWlkKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtIVE1MQ2FudmFzRWxlbWVudH0gSW1hZ2VcbiAgICovXG5cblxuICBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0SW1hZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgcmV0dXJuIGNvbnRleHQgPyBjb250ZXh0LmNhbnZhcyA6IG51bGw7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGltYWdlIGZyb20gYSB0aWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ltYWdlVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlIFRpbGUuXG4gICAqIEByZXR1cm4ge0hUTUxDYW52YXNFbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR8SFRNTFZpZGVvRWxlbWVudH0gSW1hZ2UuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0VGlsZUltYWdlID0gZnVuY3Rpb24gKHRpbGUpIHtcbiAgICByZXR1cm4gdGlsZS5nZXRJbWFnZSgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zb3VyY2UvVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlU291cmNlIFRpbGUgc291cmNlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLnNjaGVkdWxlRXhwaXJlQ2FjaGUgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSwgdGlsZVNvdXJjZSkge1xuICAgIGlmICh0aWxlU291cmNlLmNhbkV4cGlyZUNhY2hlKCkpIHtcbiAgICAgIC8qKlxuICAgICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zb3VyY2UvVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlU291cmNlIFRpbGUgc291cmNlLlxuICAgICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIE1hcC5cbiAgICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAgICAgKi9cbiAgICAgIHZhciBwb3N0UmVuZGVyRnVuY3Rpb24gPSBmdW5jdGlvbiAodGlsZVNvdXJjZSwgbWFwLCBmcmFtZVN0YXRlKSB7XG4gICAgICAgIHZhciB0aWxlU291cmNlS2V5ID0gZ2V0VWlkKHRpbGVTb3VyY2UpO1xuXG4gICAgICAgIGlmICh0aWxlU291cmNlS2V5IGluIGZyYW1lU3RhdGUudXNlZFRpbGVzKSB7XG4gICAgICAgICAgdGlsZVNvdXJjZS5leHBpcmVDYWNoZShmcmFtZVN0YXRlLnZpZXdTdGF0ZS5wcm9qZWN0aW9uLCBmcmFtZVN0YXRlLnVzZWRUaWxlc1t0aWxlU291cmNlS2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH0uYmluZChudWxsLCB0aWxlU291cmNlKTtcblxuICAgICAgZnJhbWVTdGF0ZS5wb3N0UmVuZGVyRnVuY3Rpb25zLnB1c2goXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5Qb3N0UmVuZGVyRnVuY3Rpb259ICovXG4gICAgICBwb3N0UmVuZGVyRnVuY3Rpb24pO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7IU9iamVjdDxzdHJpbmcsICFPYmplY3Q8c3RyaW5nLCBib29sZWFuPj59IHVzZWRUaWxlcyBVc2VkIHRpbGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3NvdXJjZS9UaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGVTb3VyY2UgVGlsZSBzb3VyY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KCcuLi8uLi9UaWxlLmpzJykuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLnVwZGF0ZVVzZWRUaWxlcyA9IGZ1bmN0aW9uICh1c2VkVGlsZXMsIHRpbGVTb3VyY2UsIHRpbGUpIHtcbiAgICAvLyBGSVhNRSBzaG91bGQgd2UgdXNlIHRpbGVzVG9EcmF3QnlaIGluc3RlYWQ/XG4gICAgdmFyIHRpbGVTb3VyY2VLZXkgPSBnZXRVaWQodGlsZVNvdXJjZSk7XG5cbiAgICBpZiAoISh0aWxlU291cmNlS2V5IGluIHVzZWRUaWxlcykpIHtcbiAgICAgIHVzZWRUaWxlc1t0aWxlU291cmNlS2V5XSA9IHt9O1xuICAgIH1cblxuICAgIHVzZWRUaWxlc1t0aWxlU291cmNlS2V5XVt0aWxlLmdldEtleSgpXSA9IHRydWU7XG4gIH07XG4gIC8qKlxuICAgKiBNYW5hZ2UgdGlsZSBweXJhbWlkLlxuICAgKiBUaGlzIGZ1bmN0aW9uIHBlcmZvcm1zIGEgbnVtYmVyIG9mIGZ1bmN0aW9ucyByZWxhdGVkIHRvIHRoZSB0aWxlcyBhdCB0aGVcbiAgICogY3VycmVudCB6b29tIGFuZCBsb3dlciB6b29tIGxldmVsczpcbiAgICogLSByZWdpc3RlcnMgaWRsZSB0aWxlcyBpbiBmcmFtZVN0YXRlLndhbnRlZFRpbGVzIHNvIHRoYXQgdGhleSBhcmUgbm90XG4gICAqICAgZGlzY2FyZGVkIGJ5IHRoZSB0aWxlIHF1ZXVlXG4gICAqIC0gZW5xdWV1ZXMgbWlzc2luZyB0aWxlc1xuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3NvdXJjZS9UaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGVTb3VyY2UgVGlsZSBzb3VyY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gdGlsZUdyaWQgVGlsZSBncmlkLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjdXJyZW50WiBDdXJyZW50IFouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwcmVsb2FkIExvYWQgbG93IHJlc29sdXRpb24gdGlsZXMgdXAgdG8gJ3ByZWxvYWQnIGxldmVscy5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi8uLi9UaWxlLmpzXCIpLmRlZmF1bHQpPX0gb3B0X3RpbGVDYWxsYmFjayBUaWxlIGNhbGxiYWNrLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLm1hbmFnZVRpbGVQeXJhbWlkID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUsIHRpbGVTb3VyY2UsIHRpbGVHcmlkLCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uLCBleHRlbnQsIGN1cnJlbnRaLCBwcmVsb2FkLCBvcHRfdGlsZUNhbGxiYWNrKSB7XG4gICAgdmFyIHRpbGVTb3VyY2VLZXkgPSBnZXRVaWQodGlsZVNvdXJjZSk7XG5cbiAgICBpZiAoISh0aWxlU291cmNlS2V5IGluIGZyYW1lU3RhdGUud2FudGVkVGlsZXMpKSB7XG4gICAgICBmcmFtZVN0YXRlLndhbnRlZFRpbGVzW3RpbGVTb3VyY2VLZXldID0ge307XG4gICAgfVxuXG4gICAgdmFyIHdhbnRlZFRpbGVzID0gZnJhbWVTdGF0ZS53YW50ZWRUaWxlc1t0aWxlU291cmNlS2V5XTtcbiAgICB2YXIgdGlsZVF1ZXVlID0gZnJhbWVTdGF0ZS50aWxlUXVldWU7XG4gICAgdmFyIG1pblpvb20gPSB0aWxlR3JpZC5nZXRNaW5ab29tKCk7XG4gICAgdmFyIHRpbGVDb3VudCA9IDA7XG4gICAgdmFyIHRpbGUsIHRpbGVSYW5nZSwgdGlsZVJlc29sdXRpb24sIHgsIHksIHo7XG5cbiAgICBmb3IgKHogPSBtaW5ab29tOyB6IDw9IGN1cnJlbnRaOyArK3opIHtcbiAgICAgIHRpbGVSYW5nZSA9IHRpbGVHcmlkLmdldFRpbGVSYW5nZUZvckV4dGVudEFuZFooZXh0ZW50LCB6LCB0aWxlUmFuZ2UpO1xuICAgICAgdGlsZVJlc29sdXRpb24gPSB0aWxlR3JpZC5nZXRSZXNvbHV0aW9uKHopO1xuXG4gICAgICBmb3IgKHggPSB0aWxlUmFuZ2UubWluWDsgeCA8PSB0aWxlUmFuZ2UubWF4WDsgKyt4KSB7XG4gICAgICAgIGZvciAoeSA9IHRpbGVSYW5nZS5taW5ZOyB5IDw9IHRpbGVSYW5nZS5tYXhZOyArK3kpIHtcbiAgICAgICAgICBpZiAoY3VycmVudFogLSB6IDw9IHByZWxvYWQpIHtcbiAgICAgICAgICAgICsrdGlsZUNvdW50O1xuICAgICAgICAgICAgdGlsZSA9IHRpbGVTb3VyY2UuZ2V0VGlsZSh6LCB4LCB5LCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKTtcblxuICAgICAgICAgICAgaWYgKHRpbGUuZ2V0U3RhdGUoKSA9PSBUaWxlU3RhdGUuSURMRSkge1xuICAgICAgICAgICAgICB3YW50ZWRUaWxlc1t0aWxlLmdldEtleSgpXSA9IHRydWU7XG5cbiAgICAgICAgICAgICAgaWYgKCF0aWxlUXVldWUuaXNLZXlRdWV1ZWQodGlsZS5nZXRLZXkoKSkpIHtcbiAgICAgICAgICAgICAgICB0aWxlUXVldWUuZW5xdWV1ZShbdGlsZSwgdGlsZVNvdXJjZUtleSwgdGlsZUdyaWQuZ2V0VGlsZUNvb3JkQ2VudGVyKHRpbGUudGlsZUNvb3JkKSwgdGlsZVJlc29sdXRpb25dKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAob3B0X3RpbGVDYWxsYmFjayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIG9wdF90aWxlQ2FsbGJhY2sodGlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRpbGVTb3VyY2UudXNlVGlsZSh6LCB4LCB5LCBwcm9qZWN0aW9uKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aWxlU291cmNlLnVwZGF0ZUNhY2hlU2l6ZSh0aWxlQ291bnQsIHByb2plY3Rpb24pO1xuICB9O1xuXG4gIHJldHVybiBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlcjtcbn0oQ2FudmFzTGF5ZXJSZW5kZXJlcik7XG4vKipcbiAqIEBmdW5jdGlvblxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vLi4vbGF5ZXIvVGlsZS5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uLy4uL2xheWVyL1ZlY3RvclRpbGUuanNcIikuZGVmYXVsdH1cbiAqL1xuXG5cbkNhbnZhc1RpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5nZXRMYXllcjtcbmV4cG9ydCBkZWZhdWx0IENhbnZhc1RpbGVMYXllclJlbmRlcmVyOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvbGF5ZXIvVGlsZVxuICovXG5cblxuaW1wb3J0IEJhc2VUaWxlTGF5ZXIgZnJvbSAnLi9CYXNlVGlsZS5qcyc7XG5pbXBvcnQgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIgZnJvbSAnLi4vcmVuZGVyZXIvY2FudmFzL1RpbGVMYXllci5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEZvciBsYXllciBzb3VyY2VzIHRoYXQgcHJvdmlkZSBwcmUtcmVuZGVyZWQsIHRpbGVkIGltYWdlcyBpbiBncmlkcyB0aGF0IGFyZVxuICogb3JnYW5pemVkIGJ5IHpvb20gbGV2ZWxzIGZvciBzcGVjaWZpYyByZXNvbHV0aW9ucy5cbiAqIE5vdGUgdGhhdCBhbnkgcHJvcGVydHkgc2V0IGluIHRoZSBvcHRpb25zIGlzIHNldCBhcyBhIHtAbGluayBtb2R1bGU6b2wvT2JqZWN0fkJhc2VPYmplY3R9XG4gKiBwcm9wZXJ0eSBvbiB0aGUgbGF5ZXIgb2JqZWN0OyBmb3IgZXhhbXBsZSwgc2V0dGluZyBgdGl0bGU6ICdNeSBUaXRsZSdgIGluIHRoZVxuICogb3B0aW9ucyBtZWFucyB0aGF0IGB0aXRsZWAgaXMgb2JzZXJ2YWJsZSwgYW5kIGhhcyBnZXQvc2V0IGFjY2Vzc29ycy5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIFRpbGVMYXllciA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhUaWxlTGF5ZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vQmFzZVRpbGUuanNcIikuT3B0aW9ucz19IG9wdF9vcHRpb25zIFRpbGUgbGF5ZXIgb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBUaWxlTGF5ZXIob3B0X29wdGlvbnMpIHtcbiAgICByZXR1cm4gX3N1cGVyLmNhbGwodGhpcywgb3B0X29wdGlvbnMpIHx8IHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHJlbmRlcmVyIGZvciB0aGlzIGxheWVyLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9yZW5kZXJlci9MYXllci5qc1wiKS5kZWZhdWx0fSBBIGxheWVyIHJlbmRlcmVyLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgVGlsZUxheWVyLnByb3RvdHlwZS5jcmVhdGVSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbmV3IENhbnZhc1RpbGVMYXllclJlbmRlcmVyKHRoaXMpO1xuICB9O1xuXG4gIHJldHVybiBUaWxlTGF5ZXI7XG59KEJhc2VUaWxlTGF5ZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBUaWxlTGF5ZXI7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2xheWVyL1ZlY3RvclRpbGVSZW5kZXJUeXBlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICogUmVuZGVyIG1vZGUgZm9yIHZlY3RvciB0aWxlczpcbiAqICAqIGAnaW1hZ2UnYDogVmVjdG9yIHRpbGVzIGFyZSByZW5kZXJlZCBhcyBpbWFnZXMuIEdyZWF0IHBlcmZvcm1hbmNlLCBidXRcbiAqICAgIHBvaW50IHN5bWJvbHMgYW5kIHRleHRzIGFyZSBhbHdheXMgcm90YXRlZCB3aXRoIHRoZSB2aWV3IGFuZCBwaXhlbHMgYXJlXG4gKiAgICBzY2FsZWQgZHVyaW5nIHpvb20gYW5pbWF0aW9ucy5cbiAqICAqIGAnaHlicmlkJ2A6IFBvbHlnb24gYW5kIGxpbmUgZWxlbWVudHMgYXJlIHJlbmRlcmVkIGFzIGltYWdlcywgc28gcGl4ZWxzXG4gKiAgICBhcmUgc2NhbGVkIGR1cmluZyB6b29tIGFuaW1hdGlvbnMuIFBvaW50IHN5bWJvbHMgYW5kIHRleHRzIGFyZSBhY2N1cmF0ZWx5XG4gKiAgICByZW5kZXJlZCBhcyB2ZWN0b3JzIGFuZCBjYW4gc3RheSB1cHJpZ2h0IG9uIHJvdGF0ZWQgdmlld3MuXG4gKiAgKiBgJ3ZlY3RvcidgOiBFdmVyeXRoaW5nIGlzIHJlbmRlcmVkIGFzIHZlY3RvcnMuIFVzZSB0aGlzIG1vZGUgZm9yIGltcHJvdmVkXG4gKiAgICBwZXJmb3JtYW5jZSBvbiB2ZWN0b3IgdGlsZSBsYXllcnMgd2l0aCBvbmx5IGEgZmV3IHJlbmRlcmVkIGZlYXR1cmVzIChlLmcuXG4gKiAgICBmb3IgaGlnaGxpZ2h0aW5nIGEgc3Vic2V0IG9mIGZlYXR1cmVzIG9mIGFub3RoZXIgbGF5ZXIgd2l0aCB0aGUgc2FtZVxuICogICAgc291cmNlKS5cbiAqIEBhcGlcbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBJTUFHRTogJ2ltYWdlJyxcbiAgSFlCUklEOiAnaHlicmlkJyxcbiAgVkVDVE9SOiAndmVjdG9yJ1xufTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlcmVyL2NhbnZhcy9WZWN0b3JUaWxlTGF5ZXJcbiAqL1xuXG5cbmltcG9ydCBDYW52YXNCdWlsZGVyR3JvdXAgZnJvbSAnLi4vLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanMnO1xuaW1wb3J0IENhbnZhc0V4ZWN1dG9yR3JvdXAgZnJvbSAnLi4vLi4vcmVuZGVyL2NhbnZhcy9FeGVjdXRvckdyb3VwLmpzJztcbmltcG9ydCBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlciBmcm9tICcuL1RpbGVMYXllci5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uLy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IFJlcGxheVR5cGUgZnJvbSAnLi4vLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyVHlwZS5qcyc7XG5pbXBvcnQgVGlsZVN0YXRlIGZyb20gJy4uLy4uL1RpbGVTdGF0ZS5qcyc7XG5pbXBvcnQgVmVjdG9yVGlsZVJlbmRlclR5cGUgZnJvbSAnLi4vLi4vbGF5ZXIvVmVjdG9yVGlsZVJlbmRlclR5cGUuanMnO1xuaW1wb3J0IFZpZXdIaW50IGZyb20gJy4uLy4uL1ZpZXdIaW50LmpzJztcbmltcG9ydCB7IGFwcGx5IGFzIGFwcGx5VHJhbnNmb3JtLCBjcmVhdGUgYXMgY3JlYXRlVHJhbnNmb3JtLCBtdWx0aXBseSwgcmVzZXQgYXMgcmVzZXRUcmFuc2Zvcm0sIHNjYWxlLCBzY2FsZSBhcyBzY2FsZVRyYW5zZm9ybSwgdHJhbnNsYXRlIGFzIHRyYW5zbGF0ZVRyYW5zZm9ybSB9IGZyb20gJy4uLy4uL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgeyBib3VuZGluZ0V4dGVudCwgYnVmZmVyLCBjb250YWluc0V4dGVudCwgZXF1YWxzLCBnZXRJbnRlcnNlY3Rpb24sIGdldFRvcExlZnQsIGludGVyc2VjdHMgfSBmcm9tICcuLi8uLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgY2xlYXIgfSBmcm9tICcuLi8uLi9vYmouanMnO1xuaW1wb3J0IHsgY3JlYXRlSGl0RGV0ZWN0aW9uSW1hZ2VEYXRhLCBoaXREZXRlY3QgfSBmcm9tICcuLi8uLi9yZW5kZXIvY2FudmFzL2hpdGRldGVjdC5qcyc7XG5pbXBvcnQgeyBnZXRTcXVhcmVkVG9sZXJhbmNlIGFzIGdldFNxdWFyZWRSZW5kZXJUb2xlcmFuY2UsIHJlbmRlckZlYXR1cmUgfSBmcm9tICcuLi92ZWN0b3IuanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi4vLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBsaXN0ZW4sIHVubGlzdGVuQnlLZXkgfSBmcm9tICcuLi8uLi9ldmVudHMuanMnO1xuaW1wb3J0IHsgdG9TaXplIH0gZnJvbSAnLi4vLi4vc2l6ZS5qcyc7XG5pbXBvcnQgeyB3cmFwWCB9IGZyb20gJy4uLy4uL2Nvb3JkaW5hdGUuanMnO1xuLyoqXG4gKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIEFycmF5PGltcG9ydChcIi4uLy4uL3JlbmRlci9jYW52YXMvQnVpbGRlclR5cGUuanNcIikuZGVmYXVsdD4+fVxuICovXG5cbnZhciBJTUFHRV9SRVBMQVlTID0ge1xuICAnaW1hZ2UnOiBbUmVwbGF5VHlwZS5QT0xZR09OLCBSZXBsYXlUeXBlLkNJUkNMRSwgUmVwbGF5VHlwZS5MSU5FX1NUUklORywgUmVwbGF5VHlwZS5JTUFHRSwgUmVwbGF5VHlwZS5URVhUXSxcbiAgJ2h5YnJpZCc6IFtSZXBsYXlUeXBlLlBPTFlHT04sIFJlcGxheVR5cGUuTElORV9TVFJJTkddLFxuICAndmVjdG9yJzogW11cbn07XG4vKipcbiAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgQXJyYXk8aW1wb3J0KFwiLi4vLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyVHlwZS5qc1wiKS5kZWZhdWx0Pj59XG4gKi9cblxudmFyIFZFQ1RPUl9SRVBMQVlTID0ge1xuICAnaW1hZ2UnOiBbUmVwbGF5VHlwZS5ERUZBVUxUXSxcbiAgJ2h5YnJpZCc6IFtSZXBsYXlUeXBlLklNQUdFLCBSZXBsYXlUeXBlLlRFWFQsIFJlcGxheVR5cGUuREVGQVVMVF0sXG4gICd2ZWN0b3InOiBbUmVwbGF5VHlwZS5QT0xZR09OLCBSZXBsYXlUeXBlLkNJUkNMRSwgUmVwbGF5VHlwZS5MSU5FX1NUUklORywgUmVwbGF5VHlwZS5JTUFHRSwgUmVwbGF5VHlwZS5URVhULCBSZXBsYXlUeXBlLkRFRkFVTFRdXG59O1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBDYW52YXMgcmVuZGVyZXIgZm9yIHZlY3RvciB0aWxlIGxheWVycy5cbiAqIEBhcGlcbiAqL1xuXG52YXIgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2xheWVyL1ZlY3RvclRpbGUuanNcIikuZGVmYXVsdH0gbGF5ZXIgVmVjdG9yVGlsZSBsYXllci5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlcihsYXllcikge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGxheWVyKSB8fCB0aGlzO1xuICAgIC8qKiBAcHJpdmF0ZSAqL1xuXG5cbiAgICBfdGhpcy5ib3VuZEhhbmRsZVN0eWxlSW1hZ2VDaGFuZ2VfID0gX3RoaXMuaGFuZGxlU3R5bGVJbWFnZUNoYW5nZV8uYmluZChfdGhpcyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmRpcnR5XyA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkTGF5ZXJSZXZpc2lvbl87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtXCIpLlRyYW5zZm9ybX1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkUGl4ZWxUb0Nvb3JkaW5hdGVUcmFuc2Zvcm1fID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZFJvdGF0aW9uXztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vLi4vVmVjdG9yUmVuZGVyVGlsZS5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlclRpbGVJbWFnZVF1ZXVlXyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi8uLi9ldmVudHMuanNcIikuRXZlbnRzS2V5Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVMaXN0ZW5lcktleXNfID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRtcFRyYW5zZm9ybV8gPSBjcmVhdGVUcmFuc2Zvcm0oKTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vVmVjdG9yUmVuZGVyVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlIFRpbGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3Byb2ovUHJvamVjdGlvblwiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gcXVldWUgUXVldWUgdGlsZSBmb3IgcmVuZGVyaW5nLlxuICAgKiBAcmV0dXJuIHtib29sZWFufHVuZGVmaW5lZH0gVGlsZSBuZWVkcyB0byBiZSByZW5kZXJlZC5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucHJlcGFyZVRpbGUgPSBmdW5jdGlvbiAodGlsZSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbiwgcXVldWUpIHtcbiAgICB2YXIgcmVuZGVyO1xuICAgIHZhciB0aWxlVWlkID0gZ2V0VWlkKHRpbGUpO1xuICAgIHZhciBzdGF0ZSA9IHRpbGUuZ2V0U3RhdGUoKTtcblxuICAgIGlmICgoc3RhdGUgPT09IFRpbGVTdGF0ZS5MT0FERUQgJiYgdGlsZS5oaWZpIHx8IHN0YXRlID09PSBUaWxlU3RhdGUuRVJST1IpICYmIHRpbGVVaWQgaW4gdGhpcy50aWxlTGlzdGVuZXJLZXlzXykge1xuICAgICAgdW5saXN0ZW5CeUtleSh0aGlzLnRpbGVMaXN0ZW5lcktleXNfW3RpbGVVaWRdKTtcbiAgICAgIGRlbGV0ZSB0aGlzLnRpbGVMaXN0ZW5lcktleXNfW3RpbGVVaWRdO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZSA9PT0gVGlsZVN0YXRlLkxPQURFRCB8fCBzdGF0ZSA9PT0gVGlsZVN0YXRlLkVSUk9SKSB7XG4gICAgICB0aGlzLnVwZGF0ZUV4ZWN1dG9yR3JvdXBfKHRpbGUsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pO1xuXG4gICAgICBpZiAodGhpcy50aWxlSW1hZ2VOZWVkc1JlbmRlcl8odGlsZSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikpIHtcbiAgICAgICAgcmVuZGVyID0gdHJ1ZTtcblxuICAgICAgICBpZiAocXVldWUpIHtcbiAgICAgICAgICB0aGlzLnJlbmRlclRpbGVJbWFnZVF1ZXVlX1t0aWxlVWlkXSA9IHRpbGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVuZGVyO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHogVGlsZSBjb29yZGluYXRlIHouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFRpbGUgY29vcmRpbmF0ZSB4LlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBUaWxlIGNvb3JkaW5hdGUgeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uLy4uL1RpbGUuanNcIikuZGVmYXVsdH0gVGlsZS5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0VGlsZSA9IGZ1bmN0aW9uICh6LCB4LCB5LCBmcmFtZVN0YXRlKSB7XG4gICAgdmFyIHBpeGVsUmF0aW8gPSBmcmFtZVN0YXRlLnBpeGVsUmF0aW87XG4gICAgdmFyIHZpZXdTdGF0ZSA9IGZyYW1lU3RhdGUudmlld1N0YXRlO1xuICAgIHZhciByZXNvbHV0aW9uID0gdmlld1N0YXRlLnJlc29sdXRpb247XG4gICAgdmFyIHByb2plY3Rpb24gPSB2aWV3U3RhdGUucHJvamVjdGlvbjtcbiAgICB2YXIgbGF5ZXIgPSB0aGlzLmdldExheWVyKCk7XG4gICAgdmFyIHRpbGUgPSBsYXllci5nZXRTb3VyY2UoKS5nZXRUaWxlKHosIHgsIHksIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pO1xuXG4gICAgaWYgKHRpbGUuZ2V0U3RhdGUoKSA8IFRpbGVTdGF0ZS5MT0FERUQpIHtcbiAgICAgIHRpbGUud2FudGVkUmVzb2x1dGlvbiA9IHJlc29sdXRpb247XG4gICAgICB2YXIgdGlsZVVpZCA9IGdldFVpZCh0aWxlKTtcblxuICAgICAgaWYgKCEodGlsZVVpZCBpbiB0aGlzLnRpbGVMaXN0ZW5lcktleXNfKSkge1xuICAgICAgICB2YXIgbGlzdGVuZXJLZXkgPSBsaXN0ZW4odGlsZSwgRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5wcmVwYXJlVGlsZS5iaW5kKHRoaXMsIHRpbGUsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24sIHRydWUpKTtcbiAgICAgICAgdGhpcy50aWxlTGlzdGVuZXJLZXlzX1t0aWxlVWlkXSA9IGxpc3RlbmVyS2V5O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdmlld0hpbnRzID0gZnJhbWVTdGF0ZS52aWV3SGludHM7XG4gICAgICB2YXIgaGlmaSA9ICEodmlld0hpbnRzW1ZpZXdIaW50LkFOSU1BVElOR10gfHwgdmlld0hpbnRzW1ZpZXdIaW50LklOVEVSQUNUSU5HXSk7XG5cbiAgICAgIGlmIChoaWZpIHx8ICF0aWxlLndhbnRlZFJlc29sdXRpb24pIHtcbiAgICAgICAgdGlsZS53YW50ZWRSZXNvbHV0aW9uID0gcmVzb2x1dGlvbjtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlbmRlciA9IHRoaXMucHJlcGFyZVRpbGUodGlsZSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbiwgZmFsc2UpO1xuXG4gICAgICBpZiAocmVuZGVyICYmIGxheWVyLmdldFJlbmRlck1vZGUoKSAhPT0gVmVjdG9yVGlsZVJlbmRlclR5cGUuVkVDVE9SKSB7XG4gICAgICAgIHRoaXMucmVuZGVyVGlsZUltYWdlXyh0aWxlLCBmcmFtZVN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5nZXRUaWxlLmNhbGwodGhpcywgeiwgeCwgeSwgZnJhbWVTdGF0ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1ZlY3RvclJlbmRlclRpbGUuanNcIikuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaWxlIGlzIGRyYXdhYmxlLlxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5pc0RyYXdhYmxlVGlsZSA9IGZ1bmN0aW9uICh0aWxlKSB7XG4gICAgdmFyIGxheWVyID0gdGhpcy5nZXRMYXllcigpO1xuICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLmlzRHJhd2FibGVUaWxlLmNhbGwodGhpcywgdGlsZSkgJiYgKGxheWVyLmdldFJlbmRlck1vZGUoKSA9PT0gVmVjdG9yVGlsZVJlbmRlclR5cGUuVkVDVE9SID8gZ2V0VWlkKGxheWVyKSBpbiB0aWxlLmV4ZWN1dG9yR3JvdXBzIDogdGlsZS5oYXNDb250ZXh0KGxheWVyKSk7XG4gIH07XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5nZXRUaWxlSW1hZ2UgPSBmdW5jdGlvbiAodGlsZSkge1xuICAgIHJldHVybiB0aWxlLmdldEltYWdlKHRoaXMuZ2V0TGF5ZXIoKSk7XG4gIH07XG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgd2hldGhlciByZW5kZXIgc2hvdWxkIGJlIGNhbGxlZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gTGF5ZXIgaXMgcmVhZHkgdG8gYmUgcmVuZGVyZWQuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLnByZXBhcmVGcmFtZSA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgdmFyIGxheWVyUmV2aXNpb24gPSB0aGlzLmdldExheWVyKCkuZ2V0UmV2aXNpb24oKTtcblxuICAgIGlmICh0aGlzLnJlbmRlcmVkTGF5ZXJSZXZpc2lvbl8gIT0gbGF5ZXJSZXZpc2lvbikge1xuICAgICAgdGhpcy5yZW5kZXJlZFRpbGVzLmxlbmd0aCA9IDA7XG4gICAgfVxuXG4gICAgdGhpcy5yZW5kZXJlZExheWVyUmV2aXNpb25fID0gbGF5ZXJSZXZpc2lvbjtcbiAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5wcmVwYXJlRnJhbWUuY2FsbCh0aGlzLCBmcmFtZVN0YXRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vVmVjdG9yUmVuZGVyVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlIFRpbGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLnVwZGF0ZUV4ZWN1dG9yR3JvdXBfID0gZnVuY3Rpb24gKHRpbGUsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIHtcbiAgICB2YXIgbGF5ZXIgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vbGF5ZXIvVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICB2YXIgcmV2aXNpb24gPSBsYXllci5nZXRSZXZpc2lvbigpO1xuICAgIHZhciByZW5kZXJPcmRlciA9IGxheWVyLmdldFJlbmRlck9yZGVyKCkgfHwgbnVsbDtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHRpbGUud2FudGVkUmVzb2x1dGlvbjtcbiAgICB2YXIgYnVpbGRlclN0YXRlID0gdGlsZS5nZXRSZXBsYXlTdGF0ZShsYXllcik7XG5cbiAgICBpZiAoIWJ1aWxkZXJTdGF0ZS5kaXJ0eSAmJiBidWlsZGVyU3RhdGUucmVuZGVyZWRSZXNvbHV0aW9uID09PSByZXNvbHV0aW9uICYmIGJ1aWxkZXJTdGF0ZS5yZW5kZXJlZFJldmlzaW9uID09IHJldmlzaW9uICYmIGJ1aWxkZXJTdGF0ZS5yZW5kZXJlZFJlbmRlck9yZGVyID09IHJlbmRlck9yZGVyICYmIGJ1aWxkZXJTdGF0ZS5yZW5kZXJlZFogPT09IHRpbGUuc291cmNlWikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBzb3VyY2UgPSBsYXllci5nZXRTb3VyY2UoKTtcbiAgICB2YXIgZGVjbHV0dGVyID0gbGF5ZXIuZ2V0RGVjbHV0dGVyKCk7XG4gICAgdmFyIHNvdXJjZVRpbGVHcmlkID0gc291cmNlLmdldFRpbGVHcmlkKCk7XG4gICAgdmFyIHRpbGVHcmlkID0gc291cmNlLmdldFRpbGVHcmlkRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgICB2YXIgdGlsZUV4dGVudCA9IHRpbGVHcmlkLmdldFRpbGVDb29yZEV4dGVudCh0aWxlLndyYXBwZWRUaWxlQ29vcmQpO1xuICAgIHZhciBzb3VyY2VUaWxlcyA9IHNvdXJjZS5nZXRTb3VyY2VUaWxlcyhwaXhlbFJhdGlvLCBwcm9qZWN0aW9uLCB0aWxlKTtcbiAgICB2YXIgbGF5ZXJVaWQgPSBnZXRVaWQobGF5ZXIpO1xuICAgIGRlbGV0ZSB0aWxlLmhpdERldGVjdGlvbkltYWdlRGF0YVtsYXllclVpZF07XG4gICAgdGlsZS5leGVjdXRvckdyb3Vwc1tsYXllclVpZF0gPSBbXTtcblxuICAgIGlmIChkZWNsdXR0ZXIpIHtcbiAgICAgIHRpbGUuZGVjbHV0dGVyRXhlY3V0b3JHcm91cHNbbGF5ZXJVaWRdID0gW107XG4gICAgfVxuXG4gICAgdmFyIF9sb29wXzEgPSBmdW5jdGlvbiBfbG9vcF8xKHQsIHR0KSB7XG4gICAgICB2YXIgc291cmNlVGlsZSA9IHNvdXJjZVRpbGVzW3RdO1xuXG4gICAgICBpZiAoc291cmNlVGlsZS5nZXRTdGF0ZSgpICE9IFRpbGVTdGF0ZS5MT0FERUQpIHtcbiAgICAgICAgcmV0dXJuIFwiY29udGludWVcIjtcbiAgICAgIH1cblxuICAgICAgdmFyIHNvdXJjZVRpbGVDb29yZCA9IHNvdXJjZVRpbGUudGlsZUNvb3JkO1xuICAgICAgdmFyIHNvdXJjZVRpbGVFeHRlbnQgPSBzb3VyY2VUaWxlR3JpZC5nZXRUaWxlQ29vcmRFeHRlbnQoc291cmNlVGlsZUNvb3JkKTtcbiAgICAgIHZhciBzaGFyZWRFeHRlbnQgPSBnZXRJbnRlcnNlY3Rpb24odGlsZUV4dGVudCwgc291cmNlVGlsZUV4dGVudCk7XG4gICAgICB2YXIgYnVmZmVyZWRFeHRlbnQgPSBlcXVhbHMoc291cmNlVGlsZUV4dGVudCwgc2hhcmVkRXh0ZW50KSA/IG51bGwgOiBidWZmZXIoc2hhcmVkRXh0ZW50LCBsYXllci5nZXRSZW5kZXJCdWZmZXIoKSAqIHJlc29sdXRpb24sIHRoaXNfMS50bXBFeHRlbnQpO1xuICAgICAgYnVpbGRlclN0YXRlLmRpcnR5ID0gZmFsc2U7XG4gICAgICB2YXIgYnVpbGRlckdyb3VwID0gbmV3IENhbnZhc0J1aWxkZXJHcm91cCgwLCBzaGFyZWRFeHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8pO1xuICAgICAgdmFyIGRlY2x1dHRlckJ1aWxkZXJHcm91cCA9IGRlY2x1dHRlciA/IG5ldyBDYW52YXNCdWlsZGVyR3JvdXAoMCwgc2hhcmVkRXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSA6IHVuZGVmaW5lZDtcbiAgICAgIHZhciBzcXVhcmVkVG9sZXJhbmNlID0gZ2V0U3F1YXJlZFJlbmRlclRvbGVyYW5jZShyZXNvbHV0aW9uLCBwaXhlbFJhdGlvKTtcbiAgICAgIC8qKlxuICAgICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAgICAgKiBAdGhpcyB7Q2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXJ9XG4gICAgICAgKi9cblxuICAgICAgdmFyIHJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcihmZWF0dXJlKSB7XG4gICAgICAgIHZhciBzdHlsZXM7XG4gICAgICAgIHZhciBzdHlsZUZ1bmN0aW9uID0gZmVhdHVyZS5nZXRTdHlsZUZ1bmN0aW9uKCkgfHwgbGF5ZXIuZ2V0U3R5bGVGdW5jdGlvbigpO1xuXG4gICAgICAgIGlmIChzdHlsZUZ1bmN0aW9uKSB7XG4gICAgICAgICAgc3R5bGVzID0gc3R5bGVGdW5jdGlvbihmZWF0dXJlLCByZXNvbHV0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHlsZXMpIHtcbiAgICAgICAgICB2YXIgZGlydHkgPSB0aGlzLnJlbmRlckZlYXR1cmUoZmVhdHVyZSwgc3F1YXJlZFRvbGVyYW5jZSwgc3R5bGVzLCBidWlsZGVyR3JvdXAsIGRlY2x1dHRlckJ1aWxkZXJHcm91cCk7XG4gICAgICAgICAgdGhpcy5kaXJ0eV8gPSB0aGlzLmRpcnR5XyB8fCBkaXJ0eTtcbiAgICAgICAgICBidWlsZGVyU3RhdGUuZGlydHkgPSBidWlsZGVyU3RhdGUuZGlydHkgfHwgZGlydHk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIHZhciBmZWF0dXJlcyA9IHNvdXJjZVRpbGUuZ2V0RmVhdHVyZXMoKTtcblxuICAgICAgaWYgKHJlbmRlck9yZGVyICYmIHJlbmRlck9yZGVyICE9PSBidWlsZGVyU3RhdGUucmVuZGVyZWRSZW5kZXJPcmRlcikge1xuICAgICAgICBmZWF0dXJlcy5zb3J0KHJlbmRlck9yZGVyKTtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZmVhdHVyZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICB2YXIgZmVhdHVyZSA9IGZlYXR1cmVzW2ldO1xuXG4gICAgICAgIGlmICghYnVmZmVyZWRFeHRlbnQgfHwgaW50ZXJzZWN0cyhidWZmZXJlZEV4dGVudCwgZmVhdHVyZS5nZXRHZW9tZXRyeSgpLmdldEV4dGVudCgpKSkge1xuICAgICAgICAgIHJlbmRlci5jYWxsKHRoaXNfMSwgZmVhdHVyZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGV4ZWN1dG9yR3JvdXBJbnN0cnVjdGlvbnMgPSBidWlsZGVyR3JvdXAuZmluaXNoKCk7IC8vIG5vIG5lZWQgdG8gY2xpcCB3aGVuIHRoZSByZW5kZXIgdGlsZSBpcyBjb3ZlcmVkIGJ5IGEgc2luZ2xlIHNvdXJjZSB0aWxlXG5cbiAgICAgIHZhciByZXBsYXlFeHRlbnQgPSBsYXllci5nZXRSZW5kZXJNb2RlKCkgIT09IFZlY3RvclRpbGVSZW5kZXJUeXBlLlZFQ1RPUiAmJiBkZWNsdXR0ZXIgJiYgc291cmNlVGlsZXMubGVuZ3RoID09PSAxID8gbnVsbCA6IHNoYXJlZEV4dGVudDtcbiAgICAgIHZhciByZW5kZXJpbmdSZXBsYXlHcm91cCA9IG5ldyBDYW52YXNFeGVjdXRvckdyb3VwKHJlcGxheUV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbywgc291cmNlLmdldE92ZXJsYXBzKCksIGV4ZWN1dG9yR3JvdXBJbnN0cnVjdGlvbnMsIGxheWVyLmdldFJlbmRlckJ1ZmZlcigpKTtcbiAgICAgIHRpbGUuZXhlY3V0b3JHcm91cHNbbGF5ZXJVaWRdLnB1c2gocmVuZGVyaW5nUmVwbGF5R3JvdXApO1xuXG4gICAgICBpZiAoZGVjbHV0dGVyQnVpbGRlckdyb3VwKSB7XG4gICAgICAgIHZhciBkZWNsdXR0ZXJFeGVjdXRvckdyb3VwID0gbmV3IENhbnZhc0V4ZWN1dG9yR3JvdXAocmVwbGF5RXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvLCBzb3VyY2UuZ2V0T3ZlcmxhcHMoKSwgZGVjbHV0dGVyQnVpbGRlckdyb3VwLmZpbmlzaCgpLCBsYXllci5nZXRSZW5kZXJCdWZmZXIoKSk7XG4gICAgICAgIHRpbGUuZGVjbHV0dGVyRXhlY3V0b3JHcm91cHNbbGF5ZXJVaWRdLnB1c2goZGVjbHV0dGVyRXhlY3V0b3JHcm91cCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHZhciB0aGlzXzEgPSB0aGlzO1xuXG4gICAgZm9yICh2YXIgdCA9IDAsIHR0ID0gc291cmNlVGlsZXMubGVuZ3RoOyB0IDwgdHQ7ICsrdCkge1xuICAgICAgX2xvb3BfMSh0LCB0dCk7XG4gICAgfVxuXG4gICAgYnVpbGRlclN0YXRlLnJlbmRlcmVkUmV2aXNpb24gPSByZXZpc2lvbjtcbiAgICBidWlsZGVyU3RhdGUucmVuZGVyZWRaID0gdGlsZS5zb3VyY2VaO1xuICAgIGJ1aWxkZXJTdGF0ZS5yZW5kZXJlZFJlbmRlck9yZGVyID0gcmVuZGVyT3JkZXI7XG4gICAgYnVpbGRlclN0YXRlLnJlbmRlcmVkUmVzb2x1dGlvbiA9IHJlc29sdXRpb247XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaGl0VG9sZXJhbmNlIEhpdCB0b2xlcmFuY2UgaW4gcGl4ZWxzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3ZlY3Rvci5qc1wiKS5GZWF0dXJlQ2FsbGJhY2s8VD59IGNhbGxiYWNrIEZlYXR1cmUgY2FsbGJhY2suXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi4vTWFwLmpzXCIpLkhpdE1hdGNoPFQ+Pn0gbWF0Y2hlcyBUaGUgaGl0IGRldGVjdGVkIG1hdGNoZXMgd2l0aCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLmZvckVhY2hGZWF0dXJlQXRDb29yZGluYXRlID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUsIGZyYW1lU3RhdGUsIGhpdFRvbGVyYW5jZSwgY2FsbGJhY2ssIG1hdGNoZXMpIHtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IGZyYW1lU3RhdGUudmlld1N0YXRlLnJlc29sdXRpb247XG4gICAgdmFyIHJvdGF0aW9uID0gZnJhbWVTdGF0ZS52aWV3U3RhdGUucm90YXRpb247XG4gICAgaGl0VG9sZXJhbmNlID0gaGl0VG9sZXJhbmNlID09IHVuZGVmaW5lZCA/IDAgOiBoaXRUb2xlcmFuY2U7XG4gICAgdmFyIGxheWVyID0gdGhpcy5nZXRMYXllcigpO1xuICAgIHZhciBzb3VyY2UgPSBsYXllci5nZXRTb3VyY2UoKTtcbiAgICB2YXIgdGlsZUdyaWQgPSBzb3VyY2UuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKGZyYW1lU3RhdGUudmlld1N0YXRlLnByb2plY3Rpb24pO1xuICAgIHZhciBoaXRFeHRlbnQgPSBib3VuZGluZ0V4dGVudChbY29vcmRpbmF0ZV0pO1xuICAgIGJ1ZmZlcihoaXRFeHRlbnQsIHJlc29sdXRpb24gKiBoaXRUb2xlcmFuY2UsIGhpdEV4dGVudCk7XG4gICAgLyoqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vTWFwLmpzXCIpLkhpdE1hdGNoPFQ+fHRydWU+fSAqL1xuXG4gICAgdmFyIGZlYXR1cmVzID0ge307XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkaXN0YW5jZVNxIFRoZSBzcXVhcmVkIGRpc3RhbmNlIHRvIHRoZSBjbGljayBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgICAqL1xuXG4gICAgdmFyIGZlYXR1cmVDYWxsYmFjayA9IGZ1bmN0aW9uIGZlYXR1cmVDYWxsYmFjayhmZWF0dXJlLCBnZW9tZXRyeSwgZGlzdGFuY2VTcSkge1xuICAgICAgdmFyIGtleSA9IGZlYXR1cmUuZ2V0SWQoKTtcblxuICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGtleSA9IGdldFVpZChmZWF0dXJlKTtcbiAgICAgIH1cblxuICAgICAgdmFyIG1hdGNoID0gZmVhdHVyZXNba2V5XTtcblxuICAgICAgaWYgKCFtYXRjaCkge1xuICAgICAgICBpZiAoZGlzdGFuY2VTcSA9PT0gMCkge1xuICAgICAgICAgIGZlYXR1cmVzW2tleV0gPSB0cnVlO1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhmZWF0dXJlLCBsYXllciwgZ2VvbWV0cnkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbWF0Y2hlcy5wdXNoKGZlYXR1cmVzW2tleV0gPSB7XG4gICAgICAgICAgZmVhdHVyZTogZmVhdHVyZSxcbiAgICAgICAgICBsYXllcjogbGF5ZXIsXG4gICAgICAgICAgZ2VvbWV0cnk6IGdlb21ldHJ5LFxuICAgICAgICAgIGRpc3RhbmNlU3E6IGRpc3RhbmNlU3EsXG4gICAgICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChtYXRjaCAhPT0gdHJ1ZSAmJiBkaXN0YW5jZVNxIDwgbWF0Y2guZGlzdGFuY2VTcSkge1xuICAgICAgICBpZiAoZGlzdGFuY2VTcSA9PT0gMCkge1xuICAgICAgICAgIGZlYXR1cmVzW2tleV0gPSB0cnVlO1xuICAgICAgICAgIG1hdGNoZXMuc3BsaWNlKG1hdGNoZXMubGFzdEluZGV4T2YobWF0Y2gpLCAxKTtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZmVhdHVyZSwgbGF5ZXIsIGdlb21ldHJ5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIG1hdGNoLmdlb21ldHJ5ID0gZ2VvbWV0cnk7XG4gICAgICAgIG1hdGNoLmRpc3RhbmNlU3EgPSBkaXN0YW5jZVNxO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICB2YXIgcmVuZGVyZWRUaWxlcyA9XG4gICAgLyoqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuLi8uLi9WZWN0b3JSZW5kZXJUaWxlLmpzXCIpLmRlZmF1bHQ+fSAqL1xuICAgIHRoaXMucmVuZGVyZWRUaWxlcztcbiAgICB2YXIgZm91bmQ7XG5cbiAgICB2YXIgX2xvb3BfMiA9IGZ1bmN0aW9uIF9sb29wXzIoaSwgaWkpIHtcbiAgICAgIHZhciB0aWxlID0gcmVuZGVyZWRUaWxlc1tpXTtcbiAgICAgIHZhciB0aWxlRXh0ZW50ID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHRpbGUud3JhcHBlZFRpbGVDb29yZCk7XG5cbiAgICAgIGlmICghaW50ZXJzZWN0cyh0aWxlRXh0ZW50LCBoaXRFeHRlbnQpKSB7XG4gICAgICAgIHJldHVybiBcImNvbnRpbnVlXCI7XG4gICAgICB9XG5cbiAgICAgIHZhciBsYXllclVpZCA9IGdldFVpZChsYXllcik7XG4gICAgICB2YXIgZXhlY3V0b3JHcm91cHMgPSBbdGlsZS5leGVjdXRvckdyb3Vwc1tsYXllclVpZF1dO1xuICAgICAgdmFyIGRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzID0gdGlsZS5kZWNsdXR0ZXJFeGVjdXRvckdyb3Vwc1tsYXllclVpZF07XG5cbiAgICAgIGlmIChkZWNsdXR0ZXJFeGVjdXRvckdyb3Vwcykge1xuICAgICAgICBleGVjdXRvckdyb3Vwcy5wdXNoKGRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzKTtcbiAgICAgIH1cblxuICAgICAgZXhlY3V0b3JHcm91cHMuc29tZShmdW5jdGlvbiAoZXhlY3V0b3JHcm91cHMpIHtcbiAgICAgICAgdmFyIGRlY2x1dHRlcmVkRmVhdHVyZXMgPSBleGVjdXRvckdyb3VwcyA9PT0gZGVjbHV0dGVyRXhlY3V0b3JHcm91cHMgPyBmcmFtZVN0YXRlLmRlY2x1dHRlclRyZWUuYWxsKCkubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZW0udmFsdWU7XG4gICAgICAgIH0pIDogbnVsbDtcblxuICAgICAgICBmb3IgKHZhciB0ID0gMCwgdHQgPSBleGVjdXRvckdyb3Vwcy5sZW5ndGg7IHQgPCB0dDsgKyt0KSB7XG4gICAgICAgICAgdmFyIGV4ZWN1dG9yR3JvdXAgPSBleGVjdXRvckdyb3Vwc1t0XTtcbiAgICAgICAgICBmb3VuZCA9IGV4ZWN1dG9yR3JvdXAuZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGUoY29vcmRpbmF0ZSwgcmVzb2x1dGlvbiwgcm90YXRpb24sIGhpdFRvbGVyYW5jZSwgZmVhdHVyZUNhbGxiYWNrLCBkZWNsdXR0ZXJlZEZlYXR1cmVzKTtcblxuICAgICAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gcmVuZGVyZWRUaWxlcy5sZW5ndGg7ICFmb3VuZCAmJiBpIDwgaWk7ICsraSkge1xuICAgICAgX2xvb3BfMihpLCBpaSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZvdW5kO1xuICB9O1xuICAvKipcbiAgICogQXN5bmNocm9ub3VzIGxheWVyIGxldmVsIGhpdCBkZXRlY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PGltcG9ydChcIi4uLy4uL0ZlYXR1cmVcIikuZGVmYXVsdD4+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCBhbiBhcnJheSBvZiBmZWF0dXJlcy5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0RmVhdHVyZXMgPSBmdW5jdGlvbiAocGl4ZWwpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIGxheWVyID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vbGF5ZXIvVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgdGhpcy5nZXRMYXllcigpO1xuICAgICAgdmFyIGxheWVyVWlkID0gZ2V0VWlkKGxheWVyKTtcbiAgICAgIHZhciBzb3VyY2UgPSBsYXllci5nZXRTb3VyY2UoKTtcbiAgICAgIHZhciBwcm9qZWN0aW9uID0gdGhpcy5yZW5kZXJlZFByb2plY3Rpb247XG4gICAgICB2YXIgcHJvamVjdGlvbkV4dGVudCA9IHByb2plY3Rpb24uZ2V0RXh0ZW50KCk7XG4gICAgICB2YXIgcmVzb2x1dGlvbiA9IHRoaXMucmVuZGVyZWRSZXNvbHV0aW9uO1xuICAgICAgdmFyIHRpbGVHcmlkID0gc291cmNlLmdldFRpbGVHcmlkRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgICAgIHZhciBjb29yZGluYXRlID0gYXBwbHlUcmFuc2Zvcm0odGhpcy5yZW5kZXJlZFBpeGVsVG9Db29yZGluYXRlVHJhbnNmb3JtXywgcGl4ZWwuc2xpY2UoKSk7XG4gICAgICB2YXIgdGlsZUNvb3JkID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRm9yQ29vcmRBbmRSZXNvbHV0aW9uKGNvb3JkaW5hdGUsIHJlc29sdXRpb24pO1xuICAgICAgdmFyIHRpbGU7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRoaXMucmVuZGVyZWRUaWxlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIGlmICh0aWxlQ29vcmQudG9TdHJpbmcoKSA9PT0gdGhpcy5yZW5kZXJlZFRpbGVzW2ldLnRpbGVDb29yZC50b1N0cmluZygpKSB7XG4gICAgICAgICAgdGlsZSA9IHRoaXMucmVuZGVyZWRUaWxlc1tpXTtcblxuICAgICAgICAgIGlmICh0aWxlLmdldFN0YXRlKCkgPT09IFRpbGVTdGF0ZS5MT0FERUQgJiYgdGlsZS5oaWZpKSB7XG4gICAgICAgICAgICB2YXIgZXh0ZW50XzEgPSB0aWxlR3JpZC5nZXRUaWxlQ29vcmRFeHRlbnQodGlsZS50aWxlQ29vcmQpO1xuXG4gICAgICAgICAgICBpZiAoc291cmNlLmdldFdyYXBYKCkgJiYgcHJvamVjdGlvbi5jYW5XcmFwWCgpICYmICFjb250YWluc0V4dGVudChwcm9qZWN0aW9uRXh0ZW50LCBleHRlbnRfMSkpIHtcbiAgICAgICAgICAgICAgd3JhcFgoY29vcmRpbmF0ZSwgcHJvamVjdGlvbik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRpbGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCF0aWxlIHx8IHRpbGUubG9hZGluZ1NvdXJjZVRpbGVzID4gMCkge1xuICAgICAgICByZXNvbHZlKFtdKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgZXh0ZW50ID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHRpbGUud3JhcHBlZFRpbGVDb29yZCk7XG4gICAgICB2YXIgY29ybmVyID0gZ2V0VG9wTGVmdChleHRlbnQpO1xuICAgICAgdmFyIHRpbGVQaXhlbCA9IFsoY29vcmRpbmF0ZVswXSAtIGNvcm5lclswXSkgLyByZXNvbHV0aW9uLCAoY29ybmVyWzFdIC0gY29vcmRpbmF0ZVsxXSkgLyByZXNvbHV0aW9uXTtcbiAgICAgIHZhciBmZWF0dXJlcyA9IHRpbGUuZ2V0U291cmNlVGlsZXMoKS5yZWR1Y2UoZnVuY3Rpb24gKGFjY3VtdWxhdG9yLCBzb3VyY2VUaWxlKSB7XG4gICAgICAgIHJldHVybiBhY2N1bXVsYXRvci5jb25jYXQoc291cmNlVGlsZS5nZXRGZWF0dXJlcygpKTtcbiAgICAgIH0sIFtdKTtcbiAgICAgIHZhciBoaXREZXRlY3Rpb25JbWFnZURhdGEgPSB0aWxlLmhpdERldGVjdGlvbkltYWdlRGF0YVtsYXllclVpZF07XG5cbiAgICAgIGlmICghaGl0RGV0ZWN0aW9uSW1hZ2VEYXRhICYmICF0aGlzLmFuaW1hdGluZ09ySW50ZXJhY3RpbmdfKSB7XG4gICAgICAgIHZhciB0aWxlU2l6ZSA9IHRvU2l6ZSh0aWxlR3JpZC5nZXRUaWxlU2l6ZSh0aWxlR3JpZC5nZXRaRm9yUmVzb2x1dGlvbihyZXNvbHV0aW9uKSkpO1xuICAgICAgICB2YXIgc2l6ZSA9IFt0aWxlU2l6ZVswXSAvIDIsIHRpbGVTaXplWzFdIC8gMl07XG4gICAgICAgIHZhciByb3RhdGlvbiA9IHRoaXMucmVuZGVyZWRSb3RhdGlvbl87XG4gICAgICAgIHZhciB0cmFuc2Zvcm1zID0gW3RoaXMuZ2V0UmVuZGVyVHJhbnNmb3JtKHRpbGVHcmlkLmdldFRpbGVDb29yZENlbnRlcih0aWxlLndyYXBwZWRUaWxlQ29vcmQpLCByZXNvbHV0aW9uLCAwLCAwLjUsIHNpemVbMF0sIHNpemVbMV0sIDApXTtcbiAgICAgICAgaGl0RGV0ZWN0aW9uSW1hZ2VEYXRhID0gY3JlYXRlSGl0RGV0ZWN0aW9uSW1hZ2VEYXRhKHRpbGVTaXplLCB0cmFuc2Zvcm1zLCBmZWF0dXJlcywgbGF5ZXIuZ2V0U3R5bGVGdW5jdGlvbigpLCB0aWxlR3JpZC5nZXRUaWxlQ29vcmRFeHRlbnQodGlsZS53cmFwcGVkVGlsZUNvb3JkKSwgdGlsZS5nZXRSZXBsYXlTdGF0ZShsYXllcikucmVuZGVyZWRSZXNvbHV0aW9uLCByb3RhdGlvbik7XG4gICAgICAgIHRpbGUuaGl0RGV0ZWN0aW9uSW1hZ2VEYXRhW2xheWVyVWlkXSA9IGhpdERldGVjdGlvbkltYWdlRGF0YTtcbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZShoaXREZXRlY3QodGlsZVBpeGVsLCBmZWF0dXJlcywgaGl0RGV0ZWN0aW9uSW1hZ2VEYXRhKSk7XG4gICAgfS5iaW5kKHRoaXMpKTtcbiAgfTtcbiAgLyoqXG4gICAqIFBlcmZvcm0gYWN0aW9uIG5lY2Vzc2FyeSB0byBnZXQgdGhlIGxheWVyIHJlbmRlcmVkIGFmdGVyIG5ldyBmb250cyBoYXZlIGxvYWRlZFxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5oYW5kbGVGb250c0NoYW5nZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgY2xlYXIodGhpcy5yZW5kZXJUaWxlSW1hZ2VRdWV1ZV8pO1xuICAgIHZhciBsYXllciA9IHRoaXMuZ2V0TGF5ZXIoKTtcblxuICAgIGlmIChsYXllci5nZXRWaXNpYmxlKCkgJiYgdGhpcy5yZW5kZXJlZExheWVyUmV2aXNpb25fICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGxheWVyLmNoYW5nZWQoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGUgY2hhbmdlcyBpbiBpbWFnZSBzdHlsZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9ldmVudHMvRXZlbnQuanNcIikuZGVmYXVsdH0gZXZlbnQgSW1hZ2Ugc3R5bGUgY2hhbmdlIGV2ZW50LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5oYW5kbGVTdHlsZUltYWdlQ2hhbmdlXyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHRoaXMucmVuZGVySWZSZWFkeUFuZFZpc2libGUoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciBkZWNsdXR0ZXIgaXRlbXMgZm9yIHRoaXMgbGF5ZXJcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucmVuZGVyRGVjbHV0dGVyID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUpIHtcbiAgICB2YXIgdmlld0hpbnRzID0gZnJhbWVTdGF0ZS52aWV3SGludHM7XG4gICAgdmFyIGhpZmkgPSAhKHZpZXdIaW50c1tWaWV3SGludC5BTklNQVRJTkddIHx8IHZpZXdIaW50c1tWaWV3SGludC5JTlRFUkFDVElOR10pO1xuICAgIHZhciB0aWxlcyA9XG4gICAgLyoqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuLi8uLi9WZWN0b3JSZW5kZXJUaWxlLmpzXCIpLmRlZmF1bHQ+fSAqL1xuICAgIHRoaXMucmVuZGVyZWRUaWxlcztcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRpbGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciB0aWxlID0gdGlsZXNbaV07XG4gICAgICB2YXIgZGVjbHV0dGVyRXhlY3V0b3JHcm91cHMgPSB0aWxlLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzW2dldFVpZCh0aGlzLmdldExheWVyKCkpXTtcblxuICAgICAgaWYgKGRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzKSB7XG4gICAgICAgIGZvciAodmFyIGogPSBkZWNsdXR0ZXJFeGVjdXRvckdyb3Vwcy5sZW5ndGggLSAxOyBqID49IDA7IC0taikge1xuICAgICAgICAgIGRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzW2pdLmV4ZWN1dGUodGhpcy5jb250ZXh0LCAxLCB0aGlzLmdldFRpbGVSZW5kZXJUcmFuc2Zvcm0odGlsZSwgZnJhbWVTdGF0ZSksIGZyYW1lU3RhdGUudmlld1N0YXRlLnJvdGF0aW9uLCBoaWZpLCB1bmRlZmluZWQsIGZyYW1lU3RhdGUuZGVjbHV0dGVyVHJlZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLmdldFRpbGVSZW5kZXJUcmFuc2Zvcm0gPSBmdW5jdGlvbiAodGlsZSwgZnJhbWVTdGF0ZSkge1xuICAgIHZhciBwaXhlbFJhdGlvID0gZnJhbWVTdGF0ZS5waXhlbFJhdGlvO1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICB2YXIgY2VudGVyID0gdmlld1N0YXRlLmNlbnRlcjtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHZpZXdTdGF0ZS5yZXNvbHV0aW9uO1xuICAgIHZhciByb3RhdGlvbiA9IHZpZXdTdGF0ZS5yb3RhdGlvbjtcbiAgICB2YXIgc2l6ZSA9IGZyYW1lU3RhdGUuc2l6ZTtcbiAgICB2YXIgd2lkdGggPSBNYXRoLnJvdW5kKHNpemVbMF0gKiBwaXhlbFJhdGlvKTtcbiAgICB2YXIgaGVpZ2h0ID0gTWF0aC5yb3VuZChzaXplWzFdICogcGl4ZWxSYXRpbyk7XG4gICAgdmFyIHNvdXJjZSA9IHRoaXMuZ2V0TGF5ZXIoKS5nZXRTb3VyY2UoKTtcbiAgICB2YXIgdGlsZUdyaWQgPSBzb3VyY2UuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKGZyYW1lU3RhdGUudmlld1N0YXRlLnByb2plY3Rpb24pO1xuICAgIHZhciB0aWxlQ29vcmQgPSB0aWxlLnRpbGVDb29yZDtcbiAgICB2YXIgdGlsZUV4dGVudCA9IHRpbGVHcmlkLmdldFRpbGVDb29yZEV4dGVudCh0aWxlLndyYXBwZWRUaWxlQ29vcmQpO1xuICAgIHZhciB3b3JsZE9mZnNldCA9IHRpbGVHcmlkLmdldFRpbGVDb29yZEV4dGVudCh0aWxlQ29vcmQsIHRoaXMudG1wRXh0ZW50KVswXSAtIHRpbGVFeHRlbnRbMF07XG4gICAgdmFyIHRyYW5zZm9ybSA9IG11bHRpcGx5KHNjYWxlKHRoaXMuaW52ZXJzZVBpeGVsVHJhbnNmb3JtLnNsaWNlKCksIDEgLyBwaXhlbFJhdGlvLCAxIC8gcGl4ZWxSYXRpbyksIHRoaXMuZ2V0UmVuZGVyVHJhbnNmb3JtKGNlbnRlciwgcmVzb2x1dGlvbiwgcm90YXRpb24sIHBpeGVsUmF0aW8sIHdpZHRoLCBoZWlnaHQsIHdvcmxkT2Zmc2V0KSk7XG4gICAgcmV0dXJuIHRyYW5zZm9ybTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgbGF5ZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRhcmdldCBUYXJnZXQgdGhhdCBtYXkgYmUgdXNlZCB0byByZW5kZXIgY29udGVudCB0by5cbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9IFRoZSByZW5kZXJlZCBlbGVtZW50LlxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJGcmFtZSA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlLCB0YXJnZXQpIHtcbiAgICB2YXIgdmlld0hpbnRzID0gZnJhbWVTdGF0ZS52aWV3SGludHM7XG4gICAgdmFyIGhpZmkgPSAhKHZpZXdIaW50c1tWaWV3SGludC5BTklNQVRJTkddIHx8IHZpZXdIaW50c1tWaWV3SGludC5JTlRFUkFDVElOR10pO1xuICAgIHRoaXMucmVuZGVyUXVldWVkVGlsZUltYWdlc18oaGlmaSwgZnJhbWVTdGF0ZSk7XG5cbiAgICBfc3VwZXIucHJvdG90eXBlLnJlbmRlckZyYW1lLmNhbGwodGhpcywgZnJhbWVTdGF0ZSwgdGFyZ2V0KTtcblxuICAgIHRoaXMucmVuZGVyZWRQaXhlbFRvQ29vcmRpbmF0ZVRyYW5zZm9ybV8gPSBmcmFtZVN0YXRlLnBpeGVsVG9Db29yZGluYXRlVHJhbnNmb3JtLnNsaWNlKCk7XG4gICAgdGhpcy5yZW5kZXJlZFJvdGF0aW9uXyA9IGZyYW1lU3RhdGUudmlld1N0YXRlLnJvdGF0aW9uO1xuICAgIHZhciBsYXllciA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9sYXllci9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgdGhpcy5nZXRMYXllcigpO1xuICAgIHZhciByZW5kZXJNb2RlID0gbGF5ZXIuZ2V0UmVuZGVyTW9kZSgpO1xuXG4gICAgaWYgKHJlbmRlck1vZGUgPT09IFZlY3RvclRpbGVSZW5kZXJUeXBlLklNQUdFKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gICAgfVxuXG4gICAgdmFyIHNvdXJjZSA9IGxheWVyLmdldFNvdXJjZSgpOyAvLyBVbnF1ZXVlIHRpbGVzIGZyb20gdGhlIGltYWdlIHF1ZXVlIHdoZW4gd2UgZG9uJ3QgbmVlZCBhbnkgbW9yZVxuXG4gICAgdmFyIHVzZWRUaWxlcyA9IGZyYW1lU3RhdGUudXNlZFRpbGVzW2dldFVpZChzb3VyY2UpXTtcblxuICAgIGZvciAodmFyIHRpbGVVaWQgaW4gdGhpcy5yZW5kZXJUaWxlSW1hZ2VRdWV1ZV8pIHtcbiAgICAgIGlmICghdXNlZFRpbGVzIHx8ICEodGlsZVVpZCBpbiB1c2VkVGlsZXMpKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnJlbmRlclRpbGVJbWFnZVF1ZXVlX1t0aWxlVWlkXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dDtcbiAgICB2YXIgcmVwbGF5VHlwZXMgPSBWRUNUT1JfUkVQTEFZU1tyZW5kZXJNb2RlXTtcbiAgICB2YXIgdmlld1N0YXRlID0gZnJhbWVTdGF0ZS52aWV3U3RhdGU7XG4gICAgdmFyIHJvdGF0aW9uID0gdmlld1N0YXRlLnJvdGF0aW9uO1xuICAgIHZhciB0aWxlcyA9IHRoaXMucmVuZGVyZWRUaWxlcztcbiAgICB2YXIgY2xpcHMgPSBbXTtcbiAgICB2YXIgY2xpcFpzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gdGlsZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHZhciB0aWxlID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vVmVjdG9yUmVuZGVyVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgdGlsZXNbaV07XG4gICAgICB2YXIgdHJhbnNmb3JtID0gdGhpcy5nZXRUaWxlUmVuZGVyVHJhbnNmb3JtKHRpbGUsIGZyYW1lU3RhdGUpO1xuICAgICAgdmFyIGV4ZWN1dG9yR3JvdXBzID0gdGlsZS5leGVjdXRvckdyb3Vwc1tnZXRVaWQobGF5ZXIpXTtcbiAgICAgIHZhciBjbGlwcGVkID0gZmFsc2U7XG5cbiAgICAgIGZvciAodmFyIHQgPSAwLCB0dCA9IGV4ZWN1dG9yR3JvdXBzLmxlbmd0aDsgdCA8IHR0OyArK3QpIHtcbiAgICAgICAgdmFyIGV4ZWN1dG9yR3JvdXAgPSBleGVjdXRvckdyb3Vwc1t0XTtcblxuICAgICAgICBpZiAoIWV4ZWN1dG9yR3JvdXAuaGFzRXhlY3V0b3JzKHJlcGxheVR5cGVzKSkge1xuICAgICAgICAgIC8vIHNvdXJjZVRpbGUgaGFzIG5vIGluc3RydWN0aW9ucyBvZiB0aGUgdHlwZXMgd2Ugd2FudCB0byByZW5kZXJcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjdXJyZW50WiA9IHRpbGUudGlsZUNvb3JkWzBdO1xuICAgICAgICB2YXIgY3VycmVudENsaXAgPSB2b2lkIDA7XG5cbiAgICAgICAgaWYgKCFjbGlwcGVkKSB7XG4gICAgICAgICAgY3VycmVudENsaXAgPSBleGVjdXRvckdyb3VwLmdldENsaXBDb29yZHModHJhbnNmb3JtKTtcblxuICAgICAgICAgIGlmIChjdXJyZW50Q2xpcCkge1xuICAgICAgICAgICAgY29udGV4dC5zYXZlKCk7IC8vIENyZWF0ZSBhIGNsaXAgbWFzayBmb3IgcmVnaW9ucyBpbiB0aGlzIGxvdyByZXNvbHV0aW9uIHRpbGUgdGhhdCBhcmVcbiAgICAgICAgICAgIC8vIGFscmVhZHkgZmlsbGVkIGJ5IGEgaGlnaGVyIHJlc29sdXRpb24gdGlsZVxuXG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMCwgamogPSBjbGlwcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgICAgICAgICAgIHZhciBjbGlwID0gY2xpcHNbal07XG5cbiAgICAgICAgICAgICAgaWYgKGN1cnJlbnRaIDwgY2xpcFpzW2pdKSB7XG4gICAgICAgICAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTsgLy8gY291bnRlci1jbG9ja3dpc2UgKG91dGVyIHJpbmcpIGZvciBjdXJyZW50IHRpbGVcblxuICAgICAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKGN1cnJlbnRDbGlwWzBdLCBjdXJyZW50Q2xpcFsxXSk7XG4gICAgICAgICAgICAgICAgY29udGV4dC5saW5lVG8oY3VycmVudENsaXBbMl0sIGN1cnJlbnRDbGlwWzNdKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhjdXJyZW50Q2xpcFs0XSwgY3VycmVudENsaXBbNV0pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGN1cnJlbnRDbGlwWzZdLCBjdXJyZW50Q2xpcFs3XSk7IC8vIGNsb2Nrd2lzZSAoaW5uZXIgcmluZykgZm9yIGhpZ2hlciByZXNvbHV0aW9uIHRpbGVcblxuICAgICAgICAgICAgICAgIGNvbnRleHQubW92ZVRvKGNsaXBbNl0sIGNsaXBbN10pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGNsaXBbNF0sIGNsaXBbNV0pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGNsaXBbMl0sIGNsaXBbM10pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGNsaXBbMF0sIGNsaXBbMV0pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQuY2xpcCgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZXhlY3V0b3JHcm91cC5leGVjdXRlKGNvbnRleHQsIDEsIHRyYW5zZm9ybSwgcm90YXRpb24sIGhpZmksIHJlcGxheVR5cGVzKTtcblxuICAgICAgICBpZiAoIWNsaXBwZWQgJiYgY3VycmVudENsaXApIHtcbiAgICAgICAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgICAgICAgICBjbGlwcy5wdXNoKGN1cnJlbnRDbGlwKTtcbiAgICAgICAgICBjbGlwWnMucHVzaChjdXJyZW50Wik7XG4gICAgICAgICAgY2xpcHBlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGhpZmkgV2UgaGF2ZSB0aW1lIHRvIHJlbmRlciBhIGhpZ2ggZmlkZWxpdHkgbWFwIGltYWdlLlxuICAgKiBAcGFyYW0ge2ltcG9ydCgnLi4vLi4vUGx1Z2dhYmxlTWFwLmpzJykuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucmVuZGVyUXVldWVkVGlsZUltYWdlc18gPSBmdW5jdGlvbiAoaGlmaSwgZnJhbWVTdGF0ZSkge1xuICAgIC8vIFdoZW4gd2UgZG9uJ3QgaGF2ZSB0aW1lIHRvIHJlbmRlciBoaWZpLCBvbmx5IHJlbmRlciB0aWxlcyB1bnRpbCB3ZSBoYXZlIHVzZWQgdXBcbiAgICAvLyBoYWxmIG9mIHRoZSBmcmFtZSBidWRnZXQgb2YgMTYgbXNcbiAgICBmb3IgKHZhciB1aWQgaW4gdGhpcy5yZW5kZXJUaWxlSW1hZ2VRdWV1ZV8pIHtcbiAgICAgIGlmICghaGlmaSAmJiBEYXRlLm5vdygpIC0gZnJhbWVTdGF0ZS50aW1lID4gOCkge1xuICAgICAgICBmcmFtZVN0YXRlLmFuaW1hdGUgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgdmFyIHRpbGUgPSB0aGlzLnJlbmRlclRpbGVJbWFnZVF1ZXVlX1t1aWRdO1xuICAgICAgZGVsZXRlIHRoaXMucmVuZGVyVGlsZUltYWdlUXVldWVfW3VpZF07XG4gICAgICB0aGlzLnJlbmRlclRpbGVJbWFnZV8odGlsZSwgZnJhbWVTdGF0ZSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzcXVhcmVkVG9sZXJhbmNlIFNxdWFyZWQgdG9sZXJhbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3N0eWxlL1N0eWxlLmpzXCIpLmRlZmF1bHR8QXJyYXk8aW1wb3J0KFwiLi4vLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdD59IHN0eWxlcyBUaGUgc3R5bGUgb3IgYXJyYXkgb2Ygc3R5bGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IGJ1aWxkZXJHcm91cCBSZXBsYXkgZ3JvdXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdD19IG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgQnVpbGRlciBncm91cCBmb3IgZGVjbHV0dGVyaW5nLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgYW4gaW1hZ2UgaXMgbG9hZGluZy5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucmVuZGVyRmVhdHVyZSA9IGZ1bmN0aW9uIChmZWF0dXJlLCBzcXVhcmVkVG9sZXJhbmNlLCBzdHlsZXMsIGJ1aWxkZXJHcm91cCwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkge1xuICAgIGlmICghc3R5bGVzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGxvYWRpbmcgPSBmYWxzZTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KHN0eWxlcykpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHN0eWxlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIGxvYWRpbmcgPSByZW5kZXJGZWF0dXJlKGJ1aWxkZXJHcm91cCwgZmVhdHVyZSwgc3R5bGVzW2ldLCBzcXVhcmVkVG9sZXJhbmNlLCB0aGlzLmJvdW5kSGFuZGxlU3R5bGVJbWFnZUNoYW5nZV8sIHVuZGVmaW5lZCwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkgfHwgbG9hZGluZztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbG9hZGluZyA9IHJlbmRlckZlYXR1cmUoYnVpbGRlckdyb3VwLCBmZWF0dXJlLCBzdHlsZXMsIHNxdWFyZWRUb2xlcmFuY2UsIHRoaXMuYm91bmRIYW5kbGVTdHlsZUltYWdlQ2hhbmdlXywgdW5kZWZpbmVkLCBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbG9hZGluZztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vVmVjdG9yUmVuZGVyVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlIFRpbGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IEEgbmV3IHRpbGUgaW1hZ2Ugd2FzIHJlbmRlcmVkLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS50aWxlSW1hZ2VOZWVkc1JlbmRlcl8gPSBmdW5jdGlvbiAodGlsZSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikge1xuICAgIHZhciBsYXllciA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9sYXllci9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgdGhpcy5nZXRMYXllcigpO1xuICAgIHZhciByZXBsYXlTdGF0ZSA9IHRpbGUuZ2V0UmVwbGF5U3RhdGUobGF5ZXIpO1xuICAgIHZhciByZXZpc2lvbiA9IGxheWVyLmdldFJldmlzaW9uKCk7XG4gICAgdmFyIHNvdXJjZVogPSB0aWxlLnNvdXJjZVo7XG4gICAgdmFyIHJlc29sdXRpb24gPSB0aWxlLndhbnRlZFJlc29sdXRpb247XG4gICAgcmV0dXJuIHJlcGxheVN0YXRlLnJlbmRlcmVkVGlsZVJlc29sdXRpb24gIT09IHJlc29sdXRpb24gfHwgcmVwbGF5U3RhdGUucmVuZGVyZWRUaWxlUmV2aXNpb24gIT09IHJldmlzaW9uIHx8IHJlcGxheVN0YXRlLnJlbmRlcmVkVGlsZVogIT09IHNvdXJjZVo7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1ZlY3RvclJlbmRlclRpbGUuanNcIikuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcFwiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJUaWxlSW1hZ2VfID0gZnVuY3Rpb24gKHRpbGUsIGZyYW1lU3RhdGUpIHtcbiAgICB2YXIgbGF5ZXIgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vbGF5ZXIvVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICB2YXIgcmVwbGF5U3RhdGUgPSB0aWxlLmdldFJlcGxheVN0YXRlKGxheWVyKTtcbiAgICB2YXIgcmV2aXNpb24gPSBsYXllci5nZXRSZXZpc2lvbigpO1xuICAgIHZhciBleGVjdXRvckdyb3VwcyA9IHRpbGUuZXhlY3V0b3JHcm91cHNbZ2V0VWlkKGxheWVyKV07XG4gICAgcmVwbGF5U3RhdGUucmVuZGVyZWRUaWxlUmV2aXNpb24gPSByZXZpc2lvbjtcbiAgICByZXBsYXlTdGF0ZS5yZW5kZXJlZFRpbGVaID0gdGlsZS5zb3VyY2VaO1xuICAgIHZhciB0aWxlQ29vcmQgPSB0aWxlLndyYXBwZWRUaWxlQ29vcmQ7XG4gICAgdmFyIHogPSB0aWxlQ29vcmRbMF07XG4gICAgdmFyIHNvdXJjZSA9IGxheWVyLmdldFNvdXJjZSgpO1xuICAgIHZhciBwaXhlbFJhdGlvID0gZnJhbWVTdGF0ZS5waXhlbFJhdGlvO1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICB2YXIgcHJvamVjdGlvbiA9IHZpZXdTdGF0ZS5wcm9qZWN0aW9uO1xuICAgIHZhciB0aWxlR3JpZCA9IHNvdXJjZS5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgdmFyIHRpbGVSZXNvbHV0aW9uID0gdGlsZUdyaWQuZ2V0UmVzb2x1dGlvbih0aWxlLnRpbGVDb29yZFswXSk7XG4gICAgdmFyIHJlbmRlclBpeGVsUmF0aW8gPSBmcmFtZVN0YXRlLnBpeGVsUmF0aW8gLyB0aWxlLndhbnRlZFJlc29sdXRpb24gKiB0aWxlUmVzb2x1dGlvbjtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHRpbGVHcmlkLmdldFJlc29sdXRpb24oeik7XG4gICAgdmFyIGNvbnRleHQgPSB0aWxlLmdldENvbnRleHQobGF5ZXIpOyAvLyBJbmNyZWFzZSB0aWxlIHNpemUgd2hlbiBvdmVyem9vbWluZyBmb3IgbG93IHBpeGVsIHJhdGlvLCB0byBhdm9pZCBibHVycnkgdGlsZXNcblxuICAgIHBpeGVsUmF0aW8gPSBNYXRoLnJvdW5kKE1hdGgubWF4KHBpeGVsUmF0aW8sIHJlbmRlclBpeGVsUmF0aW8gLyBwaXhlbFJhdGlvKSk7XG4gICAgdmFyIHNpemUgPSBzb3VyY2UuZ2V0VGlsZVBpeGVsU2l6ZSh6LCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKTtcbiAgICBjb250ZXh0LmNhbnZhcy53aWR0aCA9IHNpemVbMF07XG4gICAgY29udGV4dC5jYW52YXMuaGVpZ2h0ID0gc2l6ZVsxXTtcbiAgICB2YXIgcmVuZGVyU2NhbGUgPSBwaXhlbFJhdGlvIC8gcmVuZGVyUGl4ZWxSYXRpbztcblxuICAgIGlmIChyZW5kZXJTY2FsZSAhPT0gMSkge1xuICAgICAgdmFyIGNhbnZhc1RyYW5zZm9ybSA9IHJlc2V0VHJhbnNmb3JtKHRoaXMudG1wVHJhbnNmb3JtXyk7XG4gICAgICBzY2FsZVRyYW5zZm9ybShjYW52YXNUcmFuc2Zvcm0sIHJlbmRlclNjYWxlLCByZW5kZXJTY2FsZSk7XG4gICAgICBjb250ZXh0LnNldFRyYW5zZm9ybS5hcHBseShjb250ZXh0LCBjYW52YXNUcmFuc2Zvcm0pO1xuICAgIH1cblxuICAgIHZhciB0aWxlRXh0ZW50ID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHRpbGVDb29yZCwgdGhpcy50bXBFeHRlbnQpO1xuICAgIHZhciBwaXhlbFNjYWxlID0gcmVuZGVyUGl4ZWxSYXRpbyAvIHJlc29sdXRpb247XG4gICAgdmFyIHRyYW5zZm9ybSA9IHJlc2V0VHJhbnNmb3JtKHRoaXMudG1wVHJhbnNmb3JtXyk7XG4gICAgc2NhbGVUcmFuc2Zvcm0odHJhbnNmb3JtLCBwaXhlbFNjYWxlLCAtcGl4ZWxTY2FsZSk7XG4gICAgdHJhbnNsYXRlVHJhbnNmb3JtKHRyYW5zZm9ybSwgLXRpbGVFeHRlbnRbMF0sIC10aWxlRXh0ZW50WzNdKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGV4ZWN1dG9yR3JvdXBzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBleGVjdXRvckdyb3VwID0gZXhlY3V0b3JHcm91cHNbaV07XG4gICAgICBleGVjdXRvckdyb3VwLmV4ZWN1dGUoY29udGV4dCwgcmVuZGVyU2NhbGUsIHRyYW5zZm9ybSwgMCwgdHJ1ZSwgSU1BR0VfUkVQTEFZU1tsYXllci5nZXRSZW5kZXJNb2RlKCldKTtcbiAgICB9XG5cbiAgICByZXBsYXlTdGF0ZS5yZW5kZXJlZFRpbGVSZXNvbHV0aW9uID0gdGlsZS53YW50ZWRSZXNvbHV0aW9uO1xuICB9O1xuXG4gIHJldHVybiBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlcjtcbn0oQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlcjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2xheWVyL1ZlY3RvclRpbGVcbiAqL1xuXG5cbmltcG9ydCBCYXNlVmVjdG9yTGF5ZXIgZnJvbSAnLi9CYXNlVmVjdG9yLmpzJztcbmltcG9ydCBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlciBmcm9tICcuLi9yZW5kZXJlci9jYW52YXMvVmVjdG9yVGlsZUxheWVyLmpzJztcbmltcG9ydCBUaWxlUHJvcGVydHkgZnJvbSAnLi9UaWxlUHJvcGVydHkuanMnO1xuaW1wb3J0IFZlY3RvclRpbGVSZW5kZXJUeXBlIGZyb20gJy4vVmVjdG9yVGlsZVJlbmRlclR5cGUuanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vYXNzZXJ0cy5qcyc7XG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICcuLi9vYmouanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NsYXNzTmFtZT0nb2wtbGF5ZXInXSBBIENTUyBjbGFzcyBuYW1lIHRvIHNldCB0byB0aGUgbGF5ZXIgZWxlbWVudC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbb3BhY2l0eT0xXSBPcGFjaXR5ICgwLCAxKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3Zpc2libGU9dHJ1ZV0gVmlzaWJpbGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF0gVGhlIGJvdW5kaW5nIGV4dGVudCBmb3IgbGF5ZXIgcmVuZGVyaW5nLiAgVGhlIGxheWVyIHdpbGwgbm90IGJlXG4gKiByZW5kZXJlZCBvdXRzaWRlIG9mIHRoaXMgZXh0ZW50LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6SW5kZXhdIFRoZSB6LWluZGV4IGZvciBsYXllciByZW5kZXJpbmcuICBBdCByZW5kZXJpbmcgdGltZSwgdGhlIGxheWVyc1xuICogd2lsbCBiZSBvcmRlcmVkLCBmaXJzdCBieSBaLWluZGV4IGFuZCB0aGVuIGJ5IHBvc2l0aW9uLiBXaGVuIGB1bmRlZmluZWRgLCBhIGB6SW5kZXhgIG9mIDAgaXMgYXNzdW1lZFxuICogZm9yIGxheWVycyB0aGF0IGFyZSBhZGRlZCB0byB0aGUgbWFwJ3MgYGxheWVyc2AgY29sbGVjdGlvbiwgb3IgYEluZmluaXR5YCB3aGVuIHRoZSBsYXllcidzIGBzZXRNYXAoKWBcbiAqIG1ldGhvZCB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluUmVzb2x1dGlvbl0gVGhlIG1pbmltdW0gcmVzb2x1dGlvbiAoaW5jbHVzaXZlKSBhdCB3aGljaCB0aGlzIGxheWVyIHdpbGwgYmVcbiAqIHZpc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFJlc29sdXRpb25dIFRoZSBtYXhpbXVtIHJlc29sdXRpb24gKGV4Y2x1c2l2ZSkgYmVsb3cgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5ab29tXSBUaGUgbWluaW11bSB2aWV3IHpvb20gbGV2ZWwgKGV4Y2x1c2l2ZSkgYWJvdmUgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhab29tXSBUaGUgbWF4aW11bSB2aWV3IHpvb20gbGV2ZWwgKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9yZW5kZXIuanNcIikuT3JkZXJGdW5jdGlvbn0gW3JlbmRlck9yZGVyXSBSZW5kZXIgb3JkZXIuIEZ1bmN0aW9uIHRvIGJlIHVzZWQgd2hlbiBzb3J0aW5nXG4gKiBmZWF0dXJlcyBiZWZvcmUgcmVuZGVyaW5nLiBCeSBkZWZhdWx0IGZlYXR1cmVzIGFyZSBkcmF3biBpbiB0aGUgb3JkZXIgdGhhdCB0aGV5IGFyZSBjcmVhdGVkLiBVc2VcbiAqIGBudWxsYCB0byBhdm9pZCB0aGUgc29ydCwgYnV0IGdldCBhbiB1bmRlZmluZWQgZHJhdyBvcmRlci5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmVuZGVyQnVmZmVyPTEwMF0gVGhlIGJ1ZmZlciBpbiBwaXhlbHMgYXJvdW5kIHRoZSB0aWxlIGV4dGVudCB1c2VkIGJ5IHRoZVxuICogcmVuZGVyZXIgd2hlbiBnZXR0aW5nIGZlYXR1cmVzIGZyb20gdGhlIHZlY3RvciB0aWxlIGZvciB0aGUgcmVuZGVyaW5nIG9yIGhpdC1kZXRlY3Rpb24uXG4gKiBSZWNvbW1lbmRlZCB2YWx1ZTogVmVjdG9yIHRpbGVzIGFyZSB1c3VhbGx5IGdlbmVyYXRlZCB3aXRoIGEgYnVmZmVyLCBzbyB0aGlzIHZhbHVlIHNob3VsZCBtYXRjaFxuICogdGhlIGxhcmdlc3QgcG9zc2libGUgYnVmZmVyIG9mIHRoZSB1c2VkIHRpbGVzLiBJdCBzaG91bGQgYmUgYXQgbGVhc3QgdGhlIHNpemUgb2YgdGhlIGxhcmdlc3RcbiAqIHBvaW50IHN5bWJvbCBvciBsaW5lIHdpZHRoLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1ZlY3RvclRpbGVSZW5kZXJUeXBlLmpzXCIpLmRlZmF1bHR8c3RyaW5nfSBbcmVuZGVyTW9kZT0naHlicmlkJ10gUmVuZGVyIG1vZGUgZm9yIHZlY3RvciB0aWxlczpcbiAqICAqIGAnaW1hZ2UnYDogVmVjdG9yIHRpbGVzIGFyZSByZW5kZXJlZCBhcyBpbWFnZXMuIE9ubHkgYXZhaWxhYmxlIHdoZW4gYGRlY2x1dHRlcmAgaXMgc2V0IHRvIGBmYWxzZWAgKGRlZmF1bHQpLlxuICogICAgT3RoZXJ3aXNlLCBgJ2h5YnJpZCdgIG1vZGUgd2lsbCB1c2VkIGluc3RlYWQuIEdyZWF0IHBlcmZvcm1hbmNlLCBidXQgcG9pbnQgc3ltYm9scyBhbmQgdGV4dHNcbiAqICAgIGFyZSBhbHdheXMgcm90YXRlZCB3aXRoIHRoZSB2aWV3IGFuZCBwaXhlbHMgYXJlIHNjYWxlZCBkdXJpbmcgem9vbSBhbmltYXRpb25zLiBMYWJlbHMgYW5kIHBvaW50IHN5bWJvbHMgd2lsbFxuICogICAgZ2V0IGN1dCBvZmYgYXQgdGlsZSBib3VuZGFyaWVzLlxuICogICogYCdoeWJyaWQnYDogUG9seWdvbiBhbmQgbGluZSBlbGVtZW50cyBhcmUgcmVuZGVyZWQgYXMgaW1hZ2VzLCBzbyBwaXhlbHMgYXJlIHNjYWxlZCBkdXJpbmcgem9vbVxuICogICAgYW5pbWF0aW9ucy4gUG9pbnQgc3ltYm9scyBhbmQgdGV4dHMgYXJlIGFjY3VyYXRlbHkgcmVuZGVyZWQgYXMgdmVjdG9ycyBhbmQgY2FuIHN0YXkgdXByaWdodCBvblxuICogICAgcm90YXRlZCB2aWV3cy5cbiAqICAqIGAndmVjdG9yJ2A6IEV2ZXJ5dGhpbmcgaXMgcmVuZGVyZWQgYXMgdmVjdG9ycy4gVXNlIHRoaXMgbW9kZSBmb3IgaW1wcm92ZWQgcGVyZm9ybWFuY2Ugb24gdmVjdG9yXG4gKiAgICB0aWxlIGxheWVycyB3aXRoIG9ubHkgYSBmZXcgcmVuZGVyZWQgZmVhdHVyZXMgKGUuZy4gZm9yIGhpZ2hsaWdodGluZyBhIHN1YnNldCBvZiBmZWF0dXJlcyBvZlxuICogICAgYW5vdGhlciBsYXllciB3aXRoIHRoZSBzYW1lIHNvdXJjZSkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3NvdXJjZS9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9IFtzb3VyY2VdIFNvdXJjZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IFttYXBdIFNldHMgdGhlIGxheWVyIGFzIG92ZXJsYXkgb24gYSBtYXAuIFRoZSBtYXAgd2lsbCBub3QgbWFuYWdlXG4gKiB0aGlzIGxheWVyIGluIGl0cyBsYXllcnMgY29sbGVjdGlvbiwgYW5kIHRoZSBsYXllciB3aWxsIGJlIHJlbmRlcmVkIG9uIHRvcC4gVGhpcyBpcyB1c2VmdWwgZm9yXG4gKiB0ZW1wb3JhcnkgbGF5ZXJzLiBUaGUgc3RhbmRhcmQgd2F5IHRvIGFkZCBhIGxheWVyIHRvIGEgbWFwIGFuZCBoYXZlIGl0IG1hbmFnZWQgYnkgdGhlIG1hcCBpcyB0b1xuICogdXNlIHtAbGluayBtb2R1bGU6b2wvTWFwI2FkZExheWVyfS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2RlY2x1dHRlcj1mYWxzZV0gRGVjbHV0dGVyIGltYWdlcyBhbmQgdGV4dC4gRGVjbHV0dGVyaW5nIGlzIGFwcGxpZWQgdG8gYWxsXG4gKiBpbWFnZSBhbmQgdGV4dCBzdHlsZXMgb2YgYWxsIFZlY3RvciBhbmQgVmVjdG9yVGlsZSBsYXllcnMgdGhhdCBoYXZlIHNldCB0aGlzIHRvIGB0cnVlYC4gVGhlIHByaW9yaXR5XG4gKiBpcyBkZWZpbmVkIGJ5IHRoZSB6LWluZGV4IG9mIHRoZSBsYXllciwgdGhlIGB6SW5kZXhgIG9mIHRoZSBzdHlsZSBhbmQgdGhlIHJlbmRlciBvcmRlciBvZiBmZWF0dXJlcy5cbiAqIEhpZ2hlciB6LWluZGV4IG1lYW5zIGhpZ2hlciBwcmlvcml0eS4gV2l0aGluIHRoZSBzYW1lIHotaW5kZXgsIGEgZmVhdHVyZSByZW5kZXJlZCBiZWZvcmUgYW5vdGhlciBoYXNcbiAqIGhpZ2hlciBwcmlvcml0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuU3R5bGVMaWtlfSBbc3R5bGVdIExheWVyIHN0eWxlLiBTZWVcbiAqIHtAbGluayBtb2R1bGU6b2wvc3R5bGV9IGZvciBkZWZhdWx0IHN0eWxlIHdoaWNoIHdpbGwgYmUgdXNlZCBpZiB0aGlzIGlzIG5vdCBkZWZpbmVkLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbdXBkYXRlV2hpbGVBbmltYXRpbmc9ZmFsc2VdIFdoZW4gc2V0IHRvIGB0cnVlYCwgZmVhdHVyZSBiYXRjaGVzIHdpbGwgYmVcbiAqIHJlY3JlYXRlZCBkdXJpbmcgYW5pbWF0aW9ucy4gVGhpcyBtZWFucyB0aGF0IG5vIHZlY3RvcnMgd2lsbCBiZSBzaG93biBjbGlwcGVkLCBidXQgdGhlIHNldHRpbmdcbiAqIHdpbGwgaGF2ZSBhIHBlcmZvcm1hbmNlIGltcGFjdCBmb3IgbGFyZ2UgYW1vdW50cyBvZiB2ZWN0b3IgZGF0YS4gV2hlbiBzZXQgdG8gYGZhbHNlYCwgYmF0Y2hlc1xuICogd2lsbCBiZSByZWNyZWF0ZWQgd2hlbiBubyBhbmltYXRpb24gaXMgYWN0aXZlLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbdXBkYXRlV2hpbGVJbnRlcmFjdGluZz1mYWxzZV0gV2hlbiBzZXQgdG8gYHRydWVgLCBmZWF0dXJlIGJhdGNoZXMgd2lsbCBiZVxuICogcmVjcmVhdGVkIGR1cmluZyBpbnRlcmFjdGlvbnMuIFNlZSBhbHNvIGB1cGRhdGVXaGlsZUFuaW1hdGluZ2AuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3ByZWxvYWQ9MF0gUHJlbG9hZC4gTG9hZCBsb3ctcmVzb2x1dGlvbiB0aWxlcyB1cCB0byBgcHJlbG9hZGAgbGV2ZWxzLiBgMGBcbiAqIG1lYW5zIG5vIHByZWxvYWRpbmcuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt1c2VJbnRlcmltVGlsZXNPbkVycm9yPXRydWVdIFVzZSBpbnRlcmltIHRpbGVzIG9uIGVycm9yLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogTGF5ZXIgZm9yIHZlY3RvciB0aWxlIGRhdGEgdGhhdCBpcyByZW5kZXJlZCBjbGllbnQtc2lkZS5cbiAqIE5vdGUgdGhhdCBhbnkgcHJvcGVydHkgc2V0IGluIHRoZSBvcHRpb25zIGlzIHNldCBhcyBhIHtAbGluayBtb2R1bGU6b2wvT2JqZWN0fkJhc2VPYmplY3R9XG4gKiBwcm9wZXJ0eSBvbiB0aGUgbGF5ZXIgb2JqZWN0OyBmb3IgZXhhbXBsZSwgc2V0dGluZyBgdGl0bGU6ICdNeSBUaXRsZSdgIGluIHRoZVxuICogb3B0aW9ucyBtZWFucyB0aGF0IGB0aXRsZWAgaXMgb2JzZXJ2YWJsZSwgYW5kIGhhcyBnZXQvc2V0IGFjY2Vzc29ycy5cbiAqXG4gKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICogQGV4dGVuZHMge0Jhc2VWZWN0b3JMYXllcjxpbXBvcnQoXCIuLi9zb3VyY2UvVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0Pn1cbiAqIEBhcGlcbiAqL1xuXG52YXIgVmVjdG9yVGlsZUxheWVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFZlY3RvclRpbGVMYXllciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gVmVjdG9yVGlsZUxheWVyKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIHZhciBiYXNlT3B0aW9ucyA9XG4gICAgLyoqIEB0eXBlIHtPYmplY3R9ICovXG4gICAgYXNzaWduKHt9LCBvcHRpb25zKTtcbiAgICBkZWxldGUgYmFzZU9wdGlvbnMucHJlbG9hZDtcbiAgICBkZWxldGUgYmFzZU9wdGlvbnMudXNlSW50ZXJpbVRpbGVzT25FcnJvcjtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL0Jhc2VWZWN0b3IuanNcIikuT3B0aW9uc30gKi9cbiAgICBiYXNlT3B0aW9ucykgfHwgdGhpcztcbiAgICB2YXIgcmVuZGVyTW9kZSA9IG9wdGlvbnMucmVuZGVyTW9kZSB8fCBWZWN0b3JUaWxlUmVuZGVyVHlwZS5IWUJSSUQ7XG4gICAgYXNzZXJ0KHJlbmRlck1vZGUgPT0gdW5kZWZpbmVkIHx8IHJlbmRlck1vZGUgPT0gVmVjdG9yVGlsZVJlbmRlclR5cGUuSU1BR0UgfHwgcmVuZGVyTW9kZSA9PSBWZWN0b3JUaWxlUmVuZGVyVHlwZS5IWUJSSUQgfHwgcmVuZGVyTW9kZSA9PSBWZWN0b3JUaWxlUmVuZGVyVHlwZS5WRUNUT1IsIDI4KTsgLy8gYHJlbmRlck1vZGVgIG11c3QgYmUgYCdpbWFnZSdgLCBgJ2h5YnJpZCdgIG9yIGAndmVjdG9yJ2AuXG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL1ZlY3RvclRpbGVSZW5kZXJUeXBlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJNb2RlXyA9IHJlbmRlck1vZGU7XG5cbiAgICBfdGhpcy5zZXRQcmVsb2FkKG9wdGlvbnMucHJlbG9hZCA/IG9wdGlvbnMucHJlbG9hZCA6IDApO1xuXG4gICAgX3RoaXMuc2V0VXNlSW50ZXJpbVRpbGVzT25FcnJvcihvcHRpb25zLnVzZUludGVyaW1UaWxlc09uRXJyb3IgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudXNlSW50ZXJpbVRpbGVzT25FcnJvciA6IHRydWUpO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBDcmVhdGUgYSByZW5kZXJlciBmb3IgdGhpcyBsYXllci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vcmVuZGVyZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gQSBsYXllciByZW5kZXJlci5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFZlY3RvclRpbGVMYXllci5wcm90b3R5cGUuY3JlYXRlUmVuZGVyZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlcih0aGlzKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdG9wbW9zdCBmZWF0dXJlIHRoYXQgaW50ZXJzZWN0cyB0aGUgZ2l2ZW4gcGl4ZWwgb24gdGhlIHZpZXdwb3J0LiBSZXR1cm5zIGEgcHJvbWlzZVxuICAgKiB0aGF0IHJlc29sdmVzIHdpdGggYW4gYXJyYXkgb2YgZmVhdHVyZXMuIFRoZSBhcnJheSB3aWxsIGVpdGhlciBjb250YWluIHRoZSB0b3Btb3N0IGZlYXR1cmVcbiAgICogd2hlbiBhIGhpdCB3YXMgZGV0ZWN0ZWQsIG9yIGl0IHdpbGwgYmUgZW1wdHkuXG4gICAqXG4gICAqIFRoZSBoaXQgZGV0ZWN0aW9uIGFsZ29yaXRobSB1c2VkIGZvciB0aGlzIG1ldGhvZCBpcyBvcHRpbWl6ZWQgZm9yIHBlcmZvcm1hbmNlLCBidXQgaXMgbGVzc1xuICAgKiBhY2N1cmF0ZSB0aGFuIHRoZSBvbmUgdXNlZCBpbiB7QGxpbmsgaW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHQjZ2V0RmVhdHVyZXNBdFBpeGVsfTogVGV4dFxuICAgKiBpcyBub3QgY29uc2lkZXJlZCwgYW5kIGljb25zIGFyZSBvbmx5IHJlcHJlc2VudGVkIGJ5IHRoZWlyIGJvdW5kaW5nIGJveCBpbnN0ZWFkIG9mIHRoZSBleGFjdFxuICAgKiBpbWFnZS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZVwiKS5kZWZhdWx0Pj59IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIGFuIGFycmF5IG9mIGZlYXR1cmVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yVGlsZUxheWVyLnByb3RvdHlwZS5nZXRGZWF0dXJlcyA9IGZ1bmN0aW9uIChwaXhlbCkge1xuICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLmdldEZlYXR1cmVzLmNhbGwodGhpcywgcGl4ZWwpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9WZWN0b3JUaWxlUmVuZGVyVHlwZS5qc1wiKS5kZWZhdWx0fSBUaGUgcmVuZGVyIG1vZGUuXG4gICAqL1xuXG5cbiAgVmVjdG9yVGlsZUxheWVyLnByb3RvdHlwZS5nZXRSZW5kZXJNb2RlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlbmRlck1vZGVfO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBsZXZlbCBhcyBudW1iZXIgdG8gd2hpY2ggd2Ugd2lsbCBwcmVsb2FkIHRpbGVzIHVwIHRvLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBsZXZlbCB0byBwcmVsb2FkIHRpbGVzIHVwIHRvLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yVGlsZUxheWVyLnByb3RvdHlwZS5nZXRQcmVsb2FkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgIHRoaXMuZ2V0KFRpbGVQcm9wZXJ0eS5QUkVMT0FEKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBXaGV0aGVyIHdlIHVzZSBpbnRlcmltIHRpbGVzIG9uIGVycm9yLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBVc2UgaW50ZXJpbSB0aWxlcyBvbiBlcnJvci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclRpbGVMYXllci5wcm90b3R5cGUuZ2V0VXNlSW50ZXJpbVRpbGVzT25FcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtib29sZWFufSAqL1xuICAgICAgdGhpcy5nZXQoVGlsZVByb3BlcnR5LlVTRV9JTlRFUklNX1RJTEVTX09OX0VSUk9SKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGxldmVsIGFzIG51bWJlciB0byB3aGljaCB3ZSB3aWxsIHByZWxvYWQgdGlsZXMgdXAgdG8uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwcmVsb2FkIFRoZSBsZXZlbCB0byBwcmVsb2FkIHRpbGVzIHVwIHRvLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yVGlsZUxheWVyLnByb3RvdHlwZS5zZXRQcmVsb2FkID0gZnVuY3Rpb24gKHByZWxvYWQpIHtcbiAgICB0aGlzLnNldChUaWxlUHJvcGVydHkuUFJFTE9BRCwgcHJlbG9hZCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgd2hldGhlciB3ZSB1c2UgaW50ZXJpbSB0aWxlcyBvbiBlcnJvci5cbiAgICogQHBhcmFtIHtib29sZWFufSB1c2VJbnRlcmltVGlsZXNPbkVycm9yIFVzZSBpbnRlcmltIHRpbGVzIG9uIGVycm9yLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yVGlsZUxheWVyLnByb3RvdHlwZS5zZXRVc2VJbnRlcmltVGlsZXNPbkVycm9yID0gZnVuY3Rpb24gKHVzZUludGVyaW1UaWxlc09uRXJyb3IpIHtcbiAgICB0aGlzLnNldChUaWxlUHJvcGVydHkuVVNFX0lOVEVSSU1fVElMRVNfT05fRVJST1IsIHVzZUludGVyaW1UaWxlc09uRXJyb3IpO1xuICB9O1xuXG4gIHJldHVybiBWZWN0b3JUaWxlTGF5ZXI7XG59KEJhc2VWZWN0b3JMYXllcik7XG5cbmV4cG9ydCBkZWZhdWx0IFZlY3RvclRpbGVMYXllcjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL1RpbGVcbiAqL1xuXG5cbmltcG9ydCBFdmVudFRhcmdldCBmcm9tICcuL2V2ZW50cy9UYXJnZXQuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IFRpbGVTdGF0ZSBmcm9tICcuL1RpbGVTdGF0ZS5qcyc7XG5pbXBvcnQgeyBhYnN0cmFjdCB9IGZyb20gJy4vdXRpbC5qcyc7XG5pbXBvcnQgeyBlYXNlSW4gfSBmcm9tICcuL2Vhc2luZy5qcyc7XG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhbiB7QGxpbmsgbW9kdWxlOm9sL1RpbGV9IGZvciB0aGUgdGlsZSBhbmQgYVxuICogYHtzdHJpbmd9YCBmb3IgdGhlIHVybCBhcyBhcmd1bWVudHMuIFRoZSBkZWZhdWx0IGlzXG4gKiBgYGBqc1xuICogc291cmNlLnNldFRpbGVMb2FkRnVuY3Rpb24oZnVuY3Rpb24odGlsZSwgc3JjKSB7XG4gKiAgIHRpbGUuZ2V0SW1hZ2UoKS5zcmMgPSBzcmM7XG4gKiB9KTtcbiAqIGBgYFxuICogRm9yIG1vcmUgZmluZSBncmFpbmVkIGNvbnRyb2wsIHRoZSBsb2FkIGZ1bmN0aW9uIGNhbiB1c2UgZmV0Y2ggb3IgWE1MSHR0cFJlcXVlc3QgYW5kIGludm9sdmVcbiAqIGVycm9yIGhhbmRsaW5nOlxuICpcbiAqIGBgYGpzXG4gKiBpbXBvcnQgVGlsZVN0YXRlIGZyb20gJ29sL1RpbGVTdGF0ZSc7XG4gKlxuICogc291cmNlLnNldFRpbGVMb2FkRnVuY3Rpb24oZnVuY3Rpb24odGlsZSwgc3JjKSB7XG4gKiAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAqICAgeGhyLnJlc3BvbnNlVHlwZSA9ICdibG9iJztcbiAqICAgeGhyLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlbmQnLCBmdW5jdGlvbiAoZXZ0KSB7XG4gKiAgICAgdmFyIGRhdGEgPSB0aGlzLnJlc3BvbnNlO1xuICogICAgIGlmIChkYXRhICE9PSB1bmRlZmluZWQpIHtcbiAqICAgICAgIHRpbGUuZ2V0SW1hZ2UoKS5zcmMgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGRhdGEpO1xuICogICAgIH0gZWxzZSB7XG4gKiAgICAgICB0aWxlLnNldFN0YXRlKFRpbGVTdGF0ZS5FUlJPUik7XG4gKiAgICAgfVxuICogICB9KTtcbiAqICAgeGhyLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgZnVuY3Rpb24gKCkge1xuICogICAgIHRpbGUuc2V0U3RhdGUoVGlsZVN0YXRlLkVSUk9SKTtcbiAqICAgfSk7XG4gKiAgIHhoci5vcGVuKCdHRVQnLCBzcmMpO1xuICogICB4aHIuc2VuZCgpO1xuICogfSk7XG4gKiBgYGBcbiAqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oVGlsZSwgc3RyaW5nKTogdm9pZH0gTG9hZEZ1bmN0aW9uXG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9UaWxlflRpbGV9IHNvdXJjZXMgdXNlIGEgZnVuY3Rpb24gb2YgdGhpcyB0eXBlIHRvIGdldFxuICogdGhlIHVybCB0aGF0IHByb3ZpZGVzIGEgdGlsZSBmb3IgYSBnaXZlbiB0aWxlIGNvb3JkaW5hdGUuXG4gKlxuICogVGhpcyBmdW5jdGlvbiB0YWtlcyBhbiB7QGxpbmsgbW9kdWxlOm9sL3RpbGVjb29yZH5UaWxlQ29vcmR9IGZvciB0aGUgdGlsZVxuICogY29vcmRpbmF0ZSwgYSBge251bWJlcn1gIHJlcHJlc2VudGluZyB0aGUgcGl4ZWwgcmF0aW8gYW5kIGFcbiAqIHtAbGluayBtb2R1bGU6b2wvcHJvai9Qcm9qZWN0aW9ufSBmb3IgdGhlIHByb2plY3Rpb24gIGFzIGFyZ3VtZW50c1xuICogYW5kIHJldHVybnMgYSBge3N0cmluZ31gIHJlcHJlc2VudGluZyB0aGUgdGlsZSBVUkwsIG9yIHVuZGVmaW5lZCBpZiBubyB0aWxlXG4gKiBzaG91bGQgYmUgcmVxdWVzdGVkIGZvciB0aGUgcGFzc2VkIHRpbGUgY29vcmRpbmF0ZS5cbiAqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oaW1wb3J0KFwiLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkLCBudW1iZXIsXG4gKiAgICAgICAgICAgaW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdCk6IChzdHJpbmd8dW5kZWZpbmVkKX0gVXJsRnVuY3Rpb25cbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdHJhbnNpdGlvbj0yNTBdIEEgZHVyYXRpb24gZm9yIHRpbGUgb3BhY2l0eVxuICogdHJhbnNpdGlvbnMgaW4gbWlsbGlzZWNvbmRzLiBBIGR1cmF0aW9uIG9mIDAgZGlzYWJsZXMgdGhlIG9wYWNpdHkgdHJhbnNpdGlvbi5cbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEJhc2UgY2xhc3MgZm9yIHRpbGVzLlxuICpcbiAqIEBhYnN0cmFjdFxuICovXG5cbnZhciBUaWxlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFRpbGUsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1RpbGVTdGF0ZS5qc1wiKS5kZWZhdWx0fSBzdGF0ZSBTdGF0ZS5cbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgVGlsZSBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFRpbGUodGlsZUNvb3JkLCBzdGF0ZSwgb3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyA/IG9wdF9vcHRpb25zIDoge307XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVDb29yZCA9IHRpbGVDb29yZDtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vVGlsZVN0YXRlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5zdGF0ZSA9IHN0YXRlO1xuICAgIC8qKlxuICAgICAqIEFuIFwiaW50ZXJpbVwiIHRpbGUgZm9yIHRoaXMgdGlsZS4gVGhlIGludGVyaW0gdGlsZSBtYXkgYmUgdXNlZCB3aGlsZSB0aGlzXG4gICAgICogb25lIGlzIGxvYWRpbmcsIGZvciBcInNtb290aFwiIHRyYW5zaXRpb25zIHdoZW4gY2hhbmdpbmcgcGFyYW1zL2RpbWVuc2lvbnNcbiAgICAgKiBvbiB0aGUgc291cmNlLlxuICAgICAqIEB0eXBlIHtUaWxlfVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW50ZXJpbVRpbGUgPSBudWxsO1xuICAgIC8qKlxuICAgICAqIFRoZSB0aWxlIGlzIGF2YWlsYWJsZSBhdCB0aGUgaGlnaGVzdCBwb3NzaWJsZSByZXNvbHV0aW9uLiBTdWJjbGFzc2VzIGNhblxuICAgICAqIHNldCB0aGlzIHRvIGBmYWxzZWAgaW5pdGlhbGx5LiBUaWxlIGxvYWQgbGlzdGVuZXJzIHdpbGwgbm90IGJlXG4gICAgICogdW5yZWdpc3RlcmVkIGJlZm9yZSB0aGlzIGlzIHNldCB0byBgdHJ1ZWAgYW5kIGEgYCNjaGFuZ2VkKClgIGlzIGNhbGxlZC5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmhpZmkgPSB0cnVlO1xuICAgIC8qKlxuICAgICAqIEEga2V5IGFzc2lnbmVkIHRvIHRoZSB0aWxlLiBUaGlzIGlzIHVzZWQgYnkgdGhlIHRpbGUgc291cmNlIHRvIGRldGVybWluZVxuICAgICAqIGlmIHRoaXMgdGlsZSBjYW4gZWZmZWN0aXZlbHkgYmUgdXNlZCwgb3IgaWYgYSBuZXcgdGlsZSBzaG91bGQgYmUgY3JlYXRlZFxuICAgICAqIGFuZCB0aGlzIG9uZSBiZSB1c2VkIGFzIGFuIGludGVyaW0gdGlsZSBmb3IgdGhpcyBuZXcgdGlsZS5cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuXG4gICAgX3RoaXMua2V5ID0gJyc7XG4gICAgLyoqXG4gICAgICogVGhlIGR1cmF0aW9uIGZvciB0aGUgb3BhY2l0eSB0cmFuc2l0aW9uLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy50cmFuc2l0aW9uXyA9IG9wdGlvbnMudHJhbnNpdGlvbiA9PT0gdW5kZWZpbmVkID8gMjUwIDogb3B0aW9ucy50cmFuc2l0aW9uO1xuICAgIC8qKlxuICAgICAqIExvb2t1cCBvZiBzdGFydCB0aW1lcyBmb3IgcmVuZGVyaW5nIHRyYW5zaXRpb25zLiAgSWYgdGhlIHN0YXJ0IHRpbWUgaXNcbiAgICAgKiBlcXVhbCB0byAtMSwgdGhlIHRyYW5zaXRpb24gaXMgY29tcGxldGUuXG4gICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsIG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy50cmFuc2l0aW9uU3RhcnRzXyA9IHt9O1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFRpbGUucHJvdG90eXBlLmNoYW5nZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KEV2ZW50VHlwZS5DSEFOR0UpO1xuICB9O1xuICAvKipcbiAgICogQ2FsbGVkIGJ5IHRoZSB0aWxlIGNhY2hlIHdoZW4gdGhlIHRpbGUgaXMgcmVtb3ZlZCBmcm9tIHRoZSBjYWNoZSBkdWUgdG8gZXhwaXJ5XG4gICAqL1xuXG5cbiAgVGlsZS5wcm90b3R5cGUucmVsZWFzZSA9IGZ1bmN0aW9uICgpIHt9O1xuICAvKipcbiAgICogQHJldHVybiB7c3RyaW5nfSBLZXkuXG4gICAqL1xuXG5cbiAgVGlsZS5wcm90b3R5cGUuZ2V0S2V5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmtleSArICcvJyArIHRoaXMudGlsZUNvb3JkO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBpbnRlcmltIHRpbGUgbW9zdCBzdWl0YWJsZSBmb3IgcmVuZGVyaW5nIHVzaW5nIHRoZSBjaGFpbiBvZiBpbnRlcmltXG4gICAqIHRpbGVzLiBUaGlzIGNvcnJlc3BvbmRzIHRvIHRoZSAgbW9zdCByZWNlbnQgdGlsZSB0aGF0IGhhcyBiZWVuIGxvYWRlZCwgaWYgbm9cbiAgICogc3VjaCB0aWxlIGV4aXN0cywgdGhlIG9yaWdpbmFsIHRpbGUgaXMgcmV0dXJuZWQuXG4gICAqIEByZXR1cm4geyFUaWxlfSBCZXN0IHRpbGUgZm9yIHJlbmRlcmluZy5cbiAgICovXG5cblxuICBUaWxlLnByb3RvdHlwZS5nZXRJbnRlcmltVGlsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuaW50ZXJpbVRpbGUpIHtcbiAgICAgIC8vZW1wdHkgY2hhaW5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHZhciB0aWxlID0gdGhpcy5pbnRlcmltVGlsZTsgLy8gZmluZCB0aGUgZmlyc3QgbG9hZGVkIHRpbGUgYW5kIHJldHVybiBpdC4gU2luY2UgdGhlIGNoYWluIGlzIHNvcnRlZCBpblxuICAgIC8vIGRlY3JlYXNpbmcgb3JkZXIgb2YgY3JlYXRpb24gdGltZSwgdGhlcmUgaXMgbm8gbmVlZCB0byBzZWFyY2ggdGhlIHJlbWFpbmRlclxuICAgIC8vIG9mIHRoZSBsaXN0IChhbGwgdGhvc2UgdGlsZXMgY29ycmVzcG9uZCB0byBvbGRlciByZXF1ZXN0cyBhbmQgd2lsbCBiZVxuICAgIC8vIGNsZWFuZWQgdXAgYnkgcmVmcmVzaEludGVyaW1DaGFpbilcblxuICAgIGRvIHtcbiAgICAgIGlmICh0aWxlLmdldFN0YXRlKCkgPT0gVGlsZVN0YXRlLkxPQURFRCkge1xuICAgICAgICAvLyBTaG93IHRpbGUgaW1tZWRpYXRlbHkgaW5zdGVhZCBvZiBmYWRpbmcgaXQgaW4gYWZ0ZXIgbG9hZGluZywgYmVjYXVzZVxuICAgICAgICAvLyB0aGUgaW50ZXJpbSB0aWxlIGlzIGluIHBsYWNlIGFscmVhZHlcbiAgICAgICAgdGhpcy50cmFuc2l0aW9uXyA9IDA7XG4gICAgICAgIHJldHVybiB0aWxlO1xuICAgICAgfVxuXG4gICAgICB0aWxlID0gdGlsZS5pbnRlcmltVGlsZTtcbiAgICB9IHdoaWxlICh0aWxlKTsgLy8gd2UgY2FuIG5vdCBmaW5kIGEgYmV0dGVyIHRpbGVcblxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG4gIC8qKlxuICAgKiBHb2VzIHRocm91Z2ggdGhlIGNoYWluIG9mIGludGVyaW0gdGlsZXMgYW5kIGRpc2NhcmRzIHNlY3Rpb25zIG9mIHRoZSBjaGFpblxuICAgKiB0aGF0IGFyZSBubyBsb25nZXIgcmVsZXZhbnQuXG4gICAqL1xuXG5cbiAgVGlsZS5wcm90b3R5cGUucmVmcmVzaEludGVyaW1DaGFpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuaW50ZXJpbVRpbGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgdGlsZSA9IHRoaXMuaW50ZXJpbVRpbGU7XG4gICAgdmFyIHByZXYgPVxuICAgIC8qKiBAdHlwZSB7VGlsZX0gKi9cbiAgICB0aGlzO1xuXG4gICAgZG8ge1xuICAgICAgaWYgKHRpbGUuZ2V0U3RhdGUoKSA9PSBUaWxlU3RhdGUuTE9BREVEKSB7XG4gICAgICAgIC8vd2UgaGF2ZSBhIGxvYWRlZCB0aWxlLCB3ZSBjYW4gZGlzY2FyZCB0aGUgcmVzdCBvZiB0aGUgbGlzdFxuICAgICAgICAvL3dlIHdvdWxkIGNvdWxkIGFib3J0IGFueSBMT0FESU5HIHRpbGUgcmVxdWVzdFxuICAgICAgICAvL29sZGVyIHRoYW4gdGhpcyB0aWxlIChpLmUuIGFueSBMT0FESU5HIHRpbGUgZm9sbG93aW5nIHRoaXMgZW50cnkgaW4gdGhlIGNoYWluKVxuICAgICAgICB0aWxlLmludGVyaW1UaWxlID0gbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IGVsc2UgaWYgKHRpbGUuZ2V0U3RhdGUoKSA9PSBUaWxlU3RhdGUuTE9BRElORykge1xuICAgICAgICAvL2tlZXAgdGhpcyBMT0FESU5HIHRpbGUgYW55IGxvYWRlZCB0aWxlcyBsYXRlciBpbiB0aGUgY2hhaW4gYXJlXG4gICAgICAgIC8vb2xkZXIgdGhhbiB0aGlzIHRpbGUsIHNvIHdlJ3JlIHN0aWxsIGludGVyZXN0ZWQgaW4gdGhlIHJlcXVlc3RcbiAgICAgICAgcHJldiA9IHRpbGU7XG4gICAgICB9IGVsc2UgaWYgKHRpbGUuZ2V0U3RhdGUoKSA9PSBUaWxlU3RhdGUuSURMRSkge1xuICAgICAgICAvL3RoZSBoZWFkIG9mIHRoZSBsaXN0IGlzIHRoZSBtb3N0IGN1cnJlbnQgdGlsZSwgd2UgZG9uJ3QgbmVlZFxuICAgICAgICAvL3RvIHN0YXJ0IGFueSBvdGhlciByZXF1ZXN0cyBmb3IgdGhpcyBjaGFpblxuICAgICAgICBwcmV2LmludGVyaW1UaWxlID0gdGlsZS5pbnRlcmltVGlsZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByZXYgPSB0aWxlO1xuICAgICAgfVxuXG4gICAgICB0aWxlID0gcHJldi5pbnRlcmltVGlsZTtcbiAgICB9IHdoaWxlICh0aWxlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdGlsZSBjb29yZGluYXRlIGZvciB0aGlzIHRpbGUuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gVGhlIHRpbGUgY29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGUucHJvdG90eXBlLmdldFRpbGVDb29yZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aWxlQ29vcmQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL1RpbGVTdGF0ZS5qc1wiKS5kZWZhdWx0fSBTdGF0ZS5cbiAgICovXG5cblxuICBUaWxlLnByb3RvdHlwZS5nZXRTdGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldHMgdGhlIHN0YXRlIG9mIHRoaXMgdGlsZS4gSWYgeW91IHdyaXRlIHlvdXIgb3duIHtAbGluayBtb2R1bGU6b2wvVGlsZX5Mb2FkRnVuY3Rpb24gdGlsZUxvYWRGdW5jdGlvbn0gLFxuICAgKiBpdCBpcyBpbXBvcnRhbnQgdG8gc2V0IHRoZSBzdGF0ZSBjb3JyZWN0bHkgdG8ge0BsaW5rIG1vZHVsZTpvbC9UaWxlU3RhdGV+RVJST1J9XG4gICAqIHdoZW4gdGhlIHRpbGUgY2Fubm90IGJlIGxvYWRlZC4gT3RoZXJ3aXNlIHRoZSB0aWxlIGNhbm5vdCBiZSByZW1vdmVkIGZyb21cbiAgICogdGhlIHRpbGUgcXVldWUgYW5kIHdpbGwgYmxvY2sgb3RoZXIgcmVxdWVzdHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UaWxlU3RhdGUuanNcIikuZGVmYXVsdH0gc3RhdGUgU3RhdGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlLnByb3RvdHlwZS5zZXRTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgIGlmICh0aGlzLnN0YXRlICE9PSBUaWxlU3RhdGUuRVJST1IgJiYgdGhpcy5zdGF0ZSA+IHN0YXRlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RpbGUgbG9hZCBzZXF1ZW5jZSB2aW9sYXRpb24nKTtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlID0gc3RhdGU7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBMb2FkIHRoZSBpbWFnZSBvciByZXRyeSBpZiBsb2FkaW5nIHByZXZpb3VzbHkgZmFpbGVkLlxuICAgKiBMb2FkaW5nIGlzIHRha2VuIGNhcmUgb2YgYnkgdGhlIHRpbGUgcXVldWUsIGFuZCBjYWxsaW5nIHRoaXMgbWV0aG9kIGlzXG4gICAqIG9ubHkgbmVlZGVkIGZvciBwcmVsb2FkaW5nIG9yIGZvciByZWxvYWRpbmcgaW4gY2FzZSBvZiBhbiBlcnJvci5cbiAgICogQGFic3RyYWN0XG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGFscGhhIHZhbHVlIGZvciByZW5kZXJpbmcuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBBbiBpZCBmb3IgdGhlIHJlbmRlcmVyLlxuICAgKiBAcGFyYW0ge251bWJlcn0gdGltZSBUaGUgcmVuZGVyIGZyYW1lIHRpbWUuXG4gICAqIEByZXR1cm4ge251bWJlcn0gQSBudW1iZXIgYmV0d2VlbiAwIGFuZCAxLlxuICAgKi9cblxuXG4gIFRpbGUucHJvdG90eXBlLmdldEFscGhhID0gZnVuY3Rpb24gKGlkLCB0aW1lKSB7XG4gICAgaWYgKCF0aGlzLnRyYW5zaXRpb25fKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG5cbiAgICB2YXIgc3RhcnQgPSB0aGlzLnRyYW5zaXRpb25TdGFydHNfW2lkXTtcblxuICAgIGlmICghc3RhcnQpIHtcbiAgICAgIHN0YXJ0ID0gdGltZTtcbiAgICAgIHRoaXMudHJhbnNpdGlvblN0YXJ0c19baWRdID0gc3RhcnQ7XG4gICAgfSBlbHNlIGlmIChzdGFydCA9PT0gLTEpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIHZhciBkZWx0YSA9IHRpbWUgLSBzdGFydCArIDEwMDAgLyA2MDsgLy8gYXZvaWQgcmVuZGVyaW5nIGF0IDBcblxuICAgIGlmIChkZWx0YSA+PSB0aGlzLnRyYW5zaXRpb25fKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWFzZUluKGRlbHRhIC8gdGhpcy50cmFuc2l0aW9uXyk7XG4gIH07XG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgaWYgYSB0aWxlIGlzIGluIGFuIGFscGhhIHRyYW5zaXRpb24uICBBIHRpbGUgaXMgY29uc2lkZXJlZCBpblxuICAgKiB0cmFuc2l0aW9uIGlmIHRpbGUuZ2V0QWxwaGEoKSBoYXMgbm90IHlldCBiZWVuIGNhbGxlZCBvciBoYXMgYmVlbiBjYWxsZWRcbiAgICogYW5kIHJldHVybmVkIDEuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBBbiBpZCBmb3IgdGhlIHJlbmRlcmVyLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaGUgdGlsZSBpcyBpbiB0cmFuc2l0aW9uLlxuICAgKi9cblxuXG4gIFRpbGUucHJvdG90eXBlLmluVHJhbnNpdGlvbiA9IGZ1bmN0aW9uIChpZCkge1xuICAgIGlmICghdGhpcy50cmFuc2l0aW9uXykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnRyYW5zaXRpb25TdGFydHNfW2lkXSAhPT0gLTE7XG4gIH07XG4gIC8qKlxuICAgKiBNYXJrIGEgdHJhbnNpdGlvbiBhcyBjb21wbGV0ZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGlkIEFuIGlkIGZvciB0aGUgcmVuZGVyZXIuXG4gICAqL1xuXG5cbiAgVGlsZS5wcm90b3R5cGUuZW5kVHJhbnNpdGlvbiA9IGZ1bmN0aW9uIChpZCkge1xuICAgIGlmICh0aGlzLnRyYW5zaXRpb25fKSB7XG4gICAgICB0aGlzLnRyYW5zaXRpb25TdGFydHNfW2lkXSA9IC0xO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gVGlsZTtcbn0oRXZlbnRUYXJnZXQpO1xuXG5leHBvcnQgZGVmYXVsdCBUaWxlOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvVmVjdG9yVGlsZVxuICovXG5cblxuaW1wb3J0IFRpbGUgZnJvbSAnLi9UaWxlLmpzJztcbmltcG9ydCBUaWxlU3RhdGUgZnJvbSAnLi9UaWxlU3RhdGUuanMnO1xuXG52YXIgVmVjdG9yVGlsZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhWZWN0b3JUaWxlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UaWxlU3RhdGUuanNcIikuZGVmYXVsdH0gc3RhdGUgU3RhdGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgRGF0YSBzb3VyY2UgdXJsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZm9ybWF0L0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZm9ybWF0IEZlYXR1cmUgZm9ybWF0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vVGlsZS5qc1wiKS5Mb2FkRnVuY3Rpb259IHRpbGVMb2FkRnVuY3Rpb24gVGlsZSBsb2FkIGZ1bmN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vVGlsZS5qc1wiKS5PcHRpb25zPX0gb3B0X29wdGlvbnMgVGlsZSBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFZlY3RvclRpbGUodGlsZUNvb3JkLCBzdGF0ZSwgc3JjLCBmb3JtYXQsIHRpbGVMb2FkRnVuY3Rpb24sIG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdGlsZUNvb3JkLCBzdGF0ZSwgb3B0X29wdGlvbnMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogRXh0ZW50IG9mIHRoaXMgdGlsZTsgc2V0IGJ5IHRoZSBzb3VyY2UuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuZXh0ZW50ID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL2Zvcm1hdC9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5mb3JtYXRfID0gZm9ybWF0O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmZlYXR1cmVzXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9mZWF0dXJlbG9hZGVyLmpzXCIpLkZlYXR1cmVMb2FkZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5sb2FkZXJfO1xuICAgIC8qKlxuICAgICAqIEZlYXR1cmUgcHJvamVjdGlvbiBvZiB0aGlzIHRpbGU7IHNldCBieSB0aGUgc291cmNlLlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMucHJvamVjdGlvbiA9IG51bGw7XG4gICAgLyoqXG4gICAgICogUmVzb2x1dGlvbiBvZiB0aGlzIHRpbGU7IHNldCBieSB0aGUgc291cmNlLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZXNvbHV0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vVGlsZS5qc1wiKS5Mb2FkRnVuY3Rpb259XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlTG9hZEZ1bmN0aW9uXyA9IHRpbGVMb2FkRnVuY3Rpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuXG4gICAgX3RoaXMudXJsXyA9IHNyYztcbiAgICBfdGhpcy5rZXkgPSBzcmM7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIGZlYXR1cmUgZm9ybWF0IGFzc2lnbmVkIGZvciByZWFkaW5nIHRoaXMgdGlsZSdzIGZlYXR1cmVzLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Zvcm1hdC9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IEZlYXR1cmUgZm9ybWF0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yVGlsZS5wcm90b3R5cGUuZ2V0Rm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZvcm1hdF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGZlYXR1cmVzIGZvciB0aGlzIHRpbGUuIEdlb21ldHJpZXMgd2lsbCBiZSBpbiB0aGUgdmlldyBwcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2U+fSBGZWF0dXJlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLmdldEZlYXR1cmVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZlYXR1cmVzXztcbiAgfTtcbiAgLyoqXG4gICAqIExvYWQgbm90IHlldCBsb2FkZWQgVVJJLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUgPT0gVGlsZVN0YXRlLklETEUpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoVGlsZVN0YXRlLkxPQURJTkcpO1xuICAgICAgdGhpcy50aWxlTG9hZEZ1bmN0aW9uXyh0aGlzLCB0aGlzLnVybF8pO1xuXG4gICAgICBpZiAodGhpcy5sb2FkZXJfKSB7XG4gICAgICAgIHRoaXMubG9hZGVyXyh0aGlzLmV4dGVudCwgdGhpcy5yZXNvbHV0aW9uLCB0aGlzLnByb2plY3Rpb24pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZXIgZm9yIHN1Y2Nlc3NmdWwgdGlsZSBsb2FkLlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0Pn0gZmVhdHVyZXMgVGhlIGxvYWRlZCBmZWF0dXJlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBkYXRhUHJvamVjdGlvbiBEYXRhIHByb2plY3Rpb24uXG4gICAqL1xuXG5cbiAgVmVjdG9yVGlsZS5wcm90b3R5cGUub25Mb2FkID0gZnVuY3Rpb24gKGZlYXR1cmVzLCBkYXRhUHJvamVjdGlvbikge1xuICAgIHRoaXMuc2V0RmVhdHVyZXMoZmVhdHVyZXMpO1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlciBmb3IgdGlsZSBsb2FkIGVycm9ycy5cbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc2V0U3RhdGUoVGlsZVN0YXRlLkVSUk9SKTtcbiAgfTtcbiAgLyoqXG4gICAqIEZ1bmN0aW9uIGZvciB1c2UgaW4gYW4ge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yVGlsZX5WZWN0b3JUaWxlfSdzIGB0aWxlTG9hZEZ1bmN0aW9uYC5cbiAgICogU2V0cyB0aGUgZmVhdHVyZXMgZm9yIHRoZSB0aWxlLlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0Pn0gZmVhdHVyZXMgRmVhdHVyZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5zZXRGZWF0dXJlcyA9IGZ1bmN0aW9uIChmZWF0dXJlcykge1xuICAgIHRoaXMuZmVhdHVyZXNfID0gZmVhdHVyZXM7XG4gICAgdGhpcy5zZXRTdGF0ZShUaWxlU3RhdGUuTE9BREVEKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgZmVhdHVyZSBsb2FkZXIgZm9yIHJlYWRpbmcgdGhpcyB0aWxlJ3MgZmVhdHVyZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9mZWF0dXJlbG9hZGVyLmpzXCIpLkZlYXR1cmVMb2FkZXJ9IGxvYWRlciBGZWF0dXJlIGxvYWRlci5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLnNldExvYWRlciA9IGZ1bmN0aW9uIChsb2FkZXIpIHtcbiAgICB0aGlzLmxvYWRlcl8gPSBsb2FkZXI7XG4gIH07XG5cbiAgcmV0dXJuIFZlY3RvclRpbGU7XG59KFRpbGUpO1xuXG5leHBvcnQgZGVmYXVsdCBWZWN0b3JUaWxlOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHJ1Y3RzL0xSVUNhY2hlXG4gKi9cbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uL2Fzc2VydHMuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBFbnRyeVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGtleV9cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBuZXdlclxuICogQHByb3BlcnR5IHtPYmplY3R9IG9sZGVyXG4gKiBAcHJvcGVydHkgeyp9IHZhbHVlX1xuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogSW1wbGVtZW50cyBhIExlYXN0LVJlY2VudGx5LVVzZWQgY2FjaGUgd2hlcmUgdGhlIGtleXMgZG8gbm90IGNvbmZsaWN0IHdpdGhcbiAqIE9iamVjdCdzIHByb3BlcnRpZXMgKGUuZy4gJ2hhc093blByb3BlcnR5JyBpcyBub3QgYWxsb3dlZCBhcyBhIGtleSkuIEV4cGlyaW5nXG4gKiBpdGVtcyBmcm9tIHRoZSBjYWNoZSBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIHVzZXIuXG4gKlxuICogQGZpcmVzIGltcG9ydChcIi4uL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0XG4gKiBAdGVtcGxhdGUgVFxuICovXG5cbnZhciBMUlVDYWNoZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9oaWdoV2F0ZXJNYXJrIEhpZ2ggd2F0ZXIgbWFyay5cbiAgICovXG4gIGZ1bmN0aW9uIExSVUNhY2hlKG9wdF9oaWdoV2F0ZXJNYXJrKSB7XG4gICAgLyoqXG4gICAgICogRGVzaXJlZCBtYXggY2FjaGUgc2l6ZSBhZnRlciBleHBpcmVDYWNoZSgpLiBJZiBzZXQgdG8gMCwgbm8gY2FjaGUgZW50cmllc1xuICAgICAqIHdpbGwgYmUgcHJ1bmVkIGF0IGFsbC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMuaGlnaFdhdGVyTWFyayA9IG9wdF9oaWdoV2F0ZXJNYXJrICE9PSB1bmRlZmluZWQgPyBvcHRfaGlnaFdhdGVyTWFyayA6IDIwNDg7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5jb3VudF8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBFbnRyeT59XG4gICAgICovXG5cbiAgICB0aGlzLmVudHJpZXNfID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P0VudHJ5fVxuICAgICAqL1xuXG4gICAgdGhpcy5vbGRlc3RfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/RW50cnl9XG4gICAgICovXG5cbiAgICB0aGlzLm5ld2VzdF8gPSBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBDYW4gZXhwaXJlIGNhY2hlLlxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5jYW5FeHBpcmVDYWNoZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5oaWdoV2F0ZXJNYXJrID4gMCAmJiB0aGlzLmdldENvdW50KCkgPiB0aGlzLmhpZ2hXYXRlck1hcms7XG4gIH07XG4gIC8qKlxuICAgKiBGSVhNRSBlbXB0eSBkZXNjcmlwdGlvbiBmb3IganNkb2NcbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5jb3VudF8gPSAwO1xuICAgIHRoaXMuZW50cmllc18gPSB7fTtcbiAgICB0aGlzLm9sZGVzdF8gPSBudWxsO1xuICAgIHRoaXMubmV3ZXN0XyA9IG51bGw7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IEtleS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMga2V5LlxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5jb250YWluc0tleSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5lbnRyaWVzXy5oYXNPd25Qcm9wZXJ0eShrZXkpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtmdW5jdGlvbihULCBzdHJpbmcsIExSVUNhY2hlPFQ+KTogP30gZiBUaGUgZnVuY3Rpb25cbiAgICogICAgIHRvIGNhbGwgZm9yIGV2ZXJ5IGVudHJ5IGZyb20gdGhlIG9sZGVzdCB0byB0aGUgbmV3ZXIuIFRoaXMgZnVuY3Rpb24gdGFrZXNcbiAgICogICAgIDMgYXJndW1lbnRzICh0aGUgZW50cnkgdmFsdWUsIHRoZSBlbnRyeSBrZXkgYW5kIHRoZSBMUlVDYWNoZSBvYmplY3QpLlxuICAgKiAgICAgVGhlIHJldHVybiB2YWx1ZSBpcyBpZ25vcmVkLlxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24gKGYpIHtcbiAgICB2YXIgZW50cnkgPSB0aGlzLm9sZGVzdF87XG5cbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIGYoZW50cnkudmFsdWVfLCBlbnRyeS5rZXlfLCB0aGlzKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV3ZXI7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkuXG4gICAqIEBwYXJhbSB7Kj19IG9wdF9vcHRpb25zIE9wdGlvbnMgKHJlc2VydmVyZCBmb3Igc3ViY2xhc3NlcykuXG4gICAqIEByZXR1cm4ge1R9IFZhbHVlLlxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5LCBvcHRfb3B0aW9ucykge1xuICAgIHZhciBlbnRyeSA9IHRoaXMuZW50cmllc19ba2V5XTtcbiAgICBhc3NlcnQoZW50cnkgIT09IHVuZGVmaW5lZCwgMTUpOyAvLyBUcmllZCB0byBnZXQgYSB2YWx1ZSBmb3IgYSBrZXkgdGhhdCBkb2VzIG5vdCBleGlzdCBpbiB0aGUgY2FjaGVcblxuICAgIGlmIChlbnRyeSA9PT0gdGhpcy5uZXdlc3RfKSB7XG4gICAgICByZXR1cm4gZW50cnkudmFsdWVfO1xuICAgIH0gZWxzZSBpZiAoZW50cnkgPT09IHRoaXMub2xkZXN0Xykge1xuICAgICAgdGhpcy5vbGRlc3RfID1cbiAgICAgIC8qKiBAdHlwZSB7RW50cnl9ICovXG4gICAgICB0aGlzLm9sZGVzdF8ubmV3ZXI7XG4gICAgICB0aGlzLm9sZGVzdF8ub2xkZXIgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbnRyeS5uZXdlci5vbGRlciA9IGVudHJ5Lm9sZGVyO1xuICAgICAgZW50cnkub2xkZXIubmV3ZXIgPSBlbnRyeS5uZXdlcjtcbiAgICB9XG5cbiAgICBlbnRyeS5uZXdlciA9IG51bGw7XG4gICAgZW50cnkub2xkZXIgPSB0aGlzLm5ld2VzdF87XG4gICAgdGhpcy5uZXdlc3RfLm5ld2VyID0gZW50cnk7XG4gICAgdGhpcy5uZXdlc3RfID0gZW50cnk7XG4gICAgcmV0dXJuIGVudHJ5LnZhbHVlXztcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSBhbiBlbnRyeSBmcm9tIHRoZSBjYWNoZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgZW50cnkga2V5LlxuICAgKiBAcmV0dXJuIHtUfSBUaGUgcmVtb3ZlZCBlbnRyeS5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBlbnRyeSA9IHRoaXMuZW50cmllc19ba2V5XTtcbiAgICBhc3NlcnQoZW50cnkgIT09IHVuZGVmaW5lZCwgMTUpOyAvLyBUcmllZCB0byBnZXQgYSB2YWx1ZSBmb3IgYSBrZXkgdGhhdCBkb2VzIG5vdCBleGlzdCBpbiB0aGUgY2FjaGVcblxuICAgIGlmIChlbnRyeSA9PT0gdGhpcy5uZXdlc3RfKSB7XG4gICAgICB0aGlzLm5ld2VzdF8gPVxuICAgICAgLyoqIEB0eXBlIHtFbnRyeX0gKi9cbiAgICAgIGVudHJ5Lm9sZGVyO1xuXG4gICAgICBpZiAodGhpcy5uZXdlc3RfKSB7XG4gICAgICAgIHRoaXMubmV3ZXN0Xy5uZXdlciA9IG51bGw7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbnRyeSA9PT0gdGhpcy5vbGRlc3RfKSB7XG4gICAgICB0aGlzLm9sZGVzdF8gPVxuICAgICAgLyoqIEB0eXBlIHtFbnRyeX0gKi9cbiAgICAgIGVudHJ5Lm5ld2VyO1xuXG4gICAgICBpZiAodGhpcy5vbGRlc3RfKSB7XG4gICAgICAgIHRoaXMub2xkZXN0Xy5vbGRlciA9IG51bGw7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudHJ5Lm5ld2VyLm9sZGVyID0gZW50cnkub2xkZXI7XG4gICAgICBlbnRyeS5vbGRlci5uZXdlciA9IGVudHJ5Lm5ld2VyO1xuICAgIH1cblxuICAgIGRlbGV0ZSB0aGlzLmVudHJpZXNfW2tleV07XG4gICAgLS10aGlzLmNvdW50XztcbiAgICByZXR1cm4gZW50cnkudmFsdWVfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBDb3VudC5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUuZ2V0Q291bnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY291bnRfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn0gS2V5cy5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUuZ2V0S2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIga2V5cyA9IG5ldyBBcnJheSh0aGlzLmNvdW50Xyk7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciBlbnRyeTtcblxuICAgIGZvciAoZW50cnkgPSB0aGlzLm5ld2VzdF87IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm9sZGVyKSB7XG4gICAgICBrZXlzW2krK10gPSBlbnRyeS5rZXlfO1xuICAgIH1cblxuICAgIHJldHVybiBrZXlzO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8VD59IFZhbHVlcy5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUuZ2V0VmFsdWVzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZXMgPSBuZXcgQXJyYXkodGhpcy5jb3VudF8pO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgZW50cnk7XG5cbiAgICBmb3IgKGVudHJ5ID0gdGhpcy5uZXdlc3RfOyBlbnRyeTsgZW50cnkgPSBlbnRyeS5vbGRlcikge1xuICAgICAgdmFsdWVzW2krK10gPSBlbnRyeS52YWx1ZV87XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge1R9IExhc3QgdmFsdWUuXG4gICAqL1xuXG5cbiAgTFJVQ2FjaGUucHJvdG90eXBlLnBlZWtMYXN0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm9sZGVzdF8udmFsdWVfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7c3RyaW5nfSBMYXN0IGtleS5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUucGVla0xhc3RLZXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMub2xkZXN0Xy5rZXlfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBrZXkgb2YgdGhlIG5ld2VzdCBpdGVtIGluIHRoZSBjYWNoZS4gIFRocm93cyBpZiB0aGUgY2FjaGUgaXMgZW1wdHkuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIG5ld2VzdCBrZXkuXG4gICAqL1xuXG5cbiAgTFJVQ2FjaGUucHJvdG90eXBlLnBlZWtGaXJzdEtleSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5uZXdlc3RfLmtleV87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtUfSB2YWx1ZSBWYWx1ZS5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUucG9wID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBlbnRyeSA9IHRoaXMub2xkZXN0XztcbiAgICBkZWxldGUgdGhpcy5lbnRyaWVzX1tlbnRyeS5rZXlfXTtcblxuICAgIGlmIChlbnRyeS5uZXdlcikge1xuICAgICAgZW50cnkubmV3ZXIub2xkZXIgPSBudWxsO1xuICAgIH1cblxuICAgIHRoaXMub2xkZXN0XyA9XG4gICAgLyoqIEB0eXBlIHtFbnRyeX0gKi9cbiAgICBlbnRyeS5uZXdlcjtcblxuICAgIGlmICghdGhpcy5vbGRlc3RfKSB7XG4gICAgICB0aGlzLm5ld2VzdF8gPSBudWxsO1xuICAgIH1cblxuICAgIC0tdGhpcy5jb3VudF87XG4gICAgcmV0dXJuIGVudHJ5LnZhbHVlXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5LlxuICAgKiBAcGFyYW0ge1R9IHZhbHVlIFZhbHVlLlxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5yZXBsYWNlID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICB0aGlzLmdldChrZXkpOyAvLyB1cGRhdGUgYG5ld2VzdF9gXG5cbiAgICB0aGlzLmVudHJpZXNfW2tleV0udmFsdWVfID0gdmFsdWU7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IEtleS5cbiAgICogQHBhcmFtIHtUfSB2YWx1ZSBWYWx1ZS5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICBhc3NlcnQoIShrZXkgaW4gdGhpcy5lbnRyaWVzXyksIDE2KTsgLy8gVHJpZWQgdG8gc2V0IGEgdmFsdWUgZm9yIGEga2V5IHRoYXQgaXMgdXNlZCBhbHJlYWR5XG5cbiAgICB2YXIgZW50cnkgPSB7XG4gICAgICBrZXlfOiBrZXksXG4gICAgICBuZXdlcjogbnVsbCxcbiAgICAgIG9sZGVyOiB0aGlzLm5ld2VzdF8sXG4gICAgICB2YWx1ZV86IHZhbHVlXG4gICAgfTtcblxuICAgIGlmICghdGhpcy5uZXdlc3RfKSB7XG4gICAgICB0aGlzLm9sZGVzdF8gPSBlbnRyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5uZXdlc3RfLm5ld2VyID0gZW50cnk7XG4gICAgfVxuXG4gICAgdGhpcy5uZXdlc3RfID0gZW50cnk7XG4gICAgdGhpcy5lbnRyaWVzX1trZXldID0gZW50cnk7XG4gICAgKyt0aGlzLmNvdW50XztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCBhIG1heGltdW0gbnVtYmVyIG9mIGVudHJpZXMgZm9yIHRoZSBjYWNoZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHNpemUgQ2FjaGUgc2l6ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5zZXRTaXplID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgICB0aGlzLmhpZ2hXYXRlck1hcmsgPSBzaXplO1xuICB9O1xuXG4gIHJldHVybiBMUlVDYWNoZTtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgTFJVQ2FjaGU7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3RpbGVjb29yZFxuICovXG5cbi8qKlxuICogQW4gYXJyYXkgb2YgdGhyZWUgbnVtYmVycyByZXByZXNlbnRpbmcgdGhlIGxvY2F0aW9uIG9mIGEgdGlsZSBpbiBhIHRpbGVcbiAqIGdyaWQuIFRoZSBvcmRlciBpcyBgemAgKHpvb20gbGV2ZWwpLCBgeGAgKGNvbHVtbiksIGFuZCBgeWAgKHJvdykuXG4gKiBAdHlwZWRlZiB7QXJyYXk8bnVtYmVyPn0gVGlsZUNvb3JkXG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0geiBaLlxuICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gKiBAcGFyYW0ge1RpbGVDb29yZD19IG9wdF90aWxlQ29vcmQgVGlsZSBjb29yZGluYXRlLlxuICogQHJldHVybiB7VGlsZUNvb3JkfSBUaWxlIGNvb3JkaW5hdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVPclVwZGF0ZSh6LCB4LCB5LCBvcHRfdGlsZUNvb3JkKSB7XG4gIGlmIChvcHRfdGlsZUNvb3JkICE9PSB1bmRlZmluZWQpIHtcbiAgICBvcHRfdGlsZUNvb3JkWzBdID0gejtcbiAgICBvcHRfdGlsZUNvb3JkWzFdID0geDtcbiAgICBvcHRfdGlsZUNvb3JkWzJdID0geTtcbiAgICByZXR1cm4gb3B0X3RpbGVDb29yZDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW3osIHgsIHldO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB6IFouXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqIEByZXR1cm4ge3N0cmluZ30gS2V5LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRLZXlaWFkoeiwgeCwgeSkge1xuICByZXR1cm4geiArICcvJyArIHggKyAnLycgKyB5O1xufVxuLyoqXG4gKiBHZXQgdGhlIGtleSBmb3IgYSB0aWxlIGNvb3JkLlxuICogQHBhcmFtIHtUaWxlQ29vcmR9IHRpbGVDb29yZCBUaGUgdGlsZSBjb29yZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gS2V5LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRLZXkodGlsZUNvb3JkKSB7XG4gIHJldHVybiBnZXRLZXlaWFkodGlsZUNvb3JkWzBdLCB0aWxlQ29vcmRbMV0sIHRpbGVDb29yZFsyXSk7XG59XG4vKipcbiAqIEdldCBhIHRpbGUgY29vcmQgZ2l2ZW4gYSBrZXkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSB0aWxlIGNvb3JkIGtleS5cbiAqIEByZXR1cm4ge1RpbGVDb29yZH0gVGhlIHRpbGUgY29vcmQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21LZXkoa2V5KSB7XG4gIHJldHVybiBrZXkuc3BsaXQoJy8nKS5tYXAoTnVtYmVyKTtcbn1cbi8qKlxuICogQHBhcmFtIHtUaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkLlxuICogQHJldHVybiB7bnVtYmVyfSBIYXNoLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNoKHRpbGVDb29yZCkge1xuICByZXR1cm4gKHRpbGVDb29yZFsxXSA8PCB0aWxlQ29vcmRbMF0pICsgdGlsZUNvb3JkWzJdO1xufVxuLyoqXG4gKiBAcGFyYW0ge1RpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7IWltcG9ydChcIi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gdGlsZUdyaWQgVGlsZSBncmlkLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGlsZSBjb29yZGluYXRlIGlzIHdpdGhpbiBleHRlbnQgYW5kIHpvb20gbGV2ZWwgcmFuZ2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHdpdGhpbkV4dGVudEFuZFoodGlsZUNvb3JkLCB0aWxlR3JpZCkge1xuICB2YXIgeiA9IHRpbGVDb29yZFswXTtcbiAgdmFyIHggPSB0aWxlQ29vcmRbMV07XG4gIHZhciB5ID0gdGlsZUNvb3JkWzJdO1xuXG4gIGlmICh0aWxlR3JpZC5nZXRNaW5ab29tKCkgPiB6IHx8IHogPiB0aWxlR3JpZC5nZXRNYXhab29tKCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgdGlsZVJhbmdlID0gdGlsZUdyaWQuZ2V0RnVsbFRpbGVSYW5nZSh6KTtcblxuICBpZiAoIXRpbGVSYW5nZSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aWxlUmFuZ2UuY29udGFpbnNYWSh4LCB5KTtcbiAgfVxufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvVGlsZUNhY2hlXG4gKi9cblxuXG5pbXBvcnQgTFJVQ2FjaGUgZnJvbSAnLi9zdHJ1Y3RzL0xSVUNhY2hlLmpzJztcbmltcG9ydCB7IGZyb21LZXksIGdldEtleSB9IGZyb20gJy4vdGlsZWNvb3JkLmpzJztcblxudmFyIFRpbGVDYWNoZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhUaWxlQ2FjaGUsIF9zdXBlcik7XG5cbiAgZnVuY3Rpb24gVGlsZUNhY2hlKCkge1xuICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHshT2JqZWN0PHN0cmluZywgYm9vbGVhbj59IHVzZWRUaWxlcyBVc2VkIHRpbGVzLlxuICAgKi9cblxuXG4gIFRpbGVDYWNoZS5wcm90b3R5cGUuZXhwaXJlQ2FjaGUgPSBmdW5jdGlvbiAodXNlZFRpbGVzKSB7XG4gICAgd2hpbGUgKHRoaXMuY2FuRXhwaXJlQ2FjaGUoKSkge1xuICAgICAgdmFyIHRpbGUgPSB0aGlzLnBlZWtMYXN0KCk7XG5cbiAgICAgIGlmICh0aWxlLmdldEtleSgpIGluIHVzZWRUaWxlcykge1xuICAgICAgICBicmVhaztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucG9wKCkucmVsZWFzZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFBydW5lIGFsbCB0aWxlcyBmcm9tIHRoZSBjYWNoZSB0aGF0IGRvbid0IGhhdmUgdGhlIHNhbWUgeiBhcyB0aGUgbmV3ZXN0IHRpbGUuXG4gICAqL1xuXG5cbiAgVGlsZUNhY2hlLnByb3RvdHlwZS5wcnVuZUV4Y2VwdE5ld2VzdFogPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuZ2V0Q291bnQoKSA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBrZXkgPSB0aGlzLnBlZWtGaXJzdEtleSgpO1xuICAgIHZhciB0aWxlQ29vcmQgPSBmcm9tS2V5KGtleSk7XG4gICAgdmFyIHogPSB0aWxlQ29vcmRbMF07XG4gICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uICh0aWxlKSB7XG4gICAgICBpZiAodGlsZS50aWxlQ29vcmRbMF0gIT09IHopIHtcbiAgICAgICAgdGhpcy5yZW1vdmUoZ2V0S2V5KHRpbGUudGlsZUNvb3JkKSk7XG4gICAgICAgIHRpbGUucmVsZWFzZSgpO1xuICAgICAgfVxuICAgIH0uYmluZCh0aGlzKSk7XG4gIH07XG5cbiAgcmV0dXJuIFRpbGVDYWNoZTtcbn0oTFJVQ2FjaGUpO1xuXG5leHBvcnQgZGVmYXVsdCBUaWxlQ2FjaGU7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3NvdXJjZS9UaWxlRXZlbnRUeXBlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBhIHRpbGUgc3RhcnRzIGxvYWRpbmcuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvc291cmNlL1RpbGUuVGlsZVNvdXJjZUV2ZW50I3RpbGVsb2Fkc3RhcnRcbiAgICogQGFwaVxuICAgKi9cbiAgVElMRUxPQURTVEFSVDogJ3RpbGVsb2Fkc3RhcnQnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBhIHRpbGUgZmluaXNoZXMgbG9hZGluZywgZWl0aGVyIHdoZW4gaXRzIGRhdGEgaXMgbG9hZGVkLFxuICAgKiBvciB3aGVuIGxvYWRpbmcgd2FzIGFib3J0ZWQgYmVjYXVzZSB0aGUgdGlsZSBpcyBubyBsb25nZXIgbmVlZGVkLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3NvdXJjZS9UaWxlLlRpbGVTb3VyY2VFdmVudCN0aWxlbG9hZGVuZFxuICAgKiBAYXBpXG4gICAqL1xuICBUSUxFTE9BREVORDogJ3RpbGVsb2FkZW5kJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIGlmIHRpbGUgbG9hZGluZyByZXN1bHRzIGluIGFuIGVycm9yLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3NvdXJjZS9UaWxlLlRpbGVTb3VyY2VFdmVudCN0aWxlbG9hZGVycm9yXG4gICAqIEBhcGlcbiAgICovXG4gIFRJTEVMT0FERVJST1I6ICd0aWxlbG9hZGVycm9yJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvdGlsZWdyaWQvVGlsZUdyaWRcbiAqL1xuaW1wb3J0IFRpbGVSYW5nZSwgeyBjcmVhdGVPclVwZGF0ZSBhcyBjcmVhdGVPclVwZGF0ZVRpbGVSYW5nZSB9IGZyb20gJy4uL1RpbGVSYW5nZS5qcyc7XG5pbXBvcnQgeyBERUZBVUxUX1RJTEVfU0laRSB9IGZyb20gJy4vY29tbW9uLmpzJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uL2Fzc2VydHMuanMnO1xuaW1wb3J0IHsgY2xhbXAgfSBmcm9tICcuLi9tYXRoLmpzJztcbmltcG9ydCB7IGNyZWF0ZU9yVXBkYXRlLCBnZXRUb3BMZWZ0IH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGNyZWF0ZU9yVXBkYXRlIGFzIGNyZWF0ZU9yVXBkYXRlVGlsZUNvb3JkIH0gZnJvbSAnLi4vdGlsZWNvb3JkLmpzJztcbmltcG9ydCB7IGlzU29ydGVkLCBsaW5lYXJGaW5kTmVhcmVzdCB9IGZyb20gJy4uL2FycmF5LmpzJztcbmltcG9ydCB7IHRvU2l6ZSB9IGZyb20gJy4uL3NpemUuanMnO1xuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9XG4gKi9cblxudmFyIHRtcFRpbGVDb29yZCA9IFswLCAwLCAwXTtcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBbZXh0ZW50XSBFeHRlbnQgZm9yIHRoZSB0aWxlIGdyaWQuIE5vIHRpbGVzIG91dHNpZGUgdGhpc1xuICogZXh0ZW50IHdpbGwgYmUgcmVxdWVzdGVkIGJ5IHtAbGluayBtb2R1bGU6b2wvc291cmNlL1RpbGV9IHNvdXJjZXMuIFdoZW4gbm8gYG9yaWdpbmAgb3JcbiAqIGBvcmlnaW5zYCBhcmUgY29uZmlndXJlZCwgdGhlIGBvcmlnaW5gIHdpbGwgYmUgc2V0IHRvIHRoZSB0b3AtbGVmdCBjb3JuZXIgb2YgdGhlIGV4dGVudC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluWm9vbT0wXSBNaW5pbXVtIHpvb20uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gW29yaWdpbl0gVGhlIHRpbGUgZ3JpZCBvcmlnaW4sIGkuZS4gd2hlcmUgdGhlIGB4YFxuICogYW5kIGB5YCBheGVzIG1lZXQgKGBbeiwgMCwgMF1gKS4gVGlsZSBjb29yZGluYXRlcyBpbmNyZWFzZSBsZWZ0IHRvIHJpZ2h0IGFuZCBkb3dud2FyZHMuIElmIG5vdFxuICogc3BlY2lmaWVkLCBgZXh0ZW50YCBvciBgb3JpZ2luc2AgbXVzdCBiZSBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn0gW29yaWdpbnNdIFRpbGUgZ3JpZCBvcmlnaW5zLCBpLmUuIHdoZXJlXG4gKiB0aGUgYHhgIGFuZCBgeWAgYXhlcyBtZWV0IChgW3osIDAsIDBdYCksIGZvciBlYWNoIHpvb20gbGV2ZWwuIElmIGdpdmVuLCB0aGUgYXJyYXkgbGVuZ3RoXG4gKiBzaG91bGQgbWF0Y2ggdGhlIGxlbmd0aCBvZiB0aGUgYHJlc29sdXRpb25zYCBhcnJheSwgaS5lLiBlYWNoIHJlc29sdXRpb24gY2FuIGhhdmUgYSBkaWZmZXJlbnRcbiAqIG9yaWdpbi4gVGlsZSBjb29yZGluYXRlcyBpbmNyZWFzZSBsZWZ0IHRvIHJpZ2h0IGFuZCBkb3dud2FyZHMuIElmIG5vdCBzcGVjaWZpZWQsIGBleHRlbnRgIG9yXG4gKiBgb3JpZ2luYCBtdXN0IGJlIHByb3ZpZGVkLlxuICogQHByb3BlcnR5IHshQXJyYXk8bnVtYmVyPn0gcmVzb2x1dGlvbnMgUmVzb2x1dGlvbnMuIFRoZSBhcnJheSBpbmRleCBvZiBlYWNoIHJlc29sdXRpb24gbmVlZHNcbiAqIHRvIG1hdGNoIHRoZSB6b29tIGxldmVsLiBUaGlzIG1lYW5zIHRoYXQgZXZlbiBpZiBhIGBtaW5ab29tYCBpcyBjb25maWd1cmVkLCB0aGUgcmVzb2x1dGlvbnNcbiAqIGFycmF5IHdpbGwgaGF2ZSBhIGxlbmd0aCBvZiBgbWF4Wm9vbSArIDFgLlxuICogQHByb3BlcnR5IHtBcnJheTxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemU+fSBbc2l6ZXNdIE51bWJlciBvZiB0aWxlIHJvd3MgYW5kIGNvbHVtbnNcbiAqIG9mIHRoZSBncmlkIGZvciBlYWNoIHpvb20gbGV2ZWwuIElmIHNwZWNpZmllZCB0aGUgdmFsdWVzXG4gKiBkZWZpbmUgZWFjaCB6b29tIGxldmVsJ3MgZXh0ZW50IHRvZ2V0aGVyIHdpdGggdGhlIGBvcmlnaW5gIG9yIGBvcmlnaW5zYC5cbiAqIEEgZ3JpZCBgZXh0ZW50YCBjYW4gYmUgY29uZmlndXJlZCBpbiBhZGRpdGlvbiwgYW5kIHdpbGwgZnVydGhlciBsaW1pdCB0aGUgZXh0ZW50XG4gKiBmb3Igd2hpY2ggdGlsZSByZXF1ZXN0cyBhcmUgbWFkZSBieSBzb3VyY2VzLiBJZiB0aGUgYm90dG9tLWxlZnQgY29ybmVyIG9mXG4gKiBhbiBleHRlbnQgaXMgdXNlZCBhcyBgb3JpZ2luYCBvciBgb3JpZ2luc2AsIHRoZW4gdGhlIGB5YCB2YWx1ZSBtdXN0IGJlXG4gKiBuZWdhdGl2ZSBiZWNhdXNlIE9wZW5MYXllcnMgdGlsZSBjb29yZGluYXRlcyB1c2UgdGhlIHRvcCBsZWZ0IGFzIHRoZSBvcmlnaW4uXG4gKiBAcHJvcGVydHkge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFt0aWxlU2l6ZV0gVGlsZSBzaXplLlxuICogRGVmYXVsdCBpcyBgWzI1NiwgMjU2XWAuXG4gKiBAcHJvcGVydHkge0FycmF5PGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZT59IFt0aWxlU2l6ZXNdIFRpbGUgc2l6ZXMuIElmIGdpdmVuLCB0aGUgYXJyYXkgbGVuZ3RoXG4gKiBzaG91bGQgbWF0Y2ggdGhlIGxlbmd0aCBvZiB0aGUgYHJlc29sdXRpb25zYCBhcnJheSwgaS5lLiBlYWNoIHJlc29sdXRpb24gY2FuIGhhdmUgYSBkaWZmZXJlbnRcbiAqIHRpbGUgc2l6ZS5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEJhc2UgY2xhc3MgZm9yIHNldHRpbmcgdGhlIGdyaWQgcGF0dGVybiBmb3Igc291cmNlcyBhY2Nlc3NpbmcgdGlsZWQtaW1hZ2VcbiAqIHNlcnZlcnMuXG4gKiBAYXBpXG4gKi9cblxudmFyIFRpbGVHcmlkID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBUaWxlIGdyaWQgb3B0aW9ucy5cbiAgICovXG4gIGZ1bmN0aW9uIFRpbGVHcmlkKG9wdGlvbnMpIHtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLm1pblpvb20gPSBvcHRpb25zLm1pblpvb20gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubWluWm9vbSA6IDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IUFycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICB0aGlzLnJlc29sdXRpb25zXyA9IG9wdGlvbnMucmVzb2x1dGlvbnM7XG4gICAgYXNzZXJ0KGlzU29ydGVkKHRoaXMucmVzb2x1dGlvbnNfLCBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGIgLSBhO1xuICAgIH0sIHRydWUpLCAxNyk7IC8vIGByZXNvbHV0aW9uc2AgbXVzdCBiZSBzb3J0ZWQgaW4gZGVzY2VuZGluZyBvcmRlclxuICAgIC8vIGNoZWNrIGlmIHdlJ3ZlIGdvdCBhIGNvbnNpc3RlbnQgem9vbSBmYWN0b3IgYW5kIG9yaWdpblxuXG4gICAgdmFyIHpvb21GYWN0b3I7XG5cbiAgICBpZiAoIW9wdGlvbnMub3JpZ2lucykge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5yZXNvbHV0aW9uc18ubGVuZ3RoIC0gMTsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgaWYgKCF6b29tRmFjdG9yKSB7XG4gICAgICAgICAgem9vbUZhY3RvciA9IHRoaXMucmVzb2x1dGlvbnNfW2ldIC8gdGhpcy5yZXNvbHV0aW9uc19baSArIDFdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLnJlc29sdXRpb25zX1tpXSAvIHRoaXMucmVzb2x1dGlvbnNfW2kgKyAxXSAhPT0gem9vbUZhY3Rvcikge1xuICAgICAgICAgICAgem9vbUZhY3RvciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG5cbiAgICB0aGlzLnpvb21GYWN0b3JfID0gem9vbUZhY3RvcjtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMubWF4Wm9vbSA9IHRoaXMucmVzb2x1dGlvbnNfLmxlbmd0aCAtIDE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfVxuICAgICAqL1xuXG4gICAgdGhpcy5vcmlnaW5fID0gb3B0aW9ucy5vcmlnaW4gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMub3JpZ2luIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fVxuICAgICAqL1xuXG4gICAgdGhpcy5vcmlnaW5zXyA9IG51bGw7XG5cbiAgICBpZiAob3B0aW9ucy5vcmlnaW5zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMub3JpZ2luc18gPSBvcHRpb25zLm9yaWdpbnM7XG4gICAgICBhc3NlcnQodGhpcy5vcmlnaW5zXy5sZW5ndGggPT0gdGhpcy5yZXNvbHV0aW9uc18ubGVuZ3RoLCAyMCk7IC8vIE51bWJlciBvZiBgb3JpZ2luc2AgYW5kIGByZXNvbHV0aW9uc2AgbXVzdCBiZSBlcXVhbFxuICAgIH1cblxuICAgIHZhciBleHRlbnQgPSBvcHRpb25zLmV4dGVudDtcblxuICAgIGlmIChleHRlbnQgIT09IHVuZGVmaW5lZCAmJiAhdGhpcy5vcmlnaW5fICYmICF0aGlzLm9yaWdpbnNfKSB7XG4gICAgICB0aGlzLm9yaWdpbl8gPSBnZXRUb3BMZWZ0KGV4dGVudCk7XG4gICAgfVxuXG4gICAgYXNzZXJ0KCF0aGlzLm9yaWdpbl8gJiYgdGhpcy5vcmlnaW5zXyB8fCB0aGlzLm9yaWdpbl8gJiYgIXRoaXMub3JpZ2luc18sIDE4KTsgLy8gRWl0aGVyIGBvcmlnaW5gIG9yIGBvcmlnaW5zYCBtdXN0IGJlIGNvbmZpZ3VyZWQsIG5ldmVyIGJvdGhcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemU+fVxuICAgICAqL1xuXG4gICAgdGhpcy50aWxlU2l6ZXNfID0gbnVsbDtcblxuICAgIGlmIChvcHRpb25zLnRpbGVTaXplcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnRpbGVTaXplc18gPSBvcHRpb25zLnRpbGVTaXplcztcbiAgICAgIGFzc2VydCh0aGlzLnRpbGVTaXplc18ubGVuZ3RoID09IHRoaXMucmVzb2x1dGlvbnNfLmxlbmd0aCwgMTkpOyAvLyBOdW1iZXIgb2YgYHRpbGVTaXplc2AgYW5kIGByZXNvbHV0aW9uc2AgbXVzdCBiZSBlcXVhbFxuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfVxuICAgICAqL1xuXG5cbiAgICB0aGlzLnRpbGVTaXplXyA9IG9wdGlvbnMudGlsZVNpemUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudGlsZVNpemUgOiAhdGhpcy50aWxlU2l6ZXNfID8gREVGQVVMVF9USUxFX1NJWkUgOiBudWxsO1xuICAgIGFzc2VydCghdGhpcy50aWxlU2l6ZV8gJiYgdGhpcy50aWxlU2l6ZXNfIHx8IHRoaXMudGlsZVNpemVfICYmICF0aGlzLnRpbGVTaXplc18sIDIyKTsgLy8gRWl0aGVyIGB0aWxlU2l6ZWAgb3IgYHRpbGVTaXplc2AgbXVzdCBiZSBjb25maWd1cmVkLCBuZXZlciBib3RoXG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG4gICAgdGhpcy5leHRlbnRfID0gZXh0ZW50ICE9PSB1bmRlZmluZWQgPyBleHRlbnQgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PGltcG9ydChcIi4uL1RpbGVSYW5nZS5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIHRoaXMuZnVsbFRpbGVSYW5nZXNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICB0aGlzLnRtcFNpemVfID0gWzAsIDBdO1xuXG4gICAgaWYgKG9wdGlvbnMuc2l6ZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5mdWxsVGlsZVJhbmdlc18gPSBvcHRpb25zLnNpemVzLm1hcChmdW5jdGlvbiAoc2l6ZSwgeikge1xuICAgICAgICB2YXIgdGlsZVJhbmdlID0gbmV3IFRpbGVSYW5nZShNYXRoLm1pbigwLCBzaXplWzBdKSwgTWF0aC5tYXgoc2l6ZVswXSAtIDEsIC0xKSwgTWF0aC5taW4oMCwgc2l6ZVsxXSksIE1hdGgubWF4KHNpemVbMV0gLSAxLCAtMSkpO1xuXG4gICAgICAgIGlmIChleHRlbnQpIHtcbiAgICAgICAgICB2YXIgcmVzdHJpY3RlZFRpbGVSYW5nZSA9IHRoaXMuZ2V0VGlsZVJhbmdlRm9yRXh0ZW50QW5kWihleHRlbnQsIHopO1xuICAgICAgICAgIHRpbGVSYW5nZS5taW5YID0gTWF0aC5tYXgocmVzdHJpY3RlZFRpbGVSYW5nZS5taW5YLCB0aWxlUmFuZ2UubWluWCk7XG4gICAgICAgICAgdGlsZVJhbmdlLm1heFggPSBNYXRoLm1pbihyZXN0cmljdGVkVGlsZVJhbmdlLm1heFgsIHRpbGVSYW5nZS5tYXhYKTtcbiAgICAgICAgICB0aWxlUmFuZ2UubWluWSA9IE1hdGgubWF4KHJlc3RyaWN0ZWRUaWxlUmFuZ2UubWluWSwgdGlsZVJhbmdlLm1pblkpO1xuICAgICAgICAgIHRpbGVSYW5nZS5tYXhZID0gTWF0aC5taW4ocmVzdHJpY3RlZFRpbGVSYW5nZS5tYXhZLCB0aWxlUmFuZ2UubWF4WSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGlsZVJhbmdlO1xuICAgICAgfSwgdGhpcyk7XG4gICAgfSBlbHNlIGlmIChleHRlbnQpIHtcbiAgICAgIHRoaXMuY2FsY3VsYXRlVGlsZVJhbmdlc18oZXh0ZW50KTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIENhbGwgYSBmdW5jdGlvbiB3aXRoIGVhY2ggdGlsZSBjb29yZGluYXRlIGZvciBhIGdpdmVuIGV4dGVudCBhbmQgem9vbSBsZXZlbC5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gem9vbSBJbnRlZ2VyIHpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZCk6IHZvaWR9IGNhbGxiYWNrIEZ1bmN0aW9uIGNhbGxlZCB3aXRoIGVhY2ggdGlsZSBjb29yZGluYXRlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmZvckVhY2hUaWxlQ29vcmQgPSBmdW5jdGlvbiAoZXh0ZW50LCB6b29tLCBjYWxsYmFjaykge1xuICAgIHZhciB0aWxlUmFuZ2UgPSB0aGlzLmdldFRpbGVSYW5nZUZvckV4dGVudEFuZFooZXh0ZW50LCB6b29tKTtcblxuICAgIGZvciAodmFyIGkgPSB0aWxlUmFuZ2UubWluWCwgaWkgPSB0aWxlUmFuZ2UubWF4WDsgaSA8PSBpaTsgKytpKSB7XG4gICAgICBmb3IgKHZhciBqID0gdGlsZVJhbmdlLm1pblksIGpqID0gdGlsZVJhbmdlLm1heFk7IGogPD0gamo7ICsraikge1xuICAgICAgICBjYWxsYmFjayhbem9vbSwgaSwgal0pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihudW1iZXIsIGltcG9ydChcIi4uL1RpbGVSYW5nZS5qc1wiKS5kZWZhdWx0KTogYm9vbGVhbn0gY2FsbGJhY2sgQ2FsbGJhY2suXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vVGlsZVJhbmdlLmpzXCIpLmRlZmF1bHQ9fSBvcHRfdGlsZVJhbmdlIFRlbXBvcmFyeSBpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdCBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudD19IG9wdF9leHRlbnQgVGVtcG9yYXJ5IGltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnQgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBDYWxsYmFjayBzdWNjZWVkZWQuXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmZvckVhY2hUaWxlQ29vcmRQYXJlbnRUaWxlUmFuZ2UgPSBmdW5jdGlvbiAodGlsZUNvb3JkLCBjYWxsYmFjaywgb3B0X3RpbGVSYW5nZSwgb3B0X2V4dGVudCkge1xuICAgIHZhciB0aWxlUmFuZ2UsIHgsIHk7XG4gICAgdmFyIHRpbGVDb29yZEV4dGVudCA9IG51bGw7XG4gICAgdmFyIHogPSB0aWxlQ29vcmRbMF0gLSAxO1xuXG4gICAgaWYgKHRoaXMuem9vbUZhY3Rvcl8gPT09IDIpIHtcbiAgICAgIHggPSB0aWxlQ29vcmRbMV07XG4gICAgICB5ID0gdGlsZUNvb3JkWzJdO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aWxlQ29vcmRFeHRlbnQgPSB0aGlzLmdldFRpbGVDb29yZEV4dGVudCh0aWxlQ29vcmQsIG9wdF9leHRlbnQpO1xuICAgIH1cblxuICAgIHdoaWxlICh6ID49IHRoaXMubWluWm9vbSkge1xuICAgICAgaWYgKHRoaXMuem9vbUZhY3Rvcl8gPT09IDIpIHtcbiAgICAgICAgeCA9IE1hdGguZmxvb3IoeCAvIDIpO1xuICAgICAgICB5ID0gTWF0aC5mbG9vcih5IC8gMik7XG4gICAgICAgIHRpbGVSYW5nZSA9IGNyZWF0ZU9yVXBkYXRlVGlsZVJhbmdlKHgsIHgsIHksIHksIG9wdF90aWxlUmFuZ2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGlsZVJhbmdlID0gdGhpcy5nZXRUaWxlUmFuZ2VGb3JFeHRlbnRBbmRaKHRpbGVDb29yZEV4dGVudCwgeiwgb3B0X3RpbGVSYW5nZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjYWxsYmFjayh6LCB0aWxlUmFuZ2UpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICAtLXo7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBleHRlbnQgZm9yIHRoaXMgdGlsZSBncmlkLCBpZiBpdCB3YXMgY29uZmlndXJlZC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldEV4dGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5leHRlbnRfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtYXhpbXVtIHpvb20gbGV2ZWwgZm9yIHRoZSBncmlkLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE1heCB6b29tLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldE1heFpvb20gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubWF4Wm9vbTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbWluaW11bSB6b29tIGxldmVsIGZvciB0aGUgZ3JpZC5cbiAgICogQHJldHVybiB7bnVtYmVyfSBNaW4gem9vbS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRNaW5ab29tID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm1pblpvb207XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG9yaWdpbiBmb3IgdGhlIGdyaWQgYXQgdGhlIGdpdmVuIHpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IEludGVnZXIgem9vbSBsZXZlbC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBPcmlnaW4uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0T3JpZ2luID0gZnVuY3Rpb24gKHopIHtcbiAgICBpZiAodGhpcy5vcmlnaW5fKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcmlnaW5fO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5vcmlnaW5zX1t6XTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHJlc29sdXRpb24gZm9yIHRoZSBnaXZlbiB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge251bWJlcn0geiBJbnRlZ2VyIHpvb20gbGV2ZWwuXG4gICAqIEByZXR1cm4ge251bWJlcn0gUmVzb2x1dGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRSZXNvbHV0aW9uID0gZnVuY3Rpb24gKHopIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHV0aW9uc19bel07XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGxpc3Qgb2YgcmVzb2x1dGlvbnMgZm9yIHRoZSB0aWxlIGdyaWQuXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFJlc29sdXRpb25zLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldFJlc29sdXRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlc29sdXRpb25zXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdD19IG9wdF90aWxlUmFuZ2UgVGVtcG9yYXJ5IGltcG9ydChcIi4uL1RpbGVSYW5nZS5qc1wiKS5kZWZhdWx0IG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50PX0gb3B0X2V4dGVudCBUZW1wb3JhcnkgaW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudCBvYmplY3QuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL1RpbGVSYW5nZS5qc1wiKS5kZWZhdWx0fSBUaWxlIHJhbmdlLlxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRUaWxlQ29vcmRDaGlsZFRpbGVSYW5nZSA9IGZ1bmN0aW9uICh0aWxlQ29vcmQsIG9wdF90aWxlUmFuZ2UsIG9wdF9leHRlbnQpIHtcbiAgICBpZiAodGlsZUNvb3JkWzBdIDwgdGhpcy5tYXhab29tKSB7XG4gICAgICBpZiAodGhpcy56b29tRmFjdG9yXyA9PT0gMikge1xuICAgICAgICB2YXIgbWluWCA9IHRpbGVDb29yZFsxXSAqIDI7XG4gICAgICAgIHZhciBtaW5ZID0gdGlsZUNvb3JkWzJdICogMjtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU9yVXBkYXRlVGlsZVJhbmdlKG1pblgsIG1pblggKyAxLCBtaW5ZLCBtaW5ZICsgMSwgb3B0X3RpbGVSYW5nZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciB0aWxlQ29vcmRFeHRlbnQgPSB0aGlzLmdldFRpbGVDb29yZEV4dGVudCh0aWxlQ29vcmQsIG9wdF9leHRlbnQpO1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VGlsZVJhbmdlRm9yRXh0ZW50QW5kWih0aWxlQ29vcmRFeHRlbnQsIHRpbGVDb29yZFswXSArIDEsIG9wdF90aWxlUmFuZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBleHRlbnQgZm9yIGEgdGlsZSByYW5nZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHogSW50ZWdlciB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1RpbGVSYW5nZS5qc1wiKS5kZWZhdWx0fSB0aWxlUmFuZ2UgVGlsZSByYW5nZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50PX0gb3B0X2V4dGVudCBUZW1wb3JhcnkgaW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudCBvYmplY3QuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0VGlsZVJhbmdlRXh0ZW50ID0gZnVuY3Rpb24gKHosIHRpbGVSYW5nZSwgb3B0X2V4dGVudCkge1xuICAgIHZhciBvcmlnaW4gPSB0aGlzLmdldE9yaWdpbih6KTtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHRoaXMuZ2V0UmVzb2x1dGlvbih6KTtcbiAgICB2YXIgdGlsZVNpemUgPSB0b1NpemUodGhpcy5nZXRUaWxlU2l6ZSh6KSwgdGhpcy50bXBTaXplXyk7XG4gICAgdmFyIG1pblggPSBvcmlnaW5bMF0gKyB0aWxlUmFuZ2UubWluWCAqIHRpbGVTaXplWzBdICogcmVzb2x1dGlvbjtcbiAgICB2YXIgbWF4WCA9IG9yaWdpblswXSArICh0aWxlUmFuZ2UubWF4WCArIDEpICogdGlsZVNpemVbMF0gKiByZXNvbHV0aW9uO1xuICAgIHZhciBtaW5ZID0gb3JpZ2luWzFdICsgdGlsZVJhbmdlLm1pblkgKiB0aWxlU2l6ZVsxXSAqIHJlc29sdXRpb247XG4gICAgdmFyIG1heFkgPSBvcmlnaW5bMV0gKyAodGlsZVJhbmdlLm1heFkgKyAxKSAqIHRpbGVTaXplWzFdICogcmVzb2x1dGlvbjtcbiAgICByZXR1cm4gY3JlYXRlT3JVcGRhdGUobWluWCwgbWluWSwgbWF4WCwgbWF4WSwgb3B0X2V4dGVudCk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgYSB0aWxlIHJhbmdlIGZvciB0aGUgZ2l2ZW4gZXh0ZW50IGFuZCBpbnRlZ2VyIHpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHogSW50ZWdlciB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1RpbGVSYW5nZS5qc1wiKS5kZWZhdWx0PX0gb3B0X3RpbGVSYW5nZSBUZW1wb3JhcnkgdGlsZSByYW5nZSBvYmplY3QuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL1RpbGVSYW5nZS5qc1wiKS5kZWZhdWx0fSBUaWxlIHJhbmdlLlxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRUaWxlUmFuZ2VGb3JFeHRlbnRBbmRaID0gZnVuY3Rpb24gKGV4dGVudCwgeiwgb3B0X3RpbGVSYW5nZSkge1xuICAgIHZhciB0aWxlQ29vcmQgPSB0bXBUaWxlQ29vcmQ7XG4gICAgdGhpcy5nZXRUaWxlQ29vcmRGb3JYWUFuZFpfKGV4dGVudFswXSwgZXh0ZW50WzNdLCB6LCBmYWxzZSwgdGlsZUNvb3JkKTtcbiAgICB2YXIgbWluWCA9IHRpbGVDb29yZFsxXTtcbiAgICB2YXIgbWluWSA9IHRpbGVDb29yZFsyXTtcbiAgICB0aGlzLmdldFRpbGVDb29yZEZvclhZQW5kWl8oZXh0ZW50WzJdLCBleHRlbnRbMV0sIHosIHRydWUsIHRpbGVDb29yZCk7XG4gICAgcmV0dXJuIGNyZWF0ZU9yVXBkYXRlVGlsZVJhbmdlKG1pblgsIHRpbGVDb29yZFsxXSwgbWluWSwgdGlsZUNvb3JkWzJdLCBvcHRfdGlsZVJhbmdlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBUaWxlIGNlbnRlci5cbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0VGlsZUNvb3JkQ2VudGVyID0gZnVuY3Rpb24gKHRpbGVDb29yZCkge1xuICAgIHZhciBvcmlnaW4gPSB0aGlzLmdldE9yaWdpbih0aWxlQ29vcmRbMF0pO1xuICAgIHZhciByZXNvbHV0aW9uID0gdGhpcy5nZXRSZXNvbHV0aW9uKHRpbGVDb29yZFswXSk7XG4gICAgdmFyIHRpbGVTaXplID0gdG9TaXplKHRoaXMuZ2V0VGlsZVNpemUodGlsZUNvb3JkWzBdKSwgdGhpcy50bXBTaXplXyk7XG4gICAgcmV0dXJuIFtvcmlnaW5bMF0gKyAodGlsZUNvb3JkWzFdICsgMC41KSAqIHRpbGVTaXplWzBdICogcmVzb2x1dGlvbiwgb3JpZ2luWzFdIC0gKHRpbGVDb29yZFsyXSArIDAuNSkgKiB0aWxlU2l6ZVsxXSAqIHJlc29sdXRpb25dO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBleHRlbnQgb2YgYSB0aWxlIGNvb3JkaW5hdGUuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50PX0gb3B0X2V4dGVudCBUZW1wb3JhcnkgZXh0ZW50IG9iamVjdC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldFRpbGVDb29yZEV4dGVudCA9IGZ1bmN0aW9uICh0aWxlQ29vcmQsIG9wdF9leHRlbnQpIHtcbiAgICB2YXIgb3JpZ2luID0gdGhpcy5nZXRPcmlnaW4odGlsZUNvb3JkWzBdKTtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHRoaXMuZ2V0UmVzb2x1dGlvbih0aWxlQ29vcmRbMF0pO1xuICAgIHZhciB0aWxlU2l6ZSA9IHRvU2l6ZSh0aGlzLmdldFRpbGVTaXplKHRpbGVDb29yZFswXSksIHRoaXMudG1wU2l6ZV8pO1xuICAgIHZhciBtaW5YID0gb3JpZ2luWzBdICsgdGlsZUNvb3JkWzFdICogdGlsZVNpemVbMF0gKiByZXNvbHV0aW9uO1xuICAgIHZhciBtaW5ZID0gb3JpZ2luWzFdIC0gKHRpbGVDb29yZFsyXSArIDEpICogdGlsZVNpemVbMV0gKiByZXNvbHV0aW9uO1xuICAgIHZhciBtYXhYID0gbWluWCArIHRpbGVTaXplWzBdICogcmVzb2x1dGlvbjtcbiAgICB2YXIgbWF4WSA9IG1pblkgKyB0aWxlU2l6ZVsxXSAqIHJlc29sdXRpb247XG4gICAgcmV0dXJuIGNyZWF0ZU9yVXBkYXRlKG1pblgsIG1pblksIG1heFgsIG1heFksIG9wdF9leHRlbnQpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB0aWxlIGNvb3JkaW5hdGUgZm9yIHRoZSBnaXZlbiBtYXAgY29vcmRpbmF0ZSBhbmQgcmVzb2x1dGlvbi4gIFRoaXNcbiAgICogbWV0aG9kIGNvbnNpZGVycyB0aGF0IGNvb3JkaW5hdGVzIHRoYXQgaW50ZXJzZWN0IHRpbGUgYm91bmRhcmllcyBzaG91bGQgYmVcbiAgICogYXNzaWduZWQgdGhlIGhpZ2hlciB0aWxlIGNvb3JkaW5hdGUuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZD19IG9wdF90aWxlQ29vcmQgRGVzdGluYXRpb24gaW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZCBvYmplY3QuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRUaWxlQ29vcmRGb3JDb29yZEFuZFJlc29sdXRpb24gPSBmdW5jdGlvbiAoY29vcmRpbmF0ZSwgcmVzb2x1dGlvbiwgb3B0X3RpbGVDb29yZCkge1xuICAgIHJldHVybiB0aGlzLmdldFRpbGVDb29yZEZvclhZQW5kUmVzb2x1dGlvbl8oY29vcmRpbmF0ZVswXSwgY29vcmRpbmF0ZVsxXSwgcmVzb2x1dGlvbiwgZmFsc2UsIG9wdF90aWxlQ29vcmQpO1xuICB9O1xuICAvKipcbiAgICogTm90ZSB0aGF0IHRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUgY2FsbGVkIGZvciByZXNvbHV0aW9ucyB0aGF0IGNvcnJlc3BvbmRcbiAgICogdG8gYW4gaW50ZWdlciB6b29tIGxldmVsLiAgSW5zdGVhZCBjYWxsIHRoZSBgZ2V0VGlsZUNvb3JkRm9yWFlBbmRaX2AgbWV0aG9kLlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uIChmb3IgYSBub24taW50ZWdlciB6b29tIGxldmVsKS5cbiAgICogQHBhcmFtIHtib29sZWFufSByZXZlcnNlSW50ZXJzZWN0aW9uUG9saWN5IEluc3RlYWQgb2YgbGV0dGluZyBlZGdlXG4gICAqICAgICBpbnRlcnNlY3Rpb25zIGdvIHRvIHRoZSBoaWdoZXIgdGlsZSBjb29yZGluYXRlLCBsZXQgZWRnZSBpbnRlcnNlY3Rpb25zXG4gICAqICAgICBnbyB0byB0aGUgbG93ZXIgdGlsZSBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmQ9fSBvcHRfdGlsZUNvb3JkIFRlbXBvcmFyeSBpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkIG9iamVjdC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gVGlsZSBjb29yZGluYXRlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRUaWxlQ29vcmRGb3JYWUFuZFJlc29sdXRpb25fID0gZnVuY3Rpb24gKHgsIHksIHJlc29sdXRpb24sIHJldmVyc2VJbnRlcnNlY3Rpb25Qb2xpY3ksIG9wdF90aWxlQ29vcmQpIHtcbiAgICB2YXIgeiA9IHRoaXMuZ2V0WkZvclJlc29sdXRpb24ocmVzb2x1dGlvbik7XG4gICAgdmFyIHNjYWxlID0gcmVzb2x1dGlvbiAvIHRoaXMuZ2V0UmVzb2x1dGlvbih6KTtcbiAgICB2YXIgb3JpZ2luID0gdGhpcy5nZXRPcmlnaW4oeik7XG4gICAgdmFyIHRpbGVTaXplID0gdG9TaXplKHRoaXMuZ2V0VGlsZVNpemUoeiksIHRoaXMudG1wU2l6ZV8pO1xuICAgIHZhciBhZGp1c3RYID0gcmV2ZXJzZUludGVyc2VjdGlvblBvbGljeSA/IDAuNSA6IDA7XG4gICAgdmFyIGFkanVzdFkgPSByZXZlcnNlSW50ZXJzZWN0aW9uUG9saWN5ID8gMC41IDogMDtcbiAgICB2YXIgeEZyb21PcmlnaW4gPSBNYXRoLmZsb29yKCh4IC0gb3JpZ2luWzBdKSAvIHJlc29sdXRpb24gKyBhZGp1c3RYKTtcbiAgICB2YXIgeUZyb21PcmlnaW4gPSBNYXRoLmZsb29yKChvcmlnaW5bMV0gLSB5KSAvIHJlc29sdXRpb24gKyBhZGp1c3RZKTtcbiAgICB2YXIgdGlsZUNvb3JkWCA9IHNjYWxlICogeEZyb21PcmlnaW4gLyB0aWxlU2l6ZVswXTtcbiAgICB2YXIgdGlsZUNvb3JkWSA9IHNjYWxlICogeUZyb21PcmlnaW4gLyB0aWxlU2l6ZVsxXTtcblxuICAgIGlmIChyZXZlcnNlSW50ZXJzZWN0aW9uUG9saWN5KSB7XG4gICAgICB0aWxlQ29vcmRYID0gTWF0aC5jZWlsKHRpbGVDb29yZFgpIC0gMTtcbiAgICAgIHRpbGVDb29yZFkgPSBNYXRoLmNlaWwodGlsZUNvb3JkWSkgLSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aWxlQ29vcmRYID0gTWF0aC5mbG9vcih0aWxlQ29vcmRYKTtcbiAgICAgIHRpbGVDb29yZFkgPSBNYXRoLmZsb29yKHRpbGVDb29yZFkpO1xuICAgIH1cblxuICAgIHJldHVybiBjcmVhdGVPclVwZGF0ZVRpbGVDb29yZCh6LCB0aWxlQ29vcmRYLCB0aWxlQ29vcmRZLCBvcHRfdGlsZUNvb3JkKTtcbiAgfTtcbiAgLyoqXG4gICAqIEFsdGhvdWdoIHRoZXJlIGlzIHJlcGV0aXRpb24gYmV0d2VlbiB0aGlzIG1ldGhvZCBhbmQgYGdldFRpbGVDb29yZEZvclhZQW5kUmVzb2x1dGlvbl9gLFxuICAgKiB0aGV5IHNob3VsZCBoYXZlIHNlcGFyYXRlIGltcGxlbWVudGF0aW9ucy4gIFRoaXMgbWV0aG9kIGlzIGZvciBpbnRlZ2VyIHpvb21cbiAgICogbGV2ZWxzLiAgVGhlIG90aGVyIG1ldGhvZCBzaG91bGQgb25seSBiZSBjYWxsZWQgZm9yIHJlc29sdXRpb25zIGNvcnJlc3BvbmRpbmdcbiAgICogdG8gbm9uLWludGVnZXIgem9vbSBsZXZlbHMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IE1hcCB4IGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IE1hcCB5IGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IEludGVnZXIgem9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtib29sZWFufSByZXZlcnNlSW50ZXJzZWN0aW9uUG9saWN5IEluc3RlYWQgb2YgbGV0dGluZyBlZGdlXG4gICAqICAgICBpbnRlcnNlY3Rpb25zIGdvIHRvIHRoZSBoaWdoZXIgdGlsZSBjb29yZGluYXRlLCBsZXQgZWRnZSBpbnRlcnNlY3Rpb25zXG4gICAqICAgICBnbyB0byB0aGUgbG93ZXIgdGlsZSBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmQ9fSBvcHRfdGlsZUNvb3JkIFRlbXBvcmFyeSBpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkIG9iamVjdC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gVGlsZSBjb29yZGluYXRlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRUaWxlQ29vcmRGb3JYWUFuZFpfID0gZnVuY3Rpb24gKHgsIHksIHosIHJldmVyc2VJbnRlcnNlY3Rpb25Qb2xpY3ksIG9wdF90aWxlQ29vcmQpIHtcbiAgICB2YXIgb3JpZ2luID0gdGhpcy5nZXRPcmlnaW4oeik7XG4gICAgdmFyIHJlc29sdXRpb24gPSB0aGlzLmdldFJlc29sdXRpb24oeik7XG4gICAgdmFyIHRpbGVTaXplID0gdG9TaXplKHRoaXMuZ2V0VGlsZVNpemUoeiksIHRoaXMudG1wU2l6ZV8pO1xuICAgIHZhciBhZGp1c3RYID0gcmV2ZXJzZUludGVyc2VjdGlvblBvbGljeSA/IDAuNSA6IDA7XG4gICAgdmFyIGFkanVzdFkgPSByZXZlcnNlSW50ZXJzZWN0aW9uUG9saWN5ID8gMC41IDogMDtcbiAgICB2YXIgeEZyb21PcmlnaW4gPSBNYXRoLmZsb29yKCh4IC0gb3JpZ2luWzBdKSAvIHJlc29sdXRpb24gKyBhZGp1c3RYKTtcbiAgICB2YXIgeUZyb21PcmlnaW4gPSBNYXRoLmZsb29yKChvcmlnaW5bMV0gLSB5KSAvIHJlc29sdXRpb24gKyBhZGp1c3RZKTtcbiAgICB2YXIgdGlsZUNvb3JkWCA9IHhGcm9tT3JpZ2luIC8gdGlsZVNpemVbMF07XG4gICAgdmFyIHRpbGVDb29yZFkgPSB5RnJvbU9yaWdpbiAvIHRpbGVTaXplWzFdO1xuXG4gICAgaWYgKHJldmVyc2VJbnRlcnNlY3Rpb25Qb2xpY3kpIHtcbiAgICAgIHRpbGVDb29yZFggPSBNYXRoLmNlaWwodGlsZUNvb3JkWCkgLSAxO1xuICAgICAgdGlsZUNvb3JkWSA9IE1hdGguY2VpbCh0aWxlQ29vcmRZKSAtIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRpbGVDb29yZFggPSBNYXRoLmZsb29yKHRpbGVDb29yZFgpO1xuICAgICAgdGlsZUNvb3JkWSA9IE1hdGguZmxvb3IodGlsZUNvb3JkWSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNyZWF0ZU9yVXBkYXRlVGlsZUNvb3JkKHosIHRpbGVDb29yZFgsIHRpbGVDb29yZFksIG9wdF90aWxlQ29vcmQpO1xuICB9O1xuICAvKipcbiAgICogR2V0IGEgdGlsZSBjb29yZGluYXRlIGdpdmVuIGEgbWFwIGNvb3JkaW5hdGUgYW5kIHpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZD19IG9wdF90aWxlQ29vcmQgRGVzdGluYXRpb24gaW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZCBvYmplY3QuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRUaWxlQ29vcmRGb3JDb29yZEFuZFogPSBmdW5jdGlvbiAoY29vcmRpbmF0ZSwgeiwgb3B0X3RpbGVDb29yZCkge1xuICAgIHJldHVybiB0aGlzLmdldFRpbGVDb29yZEZvclhZQW5kWl8oY29vcmRpbmF0ZVswXSwgY29vcmRpbmF0ZVsxXSwgeiwgZmFsc2UsIG9wdF90aWxlQ29vcmQpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSB0aWxlQ29vcmQgVGlsZSBjb29yZGluYXRlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRpbGUgcmVzb2x1dGlvbi5cbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0VGlsZUNvb3JkUmVzb2x1dGlvbiA9IGZ1bmN0aW9uICh0aWxlQ29vcmQpIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHV0aW9uc19bdGlsZUNvb3JkWzBdXTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdGlsZSBzaXplIGZvciBhIHpvb20gbGV2ZWwuIFRoZSB0eXBlIG9mIHRoZSByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGVcbiAgICogYHRpbGVTaXplYCBvciBgdGlsZVNpemVzYCB0aGF0IHRoZSB0aWxlIGdyaWQgd2FzIGNvbmZpZ3VyZWQgd2l0aC4gVG8gYWx3YXlzXG4gICAqIGdldCBhbiBgaW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplYCwgcnVuIHRoZSByZXN1bHQgdGhyb3VnaCBgaW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplLnRvU2l6ZSgpYC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHogWi5cbiAgICogQHJldHVybiB7bnVtYmVyfGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gVGlsZSBzaXplLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldFRpbGVTaXplID0gZnVuY3Rpb24gKHopIHtcbiAgICBpZiAodGhpcy50aWxlU2l6ZV8pIHtcbiAgICAgIHJldHVybiB0aGlzLnRpbGVTaXplXztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMudGlsZVNpemVzX1t6XTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geiBab29tIGxldmVsLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdH0gRXh0ZW50IHRpbGUgcmFuZ2UgZm9yIHRoZSBzcGVjaWZpZWQgem9vbSBsZXZlbC5cbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0RnVsbFRpbGVSYW5nZSA9IGZ1bmN0aW9uICh6KSB7XG4gICAgaWYgKCF0aGlzLmZ1bGxUaWxlUmFuZ2VzXykge1xuICAgICAgcmV0dXJuIHRoaXMuZXh0ZW50XyA/IHRoaXMuZ2V0VGlsZVJhbmdlRm9yRXh0ZW50QW5kWih0aGlzLmV4dGVudF8sIHopIDogbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZnVsbFRpbGVSYW5nZXNfW3pdO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2RpcmVjdGlvbiBJZiAwLCB0aGUgbmVhcmVzdCByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC5cbiAgICogICAgIElmIDEsIHRoZSBuZWFyZXN0IGxvd2VyIHJlc29sdXRpb24gd2lsbCBiZSB1c2VkLiBJZiAtMSwgdGhlIG5lYXJlc3RcbiAgICogICAgIGhpZ2hlciByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC4gRGVmYXVsdCBpcyAwLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFouXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0WkZvclJlc29sdXRpb24gPSBmdW5jdGlvbiAocmVzb2x1dGlvbiwgb3B0X2RpcmVjdGlvbikge1xuICAgIHZhciB6ID0gbGluZWFyRmluZE5lYXJlc3QodGhpcy5yZXNvbHV0aW9uc18sIHJlc29sdXRpb24sIG9wdF9kaXJlY3Rpb24gfHwgMCk7XG4gICAgcmV0dXJuIGNsYW1wKHosIHRoaXMubWluWm9vbSwgdGhpcy5tYXhab29tKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7IWltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQgZm9yIHRoaXMgdGlsZSBncmlkLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5jYWxjdWxhdGVUaWxlUmFuZ2VzXyA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5yZXNvbHV0aW9uc18ubGVuZ3RoO1xuICAgIHZhciBmdWxsVGlsZVJhbmdlcyA9IG5ldyBBcnJheShsZW5ndGgpO1xuXG4gICAgZm9yICh2YXIgeiA9IHRoaXMubWluWm9vbTsgeiA8IGxlbmd0aDsgKyt6KSB7XG4gICAgICBmdWxsVGlsZVJhbmdlc1t6XSA9IHRoaXMuZ2V0VGlsZVJhbmdlRm9yRXh0ZW50QW5kWihleHRlbnQsIHopO1xuICAgIH1cblxuICAgIHRoaXMuZnVsbFRpbGVSYW5nZXNfID0gZnVsbFRpbGVSYW5nZXM7XG4gIH07XG5cbiAgcmV0dXJuIFRpbGVHcmlkO1xufSgpO1xuXG5leHBvcnQgZGVmYXVsdCBUaWxlR3JpZDsiLCIvKipcbiAqIEBtb2R1bGUgb2wvdGlsZWdyaWRcbiAqL1xuaW1wb3J0IENvcm5lciBmcm9tICcuL2V4dGVudC9Db3JuZXIuanMnO1xuaW1wb3J0IFRpbGVHcmlkIGZyb20gJy4vdGlsZWdyaWQvVGlsZUdyaWQuanMnO1xuaW1wb3J0IFVuaXRzIGZyb20gJy4vcHJvai9Vbml0cy5qcyc7XG5pbXBvcnQgeyBERUZBVUxUX01BWF9aT09NLCBERUZBVUxUX1RJTEVfU0laRSB9IGZyb20gJy4vdGlsZWdyaWQvY29tbW9uLmpzJztcbmltcG9ydCB7IE1FVEVSU19QRVJfVU5JVCwgZ2V0IGFzIGdldFByb2plY3Rpb24gfSBmcm9tICcuL3Byb2ouanMnO1xuaW1wb3J0IHsgY29udGFpbnNDb29yZGluYXRlLCBjcmVhdGVPclVwZGF0ZSwgZ2V0Q29ybmVyLCBnZXRIZWlnaHQsIGdldFdpZHRoIH0gZnJvbSAnLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgdG9TaXplIH0gZnJvbSAnLi9zaXplLmpzJztcbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gKiBAcmV0dXJuIHshVGlsZUdyaWR9IERlZmF1bHQgdGlsZSBncmlkIGZvciB0aGVcbiAqIHBhc3NlZCBwcm9qZWN0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pIHtcbiAgdmFyIHRpbGVHcmlkID0gcHJvamVjdGlvbi5nZXREZWZhdWx0VGlsZUdyaWQoKTtcblxuICBpZiAoIXRpbGVHcmlkKSB7XG4gICAgdGlsZUdyaWQgPSBjcmVhdGVGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHByb2plY3Rpb24uc2V0RGVmYXVsdFRpbGVHcmlkKHRpbGVHcmlkKTtcbiAgfVxuXG4gIHJldHVybiB0aWxlR3JpZDtcbn1cbi8qKlxuICogQHBhcmFtIHtUaWxlR3JpZH0gdGlsZUdyaWQgVGlsZSBncmlkLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gVGlsZSBjb29yZGluYXRlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB3cmFwWCh0aWxlR3JpZCwgdGlsZUNvb3JkLCBwcm9qZWN0aW9uKSB7XG4gIHZhciB6ID0gdGlsZUNvb3JkWzBdO1xuICB2YXIgY2VudGVyID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkQ2VudGVyKHRpbGVDb29yZCk7XG4gIHZhciBwcm9qZWN0aW9uRXh0ZW50ID0gZXh0ZW50RnJvbVByb2plY3Rpb24ocHJvamVjdGlvbik7XG5cbiAgaWYgKCFjb250YWluc0Nvb3JkaW5hdGUocHJvamVjdGlvbkV4dGVudCwgY2VudGVyKSkge1xuICAgIHZhciB3b3JsZFdpZHRoID0gZ2V0V2lkdGgocHJvamVjdGlvbkV4dGVudCk7XG4gICAgdmFyIHdvcmxkc0F3YXkgPSBNYXRoLmNlaWwoKHByb2plY3Rpb25FeHRlbnRbMF0gLSBjZW50ZXJbMF0pIC8gd29ybGRXaWR0aCk7XG4gICAgY2VudGVyWzBdICs9IHdvcmxkV2lkdGggKiB3b3JsZHNBd2F5O1xuICAgIHJldHVybiB0aWxlR3JpZC5nZXRUaWxlQ29vcmRGb3JDb29yZEFuZFooY2VudGVyLCB6KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdGlsZUNvb3JkO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfbWF4Wm9vbSBNYXhpbXVtIHpvb20gbGV2ZWwgKGRlZmF1bHQgaXNcbiAqICAgICBERUZBVUxUX01BWF9aT09NKS5cbiAqIEBwYXJhbSB7bnVtYmVyfGltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplPX0gb3B0X3RpbGVTaXplIFRpbGUgc2l6ZSAoZGVmYXVsdCB1c2VzXG4gKiAgICAgREVGQVVMVF9USUxFX1NJWkUpLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC9Db3JuZXIuanNcIikuZGVmYXVsdD19IG9wdF9jb3JuZXIgRXh0ZW50IGNvcm5lciAoZGVmYXVsdCBpcyBgJ3RvcC1sZWZ0J2ApLlxuICogQHJldHVybiB7IVRpbGVHcmlkfSBUaWxlR3JpZCBpbnN0YW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRm9yRXh0ZW50KGV4dGVudCwgb3B0X21heFpvb20sIG9wdF90aWxlU2l6ZSwgb3B0X2Nvcm5lcikge1xuICB2YXIgY29ybmVyID0gb3B0X2Nvcm5lciAhPT0gdW5kZWZpbmVkID8gb3B0X2Nvcm5lciA6IENvcm5lci5UT1BfTEVGVDtcbiAgdmFyIHJlc29sdXRpb25zID0gcmVzb2x1dGlvbnNGcm9tRXh0ZW50KGV4dGVudCwgb3B0X21heFpvb20sIG9wdF90aWxlU2l6ZSk7XG4gIHJldHVybiBuZXcgVGlsZUdyaWQoe1xuICAgIGV4dGVudDogZXh0ZW50LFxuICAgIG9yaWdpbjogZ2V0Q29ybmVyKGV4dGVudCwgY29ybmVyKSxcbiAgICByZXNvbHV0aW9uczogcmVzb2x1dGlvbnMsXG4gICAgdGlsZVNpemU6IG9wdF90aWxlU2l6ZVxuICB9KTtcbn1cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gWFlaT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IFtleHRlbnRdIEV4dGVudCBmb3IgdGhlIHRpbGUgZ3JpZC4gVGhlIG9yaWdpbiBmb3IgYW4gWFlaIHRpbGUgZ3JpZCBpcyB0aGVcbiAqIHRvcC1sZWZ0IGNvcm5lciBvZiB0aGUgZXh0ZW50LiBJZiBgbWF4UmVzb2x1dGlvbmAgaXMgbm90IHByb3ZpZGVkIHRoZSB6ZXJvIGxldmVsIG9mIHRoZSBncmlkIGlzIGRlZmluZWQgYnkgdGhlIHJlc29sdXRpb25cbiAqIGF0IHdoaWNoIG9uZSB0aWxlIGZpdHMgaW4gdGhlIHByb3ZpZGVkIGV4dGVudC4gSWYgbm90IHByb3ZpZGVkLCB0aGUgZXh0ZW50IG9mIHRoZSBFUFNHOjM4NTcgcHJvamVjdGlvbiBpcyB1c2VkLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhSZXNvbHV0aW9uXSBSZXNvbHV0aW9uIGF0IGxldmVsIHplcm8uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFpvb21dIE1heGltdW0gem9vbS4gVGhlIGRlZmF1bHQgaXMgYDQyYC4gVGhpcyBkZXRlcm1pbmVzIHRoZSBudW1iZXIgb2YgbGV2ZWxzXG4gKiBpbiB0aGUgZ3JpZCBzZXQuIEZvciBleGFtcGxlLCBhIGBtYXhab29tYCBvZiAyMSBtZWFucyB0aGVyZSBhcmUgMjIgbGV2ZWxzIGluIHRoZSBncmlkIHNldC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluWm9vbT0wXSBNaW5pbXVtIHpvb20uXG4gKiBAcHJvcGVydHkge251bWJlcnxpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gW3RpbGVTaXplPVsyNTYsIDI1Nl1dIFRpbGUgc2l6ZSBpbiBwaXhlbHMuXG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgdGlsZSBncmlkIHdpdGggYSBzdGFuZGFyZCBYWVogdGlsaW5nIHNjaGVtZS5cbiAqIEBwYXJhbSB7WFlaT3B0aW9ucz19IG9wdF9vcHRpb25zIFRpbGUgZ3JpZCBvcHRpb25zLlxuICogQHJldHVybiB7IVRpbGVHcmlkfSBUaWxlIGdyaWQgaW5zdGFuY2UuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVhZWihvcHRfb3B0aW9ucykge1xuICB2YXIgeHl6T3B0aW9ucyA9IG9wdF9vcHRpb25zIHx8IHt9O1xuICB2YXIgZXh0ZW50ID0geHl6T3B0aW9ucy5leHRlbnQgfHwgZ2V0UHJvamVjdGlvbignRVBTRzozODU3JykuZ2V0RXh0ZW50KCk7XG4gIHZhciBncmlkT3B0aW9ucyA9IHtcbiAgICBleHRlbnQ6IGV4dGVudCxcbiAgICBtaW5ab29tOiB4eXpPcHRpb25zLm1pblpvb20sXG4gICAgdGlsZVNpemU6IHh5ek9wdGlvbnMudGlsZVNpemUsXG4gICAgcmVzb2x1dGlvbnM6IHJlc29sdXRpb25zRnJvbUV4dGVudChleHRlbnQsIHh5ek9wdGlvbnMubWF4Wm9vbSwgeHl6T3B0aW9ucy50aWxlU2l6ZSwgeHl6T3B0aW9ucy5tYXhSZXNvbHV0aW9uKVxuICB9O1xuICByZXR1cm4gbmV3IFRpbGVHcmlkKGdyaWRPcHRpb25zKTtcbn1cbi8qKlxuICogQ3JlYXRlIGEgcmVzb2x1dGlvbnMgYXJyYXkgZnJvbSBhbiBleHRlbnQuICBBIHpvb20gZmFjdG9yIG9mIDIgaXMgYXNzdW1lZC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfbWF4Wm9vbSBNYXhpbXVtIHpvb20gbGV2ZWwgKGRlZmF1bHQgaXNcbiAqICAgICBERUZBVUxUX01BWF9aT09NKS5cbiAqIEBwYXJhbSB7bnVtYmVyfGltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplPX0gb3B0X3RpbGVTaXplIFRpbGUgc2l6ZSAoZGVmYXVsdCB1c2VzXG4gKiAgICAgREVGQVVMVF9USUxFX1NJWkUpLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfbWF4UmVzb2x1dGlvbiBSZXNvbHV0aW9uIGF0IGxldmVsIHplcm8uXG4gKiBAcmV0dXJuIHshQXJyYXk8bnVtYmVyPn0gUmVzb2x1dGlvbnMgYXJyYXkuXG4gKi9cblxuZnVuY3Rpb24gcmVzb2x1dGlvbnNGcm9tRXh0ZW50KGV4dGVudCwgb3B0X21heFpvb20sIG9wdF90aWxlU2l6ZSwgb3B0X21heFJlc29sdXRpb24pIHtcbiAgdmFyIG1heFpvb20gPSBvcHRfbWF4Wm9vbSAhPT0gdW5kZWZpbmVkID8gb3B0X21heFpvb20gOiBERUZBVUxUX01BWF9aT09NO1xuICB2YXIgaGVpZ2h0ID0gZ2V0SGVpZ2h0KGV4dGVudCk7XG4gIHZhciB3aWR0aCA9IGdldFdpZHRoKGV4dGVudCk7XG4gIHZhciB0aWxlU2l6ZSA9IHRvU2l6ZShvcHRfdGlsZVNpemUgIT09IHVuZGVmaW5lZCA/IG9wdF90aWxlU2l6ZSA6IERFRkFVTFRfVElMRV9TSVpFKTtcbiAgdmFyIG1heFJlc29sdXRpb24gPSBvcHRfbWF4UmVzb2x1dGlvbiA+IDAgPyBvcHRfbWF4UmVzb2x1dGlvbiA6IE1hdGgubWF4KHdpZHRoIC8gdGlsZVNpemVbMF0sIGhlaWdodCAvIHRpbGVTaXplWzFdKTtcbiAgdmFyIGxlbmd0aCA9IG1heFpvb20gKyAxO1xuICB2YXIgcmVzb2x1dGlvbnMgPSBuZXcgQXJyYXkobGVuZ3RoKTtcblxuICBmb3IgKHZhciB6ID0gMDsgeiA8IGxlbmd0aDsgKyt6KSB7XG4gICAgcmVzb2x1dGlvbnNbel0gPSBtYXhSZXNvbHV0aW9uIC8gTWF0aC5wb3coMiwgeik7XG4gIH1cblxuICByZXR1cm4gcmVzb2x1dGlvbnM7XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9tYXhab29tIE1heGltdW0gem9vbSBsZXZlbCAoZGVmYXVsdCBpc1xuICogICAgIERFRkFVTFRfTUFYX1pPT00pLlxuICogQHBhcmFtIHtudW1iZXJ8aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemU9fSBvcHRfdGlsZVNpemUgVGlsZSBzaXplIChkZWZhdWx0IHVzZXNcbiAqICAgICBERUZBVUxUX1RJTEVfU0laRSkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50L0Nvcm5lci5qc1wiKS5kZWZhdWx0PX0gb3B0X2Nvcm5lciBFeHRlbnQgY29ybmVyIChkZWZhdWx0IGlzIGAndG9wLWxlZnQnYCkuXG4gKiBAcmV0dXJuIHshVGlsZUdyaWR9IFRpbGVHcmlkIGluc3RhbmNlLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUZvclByb2plY3Rpb24ocHJvamVjdGlvbiwgb3B0X21heFpvb20sIG9wdF90aWxlU2l6ZSwgb3B0X2Nvcm5lcikge1xuICB2YXIgZXh0ZW50ID0gZXh0ZW50RnJvbVByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gIHJldHVybiBjcmVhdGVGb3JFeHRlbnQoZXh0ZW50LCBvcHRfbWF4Wm9vbSwgb3B0X3RpbGVTaXplLCBvcHRfY29ybmVyKTtcbn1cbi8qKlxuICogR2VuZXJhdGUgYSB0aWxlIGdyaWQgZXh0ZW50IGZyb20gYSBwcm9qZWN0aW9uLiAgSWYgdGhlIHByb2plY3Rpb24gaGFzIGFuXG4gKiBleHRlbnQsIGl0IGlzIHVzZWQuICBJZiBub3QsIGEgZ2xvYmFsIGV4dGVudCBpcyBhc3N1bWVkLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleHRlbnRGcm9tUHJvamVjdGlvbihwcm9qZWN0aW9uKSB7XG4gIHByb2plY3Rpb24gPSBnZXRQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICB2YXIgZXh0ZW50ID0gcHJvamVjdGlvbi5nZXRFeHRlbnQoKTtcblxuICBpZiAoIWV4dGVudCkge1xuICAgIHZhciBoYWxmID0gMTgwICogTUVURVJTX1BFUl9VTklUW1VuaXRzLkRFR1JFRVNdIC8gcHJvamVjdGlvbi5nZXRNZXRlcnNQZXJVbml0KCk7XG4gICAgZXh0ZW50ID0gY3JlYXRlT3JVcGRhdGUoLWhhbGYsIC1oYWxmLCBoYWxmLCBoYWxmKTtcbiAgfVxuXG4gIHJldHVybiBleHRlbnQ7XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9zb3VyY2UvVGlsZVxuICovXG5cblxuaW1wb3J0IEV2ZW50IGZyb20gJy4uL2V2ZW50cy9FdmVudC5qcyc7XG5pbXBvcnQgU291cmNlIGZyb20gJy4vU291cmNlLmpzJztcbmltcG9ydCBUaWxlQ2FjaGUgZnJvbSAnLi4vVGlsZUNhY2hlLmpzJztcbmltcG9ydCBUaWxlU3RhdGUgZnJvbSAnLi4vVGlsZVN0YXRlLmpzJztcbmltcG9ydCB7IGFic3RyYWN0IH0gZnJvbSAnLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGVxdWl2YWxlbnQgfSBmcm9tICcuLi9wcm9qLmpzJztcbmltcG9ydCB7IGdldEtleVpYWSwgd2l0aGluRXh0ZW50QW5kWiB9IGZyb20gJy4uL3RpbGVjb29yZC5qcyc7XG5pbXBvcnQgeyBnZXRGb3JQcm9qZWN0aW9uIGFzIGdldFRpbGVHcmlkRm9yUHJvamVjdGlvbiwgd3JhcFggfSBmcm9tICcuLi90aWxlZ3JpZC5qcyc7XG5pbXBvcnQgeyBzY2FsZSBhcyBzY2FsZVNpemUsIHRvU2l6ZSB9IGZyb20gJy4uL3NpemUuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU291cmNlLmpzXCIpLkF0dHJpYnV0aW9uTGlrZX0gW2F0dHJpYnV0aW9uc11cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2F0dHJpYnV0aW9uc0NvbGxhcHNpYmxlPXRydWVdIEF0dHJpYnV0aW9ucyBhcmUgY29sbGFwc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2NhY2hlU2l6ZV1cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW29wYXF1ZT1mYWxzZV0gV2hldGhlciB0aGUgbGF5ZXIgaXMgb3BhcXVlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt0aWxlUGl4ZWxSYXRpb11cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gW3Byb2plY3Rpb25dXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU3RhdGUuanNcIikuZGVmYXVsdH0gW3N0YXRlXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSBbdGlsZUdyaWRdXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt3cmFwWD10cnVlXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt0cmFuc2l0aW9uXVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtrZXldXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3pEaXJlY3Rpb249MF1cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3M7IG5vcm1hbGx5IG9ubHkgdXNlZCBmb3IgY3JlYXRpbmcgc3ViY2xhc3NlcyBhbmQgbm90XG4gKiBpbnN0YW50aWF0ZWQgaW4gYXBwcy5cbiAqIEJhc2UgY2xhc3MgZm9yIHNvdXJjZXMgcHJvdmlkaW5nIGltYWdlcyBkaXZpZGVkIGludG8gYSB0aWxlIGdyaWQuXG4gKiBAYWJzdHJhY3RcbiAqIEBhcGlcbiAqL1xuXG52YXIgVGlsZVNvdXJjZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhUaWxlU291cmNlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIFNvdXJjZVRpbGUgc291cmNlIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gVGlsZVNvdXJjZShvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgYXR0cmlidXRpb25zOiBvcHRpb25zLmF0dHJpYnV0aW9ucyxcbiAgICAgIGF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlOiBvcHRpb25zLmF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlLFxuICAgICAgcHJvamVjdGlvbjogb3B0aW9ucy5wcm9qZWN0aW9uLFxuICAgICAgc3RhdGU6IG9wdGlvbnMuc3RhdGUsXG4gICAgICB3cmFwWDogb3B0aW9ucy53cmFwWFxuICAgIH0pIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMub3BhcXVlXyA9IG9wdGlvbnMub3BhcXVlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm9wYXF1ZSA6IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVQaXhlbFJhdGlvXyA9IG9wdGlvbnMudGlsZVBpeGVsUmF0aW8gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudGlsZVBpeGVsUmF0aW8gOiAxO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVHcmlkID0gb3B0aW9ucy50aWxlR3JpZCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy50aWxlR3JpZCA6IG51bGw7XG4gICAgdmFyIHRpbGVTaXplID0gWzI1NiwgMjU2XTtcbiAgICB2YXIgdGlsZUdyaWQgPSBvcHRpb25zLnRpbGVHcmlkO1xuXG4gICAgaWYgKHRpbGVHcmlkKSB7XG4gICAgICB0b1NpemUodGlsZUdyaWQuZ2V0VGlsZVNpemUodGlsZUdyaWQuZ2V0TWluWm9vbSgpKSwgdGlsZVNpemUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL1RpbGVDYWNoZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy50aWxlQ2FjaGUgPSBuZXcgVGlsZUNhY2hlKG9wdGlvbnMuY2FjaGVTaXplIHx8IDApO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfVxuICAgICAqL1xuXG4gICAgX3RoaXMudG1wU2l6ZSA9IFswLCAwXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy5rZXlfID0gb3B0aW9ucy5rZXkgfHwgJyc7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLk9wdGlvbnN9XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlT3B0aW9ucyA9IHtcbiAgICAgIHRyYW5zaXRpb246IG9wdGlvbnMudHJhbnNpdGlvblxuICAgIH07XG4gICAgLyoqXG4gICAgICogekRpcmVjdGlvbiBoaW50LCByZWFkIGJ5IHRoZSByZW5kZXJlci4gSW5kaWNhdGVzIHdoaWNoIHJlc29sdXRpb24gc2hvdWxkIGJlIHVzZWRcbiAgICAgKiBieSBhIHJlbmRlcmVyIGlmIHRoZSB2aWV3cyByZXNvbHV0aW9uIGRvZXMgbm90IG1hdGNoIGFueSByZXNvbHV0aW9uIG9mIHRoZSB0aWxlIHNvdXJjZS5cbiAgICAgKiBJZiAwLCB0aGUgbmVhcmVzdCByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC4gSWYgMSwgdGhlIG5lYXJlc3QgbG93ZXIgcmVzb2x1dGlvblxuICAgICAqIHdpbGwgYmUgdXNlZC4gSWYgLTEsIHRoZSBuZWFyZXN0IGhpZ2hlciByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuekRpcmVjdGlvbiA9IG9wdGlvbnMuekRpcmVjdGlvbiA/IG9wdGlvbnMuekRpcmVjdGlvbiA6IDA7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBDYW4gZXhwaXJlIGNhY2hlLlxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLmNhbkV4cGlyZUNhY2hlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnRpbGVDYWNoZS5jYW5FeHBpcmVDYWNoZSgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0geyFPYmplY3Q8c3RyaW5nLCBib29sZWFuPn0gdXNlZFRpbGVzIFVzZWQgdGlsZXMuXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuZXhwaXJlQ2FjaGUgPSBmdW5jdGlvbiAocHJvamVjdGlvbiwgdXNlZFRpbGVzKSB7XG4gICAgdmFyIHRpbGVDYWNoZSA9IHRoaXMuZ2V0VGlsZUNhY2hlRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKTtcblxuICAgIGlmICh0aWxlQ2FjaGUpIHtcbiAgICAgIHRpbGVDYWNoZS5leHBpcmVDYWNoZSh1c2VkVGlsZXMpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHogWm9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdH0gdGlsZVJhbmdlIFRpbGUgcmFuZ2UuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0KTooYm9vbGVhbnx2b2lkKX0gY2FsbGJhY2sgQ2FsbGVkIHdpdGggZWFjaFxuICAgKiAgICAgbG9hZGVkIHRpbGUuICBJZiB0aGUgY2FsbGJhY2sgcmV0dXJucyBgZmFsc2VgLCB0aGUgdGlsZSB3aWxsIG5vdCBiZVxuICAgKiAgICAgY29uc2lkZXJlZCBsb2FkZWQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSB0aWxlIHJhbmdlIGlzIGZ1bGx5IGNvdmVyZWQgd2l0aCBsb2FkZWQgdGlsZXMuXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuZm9yRWFjaExvYWRlZFRpbGUgPSBmdW5jdGlvbiAocHJvamVjdGlvbiwgeiwgdGlsZVJhbmdlLCBjYWxsYmFjaykge1xuICAgIHZhciB0aWxlQ2FjaGUgPSB0aGlzLmdldFRpbGVDYWNoZUZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG5cbiAgICBpZiAoIXRpbGVDYWNoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBjb3ZlcmVkID0gdHJ1ZTtcbiAgICB2YXIgdGlsZSwgdGlsZUNvb3JkS2V5LCBsb2FkZWQ7XG5cbiAgICBmb3IgKHZhciB4ID0gdGlsZVJhbmdlLm1pblg7IHggPD0gdGlsZVJhbmdlLm1heFg7ICsreCkge1xuICAgICAgZm9yICh2YXIgeSA9IHRpbGVSYW5nZS5taW5ZOyB5IDw9IHRpbGVSYW5nZS5tYXhZOyArK3kpIHtcbiAgICAgICAgdGlsZUNvb3JkS2V5ID0gZ2V0S2V5WlhZKHosIHgsIHkpO1xuICAgICAgICBsb2FkZWQgPSBmYWxzZTtcblxuICAgICAgICBpZiAodGlsZUNhY2hlLmNvbnRhaW5zS2V5KHRpbGVDb29yZEtleSkpIHtcbiAgICAgICAgICB0aWxlID1cbiAgICAgICAgICAvKiogQHR5cGUgeyFpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgICAgdGlsZUNhY2hlLmdldCh0aWxlQ29vcmRLZXkpO1xuICAgICAgICAgIGxvYWRlZCA9IHRpbGUuZ2V0U3RhdGUoKSA9PT0gVGlsZVN0YXRlLkxPQURFRDtcblxuICAgICAgICAgIGlmIChsb2FkZWQpIHtcbiAgICAgICAgICAgIGxvYWRlZCA9IGNhbGxiYWNrKHRpbGUpICE9PSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWxvYWRlZCkge1xuICAgICAgICAgIGNvdmVyZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb3ZlcmVkO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEd1dHRlci5cbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5nZXRHdXR0ZXJGb3JQcm9qZWN0aW9uID0gZnVuY3Rpb24gKHByb2plY3Rpb24pIHtcbiAgICByZXR1cm4gMDtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUga2V5IHRvIGJlIHVzZWQgZm9yIGFsbCB0aWxlcyBpbiB0aGUgc291cmNlLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBrZXkgZm9yIGFsbCB0aWxlcy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLmdldEtleSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5rZXlfO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB2YWx1ZSB0byBiZSB1c2VkIGFzIHRoZSBrZXkgZm9yIGFsbCB0aWxlcyBpbiB0aGUgc291cmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgZm9yIHRpbGVzLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuc2V0S2V5ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIGlmICh0aGlzLmtleV8gIT09IGtleSkge1xuICAgICAgdGhpcy5rZXlfID0ga2V5O1xuICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBPcGFxdWUuXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuZ2V0T3BhcXVlID0gZnVuY3Rpb24gKHByb2plY3Rpb24pIHtcbiAgICByZXR1cm4gdGhpcy5vcGFxdWVfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gUmVzb2x1dGlvbnMuXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuZ2V0UmVzb2x1dGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGlsZUdyaWQuZ2V0UmVzb2x1dGlvbnMoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge251bWJlcn0geiBUaWxlIGNvb3JkaW5hdGUgei5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHggVGlsZSBjb29yZGluYXRlIHguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFRpbGUgY29vcmRpbmF0ZSB5LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHshaW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0fSBUaWxlLlxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLmdldFRpbGUgPSBmdW5jdGlvbiAoeiwgeCwgeSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSB0aWxlIGdyaWQgb2YgdGhlIHRpbGUgc291cmNlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSBUaWxlIGdyaWQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5nZXRUaWxlR3JpZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aWxlR3JpZDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IFRpbGUgZ3JpZC5cbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24gPSBmdW5jdGlvbiAocHJvamVjdGlvbikge1xuICAgIGlmICghdGhpcy50aWxlR3JpZCkge1xuICAgICAgcmV0dXJuIGdldFRpbGVHcmlkRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMudGlsZUdyaWQ7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9UaWxlQ2FjaGUuanNcIikuZGVmYXVsdH0gVGlsZSBjYWNoZS5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLmdldFRpbGVDYWNoZUZvclByb2plY3Rpb24gPSBmdW5jdGlvbiAocHJvamVjdGlvbikge1xuICAgIGFzc2VydChlcXVpdmFsZW50KHRoaXMuZ2V0UHJvamVjdGlvbigpLCBwcm9qZWN0aW9uKSwgNjggLy8gQSBWZWN0b3JUaWxlIHNvdXJjZSBjYW4gb25seSBiZSByZW5kZXJlZCBpZiBpdCBoYXMgYSBwcm9qZWN0aW9uIGNvbXBhdGlibGUgd2l0aCB0aGUgdmlldyBwcm9qZWN0aW9uLlxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMudGlsZUNhY2hlO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB0aWxlIHBpeGVsIHJhdGlvIGZvciB0aGlzIHNvdXJjZS4gU3ViY2xhc3NlcyBtYXkgb3ZlcnJpZGUgdGhpc1xuICAgKiBtZXRob2QsIHdoaWNoIGlzIG1lYW50IHRvIHJldHVybiBhIHN1cHBvcnRlZCBwaXhlbCByYXRpbyB0aGF0IG1hdGNoZXMgdGhlXG4gICAqIHByb3ZpZGVkIGBwaXhlbFJhdGlvYCBhcyBjbG9zZSBhcyBwb3NzaWJsZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGlsZSBwaXhlbCByYXRpby5cbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5nZXRUaWxlUGl4ZWxSYXRpbyA9IGZ1bmN0aW9uIChwaXhlbFJhdGlvKSB7XG4gICAgcmV0dXJuIHRoaXMudGlsZVBpeGVsUmF0aW9fO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHogWi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBUaWxlIHNpemUuXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuZ2V0VGlsZVBpeGVsU2l6ZSA9IGZ1bmN0aW9uICh6LCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKSB7XG4gICAgdmFyIHRpbGVHcmlkID0gdGhpcy5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgdmFyIHRpbGVQaXhlbFJhdGlvID0gdGhpcy5nZXRUaWxlUGl4ZWxSYXRpbyhwaXhlbFJhdGlvKTtcbiAgICB2YXIgdGlsZVNpemUgPSB0b1NpemUodGlsZUdyaWQuZ2V0VGlsZVNpemUoeiksIHRoaXMudG1wU2l6ZSk7XG5cbiAgICBpZiAodGlsZVBpeGVsUmF0aW8gPT0gMSkge1xuICAgICAgcmV0dXJuIHRpbGVTaXplO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc2NhbGVTaXplKHRpbGVTaXplLCB0aWxlUGl4ZWxSYXRpbywgdGhpcy50bXBTaXplKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgdGlsZSBjb29yZGluYXRlIHdyYXBwZWQgYXJvdW5kIHRoZSB4LWF4aXMuIFdoZW4gdGhlIHRpbGUgY29vcmRpbmF0ZVxuICAgKiBpcyBvdXRzaWRlIHRoZSByZXNvbHV0aW9uIGFuZCBleHRlbnQgcmFuZ2Ugb2YgdGhlIHRpbGUgZ3JpZCwgYG51bGxgIHdpbGwgYmVcbiAgICogcmV0dXJuZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdD19IG9wdF9wcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IFRpbGUgY29vcmRpbmF0ZSB0byBiZSBwYXNzZWQgdG8gdGhlIHRpbGVVcmxGdW5jdGlvbiBvclxuICAgKiAgICAgbnVsbCBpZiBubyB0aWxlIFVSTCBzaG91bGQgYmUgY3JlYXRlZCBmb3IgdGhlIHBhc3NlZCBgdGlsZUNvb3JkYC5cbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5nZXRUaWxlQ29vcmRGb3JUaWxlVXJsRnVuY3Rpb24gPSBmdW5jdGlvbiAodGlsZUNvb3JkLCBvcHRfcHJvamVjdGlvbikge1xuICAgIHZhciBwcm9qZWN0aW9uID0gb3B0X3Byb2plY3Rpb24gIT09IHVuZGVmaW5lZCA/IG9wdF9wcm9qZWN0aW9uIDogdGhpcy5nZXRQcm9qZWN0aW9uKCk7XG4gICAgdmFyIHRpbGVHcmlkID0gdGhpcy5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG5cbiAgICBpZiAodGhpcy5nZXRXcmFwWCgpICYmIHByb2plY3Rpb24uaXNHbG9iYWwoKSkge1xuICAgICAgdGlsZUNvb3JkID0gd3JhcFgodGlsZUdyaWQsIHRpbGVDb29yZCwgcHJvamVjdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHdpdGhpbkV4dGVudEFuZFoodGlsZUNvb3JkLCB0aWxlR3JpZCkgPyB0aWxlQ29vcmQgOiBudWxsO1xuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIGFsbCBjYWNoZWQgdGlsZXMgZnJvbSB0aGUgc291cmNlLiBUaGUgbmV4dCByZW5kZXIgY3ljbGUgd2lsbCBmZXRjaCBuZXcgdGlsZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRpbGVDYWNoZS5jbGVhcigpO1xuICB9O1xuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5jbGVhcigpO1xuXG4gICAgX3N1cGVyLnByb3RvdHlwZS5yZWZyZXNoLmNhbGwodGhpcyk7XG4gIH07XG4gIC8qKlxuICAgKiBJbmNyZWFzZXMgdGhlIGNhY2hlIHNpemUgaWYgbmVlZGVkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0aWxlQ291bnQgTWluaW11bSBudW1iZXIgb2YgdGlsZXMgbmVlZGVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUudXBkYXRlQ2FjaGVTaXplID0gZnVuY3Rpb24gKHRpbGVDb3VudCwgcHJvamVjdGlvbikge1xuICAgIHZhciB0aWxlQ2FjaGUgPSB0aGlzLmdldFRpbGVDYWNoZUZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG5cbiAgICBpZiAodGlsZUNvdW50ID4gdGlsZUNhY2hlLmhpZ2hXYXRlck1hcmspIHtcbiAgICAgIHRpbGVDYWNoZS5oaWdoV2F0ZXJNYXJrID0gdGlsZUNvdW50O1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIE1hcmtzIGEgdGlsZSBjb29yZCBhcyBiZWluZyB1c2VkLCB3aXRob3V0IHRyaWdnZXJpbmcgYSBsb2FkLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHogVGlsZSBjb29yZGluYXRlIHouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFRpbGUgY29vcmRpbmF0ZSB4LlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBUaWxlIGNvb3JkaW5hdGUgeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLnVzZVRpbGUgPSBmdW5jdGlvbiAoeiwgeCwgeSwgcHJvamVjdGlvbikge307XG5cbiAgcmV0dXJuIFRpbGVTb3VyY2U7XG59KFNvdXJjZSk7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEV2ZW50cyBlbWl0dGVkIGJ5IHtAbGluayBtb2R1bGU6b2wvc291cmNlL1RpbGV+VGlsZVNvdXJjZX0gaW5zdGFuY2VzIGFyZSBpbnN0YW5jZXMgb2YgdGhpc1xuICogdHlwZS5cbiAqL1xuXG5cbnZhciBUaWxlU291cmNlRXZlbnQgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVGlsZVNvdXJjZUV2ZW50LCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVHlwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVGhlIHRpbGUuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gVGlsZVNvdXJjZUV2ZW50KHR5cGUsIHRpbGUpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0eXBlKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIFRoZSB0aWxlIHJlbGF0ZWQgdG8gdGhlIGV2ZW50LlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLmRlZmF1bHR9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy50aWxlID0gdGlsZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICByZXR1cm4gVGlsZVNvdXJjZUV2ZW50O1xufShFdmVudCk7XG5cbmV4cG9ydCB7IFRpbGVTb3VyY2VFdmVudCB9O1xuZXhwb3J0IGRlZmF1bHQgVGlsZVNvdXJjZTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvdGlsZXVybGZ1bmN0aW9uXG4gKi9cbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4vYXNzZXJ0cy5qcyc7XG5pbXBvcnQgeyBtb2R1bG8gfSBmcm9tICcuL21hdGguanMnO1xuaW1wb3J0IHsgaGFzaCBhcyB0aWxlQ29vcmRIYXNoIH0gZnJvbSAnLi90aWxlY29vcmQuanMnO1xuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGVtcGxhdGUgVGVtcGxhdGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gdGlsZUdyaWQgVGlsZSBncmlkLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9UaWxlLmpzXCIpLlVybEZ1bmN0aW9ufSBUaWxlIFVSTCBmdW5jdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRnJvbVRlbXBsYXRlKHRlbXBsYXRlLCB0aWxlR3JpZCkge1xuICB2YXIgelJlZ0V4ID0gL1xce3pcXH0vZztcbiAgdmFyIHhSZWdFeCA9IC9cXHt4XFx9L2c7XG4gIHZhciB5UmVnRXggPSAvXFx7eVxcfS9nO1xuICB2YXIgZGFzaFlSZWdFeCA9IC9cXHsteVxcfS9nO1xuICByZXR1cm4gKFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSB0aWxlQ29vcmQgVGlsZSBDb29yZGluYXRlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9IFRpbGUgVVJMLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uICh0aWxlQ29vcmQsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIHtcbiAgICAgIGlmICghdGlsZUNvb3JkKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGVtcGxhdGUucmVwbGFjZSh6UmVnRXgsIHRpbGVDb29yZFswXS50b1N0cmluZygpKS5yZXBsYWNlKHhSZWdFeCwgdGlsZUNvb3JkWzFdLnRvU3RyaW5nKCkpLnJlcGxhY2UoeVJlZ0V4LCB0aWxlQ29vcmRbMl0udG9TdHJpbmcoKSkucmVwbGFjZShkYXNoWVJlZ0V4LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdmFyIHogPSB0aWxlQ29vcmRbMF07XG4gICAgICAgICAgdmFyIHJhbmdlID0gdGlsZUdyaWQuZ2V0RnVsbFRpbGVSYW5nZSh6KTtcbiAgICAgICAgICBhc3NlcnQocmFuZ2UsIDU1KTsgLy8gVGhlIHsteX0gcGxhY2Vob2xkZXIgcmVxdWlyZXMgYSB0aWxlIGdyaWQgd2l0aCBleHRlbnRcblxuICAgICAgICAgIHZhciB5ID0gcmFuZ2UuZ2V0SGVpZ2h0KCkgLSB0aWxlQ29vcmRbMl0gLSAxO1xuICAgICAgICAgIHJldHVybiB5LnRvU3RyaW5nKCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSB0ZW1wbGF0ZXMgVGVtcGxhdGVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IHRpbGVHcmlkIFRpbGUgZ3JpZC5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vVGlsZS5qc1wiKS5VcmxGdW5jdGlvbn0gVGlsZSBVUkwgZnVuY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUZyb21UZW1wbGF0ZXModGVtcGxhdGVzLCB0aWxlR3JpZCkge1xuICB2YXIgbGVuID0gdGVtcGxhdGVzLmxlbmd0aDtcbiAgdmFyIHRpbGVVcmxGdW5jdGlvbnMgPSBuZXcgQXJyYXkobGVuKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgdGlsZVVybEZ1bmN0aW9uc1tpXSA9IGNyZWF0ZUZyb21UZW1wbGF0ZSh0ZW1wbGF0ZXNbaV0sIHRpbGVHcmlkKTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVGcm9tVGlsZVVybEZ1bmN0aW9ucyh0aWxlVXJsRnVuY3Rpb25zKTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL1RpbGUuanNcIikuVXJsRnVuY3Rpb24+fSB0aWxlVXJsRnVuY3Rpb25zIFRpbGUgVVJMIEZ1bmN0aW9ucy5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vVGlsZS5qc1wiKS5VcmxGdW5jdGlvbn0gVGlsZSBVUkwgZnVuY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUZyb21UaWxlVXJsRnVuY3Rpb25zKHRpbGVVcmxGdW5jdGlvbnMpIHtcbiAgaWYgKHRpbGVVcmxGdW5jdGlvbnMubGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIHRpbGVVcmxGdW5jdGlvbnNbMF07XG4gIH1cblxuICByZXR1cm4gKFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSB0aWxlQ29vcmQgVGlsZSBDb29yZGluYXRlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9IFRpbGUgVVJMLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uICh0aWxlQ29vcmQsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIHtcbiAgICAgIGlmICghdGlsZUNvb3JkKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgaCA9IHRpbGVDb29yZEhhc2godGlsZUNvb3JkKTtcbiAgICAgICAgdmFyIGluZGV4ID0gbW9kdWxvKGgsIHRpbGVVcmxGdW5jdGlvbnMubGVuZ3RoKTtcbiAgICAgICAgcmV0dXJuIHRpbGVVcmxGdW5jdGlvbnNbaW5kZXhdKHRpbGVDb29yZCwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbik7XG4gICAgICB9XG4gICAgfVxuICApO1xufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfSBUaWxlIFVSTC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbnVsbFRpbGVVcmxGdW5jdGlvbih0aWxlQ29vcmQsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIHtcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybCBVUkwuXG4gKiBAcmV0dXJuIHtBcnJheTxzdHJpbmc+fSBBcnJheSBvZiB1cmxzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleHBhbmRVcmwodXJsKSB7XG4gIHZhciB1cmxzID0gW107XG4gIHZhciBtYXRjaCA9IC9cXHsoW2Etel0pLShbYS16XSlcXH0vLmV4ZWModXJsKTtcblxuICBpZiAobWF0Y2gpIHtcbiAgICAvLyBjaGFyIHJhbmdlXG4gICAgdmFyIHN0YXJ0Q2hhckNvZGUgPSBtYXRjaFsxXS5jaGFyQ29kZUF0KDApO1xuICAgIHZhciBzdG9wQ2hhckNvZGUgPSBtYXRjaFsyXS5jaGFyQ29kZUF0KDApO1xuICAgIHZhciBjaGFyQ29kZSA9IHZvaWQgMDtcblxuICAgIGZvciAoY2hhckNvZGUgPSBzdGFydENoYXJDb2RlOyBjaGFyQ29kZSA8PSBzdG9wQ2hhckNvZGU7ICsrY2hhckNvZGUpIHtcbiAgICAgIHVybHMucHVzaCh1cmwucmVwbGFjZShtYXRjaFswXSwgU3RyaW5nLmZyb21DaGFyQ29kZShjaGFyQ29kZSkpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdXJscztcbiAgfVxuXG4gIG1hdGNoID0gL1xceyhcXGQrKS0oXFxkKylcXH0vLmV4ZWModXJsKTtcblxuICBpZiAobWF0Y2gpIHtcbiAgICAvLyBudW1iZXIgcmFuZ2VcbiAgICB2YXIgc3RvcF8xID0gcGFyc2VJbnQobWF0Y2hbMl0sIDEwKTtcblxuICAgIGZvciAodmFyIGkgPSBwYXJzZUludChtYXRjaFsxXSwgMTApOyBpIDw9IHN0b3BfMTsgaSsrKSB7XG4gICAgICB1cmxzLnB1c2godXJsLnJlcGxhY2UobWF0Y2hbMF0sIGkudG9TdHJpbmcoKSkpO1xuICAgIH1cblxuICAgIHJldHVybiB1cmxzO1xuICB9XG5cbiAgdXJscy5wdXNoKHVybCk7XG4gIHJldHVybiB1cmxzO1xufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvc291cmNlL1VybFRpbGVcbiAqL1xuXG5cbmltcG9ydCBUaWxlRXZlbnRUeXBlIGZyb20gJy4vVGlsZUV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgVGlsZVNvdXJjZSwgeyBUaWxlU291cmNlRXZlbnQgfSBmcm9tICcuL1RpbGUuanMnO1xuaW1wb3J0IFRpbGVTdGF0ZSBmcm9tICcuLi9UaWxlU3RhdGUuanMnO1xuaW1wb3J0IHsgY3JlYXRlRnJvbVRlbXBsYXRlcywgZXhwYW5kVXJsIH0gZnJvbSAnLi4vdGlsZXVybGZ1bmN0aW9uLmpzJztcbmltcG9ydCB7IGdldEtleVpYWSB9IGZyb20gJy4uL3RpbGVjb29yZC5qcyc7XG5pbXBvcnQgeyBnZXRVaWQgfSBmcm9tICcuLi91dGlsLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1NvdXJjZS5qc1wiKS5BdHRyaWJ1dGlvbkxpa2V9IFthdHRyaWJ1dGlvbnNdXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFthdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZT10cnVlXSBBdHRyaWJ1dGlvbnMgYXJlIGNvbGxhcHNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtjYWNoZVNpemVdXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtvcGFxdWU9ZmFsc2VdIFdoZXRoZXIgdGhlIGxheWVyIGlzIG9wYXF1ZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gW3Byb2plY3Rpb25dXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU3RhdGUuanNcIikuZGVmYXVsdH0gW3N0YXRlXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSBbdGlsZUdyaWRdXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL1RpbGUuanNcIikuTG9hZEZ1bmN0aW9ufSB0aWxlTG9hZEZ1bmN0aW9uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RpbGVQaXhlbFJhdGlvXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLlVybEZ1bmN0aW9ufSBbdGlsZVVybEZ1bmN0aW9uXVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFt1cmxdXG4gKiBAcHJvcGVydHkge0FycmF5PHN0cmluZz59IFt1cmxzXVxuICogQHByb3BlcnR5IHtib29sZWFufSBbd3JhcFg9dHJ1ZV1cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdHJhbnNpdGlvbl1cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBba2V5XVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6RGlyZWN0aW9uPTBdXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBCYXNlIGNsYXNzIGZvciBzb3VyY2VzIHByb3ZpZGluZyB0aWxlcyBkaXZpZGVkIGludG8gYSB0aWxlIGdyaWQgb3ZlciBodHRwLlxuICpcbiAqIEBmaXJlcyBpbXBvcnQoXCIuL1RpbGUuanNcIikuVGlsZVNvdXJjZUV2ZW50XG4gKi9cblxudmFyIFVybFRpbGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVXJsVGlsZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBJbWFnZSB0aWxlIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gVXJsVGlsZShvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgYXR0cmlidXRpb25zOiBvcHRpb25zLmF0dHJpYnV0aW9ucyxcbiAgICAgIGNhY2hlU2l6ZTogb3B0aW9ucy5jYWNoZVNpemUsXG4gICAgICBvcGFxdWU6IG9wdGlvbnMub3BhcXVlLFxuICAgICAgcHJvamVjdGlvbjogb3B0aW9ucy5wcm9qZWN0aW9uLFxuICAgICAgc3RhdGU6IG9wdGlvbnMuc3RhdGUsXG4gICAgICB0aWxlR3JpZDogb3B0aW9ucy50aWxlR3JpZCxcbiAgICAgIHRpbGVQaXhlbFJhdGlvOiBvcHRpb25zLnRpbGVQaXhlbFJhdGlvLFxuICAgICAgd3JhcFg6IG9wdGlvbnMud3JhcFgsXG4gICAgICB0cmFuc2l0aW9uOiBvcHRpb25zLnRyYW5zaXRpb24sXG4gICAgICBrZXk6IG9wdGlvbnMua2V5LFxuICAgICAgYXR0cmlidXRpb25zQ29sbGFwc2libGU6IG9wdGlvbnMuYXR0cmlidXRpb25zQ29sbGFwc2libGUsXG4gICAgICB6RGlyZWN0aW9uOiBvcHRpb25zLnpEaXJlY3Rpb25cbiAgICB9KSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cblxuICAgIF90aGlzLmdlbmVyYXRlVGlsZVVybEZ1bmN0aW9uXyA9IF90aGlzLnRpbGVVcmxGdW5jdGlvbiA9PT0gVXJsVGlsZS5wcm90b3R5cGUudGlsZVVybEZ1bmN0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5Mb2FkRnVuY3Rpb259XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlTG9hZEZ1bmN0aW9uID0gb3B0aW9ucy50aWxlTG9hZEZ1bmN0aW9uO1xuXG4gICAgaWYgKG9wdGlvbnMudGlsZVVybEZ1bmN0aW9uKSB7XG4gICAgICBfdGhpcy50aWxlVXJsRnVuY3Rpb24gPSBvcHRpb25zLnRpbGVVcmxGdW5jdGlvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHshQXJyYXk8c3RyaW5nPnxudWxsfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy51cmxzID0gbnVsbDtcblxuICAgIGlmIChvcHRpb25zLnVybHMpIHtcbiAgICAgIF90aGlzLnNldFVybHMob3B0aW9ucy51cmxzKTtcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMudXJsKSB7XG4gICAgICBfdGhpcy5zZXRVcmwob3B0aW9ucy51cmwpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgYm9vbGVhbj59XG4gICAgICovXG5cblxuICAgIF90aGlzLnRpbGVMb2FkaW5nS2V5c18gPSB7fTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgdGlsZSBsb2FkIGZ1bmN0aW9uIG9mIHRoZSBzb3VyY2UuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL1RpbGUuanNcIikuTG9hZEZ1bmN0aW9ufSBUaWxlTG9hZEZ1bmN0aW9uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBVcmxUaWxlLnByb3RvdHlwZS5nZXRUaWxlTG9hZEZ1bmN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnRpbGVMb2FkRnVuY3Rpb247XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHRpbGUgVVJMIGZ1bmN0aW9uIG9mIHRoZSBzb3VyY2UuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL1RpbGUuanNcIikuVXJsRnVuY3Rpb259IFRpbGVVcmxGdW5jdGlvblxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVXJsVGlsZS5wcm90b3R5cGUuZ2V0VGlsZVVybEZ1bmN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykudGlsZVVybEZ1bmN0aW9uID09PSB0aGlzLnRpbGVVcmxGdW5jdGlvbiA/IHRoaXMudGlsZVVybEZ1bmN0aW9uLmJpbmQodGhpcykgOiB0aGlzLnRpbGVVcmxGdW5jdGlvbjtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgVVJMcyB1c2VkIGZvciB0aGlzIHNvdXJjZS5cbiAgICogV2hlbiBhIHRpbGVVcmxGdW5jdGlvbiBpcyB1c2VkIGluc3RlYWQgb2YgdXJsIG9yIHVybHMsXG4gICAqIG51bGwgd2lsbCBiZSByZXR1cm5lZC5cbiAgICogQHJldHVybiB7IUFycmF5PHN0cmluZz58bnVsbH0gVVJMcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFVybFRpbGUucHJvdG90eXBlLmdldFVybHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudXJscztcbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSB0aWxlIGNoYW5nZSBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHR9IGV2ZW50IEV2ZW50LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgVXJsVGlsZS5wcm90b3R5cGUuaGFuZGxlVGlsZUNoYW5nZSA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHZhciB0aWxlID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL1RpbGUuanNcIikuZGVmYXVsdH0gKi9cbiAgICBldmVudC50YXJnZXQ7XG4gICAgdmFyIHVpZCA9IGdldFVpZCh0aWxlKTtcbiAgICB2YXIgdGlsZVN0YXRlID0gdGlsZS5nZXRTdGF0ZSgpO1xuICAgIHZhciB0eXBlO1xuXG4gICAgaWYgKHRpbGVTdGF0ZSA9PSBUaWxlU3RhdGUuTE9BRElORykge1xuICAgICAgdGhpcy50aWxlTG9hZGluZ0tleXNfW3VpZF0gPSB0cnVlO1xuICAgICAgdHlwZSA9IFRpbGVFdmVudFR5cGUuVElMRUxPQURTVEFSVDtcbiAgICB9IGVsc2UgaWYgKHVpZCBpbiB0aGlzLnRpbGVMb2FkaW5nS2V5c18pIHtcbiAgICAgIGRlbGV0ZSB0aGlzLnRpbGVMb2FkaW5nS2V5c19bdWlkXTtcbiAgICAgIHR5cGUgPSB0aWxlU3RhdGUgPT0gVGlsZVN0YXRlLkVSUk9SID8gVGlsZUV2ZW50VHlwZS5USUxFTE9BREVSUk9SIDogdGlsZVN0YXRlID09IFRpbGVTdGF0ZS5MT0FERUQgPyBUaWxlRXZlbnRUeXBlLlRJTEVMT0FERU5EIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmICh0eXBlICE9IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBUaWxlU291cmNlRXZlbnQodHlwZSwgdGlsZSkpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgdGlsZSBsb2FkIGZ1bmN0aW9uIG9mIHRoZSBzb3VyY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5Mb2FkRnVuY3Rpb259IHRpbGVMb2FkRnVuY3Rpb24gVGlsZSBsb2FkIGZ1bmN0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVXJsVGlsZS5wcm90b3R5cGUuc2V0VGlsZUxvYWRGdW5jdGlvbiA9IGZ1bmN0aW9uICh0aWxlTG9hZEZ1bmN0aW9uKSB7XG4gICAgdGhpcy50aWxlQ2FjaGUuY2xlYXIoKTtcbiAgICB0aGlzLnRpbGVMb2FkRnVuY3Rpb24gPSB0aWxlTG9hZEZ1bmN0aW9uO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB0aWxlIFVSTCBmdW5jdGlvbiBvZiB0aGUgc291cmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1RpbGUuanNcIikuVXJsRnVuY3Rpb259IHRpbGVVcmxGdW5jdGlvbiBUaWxlIFVSTCBmdW5jdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmc9fSBrZXkgT3B0aW9uYWwgbmV3IHRpbGUga2V5IGZvciB0aGUgc291cmNlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVXJsVGlsZS5wcm90b3R5cGUuc2V0VGlsZVVybEZ1bmN0aW9uID0gZnVuY3Rpb24gKHRpbGVVcmxGdW5jdGlvbiwga2V5KSB7XG4gICAgdGhpcy50aWxlVXJsRnVuY3Rpb24gPSB0aWxlVXJsRnVuY3Rpb247XG4gICAgdGhpcy50aWxlQ2FjaGUucHJ1bmVFeGNlcHROZXdlc3RaKCk7XG5cbiAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuc2V0S2V5KGtleSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgVVJMIHRvIHVzZSBmb3IgcmVxdWVzdHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVVJMLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVXJsVGlsZS5wcm90b3R5cGUuc2V0VXJsID0gZnVuY3Rpb24gKHVybCkge1xuICAgIHZhciB1cmxzID0gZXhwYW5kVXJsKHVybCk7XG4gICAgdGhpcy51cmxzID0gdXJscztcbiAgICB0aGlzLnNldFVybHModXJscyk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIFVSTHMgdG8gdXNlIGZvciByZXF1ZXN0cy5cbiAgICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSB1cmxzIFVSTHMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBVcmxUaWxlLnByb3RvdHlwZS5zZXRVcmxzID0gZnVuY3Rpb24gKHVybHMpIHtcbiAgICB0aGlzLnVybHMgPSB1cmxzO1xuICAgIHZhciBrZXkgPSB1cmxzLmpvaW4oJ1xcbicpO1xuXG4gICAgaWYgKHRoaXMuZ2VuZXJhdGVUaWxlVXJsRnVuY3Rpb25fKSB7XG4gICAgICB0aGlzLnNldFRpbGVVcmxGdW5jdGlvbihjcmVhdGVGcm9tVGVtcGxhdGVzKHVybHMsIHRoaXMudGlsZUdyaWQpLCBrZXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldEtleShrZXkpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH0gVGlsZSBVUkwuXG4gICAqL1xuXG5cbiAgVXJsVGlsZS5wcm90b3R5cGUudGlsZVVybEZ1bmN0aW9uID0gZnVuY3Rpb24gKHRpbGVDb29yZCwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG4gIC8qKlxuICAgKiBNYXJrcyBhIHRpbGUgY29vcmQgYXMgYmVpbmcgdXNlZCwgd2l0aG91dCB0cmlnZ2VyaW5nIGEgbG9hZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHogVGlsZSBjb29yZGluYXRlIHouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFRpbGUgY29vcmRpbmF0ZSB4LlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBUaWxlIGNvb3JkaW5hdGUgeS5cbiAgICovXG5cblxuICBVcmxUaWxlLnByb3RvdHlwZS51c2VUaWxlID0gZnVuY3Rpb24gKHosIHgsIHkpIHtcbiAgICB2YXIgdGlsZUNvb3JkS2V5ID0gZ2V0S2V5WlhZKHosIHgsIHkpO1xuXG4gICAgaWYgKHRoaXMudGlsZUNhY2hlLmNvbnRhaW5zS2V5KHRpbGVDb29yZEtleSkpIHtcbiAgICAgIHRoaXMudGlsZUNhY2hlLmdldCh0aWxlQ29vcmRLZXkpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gVXJsVGlsZTtcbn0oVGlsZVNvdXJjZSk7XG5cbmV4cG9ydCBkZWZhdWx0IFVybFRpbGU7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9WZWN0b3JSZW5kZXJUaWxlXG4gKi9cblxuXG5pbXBvcnQgVGlsZSBmcm9tICcuL1RpbGUuanMnO1xuaW1wb3J0IHsgY3JlYXRlQ2FudmFzQ29udGV4dDJEIH0gZnJvbSAnLi9kb20uanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi91dGlsLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gUmVwbGF5U3RhdGVcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZGlydHlcbiAqIEBwcm9wZXJ0eSB7bnVsbHxpbXBvcnQoXCIuL3JlbmRlci5qc1wiKS5PcmRlckZ1bmN0aW9ufSByZW5kZXJlZFJlbmRlck9yZGVyXG4gKiBAcHJvcGVydHkge251bWJlcn0gcmVuZGVyZWRUaWxlUmV2aXNpb25cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSByZW5kZXJlZFJlc29sdXRpb25cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSByZW5kZXJlZFJldmlzaW9uXG4gKiBAcHJvcGVydHkge251bWJlcn0gcmVuZGVyZWRaXG4gKiBAcHJvcGVydHkge251bWJlcn0gcmVuZGVyZWRUaWxlUmVzb2x1dGlvblxuICogQHByb3BlcnR5IHtudW1iZXJ9IHJlbmRlcmVkVGlsZVpcbiAqL1xuXG4vKipcbiAqIEB0eXBlIHtBcnJheTxIVE1MQ2FudmFzRWxlbWVudD59XG4gKi9cblxudmFyIGNhbnZhc1Bvb2wgPSBbXTtcblxudmFyIFZlY3RvclJlbmRlclRpbGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVmVjdG9yUmVuZGVyVGlsZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSB0aWxlQ29vcmQgVGlsZSBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vVGlsZVN0YXRlLmpzXCIpLmRlZmF1bHR9IHN0YXRlIFN0YXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdXJsVGlsZUNvb3JkIFdyYXBwZWQgdGlsZSBjb29yZGluYXRlIGZvciBzb3VyY2UgdXJscy5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihWZWN0b3JSZW5kZXJUaWxlKTpBcnJheTxpbXBvcnQoXCIuL1ZlY3RvclRpbGVcIikuZGVmYXVsdD59IGdldFNvdXJjZVRpbGVzIEZ1bmN0aW9uXG4gICAqIHRvIGdldCBzb3VyY2UgdGlsZXMgZm9yIHRoaXMgdGlsZS5cbiAgICovXG5cblxuICBmdW5jdGlvbiBWZWN0b3JSZW5kZXJUaWxlKHRpbGVDb29yZCwgc3RhdGUsIHVybFRpbGVDb29yZCwgZ2V0U291cmNlVGlsZXMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0aWxlQ29vcmQsIHN0YXRlLCB7XG4gICAgICB0cmFuc2l0aW9uOiAwXG4gICAgfSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEPn1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuY29udGV4dF8gPSB7fTtcbiAgICAvKipcbiAgICAgKiBFeGVjdXRvciBncm91cHMgYnkgbGF5ZXIgdWlkLiBFbnRyaWVzIGFyZSByZWFkL3dyaXR0ZW4gYnkgdGhlIHJlbmRlcmVyLlxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBBcnJheTxpbXBvcnQoXCIuL3JlbmRlci9jYW52YXMvRXhlY3V0b3JHcm91cC5qc1wiKS5kZWZhdWx0Pj59XG4gICAgICovXG5cbiAgICBfdGhpcy5leGVjdXRvckdyb3VwcyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEV4ZWN1dG9yIGdyb3VwcyBmb3IgZGVjbHV0dGVyaW5nLCBieSBsYXllciB1aWQuIEVudHJpZXMgYXJlIHJlYWQvd3JpdHRlbiBieSB0aGUgcmVuZGVyZXIuXG4gICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsIEFycmF5PGltcG9ydChcIi4vcmVuZGVyL2NhbnZhcy9FeGVjdXRvckdyb3VwLmpzXCIpLmRlZmF1bHQ+Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzID0ge307XG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGxvYWRpbmcgc291cmNlIHRpbGVzLiBSZWFkL3dyaXR0ZW4gYnkgdGhlIHNvdXJjZS5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubG9hZGluZ1NvdXJjZVRpbGVzID0gMDtcbiAgICAvKipcbiAgICAgKiBUaWxlIGtleXMgb2YgZXJyb3Igc291cmNlIHRpbGVzLiBSZWFkL3dyaXR0ZW4gYnkgdGhlIHNvdXJjZS5cbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgYm9vbGVhbj59XG4gICAgICovXG5cbiAgICBfdGhpcy5lcnJvclNvdXJjZVRpbGVLZXlzID0ge307XG4gICAgLyoqXG4gICAgICogQHR5cGUge09iamVjdDxudW1iZXIsIEltYWdlRGF0YT59XG4gICAgICovXG5cbiAgICBfdGhpcy5oaXREZXRlY3Rpb25JbWFnZURhdGEgPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgUmVwbGF5U3RhdGU+fVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVwbGF5U3RhdGVfID0ge307XG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PGltcG9ydChcIi4vVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnNvdXJjZVRpbGVzID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMud2FudGVkUmVzb2x1dGlvbjtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IWZ1bmN0aW9uKCk6QXJyYXk8aW1wb3J0KFwiLi9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZ2V0U291cmNlVGlsZXMgPSBnZXRTb3VyY2VUaWxlcy5iaW5kKHVuZGVmaW5lZCwgX3RoaXMpO1xuICAgIC8qKlxuICAgICAqIHogb2YgdGhlIHNvdXJjZSB0aWxlcyBvZiB0aGUgbGFzdCBnZXRTb3VyY2VUaWxlcyBjYWxsLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5zb3VyY2VaID0gLTE7XG4gICAgLyoqXG4gICAgICogVHJ1ZSB3aGVuIGFsbCB0aWxlcyBmb3IgdGhpcyB0aWxlJ3Mgbm9taW5hbCByZXNvbHV0aW9uIGFyZSBhdmFpbGFibGUuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5oaWZpID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH1cbiAgICAgKi9cblxuICAgIF90aGlzLndyYXBwZWRUaWxlQ29vcmQgPSB1cmxUaWxlQ29vcmQ7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gbGF5ZXIgTGF5ZXIuXG4gICAqIEByZXR1cm4ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gVGhlIHJlbmRlcmluZyBjb250ZXh0LlxuICAgKi9cblxuXG4gIFZlY3RvclJlbmRlclRpbGUucHJvdG90eXBlLmdldENvbnRleHQgPSBmdW5jdGlvbiAobGF5ZXIpIHtcbiAgICB2YXIga2V5ID0gZ2V0VWlkKGxheWVyKTtcblxuICAgIGlmICghKGtleSBpbiB0aGlzLmNvbnRleHRfKSkge1xuICAgICAgdGhpcy5jb250ZXh0X1trZXldID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKDEsIDEsIGNhbnZhc1Bvb2wpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRleHRfW2tleV07XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gbGF5ZXIgTGF5ZXIuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRpbGUgaGFzIGEgcmVuZGVyaW5nIGNvbnRleHQgZm9yIHRoZSBnaXZlbiBsYXllci5cbiAgICovXG5cblxuICBWZWN0b3JSZW5kZXJUaWxlLnByb3RvdHlwZS5oYXNDb250ZXh0ID0gZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgcmV0dXJuIGdldFVpZChsYXllcikgaW4gdGhpcy5jb250ZXh0XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgQ2FudmFzIGZvciB0aGlzIHRpbGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0fSBsYXllciBMYXllci5cbiAgICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR9IENhbnZhcy5cbiAgICovXG5cblxuICBWZWN0b3JSZW5kZXJUaWxlLnByb3RvdHlwZS5nZXRJbWFnZSA9IGZ1bmN0aW9uIChsYXllcikge1xuICAgIHJldHVybiB0aGlzLmhhc0NvbnRleHQobGF5ZXIpID8gdGhpcy5nZXRDb250ZXh0KGxheWVyKS5jYW52YXMgOiBudWxsO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHR9IGxheWVyIExheWVyLlxuICAgKiBAcmV0dXJuIHtSZXBsYXlTdGF0ZX0gVGhlIHJlcGxheSBzdGF0ZS5cbiAgICovXG5cblxuICBWZWN0b3JSZW5kZXJUaWxlLnByb3RvdHlwZS5nZXRSZXBsYXlTdGF0ZSA9IGZ1bmN0aW9uIChsYXllcikge1xuICAgIHZhciBrZXkgPSBnZXRVaWQobGF5ZXIpO1xuXG4gICAgaWYgKCEoa2V5IGluIHRoaXMucmVwbGF5U3RhdGVfKSkge1xuICAgICAgdGhpcy5yZXBsYXlTdGF0ZV9ba2V5XSA9IHtcbiAgICAgICAgZGlydHk6IGZhbHNlLFxuICAgICAgICByZW5kZXJlZFJlbmRlck9yZGVyOiBudWxsLFxuICAgICAgICByZW5kZXJlZFJlc29sdXRpb246IE5hTixcbiAgICAgICAgcmVuZGVyZWRSZXZpc2lvbjogLTEsXG4gICAgICAgIHJlbmRlcmVkVGlsZVJlc29sdXRpb246IE5hTixcbiAgICAgICAgcmVuZGVyZWRUaWxlUmV2aXNpb246IC0xLFxuICAgICAgICByZW5kZXJlZFo6IC0xLFxuICAgICAgICByZW5kZXJlZFRpbGVaOiAtMVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXBsYXlTdGF0ZV9ba2V5XTtcbiAgfTtcbiAgLyoqXG4gICAqIExvYWQgdGhlIHRpbGUuXG4gICAqL1xuXG5cbiAgVmVjdG9yUmVuZGVyVGlsZS5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmdldFNvdXJjZVRpbGVzKCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgZnJvbSB0aGUgY2FjaGUgZHVlIHRvIGV4cGlyeVxuICAgKi9cblxuXG4gIFZlY3RvclJlbmRlclRpbGUucHJvdG90eXBlLnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuY29udGV4dF8pIHtcbiAgICAgIGNhbnZhc1Bvb2wucHVzaCh0aGlzLmNvbnRleHRfW2tleV0uY2FudmFzKTtcbiAgICAgIGRlbGV0ZSB0aGlzLmNvbnRleHRfW2tleV07XG4gICAgfVxuXG4gICAgX3N1cGVyLnByb3RvdHlwZS5yZWxlYXNlLmNhbGwodGhpcyk7XG4gIH07XG5cbiAgcmV0dXJuIFZlY3RvclJlbmRlclRpbGU7XG59KFRpbGUpO1xuXG5leHBvcnQgZGVmYXVsdCBWZWN0b3JSZW5kZXJUaWxlOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zb3VyY2UvVmVjdG9yVGlsZVxuICovXG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuXG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IFRpbGUgZnJvbSAnLi4vVmVjdG9yVGlsZS5qcyc7XG5pbXBvcnQgVGlsZUNhY2hlIGZyb20gJy4uL1RpbGVDYWNoZS5qcyc7XG5pbXBvcnQgVGlsZVN0YXRlIGZyb20gJy4uL1RpbGVTdGF0ZS5qcyc7XG5pbXBvcnQgVXJsVGlsZSBmcm9tICcuL1VybFRpbGUuanMnO1xuaW1wb3J0IFZlY3RvclJlbmRlclRpbGUgZnJvbSAnLi4vVmVjdG9yUmVuZGVyVGlsZS5qcyc7XG5pbXBvcnQgeyBidWZmZXIgYXMgYnVmZmVyRXh0ZW50LCBnZXRJbnRlcnNlY3Rpb24sIGludGVyc2VjdHMgfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgY3JlYXRlRm9yUHJvamVjdGlvbiwgY3JlYXRlWFlaLCBleHRlbnRGcm9tUHJvamVjdGlvbiB9IGZyb20gJy4uL3RpbGVncmlkLmpzJztcbmltcG9ydCB7IGVxdWFscyB9IGZyb20gJy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGZyb21LZXksIGdldEtleVpYWSB9IGZyb20gJy4uL3RpbGVjb29yZC5qcyc7XG5pbXBvcnQgeyBsb2FkRmVhdHVyZXNYaHIgfSBmcm9tICcuLi9mZWF0dXJlbG9hZGVyLmpzJztcbmltcG9ydCB7IHRvU2l6ZSB9IGZyb20gJy4uL3NpemUuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU291cmNlLmpzXCIpLkF0dHJpYnV0aW9uTGlrZX0gW2F0dHJpYnV0aW9uc10gQXR0cmlidXRpb25zLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbYXR0cmlidXRpb25zQ29sbGFwc2libGU9dHJ1ZV0gQXR0cmlidXRpb25zIGFyZSBjb2xsYXBzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbY2FjaGVTaXplXSBJbml0aWFsIHRpbGUgY2FjaGUgc2l6ZS4gV2lsbCBhdXRvLWdyb3cgdG8gaG9sZCBhdCBsZWFzdCB0d2ljZSB0aGUgbnVtYmVyIG9mIHRpbGVzIGluIHRoZSB2aWV3cG9ydC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF1cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZm9ybWF0L0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gW2Zvcm1hdF0gRmVhdHVyZSBmb3JtYXQgZm9yIHRpbGVzLiBVc2VkIGFuZCByZXF1aXJlZCBieSB0aGUgZGVmYXVsdC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW292ZXJsYXBzPXRydWVdIFRoaXMgc291cmNlIG1heSBoYXZlIG92ZXJsYXBwaW5nIGdlb21ldHJpZXMuIFNldHRpbmcgdGhpc1xuICogdG8gYGZhbHNlYCAoZS5nLiBmb3Igc291cmNlcyB3aXRoIHBvbHlnb25zIHRoYXQgcmVwcmVzZW50IGFkbWluaXN0cmF0aXZlXG4gKiBib3VuZGFyaWVzIG9yIFRvcG9KU09OIHNvdXJjZXMpIGFsbG93cyB0aGUgcmVuZGVyZXIgdG8gb3B0aW1pc2UgZmlsbCBhbmRcbiAqIHN0cm9rZSBvcGVyYXRpb25zLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBbcHJvamVjdGlvbj0nRVBTRzozODU3J10gUHJvamVjdGlvbiBvZiB0aGUgdGlsZSBncmlkLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1N0YXRlLmpzXCIpLmRlZmF1bHR9IFtzdGF0ZV0gU291cmNlIHN0YXRlLlxuICogQHByb3BlcnR5IHt0eXBlb2YgaW1wb3J0KFwiLi4vVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0fSBbdGlsZUNsYXNzXSBDbGFzcyB1c2VkIHRvIGluc3RhbnRpYXRlIGltYWdlIHRpbGVzLlxuICogRGVmYXVsdCBpcyB7QGxpbmsgbW9kdWxlOm9sL1ZlY3RvclRpbGV9LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhab29tPTIyXSBPcHRpb25hbCBtYXggem9vbSBsZXZlbC4gTm90IHVzZWQgaWYgYHRpbGVHcmlkYCBpcyBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluWm9vbV0gT3B0aW9uYWwgbWluIHpvb20gbGV2ZWwuIE5vdCB1c2VkIGlmIGB0aWxlR3JpZGAgaXMgcHJvdmlkZWQuXG4gKiBAcHJvcGVydHkge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFt0aWxlU2l6ZT01MTJdIE9wdGlvbmFsIHRpbGUgc2l6ZS4gTm90IHVzZWQgaWYgYHRpbGVHcmlkYCBpcyBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4UmVzb2x1dGlvbl0gT3B0aW9uYWwgdGlsZSBncmlkIHJlc29sdXRpb24gYXQgbGV2ZWwgemVyby4gTm90IHVzZWQgaWYgYHRpbGVHcmlkYCBpcyBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gW3RpbGVHcmlkXSBUaWxlIGdyaWQuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL1RpbGUuanNcIikuTG9hZEZ1bmN0aW9ufSBbdGlsZUxvYWRGdW5jdGlvbl1cbiAqIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGxvYWQgYSB0aWxlIGdpdmVuIGEgVVJMLiBDb3VsZCBsb29rIGxpa2UgdGhpcyBmb3IgcGJmIHRpbGVzOlxuICogYGBganNcbiAqIGZ1bmN0aW9uKHRpbGUsIHVybCkge1xuICogICB0aWxlLnNldExvYWRlcihmdW5jdGlvbihleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24pIHtcbiAqICAgICBmZXRjaCh1cmwpLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAqICAgICAgIHJlc3BvbnNlLmFycmF5QnVmZmVyKCkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gKiAgICAgICAgIGNvbnN0IGZvcm1hdCA9IHRpbGUuZ2V0Rm9ybWF0KCkgLy8gb2wvZm9ybWF0L01WVCBjb25maWd1cmVkIGFzIHNvdXJjZSBmb3JtYXRcbiAqICAgICAgICAgY29uc3QgZmVhdHVyZXMgPSBmb3JtYXQucmVhZEZlYXR1cmVzKGRhdGEsIHtcbiAqICAgICAgICAgICBleHRlbnQ6IGV4dGVudCxcbiAqICAgICAgICAgICBmZWF0dXJlUHJvamVjdGlvbjogcHJvamVjdGlvblxuICogICAgICAgICB9KTtcbiAqICAgICAgICAgdGlsZS5zZXRGZWF0dXJlcyhmZWF0dXJlcyk7XG4gKiAgICAgICB9KTtcbiAqICAgICB9KTtcbiAqICAgfSk7XG4gKiB9XG4gKiBgYGBcbiAqIElmIHlvdSBkbyBub3QgbmVlZCBleHRlbnQsIHJlc29sdXRpb24gYW5kIHByb2plY3Rpb24gdG8gZ2V0IHRoZSBmZWF0dXJlcyBmb3IgYSB0aWxlIChlLmcuXG4gKiBmb3IgR2VvSlNPTiB0aWxlcyksIHlvdXIgYHRpbGVMb2FkRnVuY3Rpb25gIGRvZXMgbm90IG5lZWQgYSBgc2V0TG9hZGVyKClgIGNhbGwuIE9ubHkgbWFrZSBzdXJlXG4gKiB0byBjYWxsIGBzZXRGZWF0dXJlcygpYCBvbiB0aGUgdGlsZTpcbiAqIGBgYGpzXG4gKiBjb25zdCBmb3JtYXQgPSBuZXcgR2VvSlNPTih7ZmVhdHVyZVByb2plY3Rpb246IG1hcC5nZXRWaWV3KCkuZ2V0UHJvamVjdGlvbigpfSk7XG4gKiBhc3luYyBmdW5jdGlvbiB0aWxlTG9hZEZ1bmN0aW9uKHRpbGUsIHVybCkge1xuICogICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gKiAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gKiAgIHRpbGUuc2V0RmVhdHVyZXMoZm9ybWF0LnJlYWRGZWF0dXJlcyhkYXRhKSk7XG4gKiB9XG4gKiBgYGBcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5VcmxGdW5jdGlvbn0gW3RpbGVVcmxGdW5jdGlvbl0gT3B0aW9uYWwgZnVuY3Rpb24gdG8gZ2V0IHRpbGUgVVJMIGdpdmVuIGEgdGlsZSBjb29yZGluYXRlIGFuZCB0aGUgcHJvamVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdXJsXSBVUkwgdGVtcGxhdGUuIE11c3QgaW5jbHVkZSBge3h9YCwgYHt5fWAgb3IgYHsteX1gLCBhbmQgYHt6fWAgcGxhY2Vob2xkZXJzLlxuICogQSBgez8tP31gIHRlbXBsYXRlIHBhdHRlcm4sIGZvciBleGFtcGxlIGBzdWJkb21haW57YS1mfS5kb21haW4uY29tYCwgbWF5IGJlXG4gKiB1c2VkIGluc3RlYWQgb2YgZGVmaW5pbmcgZWFjaCBvbmUgc2VwYXJhdGVseSBpbiB0aGUgYHVybHNgIG9wdGlvbi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdHJhbnNpdGlvbl0gQSBkdXJhdGlvbiBmb3IgdGlsZSBvcGFjaXR5XG4gKiB0cmFuc2l0aW9ucyBpbiBtaWxsaXNlY29uZHMuIEEgZHVyYXRpb24gb2YgMCBkaXNhYmxlcyB0aGUgb3BhY2l0eSB0cmFuc2l0aW9uLlxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSBbdXJsc10gQW4gYXJyYXkgb2YgVVJMIHRlbXBsYXRlcy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3dyYXBYPXRydWVdIFdoZXRoZXIgdG8gd3JhcCB0aGUgd29ybGQgaG9yaXpvbnRhbGx5LlxuICogV2hlbiBzZXQgdG8gYGZhbHNlYCwgb25seSBvbmUgd29ybGRcbiAqIHdpbGwgYmUgcmVuZGVyZWQuIFdoZW4gc2V0IHRvIGB0cnVlYCwgdGlsZXMgd2lsbCBiZSB3cmFwcGVkIGhvcml6b250YWxseSB0b1xuICogcmVuZGVyIG11bHRpcGxlIHdvcmxkcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbekRpcmVjdGlvbj0xXSBJbmRpY2F0ZSB3aGljaCByZXNvbHV0aW9uIHNob3VsZCBiZSB1c2VkXG4gKiBieSBhIHJlbmRlcmVyIGlmIHRoZSB2aWV3IHJlc29sdXRpb24gZG9lcyBub3QgbWF0Y2ggYW55IHJlc29sdXRpb24gb2YgdGhlIHRpbGUgc291cmNlLlxuICogSWYgMCwgdGhlIG5lYXJlc3QgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuIElmIDEsIHRoZSBuZWFyZXN0IGxvd2VyIHJlc29sdXRpb25cbiAqIHdpbGwgYmUgdXNlZC4gSWYgLTEsIHRoZSBuZWFyZXN0IGhpZ2hlciByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIENsYXNzIGZvciBsYXllciBzb3VyY2VzIHByb3ZpZGluZyB2ZWN0b3IgZGF0YSBkaXZpZGVkIGludG8gYSB0aWxlIGdyaWQsIHRvIGJlXG4gKiB1c2VkIHdpdGgge0BsaW5rIG1vZHVsZTpvbC9sYXllci9WZWN0b3JUaWxlflZlY3RvclRpbGV9LiBBbHRob3VnaCB0aGlzIHNvdXJjZSByZWNlaXZlcyB0aWxlc1xuICogd2l0aCB2ZWN0b3IgZmVhdHVyZXMgZnJvbSB0aGUgc2VydmVyLCBpdCBpcyBub3QgbWVhbnQgZm9yIGZlYXR1cmUgZWRpdGluZy5cbiAqIEZlYXR1cmVzIGFyZSBvcHRpbWl6ZWQgZm9yIHJlbmRlcmluZywgdGhlaXIgZ2VvbWV0cmllcyBhcmUgY2xpcHBlZCBhdCBvciBuZWFyXG4gKiB0aWxlIGJvdW5kYXJpZXMgYW5kIHNpbXBsaWZpZWQgZm9yIGEgdmlldyByZXNvbHV0aW9uLiBTZWVcbiAqIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn0gZm9yIHZlY3RvciBzb3VyY2VzIHRoYXQgYXJlIHN1aXRhYmxlIGZvciBmZWF0dXJlXG4gKiBlZGl0aW5nLlxuICpcbiAqIEBmaXJlcyBpbXBvcnQoXCIuL1RpbGUuanNcIikuVGlsZVNvdXJjZUV2ZW50XG4gKiBAYXBpXG4gKi9cblxudmFyIFZlY3RvclRpbGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVmVjdG9yVGlsZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7IU9wdGlvbnN9IG9wdGlvbnMgVmVjdG9yIHRpbGUgb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBWZWN0b3JUaWxlKG9wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIHByb2plY3Rpb24gPSBvcHRpb25zLnByb2plY3Rpb24gfHwgJ0VQU0c6Mzg1Nyc7XG4gICAgdmFyIGV4dGVudCA9IG9wdGlvbnMuZXh0ZW50IHx8IGV4dGVudEZyb21Qcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHZhciB0aWxlR3JpZCA9IG9wdGlvbnMudGlsZUdyaWQgfHwgY3JlYXRlWFlaKHtcbiAgICAgIGV4dGVudDogZXh0ZW50LFxuICAgICAgbWF4UmVzb2x1dGlvbjogb3B0aW9ucy5tYXhSZXNvbHV0aW9uLFxuICAgICAgbWF4Wm9vbTogb3B0aW9ucy5tYXhab29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1heFpvb20gOiAyMixcbiAgICAgIG1pblpvb206IG9wdGlvbnMubWluWm9vbSxcbiAgICAgIHRpbGVTaXplOiBvcHRpb25zLnRpbGVTaXplIHx8IDUxMlxuICAgIH0pO1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgYXR0cmlidXRpb25zOiBvcHRpb25zLmF0dHJpYnV0aW9ucyxcbiAgICAgIGF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlOiBvcHRpb25zLmF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlLFxuICAgICAgY2FjaGVTaXplOiBvcHRpb25zLmNhY2hlU2l6ZSxcbiAgICAgIG9wYXF1ZTogZmFsc2UsXG4gICAgICBwcm9qZWN0aW9uOiBwcm9qZWN0aW9uLFxuICAgICAgc3RhdGU6IG9wdGlvbnMuc3RhdGUsXG4gICAgICB0aWxlR3JpZDogdGlsZUdyaWQsXG4gICAgICB0aWxlTG9hZEZ1bmN0aW9uOiBvcHRpb25zLnRpbGVMb2FkRnVuY3Rpb24gPyBvcHRpb25zLnRpbGVMb2FkRnVuY3Rpb24gOiBkZWZhdWx0TG9hZEZ1bmN0aW9uLFxuICAgICAgdGlsZVVybEZ1bmN0aW9uOiBvcHRpb25zLnRpbGVVcmxGdW5jdGlvbixcbiAgICAgIHVybDogb3B0aW9ucy51cmwsXG4gICAgICB1cmxzOiBvcHRpb25zLnVybHMsXG4gICAgICB3cmFwWDogb3B0aW9ucy53cmFwWCA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IG9wdGlvbnMud3JhcFgsXG4gICAgICB0cmFuc2l0aW9uOiBvcHRpb25zLnRyYW5zaXRpb24sXG4gICAgICB6RGlyZWN0aW9uOiBvcHRpb25zLnpEaXJlY3Rpb24gPT09IHVuZGVmaW5lZCA/IDEgOiBvcHRpb25zLnpEaXJlY3Rpb25cbiAgICB9KSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2Zvcm1hdC9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5mb3JtYXRfID0gb3B0aW9ucy5mb3JtYXQgPyBvcHRpb25zLmZvcm1hdCA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsIGltcG9ydChcIi4vVmVjdG9yVGlsZVwiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxvYWRpbmdUaWxlc18gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtUaWxlQ2FjaGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5zb3VyY2VUaWxlQ2FjaGUgPSBuZXcgVGlsZUNhY2hlKF90aGlzLnRpbGVDYWNoZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMub3ZlcmxhcHNfID0gb3B0aW9ucy5vdmVybGFwcyA9PSB1bmRlZmluZWQgPyB0cnVlIDogb3B0aW9ucy5vdmVybGFwcztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge3R5cGVvZiBpbXBvcnQoXCIuLi9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlQ2xhc3MgPSBvcHRpb25zLnRpbGVDbGFzcyA/IG9wdGlvbnMudGlsZUNsYXNzIDogVGlsZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVHcmlkc18gPSB7fTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCBmZWF0dXJlcyB3aG9zZSBib3VuZGluZyBib3ggaW50ZXJzZWN0cyB0aGUgcHJvdmlkZWQgZXh0ZW50LiBPbmx5IGZlYXR1cmVzIGZvciBjYWNoZWRcbiAgICogdGlsZXMgZm9yIHRoZSBsYXN0IHJlbmRlcmVkIHpvb20gbGV2ZWwgYXJlIGF2YWlsYWJsZSBpbiB0aGUgc291cmNlLiBTbyB0aGlzIG1ldGhvZCBpcyBvbmx5XG4gICAqIHN1aXRhYmxlIGZvciByZXF1ZXN0aW5nIHRpbGVzIGZvciBleHRlbnRzIHRoYXQgYXJlIGN1cnJlbnRseSByZW5kZXJlZC5cbiAgICpcbiAgICogRmVhdHVyZXMgYXJlIHJldHVybmVkIGluIHJhbmRvbSB0aWxlIG9yZGVyIGFuZCBhcyB0aGV5IGFyZSBpbmNsdWRlZCBpbiB0aGUgdGlsZXMuIFRoaXMgbWVhbnNcbiAgICogdGhleSBjYW4gYmUgY2xpcHBlZCwgZHVwbGljYXRlZCBhY3Jvc3MgdGlsZXMsIGFuZCBzaW1wbGlmaWVkIHRvIHRoZSByZW5kZXIgcmVzb2x1dGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlPn0gRmVhdHVyZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5nZXRGZWF0dXJlc0luRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCkge1xuICAgIHZhciBmZWF0dXJlcyA9IFtdO1xuICAgIHZhciB0aWxlQ2FjaGUgPSB0aGlzLnRpbGVDYWNoZTtcblxuICAgIGlmICh0aWxlQ2FjaGUuZ2V0Q291bnQoKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZlYXR1cmVzO1xuICAgIH1cblxuICAgIHZhciB6ID0gZnJvbUtleSh0aWxlQ2FjaGUucGVla0ZpcnN0S2V5KCkpWzBdO1xuICAgIHZhciB0aWxlR3JpZCA9IHRoaXMudGlsZUdyaWQ7XG4gICAgdGlsZUNhY2hlLmZvckVhY2goZnVuY3Rpb24gKHRpbGUpIHtcbiAgICAgIGlmICh0aWxlLnRpbGVDb29yZFswXSAhPT0geiB8fCB0aWxlLmdldFN0YXRlKCkgIT09IFRpbGVTdGF0ZS5MT0FERUQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgc291cmNlVGlsZXMgPSB0aWxlLmdldFNvdXJjZVRpbGVzKCk7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHNvdXJjZVRpbGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgdmFyIHNvdXJjZVRpbGUgPSBzb3VyY2VUaWxlc1tpXTtcbiAgICAgICAgdmFyIHRpbGVDb29yZCA9IHNvdXJjZVRpbGUudGlsZUNvb3JkO1xuXG4gICAgICAgIGlmIChpbnRlcnNlY3RzKGV4dGVudCwgdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHRpbGVDb29yZCkpKSB7XG4gICAgICAgICAgdmFyIHRpbGVGZWF0dXJlcyA9IHNvdXJjZVRpbGUuZ2V0RmVhdHVyZXMoKTtcblxuICAgICAgICAgIGlmICh0aWxlRmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwLCBqaiA9IHRpbGVGZWF0dXJlcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgICAgICAgICAgIHZhciBjYW5kaWRhdGUgPSB0aWxlRmVhdHVyZXNbal07XG4gICAgICAgICAgICAgIHZhciBnZW9tZXRyeSA9IGNhbmRpZGF0ZS5nZXRHZW9tZXRyeSgpO1xuXG4gICAgICAgICAgICAgIGlmIChpbnRlcnNlY3RzKGV4dGVudCwgZ2VvbWV0cnkuZ2V0RXh0ZW50KCkpKSB7XG4gICAgICAgICAgICAgICAgZmVhdHVyZXMucHVzaChjYW5kaWRhdGUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGZlYXR1cmVzO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHNvdXJjZSBjYW4gaGF2ZSBvdmVybGFwcGluZyBnZW9tZXRyaWVzLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLmdldE92ZXJsYXBzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm92ZXJsYXBzXztcbiAgfTtcbiAgLyoqXG4gICAqIGNsZWFyIHtAbGluayBtb2R1bGU6b2wvVGlsZUNhY2hlflRpbGVDYWNoZX0gYW5kIGRlbGV0ZSBhbGwgc291cmNlIHRpbGVzXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRpbGVDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMuc291cmNlVGlsZUNhY2hlLmNsZWFyKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7IU9iamVjdDxzdHJpbmcsIGJvb2xlYW4+fSB1c2VkVGlsZXMgVXNlZCB0aWxlcy5cbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5leHBpcmVDYWNoZSA9IGZ1bmN0aW9uIChwcm9qZWN0aW9uLCB1c2VkVGlsZXMpIHtcbiAgICBfc3VwZXIucHJvdG90eXBlLmV4cGlyZUNhY2hlLmNhbGwodGhpcywgcHJvamVjdGlvbiwgdXNlZFRpbGVzKTtcblxuICAgIHRoaXMuc291cmNlVGlsZUNhY2hlLmV4cGlyZUNhY2hlKHt9KTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvblwiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7VmVjdG9yUmVuZGVyVGlsZX0gdGlsZSBWZWN0b3IgaW1hZ2UgdGlsZS5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi4vVmVjdG9yVGlsZVwiKS5kZWZhdWx0Pn0gVGlsZSBrZXlzLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLmdldFNvdXJjZVRpbGVzID0gZnVuY3Rpb24gKHBpeGVsUmF0aW8sIHByb2plY3Rpb24sIHRpbGUpIHtcbiAgICB2YXIgdXJsVGlsZUNvb3JkID0gdGlsZS53cmFwcGVkVGlsZUNvb3JkO1xuICAgIHZhciB0aWxlR3JpZCA9IHRoaXMuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHZhciBleHRlbnQgPSB0aWxlR3JpZC5nZXRUaWxlQ29vcmRFeHRlbnQodXJsVGlsZUNvb3JkKTtcbiAgICB2YXIgeiA9IHVybFRpbGVDb29yZFswXTtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHRpbGVHcmlkLmdldFJlc29sdXRpb24oeik7IC8vIG1ha2UgZXh0ZW50IDEgcGl4ZWwgc21hbGxlciBzbyB3ZSBkb24ndCBsb2FkIHRpbGVzIGZvciA8IDAuNSBwaXhlbCByZW5kZXIgc3BhY2VcblxuICAgIGJ1ZmZlckV4dGVudChleHRlbnQsIC1yZXNvbHV0aW9uLCBleHRlbnQpO1xuICAgIHZhciBzb3VyY2VUaWxlR3JpZCA9IHRoaXMudGlsZUdyaWQ7XG4gICAgdmFyIHNvdXJjZUV4dGVudCA9IHNvdXJjZVRpbGVHcmlkLmdldEV4dGVudCgpO1xuXG4gICAgaWYgKHNvdXJjZUV4dGVudCkge1xuICAgICAgZ2V0SW50ZXJzZWN0aW9uKGV4dGVudCwgc291cmNlRXh0ZW50LCBleHRlbnQpO1xuICAgIH1cblxuICAgIHZhciBzb3VyY2VaID0gc291cmNlVGlsZUdyaWQuZ2V0WkZvclJlc29sdXRpb24ocmVzb2x1dGlvbiwgMSk7XG4gICAgdmFyIG1pblpvb20gPSBzb3VyY2VUaWxlR3JpZC5nZXRNaW5ab29tKCk7XG4gICAgdmFyIHByZXZpb3VzU291cmNlVGlsZXMgPSB0aWxlLnNvdXJjZVRpbGVzO1xuICAgIHZhciBzb3VyY2VUaWxlcywgY292ZXJlZCwgbG9hZGVkWjtcblxuICAgIGlmIChwcmV2aW91c1NvdXJjZVRpbGVzICYmIHByZXZpb3VzU291cmNlVGlsZXMubGVuZ3RoID4gMCAmJiBwcmV2aW91c1NvdXJjZVRpbGVzWzBdLnRpbGVDb29yZFswXSA9PT0gc291cmNlWikge1xuICAgICAgc291cmNlVGlsZXMgPSBwcmV2aW91c1NvdXJjZVRpbGVzO1xuICAgICAgY292ZXJlZCA9IHRydWU7XG4gICAgICBsb2FkZWRaID0gc291cmNlWjtcbiAgICB9IGVsc2Uge1xuICAgICAgc291cmNlVGlsZXMgPSBbXTtcbiAgICAgIGxvYWRlZFogPSBzb3VyY2VaICsgMTtcblxuICAgICAgZG8ge1xuICAgICAgICAtLWxvYWRlZFo7XG4gICAgICAgIGNvdmVyZWQgPSB0cnVlO1xuICAgICAgICBzb3VyY2VUaWxlR3JpZC5mb3JFYWNoVGlsZUNvb3JkKGV4dGVudCwgbG9hZGVkWiwgZnVuY3Rpb24gKHNvdXJjZVRpbGVDb29yZCkge1xuICAgICAgICAgIHZhciB0aWxlVXJsID0gdGhpcy50aWxlVXJsRnVuY3Rpb24oc291cmNlVGlsZUNvb3JkLCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKTtcbiAgICAgICAgICB2YXIgc291cmNlVGlsZTtcblxuICAgICAgICAgIGlmICh0aWxlVXJsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNvdXJjZVRpbGVDYWNoZS5jb250YWluc0tleSh0aWxlVXJsKSkge1xuICAgICAgICAgICAgICBzb3VyY2VUaWxlID0gdGhpcy5zb3VyY2VUaWxlQ2FjaGUuZ2V0KHRpbGVVcmwpO1xuICAgICAgICAgICAgICB2YXIgc3RhdGUgPSBzb3VyY2VUaWxlLmdldFN0YXRlKCk7XG5cbiAgICAgICAgICAgICAgaWYgKHN0YXRlID09PSBUaWxlU3RhdGUuTE9BREVEIHx8IHN0YXRlID09PSBUaWxlU3RhdGUuRVJST1IgfHwgc3RhdGUgPT09IFRpbGVTdGF0ZS5FTVBUWSkge1xuICAgICAgICAgICAgICAgIHNvdXJjZVRpbGVzLnB1c2goc291cmNlVGlsZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGxvYWRlZFogPT09IHNvdXJjZVopIHtcbiAgICAgICAgICAgICAgc291cmNlVGlsZSA9IG5ldyB0aGlzLnRpbGVDbGFzcyhzb3VyY2VUaWxlQ29vcmQsIFRpbGVTdGF0ZS5JRExFLCB0aWxlVXJsLCB0aGlzLmZvcm1hdF8sIHRoaXMudGlsZUxvYWRGdW5jdGlvbik7XG4gICAgICAgICAgICAgIHNvdXJjZVRpbGUuZXh0ZW50ID0gc291cmNlVGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHNvdXJjZVRpbGVDb29yZCk7XG4gICAgICAgICAgICAgIHNvdXJjZVRpbGUucHJvamVjdGlvbiA9IHByb2plY3Rpb247XG4gICAgICAgICAgICAgIHNvdXJjZVRpbGUucmVzb2x1dGlvbiA9IHNvdXJjZVRpbGVHcmlkLmdldFJlc29sdXRpb24oc291cmNlVGlsZUNvb3JkWzBdKTtcbiAgICAgICAgICAgICAgdGhpcy5zb3VyY2VUaWxlQ2FjaGUuc2V0KHRpbGVVcmwsIHNvdXJjZVRpbGUpO1xuICAgICAgICAgICAgICBzb3VyY2VUaWxlLmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5oYW5kbGVUaWxlQ2hhbmdlLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICBzb3VyY2VUaWxlLmxvYWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb3ZlcmVkID0gY292ZXJlZCAmJiBzb3VyY2VUaWxlICYmIHNvdXJjZVRpbGUuZ2V0U3RhdGUoKSA9PT0gVGlsZVN0YXRlLkxPQURFRDtcblxuICAgICAgICAgIGlmICghc291cmNlVGlsZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChzb3VyY2VUaWxlLmdldFN0YXRlKCkgIT09IFRpbGVTdGF0ZS5FTVBUWSAmJiB0aWxlLmdldFN0YXRlKCkgPT09IFRpbGVTdGF0ZS5JRExFKSB7XG4gICAgICAgICAgICB0aWxlLmxvYWRpbmdTb3VyY2VUaWxlcysrO1xuICAgICAgICAgICAgc291cmNlVGlsZS5hZGRFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5DSEFOR0UsIGZ1bmN0aW9uIGxpc3RlbkNoYW5nZSgpIHtcbiAgICAgICAgICAgICAgdmFyIHN0YXRlID0gc291cmNlVGlsZS5nZXRTdGF0ZSgpO1xuICAgICAgICAgICAgICB2YXIgc291cmNlVGlsZUtleSA9IHNvdXJjZVRpbGUuZ2V0S2V5KCk7XG5cbiAgICAgICAgICAgICAgaWYgKHN0YXRlID09PSBUaWxlU3RhdGUuTE9BREVEIHx8IHN0YXRlID09PSBUaWxlU3RhdGUuRVJST1IpIHtcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPT09IFRpbGVTdGF0ZS5MT0FERUQpIHtcbiAgICAgICAgICAgICAgICAgIHNvdXJjZVRpbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuQ0hBTkdFLCBsaXN0ZW5DaGFuZ2UpO1xuICAgICAgICAgICAgICAgICAgdGlsZS5sb2FkaW5nU291cmNlVGlsZXMtLTtcbiAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aWxlLmVycm9yU291cmNlVGlsZUtleXNbc291cmNlVGlsZUtleV07XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gVGlsZVN0YXRlLkVSUk9SKSB7XG4gICAgICAgICAgICAgICAgICB0aWxlLmVycm9yU291cmNlVGlsZUtleXNbc291cmNlVGlsZUtleV0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciBlcnJvclRpbGVDb3VudCA9IE9iamVjdC5rZXlzKHRpbGUuZXJyb3JTb3VyY2VUaWxlS2V5cykubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRpbGUubG9hZGluZ1NvdXJjZVRpbGVzIC0gZXJyb3JUaWxlQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgIHRpbGUuaGlmaSA9IGVycm9yVGlsZUNvdW50ID09PSAwO1xuICAgICAgICAgICAgICAgICAgdGlsZS5zb3VyY2VaID0gc291cmNlWjtcbiAgICAgICAgICAgICAgICAgIHRpbGUuc2V0U3RhdGUoVGlsZVN0YXRlLkxPQURFRCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0uYmluZCh0aGlzKSk7XG5cbiAgICAgICAgaWYgKCFjb3ZlcmVkKSB7XG4gICAgICAgICAgc291cmNlVGlsZXMubGVuZ3RoID0gMDtcbiAgICAgICAgfVxuICAgICAgfSB3aGlsZSAoIWNvdmVyZWQgJiYgbG9hZGVkWiA+IG1pblpvb20pO1xuICAgIH1cblxuICAgIGlmICh0aWxlLmdldFN0YXRlKCkgPT09IFRpbGVTdGF0ZS5JRExFKSB7XG4gICAgICB0aWxlLnNldFN0YXRlKFRpbGVTdGF0ZS5MT0FESU5HKTtcbiAgICB9XG5cbiAgICBpZiAoY292ZXJlZCkge1xuICAgICAgdGlsZS5oaWZpID0gc291cmNlWiA9PT0gbG9hZGVkWjtcbiAgICAgIHRpbGUuc291cmNlWiA9IGxvYWRlZFo7XG5cbiAgICAgIGlmICh0aWxlLmdldFN0YXRlKCkgPCBUaWxlU3RhdGUuTE9BREVEKSB7XG4gICAgICAgIHRpbGUuc2V0U3RhdGUoVGlsZVN0YXRlLkxPQURFRCk7XG4gICAgICB9IGVsc2UgaWYgKCFwcmV2aW91c1NvdXJjZVRpbGVzIHx8ICFlcXVhbHMoc291cmNlVGlsZXMsIHByZXZpb3VzU291cmNlVGlsZXMpKSB7XG4gICAgICAgIHRpbGUuc291cmNlVGlsZXMgPSBzb3VyY2VUaWxlcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc291cmNlVGlsZXM7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geiBUaWxlIGNvb3JkaW5hdGUgei5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHggVGlsZSBjb29yZGluYXRlIHguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFRpbGUgY29vcmRpbmF0ZSB5LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHshVmVjdG9yUmVuZGVyVGlsZX0gVGlsZS5cbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5nZXRUaWxlID0gZnVuY3Rpb24gKHosIHgsIHksIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIHtcbiAgICB2YXIgY29vcmRLZXkgPSBnZXRLZXlaWFkoeiwgeCwgeSk7XG4gICAgdmFyIGtleSA9IHRoaXMuZ2V0S2V5KCk7XG4gICAgdmFyIHRpbGU7XG5cbiAgICBpZiAodGhpcy50aWxlQ2FjaGUuY29udGFpbnNLZXkoY29vcmRLZXkpKSB7XG4gICAgICB0aWxlID0gdGhpcy50aWxlQ2FjaGUuZ2V0KGNvb3JkS2V5KTtcblxuICAgICAgaWYgKHRpbGUua2V5ID09PSBrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRpbGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHRpbGVDb29yZCA9IFt6LCB4LCB5XTtcbiAgICB2YXIgdXJsVGlsZUNvb3JkID0gdGhpcy5nZXRUaWxlQ29vcmRGb3JUaWxlVXJsRnVuY3Rpb24odGlsZUNvb3JkLCBwcm9qZWN0aW9uKTtcbiAgICB2YXIgc291cmNlRXh0ZW50ID0gdGhpcy5nZXRUaWxlR3JpZCgpLmdldEV4dGVudCgpO1xuICAgIHZhciB0aWxlR3JpZCA9IHRoaXMuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuXG4gICAgaWYgKHVybFRpbGVDb29yZCAmJiBzb3VyY2VFeHRlbnQpIHtcbiAgICAgIHZhciB0aWxlRXh0ZW50ID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHVybFRpbGVDb29yZCk7IC8vIG1ha2UgZXh0ZW50IDEgcGl4ZWwgc21hbGxlciBzbyB3ZSBkb24ndCBsb2FkIHRpbGVzIGZvciA8IDAuNSBwaXhlbCByZW5kZXIgc3BhY2VcblxuICAgICAgYnVmZmVyRXh0ZW50KHRpbGVFeHRlbnQsIC10aWxlR3JpZC5nZXRSZXNvbHV0aW9uKHopLCB0aWxlRXh0ZW50KTtcblxuICAgICAgaWYgKCFpbnRlcnNlY3RzKHNvdXJjZUV4dGVudCwgdGlsZUV4dGVudCkpIHtcbiAgICAgICAgdXJsVGlsZUNvb3JkID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZW1wdHkgPSB0cnVlO1xuXG4gICAgaWYgKHVybFRpbGVDb29yZCAhPT0gbnVsbCkge1xuICAgICAgdmFyIHNvdXJjZVRpbGVHcmlkID0gdGhpcy50aWxlR3JpZDtcbiAgICAgIHZhciByZXNvbHV0aW9uID0gdGlsZUdyaWQuZ2V0UmVzb2x1dGlvbih6KTtcbiAgICAgIHZhciBzb3VyY2VaID0gc291cmNlVGlsZUdyaWQuZ2V0WkZvclJlc29sdXRpb24ocmVzb2x1dGlvbiwgMSk7IC8vIG1ha2UgZXh0ZW50IDEgcGl4ZWwgc21hbGxlciBzbyB3ZSBkb24ndCBsb2FkIHRpbGVzIGZvciA8IDAuNSBwaXhlbCByZW5kZXIgc3BhY2VcblxuICAgICAgdmFyIGV4dGVudCA9IHRpbGVHcmlkLmdldFRpbGVDb29yZEV4dGVudCh1cmxUaWxlQ29vcmQpO1xuICAgICAgYnVmZmVyRXh0ZW50KGV4dGVudCwgLXJlc29sdXRpb24sIGV4dGVudCk7XG4gICAgICBzb3VyY2VUaWxlR3JpZC5mb3JFYWNoVGlsZUNvb3JkKGV4dGVudCwgc291cmNlWiwgZnVuY3Rpb24gKHNvdXJjZVRpbGVDb29yZCkge1xuICAgICAgICBlbXB0eSA9IGVtcHR5ICYmICF0aGlzLnRpbGVVcmxGdW5jdGlvbihzb3VyY2VUaWxlQ29vcmQsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pO1xuICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB2YXIgbmV3VGlsZSA9IG5ldyBWZWN0b3JSZW5kZXJUaWxlKHRpbGVDb29yZCwgZW1wdHkgPyBUaWxlU3RhdGUuRU1QVFkgOiBUaWxlU3RhdGUuSURMRSwgdXJsVGlsZUNvb3JkLCB0aGlzLmdldFNvdXJjZVRpbGVzLmJpbmQodGhpcywgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikpO1xuICAgIG5ld1RpbGUua2V5ID0ga2V5O1xuXG4gICAgaWYgKHRpbGUpIHtcbiAgICAgIG5ld1RpbGUuaW50ZXJpbVRpbGUgPSB0aWxlO1xuICAgICAgbmV3VGlsZS5yZWZyZXNoSW50ZXJpbUNoYWluKCk7XG4gICAgICB0aGlzLnRpbGVDYWNoZS5yZXBsYWNlKGNvb3JkS2V5LCBuZXdUaWxlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50aWxlQ2FjaGUuc2V0KGNvb3JkS2V5LCBuZXdUaWxlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3VGlsZTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IFRpbGUgZ3JpZC5cbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24gPSBmdW5jdGlvbiAocHJvamVjdGlvbikge1xuICAgIHZhciBjb2RlID0gcHJvamVjdGlvbi5nZXRDb2RlKCk7XG4gICAgdmFyIHRpbGVHcmlkID0gdGhpcy50aWxlR3JpZHNfW2NvZGVdO1xuXG4gICAgaWYgKCF0aWxlR3JpZCkge1xuICAgICAgLy8gQSB0aWxlIGdyaWQgdGhhdCBtYXRjaGVzIHRoZSB0aWxlIHNpemUgb2YgdGhlIHNvdXJjZSB0aWxlIGdyaWQgaXMgbW9yZVxuICAgICAgLy8gbGlrZWx5IHRvIGhhdmUgMToxIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBzb3VyY2UgdGlsZXMgYW5kIHJlbmRlcmVkIHRpbGVzLlxuICAgICAgdmFyIHNvdXJjZVRpbGVHcmlkID0gdGhpcy50aWxlR3JpZDtcbiAgICAgIHRpbGVHcmlkID0gY3JlYXRlRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uLCB1bmRlZmluZWQsIHNvdXJjZVRpbGVHcmlkID8gc291cmNlVGlsZUdyaWQuZ2V0VGlsZVNpemUoc291cmNlVGlsZUdyaWQuZ2V0TWluWm9vbSgpKSA6IHVuZGVmaW5lZCk7XG4gICAgICB0aGlzLnRpbGVHcmlkc19bY29kZV0gPSB0aWxlR3JpZDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGlsZUdyaWQ7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHRpbGUgcGl4ZWwgcmF0aW8gZm9yIHRoaXMgc291cmNlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaWxlIHBpeGVsIHJhdGlvLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLmdldFRpbGVQaXhlbFJhdGlvID0gZnVuY3Rpb24gKHBpeGVsUmF0aW8pIHtcbiAgICByZXR1cm4gcGl4ZWxSYXRpbztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gVGlsZSBzaXplLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLmdldFRpbGVQaXhlbFNpemUgPSBmdW5jdGlvbiAoeiwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikge1xuICAgIHZhciB0aWxlR3JpZCA9IHRoaXMuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHZhciB0aWxlU2l6ZSA9IHRvU2l6ZSh0aWxlR3JpZC5nZXRUaWxlU2l6ZSh6KSwgdGhpcy50bXBTaXplKTtcbiAgICByZXR1cm4gW01hdGgucm91bmQodGlsZVNpemVbMF0gKiBwaXhlbFJhdGlvKSwgTWF0aC5yb3VuZCh0aWxlU2l6ZVsxXSAqIHBpeGVsUmF0aW8pXTtcbiAgfTtcbiAgLyoqXG4gICAqIEluY3JlYXNlcyB0aGUgY2FjaGUgc2l6ZSBpZiBuZWVkZWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRpbGVDb3VudCBNaW5pbXVtIG51bWJlciBvZiB0aWxlcyBuZWVkZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS51cGRhdGVDYWNoZVNpemUgPSBmdW5jdGlvbiAodGlsZUNvdW50LCBwcm9qZWN0aW9uKSB7XG4gICAgX3N1cGVyLnByb3RvdHlwZS51cGRhdGVDYWNoZVNpemUuY2FsbCh0aGlzLCB0aWxlQ291bnQgKiAyLCBwcm9qZWN0aW9uKTtcbiAgfTtcblxuICByZXR1cm4gVmVjdG9yVGlsZTtcbn0oVXJsVGlsZSk7XG5cbmV4cG9ydCBkZWZhdWx0IFZlY3RvclRpbGU7XG4vKipcbiAqIFNldHMgdGhlIGxvYWRlciBmb3IgYSB0aWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVmVjdG9yIHRpbGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdXJsIFVSTC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdExvYWRGdW5jdGlvbih0aWxlLCB1cmwpIHtcbiAgdGlsZS5zZXRMb2FkZXIoXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIChleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24pIHtcbiAgICBsb2FkRmVhdHVyZXNYaHIodXJsLCB0aWxlLmdldEZvcm1hdCgpLCBleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24sIHRpbGUub25Mb2FkLmJpbmQodGlsZSksIHRpbGUub25FcnJvci5iaW5kKHRpbGUpKTtcbiAgfSk7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2Zvcm1hdC9GZWF0dXJlXG4gKi9cbmltcG9ydCBVbml0cyBmcm9tICcuLi9wcm9qL1VuaXRzLmpzJztcbmltcG9ydCB7IGFic3RyYWN0IH0gZnJvbSAnLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICcuLi9vYmouanMnO1xuaW1wb3J0IHsgZXF1aXZhbGVudCBhcyBlcXVpdmFsZW50UHJvamVjdGlvbiwgZ2V0IGFzIGdldFByb2plY3Rpb24sIHRyYW5zZm9ybUV4dGVudCB9IGZyb20gJy4uL3Byb2ouanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBSZWFkT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBbZGF0YVByb2plY3Rpb25dIFByb2plY3Rpb24gb2YgdGhlIGRhdGEgd2UgYXJlIHJlYWRpbmcuXG4gKiBJZiBub3QgcHJvdmlkZWQsIHRoZSBwcm9qZWN0aW9uIHdpbGwgYmUgZGVyaXZlZCBmcm9tIHRoZSBkYXRhICh3aGVyZSBwb3NzaWJsZSkgb3JcbiAqIHRoZSBgZGF0YVByb2plY3Rpb25gIG9mIHRoZSBmb3JtYXQgaXMgYXNzaWduZWQgKHdoZXJlIHNldCkuIElmIHRoZSBwcm9qZWN0aW9uXG4gKiBjYW4gbm90IGJlIGRlcml2ZWQgZnJvbSB0aGUgZGF0YSBhbmQgaWYgbm8gYGRhdGFQcm9qZWN0aW9uYCBpcyBzZXQgZm9yIGEgZm9ybWF0LFxuICogdGhlIGZlYXR1cmVzIHdpbGwgbm90IGJlIHJlcHJvamVjdGVkLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBbZXh0ZW50XSBUaWxlIGV4dGVudCBpbiBtYXAgdW5pdHMgb2YgdGhlIHRpbGUgYmVpbmcgcmVhZC5cbiAqIFRoaXMgaXMgb25seSByZXF1aXJlZCB3aGVuIHJlYWRpbmcgZGF0YSB3aXRoIHRpbGUgcGl4ZWxzIGFzIGdlb21ldHJ5IHVuaXRzLiBXaGVuIGNvbmZpZ3VyZWQsXG4gKiBhIGBkYXRhUHJvamVjdGlvbmAgd2l0aCBgVElMRV9QSVhFTFNgIGFzIGB1bml0c2AgYW5kIHRoZSB0aWxlJ3MgcGl4ZWwgZXh0ZW50IGFzIGBleHRlbnRgIG5lZWRzIHRvIGJlXG4gKiBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gW2ZlYXR1cmVQcm9qZWN0aW9uXSBQcm9qZWN0aW9uIG9mIHRoZSBmZWF0dXJlIGdlb21ldHJpZXNcbiAqIGNyZWF0ZWQgYnkgdGhlIGZvcm1hdCByZWFkZXIuIElmIG5vdCBwcm92aWRlZCwgZmVhdHVyZXMgd2lsbCBiZSByZXR1cm5lZCBpbiB0aGVcbiAqIGBkYXRhUHJvamVjdGlvbmAuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBXcml0ZU9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gW2RhdGFQcm9qZWN0aW9uXSBQcm9qZWN0aW9uIG9mIHRoZSBkYXRhIHdlIGFyZSB3cml0aW5nLlxuICogSWYgbm90IHByb3ZpZGVkLCB0aGUgYGRhdGFQcm9qZWN0aW9uYCBvZiB0aGUgZm9ybWF0IGlzIGFzc2lnbmVkICh3aGVyZSBzZXQpLlxuICogSWYgbm8gYGRhdGFQcm9qZWN0aW9uYCBpcyBzZXQgZm9yIGEgZm9ybWF0LCB0aGUgZmVhdHVyZXMgd2lsbCBiZSByZXR1cm5lZFxuICogaW4gdGhlIGBmZWF0dXJlUHJvamVjdGlvbmAuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtmZWF0dXJlUHJvamVjdGlvbl0gUHJvamVjdGlvbiBvZiB0aGUgZmVhdHVyZSBnZW9tZXRyaWVzXG4gKiB0aGF0IHdpbGwgYmUgc2VyaWFsaXplZCBieSB0aGUgZm9ybWF0IHdyaXRlci4gSWYgbm90IHByb3ZpZGVkLCBnZW9tZXRyaWVzIGFyZSBhc3N1bWVkXG4gKiB0byBiZSBpbiB0aGUgYGRhdGFQcm9qZWN0aW9uYCBpZiB0aGF0IGlzIHNldDsgaW4gb3RoZXIgd29yZHMsIHRoZXkgYXJlIG5vdCB0cmFuc2Zvcm1lZC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3JpZ2h0SGFuZGVkXSBXaGVuIHdyaXRpbmcgZ2VvbWV0cmllcywgZm9sbG93IHRoZSByaWdodC1oYW5kXG4gKiBydWxlIGZvciBsaW5lYXIgcmluZyBvcmllbnRhdGlvbi4gIFRoaXMgbWVhbnMgdGhhdCBwb2x5Z29ucyB3aWxsIGhhdmUgY291bnRlci1jbG9ja3dpc2VcbiAqIGV4dGVyaW9yIHJpbmdzIGFuZCBjbG9ja3dpc2UgaW50ZXJpb3IgcmluZ3MuICBCeSBkZWZhdWx0LCBjb29yZGluYXRlcyBhcmUgc2VyaWFsaXplZFxuICogYXMgdGhleSBhcmUgcHJvdmlkZWQgYXQgY29uc3RydWN0aW9uLiAgSWYgYHRydWVgLCB0aGUgcmlnaHQtaGFuZCBydWxlIHdpbGxcbiAqIGJlIGFwcGxpZWQuICBJZiBgZmFsc2VgLCB0aGUgbGVmdC1oYW5kIHJ1bGUgd2lsbCBiZSBhcHBsaWVkIChjbG9ja3dpc2UgZm9yXG4gKiBleHRlcmlvciBhbmQgY291bnRlci1jbG9ja3dpc2UgZm9yIGludGVyaW9yIHJpbmdzKS4gIE5vdGUgdGhhdCBub3QgYWxsXG4gKiBmb3JtYXRzIHN1cHBvcnQgdGhpcy4gIFRoZSBHZW9KU09OIGZvcm1hdCBkb2VzIHVzZSB0aGlzIHByb3BlcnR5IHdoZW4gd3JpdGluZ1xuICogZ2VvbWV0cmllcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbZGVjaW1hbHNdIE1heGltdW0gbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIGZvciBjb29yZGluYXRlcy5cbiAqIENvb3JkaW5hdGVzIGFyZSBzdG9yZWQgaW50ZXJuYWxseSBhcyBmbG9hdHMsIGJ1dCBmbG9hdGluZy1wb2ludCBhcml0aG1ldGljIGNhbiBjcmVhdGVcbiAqIGNvb3JkaW5hdGVzIHdpdGggYSBsYXJnZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMsIG5vdCBnZW5lcmFsbHkgd2FudGVkIG9uIG91dHB1dC5cbiAqIFNldCBhIG51bWJlciBoZXJlIHRvIHJvdW5kIGNvb3JkaW5hdGVzLiBDYW4gYWxzbyBiZSB1c2VkIHRvIGVuc3VyZSB0aGF0XG4gKiBjb29yZGluYXRlcyByZWFkIGluIGNhbiBiZSB3cml0dGVuIGJhY2sgb3V0IHdpdGggdGhlIHNhbWUgbnVtYmVyIG9mIGRlY2ltYWxzLlxuICogRGVmYXVsdCBpcyBubyByb3VuZGluZy5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3M7IG5vcm1hbGx5IG9ubHkgdXNlZCBmb3IgY3JlYXRpbmcgc3ViY2xhc3NlcyBhbmQgbm90XG4gKiBpbnN0YW50aWF0ZWQgaW4gYXBwcy5cbiAqIEJhc2UgY2xhc3MgZm9yIGZlYXR1cmUgZm9ybWF0cy5cbiAqIHtAbGluayBtb2R1bGU6b2wvZm9ybWF0L0ZlYXR1cmV+RmVhdHVyZUZvcm1hdH0gc3ViY2xhc3NlcyBwcm92aWRlIHRoZSBhYmlsaXR5IHRvIGRlY29kZSBhbmQgZW5jb2RlXG4gKiB7QGxpbmsgbW9kdWxlOm9sL0ZlYXR1cmV+RmVhdHVyZX0gb2JqZWN0cyBmcm9tIGEgdmFyaWV0eSBvZiBjb21tb25seSB1c2VkIGdlb3NwYXRpYWxcbiAqIGZpbGUgZm9ybWF0cy4gIFNlZSB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgZWFjaCBmb3JtYXQgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAYWJzdHJhY3RcbiAqIEBhcGlcbiAqL1xuXG52YXIgRmVhdHVyZUZvcm1hdCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEZlYXR1cmVGb3JtYXQoKSB7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH1cbiAgICAgKi9cbiAgICB0aGlzLmRhdGFQcm9qZWN0aW9uID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgdGhpcy5kZWZhdWx0RmVhdHVyZVByb2plY3Rpb24gPSBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBBZGRzIHRoZSBkYXRhIHByb2plY3Rpb24gdG8gdGhlIHJlYWQgb3B0aW9ucy5cbiAgICogQHBhcmFtIHtEb2N1bWVudHxFbGVtZW50fE9iamVjdHxzdHJpbmd9IHNvdXJjZSBTb3VyY2UuXG4gICAqIEBwYXJhbSB7UmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKiBAcmV0dXJuIHtSZWFkT3B0aW9uc3x1bmRlZmluZWR9IE9wdGlvbnMuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBGZWF0dXJlRm9ybWF0LnByb3RvdHlwZS5nZXRSZWFkT3B0aW9ucyA9IGZ1bmN0aW9uIChzb3VyY2UsIG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIG9wdGlvbnM7XG5cbiAgICBpZiAob3B0X29wdGlvbnMpIHtcbiAgICAgIHZhciBkYXRhUHJvamVjdGlvbiA9IG9wdF9vcHRpb25zLmRhdGFQcm9qZWN0aW9uID8gZ2V0UHJvamVjdGlvbihvcHRfb3B0aW9ucy5kYXRhUHJvamVjdGlvbikgOiB0aGlzLnJlYWRQcm9qZWN0aW9uKHNvdXJjZSk7XG5cbiAgICAgIGlmIChvcHRfb3B0aW9ucy5leHRlbnQgJiYgZGF0YVByb2plY3Rpb24gJiYgZGF0YVByb2plY3Rpb24uZ2V0VW5pdHMoKSA9PT0gVW5pdHMuVElMRV9QSVhFTFMpIHtcbiAgICAgICAgZGF0YVByb2plY3Rpb24gPSBnZXRQcm9qZWN0aW9uKGRhdGFQcm9qZWN0aW9uKTtcbiAgICAgICAgZGF0YVByb2plY3Rpb24uc2V0V29ybGRFeHRlbnQob3B0X29wdGlvbnMuZXh0ZW50KTtcbiAgICAgIH1cblxuICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgZGF0YVByb2plY3Rpb246IGRhdGFQcm9qZWN0aW9uLFxuICAgICAgICBmZWF0dXJlUHJvamVjdGlvbjogb3B0X29wdGlvbnMuZmVhdHVyZVByb2plY3Rpb25cbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYWRhcHRPcHRpb25zKG9wdGlvbnMpO1xuICB9O1xuICAvKipcbiAgICogU2V0cyB0aGUgYGRhdGFQcm9qZWN0aW9uYCBvbiB0aGUgb3B0aW9ucywgaWYgbm8gYGRhdGFQcm9qZWN0aW9uYFxuICAgKiBpcyBzZXQuXG4gICAqIEBwYXJhbSB7V3JpdGVPcHRpb25zfFJlYWRPcHRpb25zfHVuZGVmaW5lZH0gb3B0aW9uc1xuICAgKiAgICAgT3B0aW9ucy5cbiAgICogQHByb3RlY3RlZFxuICAgKiBAcmV0dXJuIHtXcml0ZU9wdGlvbnN8UmVhZE9wdGlvbnN8dW5kZWZpbmVkfVxuICAgKiAgICAgVXBkYXRlZCBvcHRpb25zLlxuICAgKi9cblxuXG4gIEZlYXR1cmVGb3JtYXQucHJvdG90eXBlLmFkYXB0T3B0aW9ucyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgcmV0dXJuIGFzc2lnbih7XG4gICAgICBkYXRhUHJvamVjdGlvbjogdGhpcy5kYXRhUHJvamVjdGlvbixcbiAgICAgIGZlYXR1cmVQcm9qZWN0aW9uOiB0aGlzLmRlZmF1bHRGZWF0dXJlUHJvamVjdGlvblxuICAgIH0sIG9wdGlvbnMpO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vRm9ybWF0VHlwZS5qc1wiKS5kZWZhdWx0fSBGb3JtYXQuXG4gICAqL1xuXG5cbiAgRmVhdHVyZUZvcm1hdC5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlYWQgYSBzaW5nbGUgZmVhdHVyZSBmcm9tIGEgc291cmNlLlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtEb2N1bWVudHxFbGVtZW50fE9iamVjdHxzdHJpbmd9IHNvdXJjZSBTb3VyY2UuXG4gICAqIEBwYXJhbSB7UmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgRmVhdHVyZUZvcm1hdC5wcm90b3R5cGUucmVhZEZlYXR1cmUgPSBmdW5jdGlvbiAoc291cmNlLCBvcHRfb3B0aW9ucykge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogUmVhZCBhbGwgZmVhdHVyZXMgZnJvbSBhIHNvdXJjZS5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7RG9jdW1lbnR8RWxlbWVudHxBcnJheUJ1ZmZlcnxPYmplY3R8c3RyaW5nfSBzb3VyY2UgU291cmNlLlxuICAgKiBAcGFyYW0ge1JlYWRPcHRpb25zPX0gb3B0X29wdGlvbnMgUmVhZCBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlPn0gRmVhdHVyZXMuXG4gICAqL1xuXG5cbiAgRmVhdHVyZUZvcm1hdC5wcm90b3R5cGUucmVhZEZlYXR1cmVzID0gZnVuY3Rpb24gKHNvdXJjZSwgb3B0X29wdGlvbnMpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlYWQgYSBzaW5nbGUgZ2VvbWV0cnkgZnJvbSBhIHNvdXJjZS5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7RG9jdW1lbnR8RWxlbWVudHxPYmplY3R8c3RyaW5nfSBzb3VyY2UgU291cmNlLlxuICAgKiBAcGFyYW0ge1JlYWRPcHRpb25zPX0gb3B0X29wdGlvbnMgUmVhZCBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IEdlb21ldHJ5LlxuICAgKi9cblxuXG4gIEZlYXR1cmVGb3JtYXQucHJvdG90eXBlLnJlYWRHZW9tZXRyeSA9IGZ1bmN0aW9uIChzb3VyY2UsIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZWFkIHRoZSBwcm9qZWN0aW9uIGZyb20gYSBzb3VyY2UuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge0RvY3VtZW50fEVsZW1lbnR8T2JqZWN0fHN0cmluZ30gc291cmNlIFNvdXJjZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IFByb2plY3Rpb24uXG4gICAqL1xuXG5cbiAgRmVhdHVyZUZvcm1hdC5wcm90b3R5cGUucmVhZFByb2plY3Rpb24gPSBmdW5jdGlvbiAoc291cmNlKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBFbmNvZGUgYSBmZWF0dXJlIGluIHRoaXMgZm9ybWF0LlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICogQHBhcmFtIHtXcml0ZU9wdGlvbnM9fSBvcHRfb3B0aW9ucyBXcml0ZSBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFJlc3VsdC5cbiAgICovXG5cblxuICBGZWF0dXJlRm9ybWF0LnByb3RvdHlwZS53cml0ZUZlYXR1cmUgPSBmdW5jdGlvbiAoZmVhdHVyZSwgb3B0X29wdGlvbnMpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEVuY29kZSBhbiBhcnJheSBvZiBmZWF0dXJlcyBpbiB0aGlzIGZvcm1hdC5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0Pn0gZmVhdHVyZXMgRmVhdHVyZXMuXG4gICAqIEBwYXJhbSB7V3JpdGVPcHRpb25zPX0gb3B0X29wdGlvbnMgV3JpdGUgb3B0aW9ucy5cbiAgICogQHJldHVybiB7c3RyaW5nfSBSZXN1bHQuXG4gICAqL1xuXG5cbiAgRmVhdHVyZUZvcm1hdC5wcm90b3R5cGUud3JpdGVGZWF0dXJlcyA9IGZ1bmN0aW9uIChmZWF0dXJlcywgb3B0X29wdGlvbnMpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFdyaXRlIGEgc2luZ2xlIGdlb21ldHJ5IGluIHRoaXMgZm9ybWF0LlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge1dyaXRlT3B0aW9ucz19IG9wdF9vcHRpb25zIFdyaXRlIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gUmVzdWx0LlxuICAgKi9cblxuXG4gIEZlYXR1cmVGb3JtYXQucHJvdG90eXBlLndyaXRlR2VvbWV0cnkgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG5cbiAgcmV0dXJuIEZlYXR1cmVGb3JtYXQ7XG59KCk7XG5cbmV4cG9ydCBkZWZhdWx0IEZlYXR1cmVGb3JtYXQ7XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gd3JpdGUgU2V0IHRvIHRydWUgZm9yIHdyaXRpbmcsIGZhbHNlIGZvciByZWFkaW5nLlxuICogQHBhcmFtIHsoV3JpdGVPcHRpb25zfFJlYWRPcHRpb25zKT19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IFRyYW5zZm9ybWVkIGdlb21ldHJ5LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1HZW9tZXRyeVdpdGhPcHRpb25zKGdlb21ldHJ5LCB3cml0ZSwgb3B0X29wdGlvbnMpIHtcbiAgdmFyIGZlYXR1cmVQcm9qZWN0aW9uID0gb3B0X29wdGlvbnMgPyBnZXRQcm9qZWN0aW9uKG9wdF9vcHRpb25zLmZlYXR1cmVQcm9qZWN0aW9uKSA6IG51bGw7XG4gIHZhciBkYXRhUHJvamVjdGlvbiA9IG9wdF9vcHRpb25zID8gZ2V0UHJvamVjdGlvbihvcHRfb3B0aW9ucy5kYXRhUHJvamVjdGlvbikgOiBudWxsO1xuICB2YXIgdHJhbnNmb3JtZWQ7XG5cbiAgaWYgKGZlYXR1cmVQcm9qZWN0aW9uICYmIGRhdGFQcm9qZWN0aW9uICYmICFlcXVpdmFsZW50UHJvamVjdGlvbihmZWF0dXJlUHJvamVjdGlvbiwgZGF0YVByb2plY3Rpb24pKSB7XG4gICAgdHJhbnNmb3JtZWQgPSAod3JpdGUgPyBnZW9tZXRyeS5jbG9uZSgpIDogZ2VvbWV0cnkpLnRyYW5zZm9ybSh3cml0ZSA/IGZlYXR1cmVQcm9qZWN0aW9uIDogZGF0YVByb2plY3Rpb24sIHdyaXRlID8gZGF0YVByb2plY3Rpb24gOiBmZWF0dXJlUHJvamVjdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgdHJhbnNmb3JtZWQgPSBnZW9tZXRyeTtcbiAgfVxuXG4gIGlmICh3cml0ZSAmJiBvcHRfb3B0aW9ucyAmJlxuICAvKiogQHR5cGUge1dyaXRlT3B0aW9uc30gKi9cbiAgb3B0X29wdGlvbnMuZGVjaW1hbHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBwb3dlcl8xID0gTWF0aC5wb3coMTAsXG4gICAgLyoqIEB0eXBlIHtXcml0ZU9wdGlvbnN9ICovXG4gICAgb3B0X29wdGlvbnMuZGVjaW1hbHMpOyAvLyBpZiBkZWNpbWFscyBvcHRpb24gb24gd3JpdGUsIHJvdW5kIGVhY2ggY29vcmRpbmF0ZSBhcHByb3ByaWF0ZWx5XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFRyYW5zZm9ybWVkIGNvb3JkaW5hdGVzLlxuICAgICAqL1xuXG4gICAgdmFyIHRyYW5zZm9ybSA9IGZ1bmN0aW9uIHRyYW5zZm9ybShjb29yZGluYXRlcykge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICBjb29yZGluYXRlc1tpXSA9IE1hdGgucm91bmQoY29vcmRpbmF0ZXNbaV0gKiBwb3dlcl8xKSAvIHBvd2VyXzE7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjb29yZGluYXRlcztcbiAgICB9O1xuXG4gICAgaWYgKHRyYW5zZm9ybWVkID09PSBnZW9tZXRyeSkge1xuICAgICAgdHJhbnNmb3JtZWQgPSBnZW9tZXRyeS5jbG9uZSgpO1xuICAgIH1cblxuICAgIHRyYW5zZm9ybWVkLmFwcGx5VHJhbnNmb3JtKHRyYW5zZm9ybSk7XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtZWQ7XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7UmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBUcmFuc2Zvcm1lZCBleHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybUV4dGVudFdpdGhPcHRpb25zKGV4dGVudCwgb3B0X29wdGlvbnMpIHtcbiAgdmFyIGZlYXR1cmVQcm9qZWN0aW9uID0gb3B0X29wdGlvbnMgPyBnZXRQcm9qZWN0aW9uKG9wdF9vcHRpb25zLmZlYXR1cmVQcm9qZWN0aW9uKSA6IG51bGw7XG4gIHZhciBkYXRhUHJvamVjdGlvbiA9IG9wdF9vcHRpb25zID8gZ2V0UHJvamVjdGlvbihvcHRfb3B0aW9ucy5kYXRhUHJvamVjdGlvbikgOiBudWxsO1xuXG4gIGlmIChmZWF0dXJlUHJvamVjdGlvbiAmJiBkYXRhUHJvamVjdGlvbiAmJiAhZXF1aXZhbGVudFByb2plY3Rpb24oZmVhdHVyZVByb2plY3Rpb24sIGRhdGFQcm9qZWN0aW9uKSkge1xuICAgIHJldHVybiB0cmFuc2Zvcm1FeHRlbnQoZXh0ZW50LCBkYXRhUHJvamVjdGlvbiwgZmVhdHVyZVByb2plY3Rpb24pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBleHRlbnQ7XG4gIH1cbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L2ludGVycG9sYXRlXG4gKi9cbmltcG9ydCB7IGJpbmFyeVNlYXJjaCB9IGZyb20gJy4uLy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGxlcnAgfSBmcm9tICcuLi8uLi9tYXRoLmpzJztcbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcmFjdGlvbiBGcmFjdGlvbi5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9kZXN0IERlc3RpbmF0aW9uLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZGltZW5zaW9uIERlc3RpbmF0aW9uIGRpbWVuc2lvbiAoZGVmYXVsdCBpcyBgMmApXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBEZXN0aW5hdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJwb2xhdGVQb2ludChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGZyYWN0aW9uLCBvcHRfZGVzdCwgb3B0X2RpbWVuc2lvbikge1xuICB2YXIgbywgdDtcbiAgdmFyIG4gPSAoZW5kIC0gb2Zmc2V0KSAvIHN0cmlkZTtcblxuICBpZiAobiA9PT0gMSkge1xuICAgIG8gPSBvZmZzZXQ7XG4gIH0gZWxzZSBpZiAobiA9PT0gMikge1xuICAgIG8gPSBvZmZzZXQ7XG4gICAgdCA9IGZyYWN0aW9uO1xuICB9IGVsc2UgaWYgKG4gIT09IDApIHtcbiAgICB2YXIgeDEgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgICB2YXIgeTEgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gICAgdmFyIGxlbmd0aF8xID0gMDtcbiAgICB2YXIgY3VtdWxhdGl2ZUxlbmd0aHMgPSBbMF07XG5cbiAgICBmb3IgKHZhciBpID0gb2Zmc2V0ICsgc3RyaWRlOyBpIDwgZW5kOyBpICs9IHN0cmlkZSkge1xuICAgICAgdmFyIHgyID0gZmxhdENvb3JkaW5hdGVzW2ldO1xuICAgICAgdmFyIHkyID0gZmxhdENvb3JkaW5hdGVzW2kgKyAxXTtcbiAgICAgIGxlbmd0aF8xICs9IE1hdGguc3FydCgoeDIgLSB4MSkgKiAoeDIgLSB4MSkgKyAoeTIgLSB5MSkgKiAoeTIgLSB5MSkpO1xuICAgICAgY3VtdWxhdGl2ZUxlbmd0aHMucHVzaChsZW5ndGhfMSk7XG4gICAgICB4MSA9IHgyO1xuICAgICAgeTEgPSB5MjtcbiAgICB9XG5cbiAgICB2YXIgdGFyZ2V0ID0gZnJhY3Rpb24gKiBsZW5ndGhfMTtcbiAgICB2YXIgaW5kZXggPSBiaW5hcnlTZWFyY2goY3VtdWxhdGl2ZUxlbmd0aHMsIHRhcmdldCk7XG5cbiAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICB0ID0gKHRhcmdldCAtIGN1bXVsYXRpdmVMZW5ndGhzWy1pbmRleCAtIDJdKSAvIChjdW11bGF0aXZlTGVuZ3Roc1staW5kZXggLSAxXSAtIGN1bXVsYXRpdmVMZW5ndGhzWy1pbmRleCAtIDJdKTtcbiAgICAgIG8gPSBvZmZzZXQgKyAoLWluZGV4IC0gMikgKiBzdHJpZGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG8gPSBvZmZzZXQgKyBpbmRleCAqIHN0cmlkZTtcbiAgICB9XG4gIH1cblxuICB2YXIgZGltZW5zaW9uID0gb3B0X2RpbWVuc2lvbiA+IDEgPyBvcHRfZGltZW5zaW9uIDogMjtcbiAgdmFyIGRlc3QgPSBvcHRfZGVzdCA/IG9wdF9kZXN0IDogbmV3IEFycmF5KGRpbWVuc2lvbik7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaW1lbnNpb247ICsraSkge1xuICAgIGRlc3RbaV0gPSBvID09PSB1bmRlZmluZWQgPyBOYU4gOiB0ID09PSB1bmRlZmluZWQgPyBmbGF0Q29vcmRpbmF0ZXNbbyArIGldIDogbGVycChmbGF0Q29vcmRpbmF0ZXNbbyArIGldLCBmbGF0Q29vcmRpbmF0ZXNbbyArIHN0cmlkZSArIGldLCB0KTtcbiAgfVxuXG4gIHJldHVybiBkZXN0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IG0gTS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZXh0cmFwb2xhdGUgRXh0cmFwb2xhdGUuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IENvb3JkaW5hdGUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVTdHJpbmdDb29yZGluYXRlQXRNKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgbSwgZXh0cmFwb2xhdGUpIHtcbiAgaWYgKGVuZCA9PSBvZmZzZXQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBjb29yZGluYXRlO1xuXG4gIGlmIChtIDwgZmxhdENvb3JkaW5hdGVzW29mZnNldCArIHN0cmlkZSAtIDFdKSB7XG4gICAgaWYgKGV4dHJhcG9sYXRlKSB7XG4gICAgICBjb29yZGluYXRlID0gZmxhdENvb3JkaW5hdGVzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgc3RyaWRlKTtcbiAgICAgIGNvb3JkaW5hdGVbc3RyaWRlIC0gMV0gPSBtO1xuICAgICAgcmV0dXJuIGNvb3JkaW5hdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSBlbHNlIGlmIChmbGF0Q29vcmRpbmF0ZXNbZW5kIC0gMV0gPCBtKSB7XG4gICAgaWYgKGV4dHJhcG9sYXRlKSB7XG4gICAgICBjb29yZGluYXRlID0gZmxhdENvb3JkaW5hdGVzLnNsaWNlKGVuZCAtIHN0cmlkZSwgZW5kKTtcbiAgICAgIGNvb3JkaW5hdGVbc3RyaWRlIC0gMV0gPSBtO1xuICAgICAgcmV0dXJuIGNvb3JkaW5hdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSAvLyBGSVhNRSB1c2UgTygxKSBzZWFyY2hcblxuXG4gIGlmIChtID09IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBzdHJpZGUgLSAxXSkge1xuICAgIHJldHVybiBmbGF0Q29vcmRpbmF0ZXMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBzdHJpZGUpO1xuICB9XG5cbiAgdmFyIGxvID0gb2Zmc2V0IC8gc3RyaWRlO1xuICB2YXIgaGkgPSBlbmQgLyBzdHJpZGU7XG5cbiAgd2hpbGUgKGxvIDwgaGkpIHtcbiAgICB2YXIgbWlkID0gbG8gKyBoaSA+PiAxO1xuXG4gICAgaWYgKG0gPCBmbGF0Q29vcmRpbmF0ZXNbKG1pZCArIDEpICogc3RyaWRlIC0gMV0pIHtcbiAgICAgIGhpID0gbWlkO1xuICAgIH0gZWxzZSB7XG4gICAgICBsbyA9IG1pZCArIDE7XG4gICAgfVxuICB9XG5cbiAgdmFyIG0wID0gZmxhdENvb3JkaW5hdGVzW2xvICogc3RyaWRlIC0gMV07XG5cbiAgaWYgKG0gPT0gbTApIHtcbiAgICByZXR1cm4gZmxhdENvb3JkaW5hdGVzLnNsaWNlKChsbyAtIDEpICogc3RyaWRlLCAobG8gLSAxKSAqIHN0cmlkZSArIHN0cmlkZSk7XG4gIH1cblxuICB2YXIgbTEgPSBmbGF0Q29vcmRpbmF0ZXNbKGxvICsgMSkgKiBzdHJpZGUgLSAxXTtcbiAgdmFyIHQgPSAobSAtIG0wKSAvIChtMSAtIG0wKTtcbiAgY29vcmRpbmF0ZSA9IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaWRlIC0gMTsgKytpKSB7XG4gICAgY29vcmRpbmF0ZS5wdXNoKGxlcnAoZmxhdENvb3JkaW5hdGVzWyhsbyAtIDEpICogc3RyaWRlICsgaV0sIGZsYXRDb29yZGluYXRlc1tsbyAqIHN0cmlkZSArIGldLCB0KSk7XG4gIH1cblxuICBjb29yZGluYXRlLnB1c2gobSk7XG4gIHJldHVybiBjb29yZGluYXRlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IG0gTS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZXh0cmFwb2xhdGUgRXh0cmFwb2xhdGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGludGVycG9sYXRlIEludGVycG9sYXRlLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb29yZGluYXRlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lU3RyaW5nc0Nvb3JkaW5hdGVBdE0oZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgbSwgZXh0cmFwb2xhdGUsIGludGVycG9sYXRlKSB7XG4gIGlmIChpbnRlcnBvbGF0ZSkge1xuICAgIHJldHVybiBsaW5lU3RyaW5nQ29vcmRpbmF0ZUF0TShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc1tlbmRzLmxlbmd0aCAtIDFdLCBzdHJpZGUsIG0sIGV4dHJhcG9sYXRlKTtcbiAgfVxuXG4gIHZhciBjb29yZGluYXRlO1xuXG4gIGlmIChtIDwgZmxhdENvb3JkaW5hdGVzW3N0cmlkZSAtIDFdKSB7XG4gICAgaWYgKGV4dHJhcG9sYXRlKSB7XG4gICAgICBjb29yZGluYXRlID0gZmxhdENvb3JkaW5hdGVzLnNsaWNlKDAsIHN0cmlkZSk7XG4gICAgICBjb29yZGluYXRlW3N0cmlkZSAtIDFdID0gbTtcbiAgICAgIHJldHVybiBjb29yZGluYXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBpZiAoZmxhdENvb3JkaW5hdGVzW2ZsYXRDb29yZGluYXRlcy5sZW5ndGggLSAxXSA8IG0pIHtcbiAgICBpZiAoZXh0cmFwb2xhdGUpIHtcbiAgICAgIGNvb3JkaW5hdGUgPSBmbGF0Q29vcmRpbmF0ZXMuc2xpY2UoZmxhdENvb3JkaW5hdGVzLmxlbmd0aCAtIHN0cmlkZSk7XG4gICAgICBjb29yZGluYXRlW3N0cmlkZSAtIDFdID0gbTtcbiAgICAgIHJldHVybiBjb29yZGluYXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kID0gZW5kc1tpXTtcblxuICAgIGlmIChvZmZzZXQgPT0gZW5kKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAobSA8IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBzdHJpZGUgLSAxXSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBlbHNlIGlmIChtIDw9IGZsYXRDb29yZGluYXRlc1tlbmQgLSAxXSkge1xuICAgICAgcmV0dXJuIGxpbmVTdHJpbmdDb29yZGluYXRlQXRNKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgbSwgZmFsc2UpO1xuICAgIH1cblxuICAgIG9mZnNldCA9IGVuZDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9MaW5lU3RyaW5nXG4gKi9cblxuXG5pbXBvcnQgR2VvbWV0cnlMYXlvdXQgZnJvbSAnLi9HZW9tZXRyeUxheW91dC5qcyc7XG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBTaW1wbGVHZW9tZXRyeSBmcm9tICcuL1NpbXBsZUdlb21ldHJ5LmpzJztcbmltcG9ydCB7IGFzc2lnbkNsb3Nlc3RQb2ludCwgbWF4U3F1YXJlZERlbHRhIH0gZnJvbSAnLi9mbGF0L2Nsb3Nlc3QuanMnO1xuaW1wb3J0IHsgY2xvc2VzdFNxdWFyZWREaXN0YW5jZVhZIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGRlZmxhdGVDb29yZGluYXRlcyB9IGZyb20gJy4vZmxhdC9kZWZsYXRlLmpzJztcbmltcG9ydCB7IGRvdWdsYXNQZXVja2VyIH0gZnJvbSAnLi9mbGF0L3NpbXBsaWZ5LmpzJztcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gJy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGZvckVhY2ggYXMgZm9yRWFjaFNlZ21lbnQgfSBmcm9tICcuL2ZsYXQvc2VnbWVudHMuanMnO1xuaW1wb3J0IHsgaW5mbGF0ZUNvb3JkaW5hdGVzIH0gZnJvbSAnLi9mbGF0L2luZmxhdGUuanMnO1xuaW1wb3J0IHsgaW50ZXJwb2xhdGVQb2ludCwgbGluZVN0cmluZ0Nvb3JkaW5hdGVBdE0gfSBmcm9tICcuL2ZsYXQvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IHsgaW50ZXJzZWN0c0xpbmVTdHJpbmcgfSBmcm9tICcuL2ZsYXQvaW50ZXJzZWN0c2V4dGVudC5qcyc7XG5pbXBvcnQgeyBsaW5lU3RyaW5nTGVuZ3RoIH0gZnJvbSAnLi9mbGF0L2xlbmd0aC5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIExpbmVzdHJpbmcgZ2VvbWV0cnkuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBMaW5lU3RyaW5nID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKExpbmVTdHJpbmcsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT58QXJyYXk8bnVtYmVyPn0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gICAqICAgICBGb3IgaW50ZXJuYWwgdXNlLCBmbGF0IGNvb3JkaW5hdGVzIGluIGNvbWJpbmF0aW9uIHdpdGggYG9wdF9sYXlvdXRgIGFyZSBhbHNvIGFjY2VwdGVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIExpbmVTdHJpbmcoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuZmxhdE1pZHBvaW50XyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmxhdE1pZHBvaW50UmV2aXNpb25fID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4RGVsdGFfID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4RGVsdGFSZXZpc2lvbl8gPSAtMTtcblxuICAgIGlmIChvcHRfbGF5b3V0ICE9PSB1bmRlZmluZWQgJiYgIUFycmF5LmlzQXJyYXkoY29vcmRpbmF0ZXNbMF0pKSB7XG4gICAgICBfdGhpcy5zZXRGbGF0Q29vcmRpbmF0ZXMob3B0X2xheW91dCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3RoaXMuc2V0Q29vcmRpbmF0ZXMoXG4gICAgICAvKiogQHR5cGUge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59ICovXG4gICAgICBjb29yZGluYXRlcywgb3B0X2xheW91dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBcHBlbmQgdGhlIHBhc3NlZCBjb29yZGluYXRlIHRvIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgbGluZXN0cmluZy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmFwcGVuZENvb3JkaW5hdGUgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZSkge1xuICAgIGlmICghdGhpcy5mbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzID0gY29vcmRpbmF0ZS5zbGljZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHRlbmQodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIGNvb3JkaW5hdGUpO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTWFrZSBhIGNvbXBsZXRlIGNvcHkgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHshTGluZVN0cmluZ30gQ2xvbmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lU3RyaW5nLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGluZVN0cmluZyA9IG5ldyBMaW5lU3RyaW5nKHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKCksIHRoaXMubGF5b3V0KTtcbiAgICBsaW5lU3RyaW5nLmFwcGx5UHJvcGVydGllcyh0aGlzKTtcbiAgICByZXR1cm4gbGluZVN0cmluZztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjbG9zZXN0UG9pbnQgQ2xvc2VzdCBwb2ludC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblNxdWFyZWREaXN0YW5jZSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmNsb3Nlc3RQb2ludFhZID0gZnVuY3Rpb24gKHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgaWYgKG1pblNxdWFyZWREaXN0YW5jZSA8IGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWSh0aGlzLmdldEV4dGVudCgpLCB4LCB5KSkge1xuICAgICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tYXhEZWx0YVJldmlzaW9uXyAhPSB0aGlzLmdldFJldmlzaW9uKCkpIHtcbiAgICAgIHRoaXMubWF4RGVsdGFfID0gTWF0aC5zcXJ0KG1heFNxdWFyZWREZWx0YSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSwgMCkpO1xuICAgICAgdGhpcy5tYXhEZWx0YVJldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXNzaWduQ2xvc2VzdFBvaW50KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHRoaXMuc3RyaWRlLCB0aGlzLm1heERlbHRhXywgZmFsc2UsIHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBlYWNoIHNlZ21lbnQsIGNhbGxpbmcgdGhlIHByb3ZpZGVkIGNhbGxiYWNrLlxuICAgKiBJZiB0aGUgY2FsbGJhY2sgcmV0dXJucyBhIHRydXRoeSB2YWx1ZSB0aGUgZnVuY3Rpb24gcmV0dXJucyB0aGF0XG4gICAqIHZhbHVlIGltbWVkaWF0ZWx5LiBPdGhlcndpc2UgdGhlIGZ1bmN0aW9uIHJldHVybnMgYGZhbHNlYC5cbiAgICpcbiAgICogQHBhcmFtIHtmdW5jdGlvbih0aGlzOiBTLCBpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUsIGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6IFR9IGNhbGxiYWNrIEZ1bmN0aW9uXG4gICAqICAgICBjYWxsZWQgZm9yIGVhY2ggc2VnbWVudC4gVGhlIGZ1bmN0aW9uIHdpbGwgcmVjZWl2ZSB0d28gYXJndW1lbnRzLCB0aGUgc3RhcnQgYW5kIGVuZCBjb29yZGluYXRlcyBvZiB0aGUgc2VnbWVudC5cbiAgICogQHJldHVybiB7VHxib29sZWFufSBWYWx1ZS5cbiAgICogQHRlbXBsYXRlIFQsU1xuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTGluZVN0cmluZy5wcm90b3R5cGUuZm9yRWFjaFNlZ21lbnQgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICByZXR1cm4gZm9yRWFjaFNlZ21lbnQodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgdGhpcy5zdHJpZGUsIGNhbGxiYWNrKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGNvb3JkaW5hdGUgYXQgYG1gIHVzaW5nIGxpbmVhciBpbnRlcnBvbGF0aW9uLCBvciBgbnVsbGAgaWYgbm9cbiAgICogc3VjaCBjb29yZGluYXRlIGV4aXN0cy5cbiAgICpcbiAgICogYG9wdF9leHRyYXBvbGF0ZWAgY29udHJvbHMgZXh0cmFwb2xhdGlvbiBiZXlvbmQgdGhlIHJhbmdlIG9mIE1zIGluIHRoZVxuICAgKiBNdWx0aUxpbmVTdHJpbmcuIElmIGBvcHRfZXh0cmFwb2xhdGVgIGlzIGB0cnVlYCB0aGVuIE1zIGxlc3MgdGhhbiB0aGUgZmlyc3RcbiAgICogTSB3aWxsIHJldHVybiB0aGUgZmlyc3QgY29vcmRpbmF0ZSBhbmQgTXMgZ3JlYXRlciB0aGFuIHRoZSBsYXN0IE0gd2lsbFxuICAgKiByZXR1cm4gdGhlIGxhc3QgY29vcmRpbmF0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IG0gTS5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2V4dHJhcG9sYXRlIEV4dHJhcG9sYXRlLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQ29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmdldENvb3JkaW5hdGVBdE0gPSBmdW5jdGlvbiAobSwgb3B0X2V4dHJhcG9sYXRlKSB7XG4gICAgaWYgKHRoaXMubGF5b3V0ICE9IEdlb21ldHJ5TGF5b3V0LlhZTSAmJiB0aGlzLmxheW91dCAhPSBHZW9tZXRyeUxheW91dC5YWVpNKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgZXh0cmFwb2xhdGUgPSBvcHRfZXh0cmFwb2xhdGUgIT09IHVuZGVmaW5lZCA/IG9wdF9leHRyYXBvbGF0ZSA6IGZhbHNlO1xuICAgIHJldHVybiBsaW5lU3RyaW5nQ29vcmRpbmF0ZUF0TSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSwgbSwgZXh0cmFwb2xhdGUpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgbGluZXN0cmluZy5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn0gQ29vcmRpbmF0ZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lU3RyaW5nLnByb3RvdHlwZS5nZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gaW5mbGF0ZUNvb3JkaW5hdGVzKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHRoaXMuc3RyaWRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgY29vcmRpbmF0ZSBhdCB0aGUgcHJvdmlkZWQgZnJhY3Rpb24gYWxvbmcgdGhlIGxpbmVzdHJpbmcuXG4gICAqIFRoZSBgZnJhY3Rpb25gIGlzIGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMSwgd2hlcmUgMCBpcyB0aGUgc3RhcnQgb2YgdGhlXG4gICAqIGxpbmVzdHJpbmcgYW5kIDEgaXMgdGhlIGVuZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyYWN0aW9uIEZyYWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9kZXN0IE9wdGlvbmFsIGNvb3JkaW5hdGUgd2hvc2UgdmFsdWVzIHdpbGxcbiAgICogICAgIGJlIG1vZGlmaWVkLiBJZiBub3QgcHJvdmlkZWQsIGEgbmV3IGNvb3JkaW5hdGUgd2lsbCBiZSByZXR1cm5lZC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb29yZGluYXRlIG9mIHRoZSBpbnRlcnBvbGF0ZWQgcG9pbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lU3RyaW5nLnByb3RvdHlwZS5nZXRDb29yZGluYXRlQXQgPSBmdW5jdGlvbiAoZnJhY3Rpb24sIG9wdF9kZXN0KSB7XG4gICAgcmV0dXJuIGludGVycG9sYXRlUG9pbnQodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgdGhpcy5zdHJpZGUsIGZyYWN0aW9uLCBvcHRfZGVzdCwgdGhpcy5zdHJpZGUpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGxpbmVzdHJpbmcgb24gcHJvamVjdGVkIHBsYW5lLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IExlbmd0aCAob24gcHJvamVjdGVkIHBsYW5lKS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmdldExlbmd0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbGluZVN0cmluZ0xlbmd0aCh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBGbGF0IG1pZHBvaW50LlxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmdldEZsYXRNaWRwb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5mbGF0TWlkcG9pbnRSZXZpc2lvbl8gIT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB0aGlzLmZsYXRNaWRwb2ludF8gPSB0aGlzLmdldENvb3JkaW5hdGVBdCgwLjUsIHRoaXMuZmxhdE1pZHBvaW50Xyk7XG4gICAgICB0aGlzLmZsYXRNaWRwb2ludFJldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5mbGF0TWlkcG9pbnRfO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge0xpbmVTdHJpbmd9IFNpbXBsaWZpZWQgTGluZVN0cmluZy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmdldFNpbXBsaWZpZWRHZW9tZXRyeUludGVybmFsID0gZnVuY3Rpb24gKHNxdWFyZWRUb2xlcmFuY2UpIHtcbiAgICB2YXIgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMubGVuZ3RoID0gZG91Z2xhc1BldWNrZXIodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgdGhpcy5zdHJpZGUsIHNxdWFyZWRUb2xlcmFuY2UsIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIDApO1xuICAgIHJldHVybiBuZXcgTGluZVN0cmluZyhzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBHZW9tZXRyeUxheW91dC5YWSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhpcyBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkgdHlwZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIEdlb21ldHJ5VHlwZS5MSU5FX1NUUklORztcbiAgfTtcbiAgLyoqXG4gICAqIFRlc3QgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgcGFzc2VkIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lU3RyaW5nLnByb3RvdHlwZS5pbnRlcnNlY3RzRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCkge1xuICAgIHJldHVybiBpbnRlcnNlY3RzTGluZVN0cmluZyh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSwgZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIGxpbmVzdHJpbmcuXG4gICAqIEBwYXJhbSB7IUFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTGluZVN0cmluZy5wcm90b3R5cGUuc2V0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB0aGlzLnNldExheW91dChvcHRfbGF5b3V0LCBjb29yZGluYXRlcywgMSk7XG5cbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIH1cblxuICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IGRlZmxhdGVDb29yZGluYXRlcyh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgY29vcmRpbmF0ZXMsIHRoaXMuc3RyaWRlKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcblxuICByZXR1cm4gTGluZVN0cmluZztcbn0oU2ltcGxlR2VvbWV0cnkpO1xuXG5leHBvcnQgZGVmYXVsdCBMaW5lU3RyaW5nOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9NdWx0aUxpbmVTdHJpbmdcbiAqL1xuXG5cbmltcG9ydCBHZW9tZXRyeUxheW91dCBmcm9tICcuL0dlb21ldHJ5TGF5b3V0LmpzJztcbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IExpbmVTdHJpbmcgZnJvbSAnLi9MaW5lU3RyaW5nLmpzJztcbmltcG9ydCBTaW1wbGVHZW9tZXRyeSBmcm9tICcuL1NpbXBsZUdlb21ldHJ5LmpzJztcbmltcG9ydCB7IGFycmF5TWF4U3F1YXJlZERlbHRhLCBhc3NpZ25DbG9zZXN0QXJyYXlQb2ludCB9IGZyb20gJy4vZmxhdC9jbG9zZXN0LmpzJztcbmltcG9ydCB7IGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWSB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBkZWZsYXRlQ29vcmRpbmF0ZXNBcnJheSB9IGZyb20gJy4vZmxhdC9kZWZsYXRlLmpzJztcbmltcG9ydCB7IGRvdWdsYXNQZXVja2VyQXJyYXkgfSBmcm9tICcuL2ZsYXQvc2ltcGxpZnkuanMnO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSAnLi4vYXJyYXkuanMnO1xuaW1wb3J0IHsgaW5mbGF0ZUNvb3JkaW5hdGVzQXJyYXkgfSBmcm9tICcuL2ZsYXQvaW5mbGF0ZS5qcyc7XG5pbXBvcnQgeyBpbnRlcnBvbGF0ZVBvaW50LCBsaW5lU3RyaW5nc0Nvb3JkaW5hdGVBdE0gfSBmcm9tICcuL2ZsYXQvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IHsgaW50ZXJzZWN0c0xpbmVTdHJpbmdBcnJheSB9IGZyb20gJy4vZmxhdC9pbnRlcnNlY3RzZXh0ZW50LmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogTXVsdGktbGluZXN0cmluZyBnZW9tZXRyeS5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIE11bHRpTGluZVN0cmluZyA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhNdWx0aUxpbmVTdHJpbmcsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT58TGluZVN0cmluZz58QXJyYXk8bnVtYmVyPn0gY29vcmRpbmF0ZXNcbiAgICogICAgIENvb3JkaW5hdGVzIG9yIExpbmVTdHJpbmcgZ2VvbWV0cmllcy4gKEZvciBpbnRlcm5hbCB1c2UsIGZsYXQgY29vcmRpbmF0ZXMgaW5cbiAgICogICAgIGNvbWJpbmF0aW9uIHdpdGggYG9wdF9sYXlvdXRgIGFuZCBgb3B0X2VuZHNgIGFyZSBhbHNvIGFjY2VwdGVkLilcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHQ9fSBvcHRfbGF5b3V0IExheW91dC5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X2VuZHMgRmxhdCBjb29yZGluYXRlIGVuZHMgZm9yIGludGVybmFsIHVzZS5cbiAgICovXG5cblxuICBmdW5jdGlvbiBNdWx0aUxpbmVTdHJpbmcoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQsIG9wdF9lbmRzKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5lbmRzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLm1heERlbHRhXyA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLm1heERlbHRhUmV2aXNpb25fID0gLTE7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShjb29yZGluYXRlc1swXSkpIHtcbiAgICAgIF90aGlzLnNldENvb3JkaW5hdGVzKFxuICAgICAgLyoqIEB0eXBlIHtBcnJheTxBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzLCBvcHRfbGF5b3V0KTtcbiAgICB9IGVsc2UgaWYgKG9wdF9sYXlvdXQgIT09IHVuZGVmaW5lZCAmJiBvcHRfZW5kcykge1xuICAgICAgX3RoaXMuc2V0RmxhdENvb3JkaW5hdGVzKG9wdF9sYXlvdXQsXG4gICAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG4gICAgICBjb29yZGluYXRlcyk7XG5cbiAgICAgIF90aGlzLmVuZHNfID0gb3B0X2VuZHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBsYXlvdXQgPSBfdGhpcy5nZXRMYXlvdXQoKTtcblxuICAgICAgdmFyIGxpbmVTdHJpbmdzID1cbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8TGluZVN0cmluZz59ICovXG4gICAgICBjb29yZGluYXRlcztcbiAgICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBbXTtcbiAgICAgIHZhciBlbmRzID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGxpbmVTdHJpbmdzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgdmFyIGxpbmVTdHJpbmcgPSBsaW5lU3RyaW5nc1tpXTtcblxuICAgICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgIGxheW91dCA9IGxpbmVTdHJpbmcuZ2V0TGF5b3V0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBleHRlbmQoZmxhdENvb3JkaW5hdGVzLCBsaW5lU3RyaW5nLmdldEZsYXRDb29yZGluYXRlcygpKTtcbiAgICAgICAgZW5kcy5wdXNoKGZsYXRDb29yZGluYXRlcy5sZW5ndGgpO1xuICAgICAgfVxuXG4gICAgICBfdGhpcy5zZXRGbGF0Q29vcmRpbmF0ZXMobGF5b3V0LCBmbGF0Q29vcmRpbmF0ZXMpO1xuXG4gICAgICBfdGhpcy5lbmRzXyA9IGVuZHM7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBcHBlbmQgdGhlIHBhc3NlZCBsaW5lc3RyaW5nIHRvIHRoZSBtdWx0aWxpbmVzdHJpbmcuXG4gICAqIEBwYXJhbSB7TGluZVN0cmluZ30gbGluZVN0cmluZyBMaW5lU3RyaW5nLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5hcHBlbmRMaW5lU3RyaW5nID0gZnVuY3Rpb24gKGxpbmVTdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IGxpbmVTdHJpbmcuZ2V0RmxhdENvb3JkaW5hdGVzKCkuc2xpY2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXh0ZW5kKHRoaXMuZmxhdENvb3JkaW5hdGVzLCBsaW5lU3RyaW5nLmdldEZsYXRDb29yZGluYXRlcygpLnNsaWNlKCkpO1xuICAgIH1cblxuICAgIHRoaXMuZW5kc18ucHVzaCh0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTWFrZSBhIGNvbXBsZXRlIGNvcHkgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHshTXVsdGlMaW5lU3RyaW5nfSBDbG9uZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG11bHRpTGluZVN0cmluZyA9IG5ldyBNdWx0aUxpbmVTdHJpbmcodGhpcy5mbGF0Q29vcmRpbmF0ZXMuc2xpY2UoKSwgdGhpcy5sYXlvdXQsIHRoaXMuZW5kc18uc2xpY2UoKSk7XG4gICAgbXVsdGlMaW5lU3RyaW5nLmFwcGx5UHJvcGVydGllcyh0aGlzKTtcbiAgICByZXR1cm4gbXVsdGlMaW5lU3RyaW5nO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNsb3Nlc3RQb2ludCBDbG9zZXN0IHBvaW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWluU3F1YXJlZERpc3RhbmNlIE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5jbG9zZXN0UG9pbnRYWSA9IGZ1bmN0aW9uICh4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSkge1xuICAgIGlmIChtaW5TcXVhcmVkRGlzdGFuY2UgPCBjbG9zZXN0U3F1YXJlZERpc3RhbmNlWFkodGhpcy5nZXRFeHRlbnQoKSwgeCwgeSkpIHtcbiAgICAgIHJldHVybiBtaW5TcXVhcmVkRGlzdGFuY2U7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWF4RGVsdGFSZXZpc2lvbl8gIT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB0aGlzLm1heERlbHRhXyA9IE1hdGguc3FydChhcnJheU1heFNxdWFyZWREZWx0YSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUsIDApKTtcbiAgICAgIHRoaXMubWF4RGVsdGFSZXZpc2lvbl8gPSB0aGlzLmdldFJldmlzaW9uKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzc2lnbkNsb3Nlc3RBcnJheVBvaW50KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgdGhpcy5tYXhEZWx0YV8sIGZhbHNlLCB4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb29yZGluYXRlIGF0IGBtYCB1c2luZyBsaW5lYXIgaW50ZXJwb2xhdGlvbiwgb3IgYG51bGxgIGlmIG5vXG4gICAqIHN1Y2ggY29vcmRpbmF0ZSBleGlzdHMuXG4gICAqXG4gICAqIGBvcHRfZXh0cmFwb2xhdGVgIGNvbnRyb2xzIGV4dHJhcG9sYXRpb24gYmV5b25kIHRoZSByYW5nZSBvZiBNcyBpbiB0aGVcbiAgICogTXVsdGlMaW5lU3RyaW5nLiBJZiBgb3B0X2V4dHJhcG9sYXRlYCBpcyBgdHJ1ZWAgdGhlbiBNcyBsZXNzIHRoYW4gdGhlIGZpcnN0XG4gICAqIE0gd2lsbCByZXR1cm4gdGhlIGZpcnN0IGNvb3JkaW5hdGUgYW5kIE1zIGdyZWF0ZXIgdGhhbiB0aGUgbGFzdCBNIHdpbGxcbiAgICogcmV0dXJuIHRoZSBsYXN0IGNvb3JkaW5hdGUuXG4gICAqXG4gICAqIGBvcHRfaW50ZXJwb2xhdGVgIGNvbnRyb2xzIGludGVycG9sYXRpb24gYmV0d2VlbiBjb25zZWN1dGl2ZSBMaW5lU3RyaW5nc1xuICAgKiB3aXRoaW4gdGhlIE11bHRpTGluZVN0cmluZy4gSWYgYG9wdF9pbnRlcnBvbGF0ZWAgaXMgYHRydWVgIHRoZSBjb29yZGluYXRlc1xuICAgKiB3aWxsIGJlIGxpbmVhcmx5IGludGVycG9sYXRlZCBiZXR3ZWVuIHRoZSBsYXN0IGNvb3JkaW5hdGUgb2Ygb25lIExpbmVTdHJpbmdcbiAgICogYW5kIHRoZSBmaXJzdCBjb29yZGluYXRlIG9mIHRoZSBuZXh0IExpbmVTdHJpbmcuICBJZiBgb3B0X2ludGVycG9sYXRlYCBpc1xuICAgKiBgZmFsc2VgIHRoZW4gdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGBudWxsYCBmb3IgTXMgZmFsbGluZyBiZXR3ZWVuXG4gICAqIExpbmVTdHJpbmdzLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gbSBNLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfZXh0cmFwb2xhdGUgRXh0cmFwb2xhdGUuIERlZmF1bHQgaXMgYGZhbHNlYC5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2ludGVycG9sYXRlIEludGVycG9sYXRlLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQ29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuZ2V0Q29vcmRpbmF0ZUF0TSA9IGZ1bmN0aW9uIChtLCBvcHRfZXh0cmFwb2xhdGUsIG9wdF9pbnRlcnBvbGF0ZSkge1xuICAgIGlmICh0aGlzLmxheW91dCAhPSBHZW9tZXRyeUxheW91dC5YWU0gJiYgdGhpcy5sYXlvdXQgIT0gR2VvbWV0cnlMYXlvdXQuWFlaTSB8fCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHZhciBleHRyYXBvbGF0ZSA9IG9wdF9leHRyYXBvbGF0ZSAhPT0gdW5kZWZpbmVkID8gb3B0X2V4dHJhcG9sYXRlIDogZmFsc2U7XG4gICAgdmFyIGludGVycG9sYXRlID0gb3B0X2ludGVycG9sYXRlICE9PSB1bmRlZmluZWQgPyBvcHRfaW50ZXJwb2xhdGUgOiBmYWxzZTtcbiAgICByZXR1cm4gbGluZVN0cmluZ3NDb29yZGluYXRlQXRNKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgbSwgZXh0cmFwb2xhdGUsIGludGVycG9sYXRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIG11bHRpbGluZXN0cmluZy5cbiAgICogQHJldHVybiB7QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj59IENvb3JkaW5hdGVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5nZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gaW5mbGF0ZUNvb3JkaW5hdGVzQXJyYXkodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZW5kc18sIHRoaXMuc3RyaWRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEVuZHMuXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5nZXRFbmRzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmVuZHNfO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBsaW5lc3RyaW5nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleC5cbiAgICogQHJldHVybiB7TGluZVN0cmluZ30gTGluZVN0cmluZy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuZ2V0TGluZVN0cmluZyA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgIGlmIChpbmRleCA8IDAgfHwgdGhpcy5lbmRzXy5sZW5ndGggPD0gaW5kZXgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgTGluZVN0cmluZyh0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZShpbmRleCA9PT0gMCA/IDAgOiB0aGlzLmVuZHNfW2luZGV4IC0gMV0sIHRoaXMuZW5kc19baW5kZXhdKSwgdGhpcy5sYXlvdXQpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBsaW5lc3RyaW5ncyBvZiB0aGlzIG11bHRpbGluZXN0cmluZy5cbiAgICogQHJldHVybiB7QXJyYXk8TGluZVN0cmluZz59IExpbmVTdHJpbmdzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5nZXRMaW5lU3RyaW5ncyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgdmFyIGVuZHMgPSB0aGlzLmVuZHNfO1xuICAgIHZhciBsYXlvdXQgPSB0aGlzLmxheW91dDtcbiAgICAvKiogQHR5cGUge0FycmF5PExpbmVTdHJpbmc+fSAqL1xuXG4gICAgdmFyIGxpbmVTdHJpbmdzID0gW107XG4gICAgdmFyIG9mZnNldCA9IDA7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBlbmQgPSBlbmRzW2ldO1xuICAgICAgdmFyIGxpbmVTdHJpbmcgPSBuZXcgTGluZVN0cmluZyhmbGF0Q29vcmRpbmF0ZXMuc2xpY2Uob2Zmc2V0LCBlbmQpLCBsYXlvdXQpO1xuICAgICAgbGluZVN0cmluZ3MucHVzaChsaW5lU3RyaW5nKTtcbiAgICAgIG9mZnNldCA9IGVuZDtcbiAgICB9XG5cbiAgICByZXR1cm4gbGluZVN0cmluZ3M7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBGbGF0IG1pZHBvaW50cy5cbiAgICovXG5cblxuICBNdWx0aUxpbmVTdHJpbmcucHJvdG90eXBlLmdldEZsYXRNaWRwb2ludHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG1pZHBvaW50cyA9IFtdO1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSB0aGlzLmZsYXRDb29yZGluYXRlcztcbiAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICB2YXIgZW5kcyA9IHRoaXMuZW5kc187XG4gICAgdmFyIHN0cmlkZSA9IHRoaXMuc3RyaWRlO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICAgIHZhciBtaWRwb2ludCA9IGludGVycG9sYXRlUG9pbnQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCAwLjUpO1xuICAgICAgZXh0ZW5kKG1pZHBvaW50cywgbWlkcG9pbnQpO1xuICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgIH1cblxuICAgIHJldHVybiBtaWRwb2ludHM7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICogQHJldHVybiB7TXVsdGlMaW5lU3RyaW5nfSBTaW1wbGlmaWVkIE11bHRpTGluZVN0cmluZy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuZ2V0U2ltcGxpZmllZEdlb21ldHJ5SW50ZXJuYWwgPSBmdW5jdGlvbiAoc3F1YXJlZFRvbGVyYW5jZSkge1xuICAgIHZhciBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzID0gW107XG4gICAgdmFyIHNpbXBsaWZpZWRFbmRzID0gW107XG4gICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcy5sZW5ndGggPSBkb3VnbGFzUGV1Y2tlckFycmF5KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgc3F1YXJlZFRvbGVyYW5jZSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgMCwgc2ltcGxpZmllZEVuZHMpO1xuICAgIHJldHVybiBuZXcgTXVsdGlMaW5lU3RyaW5nKHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZLCBzaW1wbGlmaWVkRW5kcyk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhpcyBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkgdHlwZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gR2VvbWV0cnlUeXBlLk1VTFRJX0xJTkVfU1RSSU5HO1xuICB9O1xuICAvKipcbiAgICogVGVzdCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBwYXNzZWQgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuaW50ZXJzZWN0c0V4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICByZXR1cm4gaW50ZXJzZWN0c0xpbmVTdHJpbmdBcnJheSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUsIGV4dGVudCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBtdWx0aWxpbmVzdHJpbmcuXG4gICAqIEBwYXJhbSB7IUFycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtHZW9tZXRyeUxheW91dD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5zZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uIChjb29yZGluYXRlcywgb3B0X2xheW91dCkge1xuICAgIHRoaXMuc2V0TGF5b3V0KG9wdF9sYXlvdXQsIGNvb3JkaW5hdGVzLCAyKTtcblxuICAgIGlmICghdGhpcy5mbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzID0gW107XG4gICAgfVxuXG4gICAgdmFyIGVuZHMgPSBkZWZsYXRlQ29vcmRpbmF0ZXNBcnJheSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgY29vcmRpbmF0ZXMsIHRoaXMuc3RyaWRlLCB0aGlzLmVuZHNfKTtcbiAgICB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggPSBlbmRzLmxlbmd0aCA9PT0gMCA/IDAgOiBlbmRzW2VuZHMubGVuZ3RoIC0gMV07XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG5cbiAgcmV0dXJuIE11bHRpTGluZVN0cmluZztcbn0oU2ltcGxlR2VvbWV0cnkpO1xuXG5leHBvcnQgZGVmYXVsdCBNdWx0aUxpbmVTdHJpbmc7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL011bHRpUG9pbnRcbiAqL1xuXG5cbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IFBvaW50IGZyb20gJy4vUG9pbnQuanMnO1xuaW1wb3J0IFNpbXBsZUdlb21ldHJ5IGZyb20gJy4vU2ltcGxlR2VvbWV0cnkuanMnO1xuaW1wb3J0IHsgY2xvc2VzdFNxdWFyZWREaXN0YW5jZVhZLCBjb250YWluc1hZIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGRlZmxhdGVDb29yZGluYXRlcyB9IGZyb20gJy4vZmxhdC9kZWZsYXRlLmpzJztcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gJy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGluZmxhdGVDb29yZGluYXRlcyB9IGZyb20gJy4vZmxhdC9pbmZsYXRlLmpzJztcbmltcG9ydCB7IHNxdWFyZWREaXN0YW5jZSBhcyBzcXVhcmVkRHggfSBmcm9tICcuLi9tYXRoLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogTXVsdGktcG9pbnQgZ2VvbWV0cnkuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBNdWx0aVBvaW50ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKE11bHRpUG9pbnQsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT58QXJyYXk8bnVtYmVyPn0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gICAqICAgICBGb3IgaW50ZXJuYWwgdXNlLCBmbGF0IGNvb3JkaW5hdGVzIGluIGNvbWJpbmF0aW9uIHdpdGggYG9wdF9sYXlvdXRgIGFyZSBhbHNvIGFjY2VwdGVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIE11bHRpUG9pbnQoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuXG4gICAgaWYgKG9wdF9sYXlvdXQgJiYgIUFycmF5LmlzQXJyYXkoY29vcmRpbmF0ZXNbMF0pKSB7XG4gICAgICBfdGhpcy5zZXRGbGF0Q29vcmRpbmF0ZXMob3B0X2xheW91dCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3RoaXMuc2V0Q29vcmRpbmF0ZXMoXG4gICAgICAvKiogQHR5cGUge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59ICovXG4gICAgICBjb29yZGluYXRlcywgb3B0X2xheW91dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBcHBlbmQgdGhlIHBhc3NlZCBwb2ludCB0byB0aGlzIG11bHRpcG9pbnQuXG4gICAqIEBwYXJhbSB7UG9pbnR9IHBvaW50IFBvaW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2ludC5wcm90b3R5cGUuYXBwZW5kUG9pbnQgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IHBvaW50LmdldEZsYXRDb29yZGluYXRlcygpLnNsaWNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4dGVuZCh0aGlzLmZsYXRDb29yZGluYXRlcywgcG9pbnQuZ2V0RmxhdENvb3JkaW5hdGVzKCkpO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTWFrZSBhIGNvbXBsZXRlIGNvcHkgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHshTXVsdGlQb2ludH0gQ2xvbmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNdWx0aVBvaW50LnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbXVsdGlQb2ludCA9IG5ldyBNdWx0aVBvaW50KHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKCksIHRoaXMubGF5b3V0KTtcbiAgICBtdWx0aVBvaW50LmFwcGx5UHJvcGVydGllcyh0aGlzKTtcbiAgICByZXR1cm4gbXVsdGlQb2ludDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjbG9zZXN0UG9pbnQgQ2xvc2VzdCBwb2ludC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblNxdWFyZWREaXN0YW5jZSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKi9cblxuXG4gIE11bHRpUG9pbnQucHJvdG90eXBlLmNsb3Nlc3RQb2ludFhZID0gZnVuY3Rpb24gKHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgaWYgKG1pblNxdWFyZWREaXN0YW5jZSA8IGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWSh0aGlzLmdldEV4dGVudCgpLCB4LCB5KSkge1xuICAgICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgICB9XG5cbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgdmFyIHN0cmlkZSA9IHRoaXMuc3RyaWRlO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZmxhdENvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyBpICs9IHN0cmlkZSkge1xuICAgICAgdmFyIHNxdWFyZWREaXN0YW5jZSA9IHNxdWFyZWREeCh4LCB5LCBmbGF0Q29vcmRpbmF0ZXNbaV0sIGZsYXRDb29yZGluYXRlc1tpICsgMV0pO1xuXG4gICAgICBpZiAoc3F1YXJlZERpc3RhbmNlIDwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgICAgIG1pblNxdWFyZWREaXN0YW5jZSA9IHNxdWFyZWREaXN0YW5jZTtcblxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN0cmlkZTsgKytqKSB7XG4gICAgICAgICAgY2xvc2VzdFBvaW50W2pdID0gZmxhdENvb3JkaW5hdGVzW2kgKyBqXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNsb3Nlc3RQb2ludC5sZW5ndGggPSBzdHJpZGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIG11bHRpcG9pbnQuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IENvb3JkaW5hdGVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2ludC5wcm90b3R5cGUuZ2V0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGluZmxhdGVDb29yZGluYXRlcyh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHBvaW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleC5cbiAgICogQHJldHVybiB7UG9pbnR9IFBvaW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2ludC5wcm90b3R5cGUuZ2V0UG9pbnQgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICB2YXIgbiA9ICF0aGlzLmZsYXRDb29yZGluYXRlcyA/IDAgOiB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggLyB0aGlzLnN0cmlkZTtcblxuICAgIGlmIChpbmRleCA8IDAgfHwgbiA8PSBpbmRleCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZShpbmRleCAqIHRoaXMuc3RyaWRlLCAoaW5kZXggKyAxKSAqIHRoaXMuc3RyaWRlKSwgdGhpcy5sYXlvdXQpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBwb2ludHMgb2YgdGhpcyBtdWx0aXBvaW50LlxuICAgKiBAcmV0dXJuIHtBcnJheTxQb2ludD59IFBvaW50cy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpUG9pbnQucHJvdG90eXBlLmdldFBvaW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgdmFyIGxheW91dCA9IHRoaXMubGF5b3V0O1xuICAgIHZhciBzdHJpZGUgPSB0aGlzLnN0cmlkZTtcbiAgICAvKiogQHR5cGUge0FycmF5PFBvaW50Pn0gKi9cblxuICAgIHZhciBwb2ludHMgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZsYXRDb29yZGluYXRlcy5sZW5ndGg7IGkgPCBpaTsgaSArPSBzdHJpZGUpIHtcbiAgICAgIHZhciBwb2ludCA9IG5ldyBQb2ludChmbGF0Q29vcmRpbmF0ZXMuc2xpY2UoaSwgaSArIHN0cmlkZSksIGxheW91dCk7XG4gICAgICBwb2ludHMucHVzaChwb2ludCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvaW50cztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdHlwZSBvZiB0aGlzIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeSB0eXBlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2ludC5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gR2VvbWV0cnlUeXBlLk1VTFRJX1BPSU5UO1xuICB9O1xuICAvKipcbiAgICogVGVzdCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBwYXNzZWQgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpUG9pbnQucHJvdG90eXBlLmludGVyc2VjdHNFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZmxhdENvb3JkaW5hdGVzO1xuICAgIHZhciBzdHJpZGUgPSB0aGlzLnN0cmlkZTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZsYXRDb29yZGluYXRlcy5sZW5ndGg7IGkgPCBpaTsgaSArPSBzdHJpZGUpIHtcbiAgICAgIHZhciB4ID0gZmxhdENvb3JkaW5hdGVzW2ldO1xuICAgICAgdmFyIHkgPSBmbGF0Q29vcmRpbmF0ZXNbaSArIDFdO1xuXG4gICAgICBpZiAoY29udGFpbnNYWShleHRlbnQsIHgsIHkpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIG11bHRpcG9pbnQuXG4gICAqIEBwYXJhbSB7IUFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2ludC5wcm90b3R5cGUuc2V0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB0aGlzLnNldExheW91dChvcHRfbGF5b3V0LCBjb29yZGluYXRlcywgMSk7XG5cbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIH1cblxuICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IGRlZmxhdGVDb29yZGluYXRlcyh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgY29vcmRpbmF0ZXMsIHRoaXMuc3RyaWRlKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcblxuICByZXR1cm4gTXVsdGlQb2ludDtcbn0oU2ltcGxlR2VvbWV0cnkpO1xuXG5leHBvcnQgZGVmYXVsdCBNdWx0aVBvaW50OyIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL2ZsYXQvY2VudGVyXG4gKi9cbmltcG9ydCB7IGNyZWF0ZUVtcHR5LCBjcmVhdGVPclVwZGF0ZUZyb21GbGF0Q29vcmRpbmF0ZXMgfSBmcm9tICcuLi8uLi9leHRlbnQuanMnO1xuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBFbmRzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gRmxhdCBjZW50ZXJzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5nc3MoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUpIHtcbiAgdmFyIGZsYXRDZW50ZXJzID0gW107XG4gIHZhciBleHRlbnQgPSBjcmVhdGVFbXB0eSgpO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHNzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kcyA9IGVuZHNzW2ldO1xuICAgIGV4dGVudCA9IGNyZWF0ZU9yVXBkYXRlRnJvbUZsYXRDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc1swXSwgc3RyaWRlKTtcbiAgICBmbGF0Q2VudGVycy5wdXNoKChleHRlbnRbMF0gKyBleHRlbnRbMl0pIC8gMiwgKGV4dGVudFsxXSArIGV4dGVudFszXSkgLyAyKTtcbiAgICBvZmZzZXQgPSBlbmRzW2VuZHMubGVuZ3RoIC0gMV07XG4gIH1cblxuICByZXR1cm4gZmxhdENlbnRlcnM7XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL011bHRpUG9seWdvblxuICovXG5cblxuaW1wb3J0IEdlb21ldHJ5TGF5b3V0IGZyb20gJy4vR2VvbWV0cnlMYXlvdXQuanMnO1xuaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICcuL0dlb21ldHJ5VHlwZS5qcyc7XG5pbXBvcnQgTXVsdGlQb2ludCBmcm9tICcuL011bHRpUG9pbnQuanMnO1xuaW1wb3J0IFBvbHlnb24gZnJvbSAnLi9Qb2x5Z29uLmpzJztcbmltcG9ydCBTaW1wbGVHZW9tZXRyeSBmcm9tICcuL1NpbXBsZUdlb21ldHJ5LmpzJztcbmltcG9ydCB7IGFzc2lnbkNsb3Nlc3RNdWx0aUFycmF5UG9pbnQsIG11bHRpQXJyYXlNYXhTcXVhcmVkRGVsdGEgfSBmcm9tICcuL2ZsYXQvY2xvc2VzdC5qcyc7XG5pbXBvcnQgeyBjbG9zZXN0U3F1YXJlZERpc3RhbmNlWFkgfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZGVmbGF0ZU11bHRpQ29vcmRpbmF0ZXNBcnJheSB9IGZyb20gJy4vZmxhdC9kZWZsYXRlLmpzJztcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gJy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGdldEludGVyaW9yUG9pbnRzT2ZNdWx0aUFycmF5IH0gZnJvbSAnLi9mbGF0L2ludGVyaW9ycG9pbnQuanMnO1xuaW1wb3J0IHsgaW5mbGF0ZU11bHRpQ29vcmRpbmF0ZXNBcnJheSB9IGZyb20gJy4vZmxhdC9pbmZsYXRlLmpzJztcbmltcG9ydCB7IGludGVyc2VjdHNMaW5lYXJSaW5nTXVsdGlBcnJheSB9IGZyb20gJy4vZmxhdC9pbnRlcnNlY3RzZXh0ZW50LmpzJztcbmltcG9ydCB7IGxpbmVhclJpbmdzc0FyZU9yaWVudGVkLCBvcmllbnRMaW5lYXJSaW5nc0FycmF5IH0gZnJvbSAnLi9mbGF0L29yaWVudC5qcyc7XG5pbXBvcnQgeyBsaW5lYXJSaW5nc3MgYXMgbGluZWFyUmluZ3NzQXJlYSB9IGZyb20gJy4vZmxhdC9hcmVhLmpzJztcbmltcG9ydCB7IGxpbmVhclJpbmdzcyBhcyBsaW5lYXJSaW5nc3NDZW50ZXIgfSBmcm9tICcuL2ZsYXQvY2VudGVyLmpzJztcbmltcG9ydCB7IGxpbmVhclJpbmdzc0NvbnRhaW5zWFkgfSBmcm9tICcuL2ZsYXQvY29udGFpbnMuanMnO1xuaW1wb3J0IHsgcXVhbnRpemVNdWx0aUFycmF5IH0gZnJvbSAnLi9mbGF0L3NpbXBsaWZ5LmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogTXVsdGktcG9seWdvbiBnZW9tZXRyeS5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIE11bHRpUG9seWdvbiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhNdWx0aVBvbHlnb24sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PEFycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+fFBvbHlnb24+fEFycmF5PG51bWJlcj59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgKiAgICAgRm9yIGludGVybmFsIHVzZSwgZmxhdCBjb29yZGluYXRlcyBpbiBjb21iaW5hdGlvbiB3aXRoIGBvcHRfbGF5b3V0YCBhbmQgYG9wdF9lbmRzc2AgYXJlIGFsc28gYWNjZXB0ZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9HZW9tZXRyeUxheW91dC5qc1wiKS5kZWZhdWx0PX0gb3B0X2xheW91dCBMYXlvdXQuXG4gICAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj49fSBvcHRfZW5kc3MgQXJyYXkgb2YgZW5kcyBmb3IgaW50ZXJuYWwgdXNlIHdpdGggZmxhdCBjb29yZGluYXRlcy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBNdWx0aVBvbHlnb24oY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQsIG9wdF9lbmRzcykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PEFycmF5PG51bWJlcj4+fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cblxuICAgIF90aGlzLmVuZHNzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmZsYXRJbnRlcmlvclBvaW50c1JldmlzaW9uXyA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5mbGF0SW50ZXJpb3JQb2ludHNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5tYXhEZWx0YV8gPSAtMTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5tYXhEZWx0YVJldmlzaW9uXyA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLm9yaWVudGVkUmV2aXNpb25fID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIF90aGlzLm9yaWVudGVkRmxhdENvb3JkaW5hdGVzXyA9IG51bGw7XG5cbiAgICBpZiAoIW9wdF9lbmRzcyAmJiAhQXJyYXkuaXNBcnJheShjb29yZGluYXRlc1swXSkpIHtcbiAgICAgIHZhciBsYXlvdXQgPSBfdGhpcy5nZXRMYXlvdXQoKTtcblxuICAgICAgdmFyIHBvbHlnb25zID1cbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8UG9seWdvbj59ICovXG4gICAgICBjb29yZGluYXRlcztcbiAgICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBbXTtcbiAgICAgIHZhciBlbmRzcyA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBwb2x5Z29ucy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIHZhciBwb2x5Z29uID0gcG9seWdvbnNbaV07XG5cbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICBsYXlvdXQgPSBwb2x5Z29uLmdldExheW91dCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG9mZnNldCA9IGZsYXRDb29yZGluYXRlcy5sZW5ndGg7XG4gICAgICAgIHZhciBlbmRzID0gcG9seWdvbi5nZXRFbmRzKCk7XG5cbiAgICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0gZW5kcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgICAgICAgZW5kc1tqXSArPSBvZmZzZXQ7XG4gICAgICAgIH1cblxuICAgICAgICBleHRlbmQoZmxhdENvb3JkaW5hdGVzLCBwb2x5Z29uLmdldEZsYXRDb29yZGluYXRlcygpKTtcbiAgICAgICAgZW5kc3MucHVzaChlbmRzKTtcbiAgICAgIH1cblxuICAgICAgb3B0X2xheW91dCA9IGxheW91dDtcbiAgICAgIGNvb3JkaW5hdGVzID0gZmxhdENvb3JkaW5hdGVzO1xuICAgICAgb3B0X2VuZHNzID0gZW5kc3M7XG4gICAgfVxuXG4gICAgaWYgKG9wdF9sYXlvdXQgIT09IHVuZGVmaW5lZCAmJiBvcHRfZW5kc3MpIHtcbiAgICAgIF90aGlzLnNldEZsYXRDb29yZGluYXRlcyhvcHRfbGF5b3V0LFxuICAgICAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuICAgICAgY29vcmRpbmF0ZXMpO1xuXG4gICAgICBfdGhpcy5lbmRzc18gPSBvcHRfZW5kc3M7XG4gICAgfSBlbHNlIHtcbiAgICAgIF90aGlzLnNldENvb3JkaW5hdGVzKFxuICAgICAgLyoqIEB0eXBlIHtBcnJheTxBcnJheTxBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pj59ICovXG4gICAgICBjb29yZGluYXRlcywgb3B0X2xheW91dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBcHBlbmQgdGhlIHBhc3NlZCBwb2x5Z29uIHRvIHRoaXMgbXVsdGlwb2x5Z29uLlxuICAgKiBAcGFyYW0ge1BvbHlnb259IHBvbHlnb24gUG9seWdvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuYXBwZW5kUG9seWdvbiA9IGZ1bmN0aW9uIChwb2x5Z29uKSB7XG4gICAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuICAgIHZhciBlbmRzO1xuXG4gICAgaWYgKCF0aGlzLmZsYXRDb29yZGluYXRlcykge1xuICAgICAgdGhpcy5mbGF0Q29vcmRpbmF0ZXMgPSBwb2x5Z29uLmdldEZsYXRDb29yZGluYXRlcygpLnNsaWNlKCk7XG4gICAgICBlbmRzID0gcG9seWdvbi5nZXRFbmRzKCkuc2xpY2UoKTtcbiAgICAgIHRoaXMuZW5kc3NfLnB1c2goKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIG9mZnNldCA9IHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICAgIGV4dGVuZCh0aGlzLmZsYXRDb29yZGluYXRlcywgcG9seWdvbi5nZXRGbGF0Q29vcmRpbmF0ZXMoKSk7XG4gICAgICBlbmRzID0gcG9seWdvbi5nZXRFbmRzKCkuc2xpY2UoKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIGVuZHNbaV0gKz0gb2Zmc2V0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZW5kc3NfLnB1c2goZW5kcyk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBNYWtlIGEgY29tcGxldGUgY29weSBvZiB0aGUgZ2VvbWV0cnkuXG4gICAqIEByZXR1cm4geyFNdWx0aVBvbHlnb259IENsb25lLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGVuID0gdGhpcy5lbmRzc18ubGVuZ3RoO1xuICAgIHZhciBuZXdFbmRzcyA9IG5ldyBBcnJheShsZW4pO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgbmV3RW5kc3NbaV0gPSB0aGlzLmVuZHNzX1tpXS5zbGljZSgpO1xuICAgIH1cblxuICAgIHZhciBtdWx0aVBvbHlnb24gPSBuZXcgTXVsdGlQb2x5Z29uKHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKCksIHRoaXMubGF5b3V0LCBuZXdFbmRzcyk7XG4gICAgbXVsdGlQb2x5Z29uLmFwcGx5UHJvcGVydGllcyh0aGlzKTtcbiAgICByZXR1cm4gbXVsdGlQb2x5Z29uO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNsb3Nlc3RQb2ludCBDbG9zZXN0IHBvaW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWluU3F1YXJlZERpc3RhbmNlIE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5jbG9zZXN0UG9pbnRYWSA9IGZ1bmN0aW9uICh4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSkge1xuICAgIGlmIChtaW5TcXVhcmVkRGlzdGFuY2UgPCBjbG9zZXN0U3F1YXJlZERpc3RhbmNlWFkodGhpcy5nZXRFeHRlbnQoKSwgeCwgeSkpIHtcbiAgICAgIHJldHVybiBtaW5TcXVhcmVkRGlzdGFuY2U7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWF4RGVsdGFSZXZpc2lvbl8gIT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB0aGlzLm1heERlbHRhXyA9IE1hdGguc3FydChtdWx0aUFycmF5TWF4U3F1YXJlZERlbHRhKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNzXywgdGhpcy5zdHJpZGUsIDApKTtcbiAgICAgIHRoaXMubWF4RGVsdGFSZXZpc2lvbl8gPSB0aGlzLmdldFJldmlzaW9uKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzc2lnbkNsb3Nlc3RNdWx0aUFycmF5UG9pbnQodGhpcy5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpLCAwLCB0aGlzLmVuZHNzXywgdGhpcy5zdHJpZGUsIHRoaXMubWF4RGVsdGFfLCB0cnVlLCB4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBDb250YWlucyAoeCwgeSkuXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5jb250YWluc1hZID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICByZXR1cm4gbGluZWFyUmluZ3NzQ29udGFpbnNYWSh0aGlzLmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzKCksIDAsIHRoaXMuZW5kc3NfLCB0aGlzLnN0cmlkZSwgeCwgeSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGFyZWEgb2YgdGhlIG11bHRpcG9seWdvbiBvbiBwcm9qZWN0ZWQgcGxhbmUuXG4gICAqIEByZXR1cm4ge251bWJlcn0gQXJlYSAob24gcHJvamVjdGVkIHBsYW5lKS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuZ2V0QXJlYSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbGluZWFyUmluZ3NzQXJlYSh0aGlzLmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzKCksIDAsIHRoaXMuZW5kc3NfLCB0aGlzLnN0cmlkZSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGNvb3JkaW5hdGUgYXJyYXkgZm9yIHRoaXMgZ2VvbWV0cnkuICBUaGlzIGFycmF5IGhhcyB0aGUgc3RydWN0dXJlXG4gICAqIG9mIGEgR2VvSlNPTiBjb29yZGluYXRlIGFycmF5IGZvciBtdWx0aS1wb2x5Z29ucy5cbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JpZ2h0IE9yaWVudCBjb29yZGluYXRlcyBhY2NvcmRpbmcgdG8gdGhlIHJpZ2h0LWhhbmRcbiAgICogICAgIHJ1bGUgKGNvdW50ZXItY2xvY2t3aXNlIGZvciBleHRlcmlvciBhbmQgY2xvY2t3aXNlIGZvciBpbnRlcmlvciByaW5ncykuXG4gICAqICAgICBJZiBgZmFsc2VgLCBjb29yZGluYXRlcyB3aWxsIGJlIG9yaWVudGVkIGFjY29yZGluZyB0byB0aGUgbGVmdC1oYW5kIHJ1bGVcbiAgICogICAgIChjbG9ja3dpc2UgZm9yIGV4dGVyaW9yIGFuZCBjb3VudGVyLWNsb2Nrd2lzZSBmb3IgaW50ZXJpb3IgcmluZ3MpLlxuICAgKiAgICAgQnkgZGVmYXVsdCwgY29vcmRpbmF0ZSBvcmllbnRhdGlvbiB3aWxsIGRlcGVuZCBvbiBob3cgdGhlIGdlb21ldHJ5IHdhc1xuICAgKiAgICAgY29uc3RydWN0ZWQuXG4gICAqIEByZXR1cm4ge0FycmF5PEFycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+Pn0gQ29vcmRpbmF0ZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNdWx0aVBvbHlnb24ucHJvdG90eXBlLmdldENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKG9wdF9yaWdodCkge1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXM7XG5cbiAgICBpZiAob3B0X3JpZ2h0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKS5zbGljZSgpO1xuICAgICAgb3JpZW50TGluZWFyUmluZ3NBcnJheShmbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZW5kc3NfLCB0aGlzLnN0cmlkZSwgb3B0X3JpZ2h0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIGluZmxhdGVNdWx0aUNvb3JkaW5hdGVzQXJyYXkoZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNzXywgdGhpcy5zdHJpZGUpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IEVuZHNzLlxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuZ2V0RW5kc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZW5kc3NfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gRmxhdCBpbnRlcmlvciBwb2ludHMuXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5nZXRGbGF0SW50ZXJpb3JQb2ludHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuZmxhdEludGVyaW9yUG9pbnRzUmV2aXNpb25fICE9IHRoaXMuZ2V0UmV2aXNpb24oKSkge1xuICAgICAgdmFyIGZsYXRDZW50ZXJzID0gbGluZWFyUmluZ3NzQ2VudGVyKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNzXywgdGhpcy5zdHJpZGUpO1xuICAgICAgdGhpcy5mbGF0SW50ZXJpb3JQb2ludHNfID0gZ2V0SW50ZXJpb3JQb2ludHNPZk11bHRpQXJyYXkodGhpcy5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpLCAwLCB0aGlzLmVuZHNzXywgdGhpcy5zdHJpZGUsIGZsYXRDZW50ZXJzKTtcbiAgICAgIHRoaXMuZmxhdEludGVyaW9yUG9pbnRzUmV2aXNpb25fID0gdGhpcy5nZXRSZXZpc2lvbigpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZsYXRJbnRlcmlvclBvaW50c187XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGludGVyaW9yIHBvaW50cyBhcyB7QGxpbmsgbW9kdWxlOm9sL2dlb20vTXVsdGlQb2ludCBtdWx0aXBvaW50fS5cbiAgICogQHJldHVybiB7TXVsdGlQb2ludH0gSW50ZXJpb3IgcG9pbnRzIGFzIFhZTSBjb29yZGluYXRlcywgd2hlcmUgTSBpc1xuICAgKiB0aGUgbGVuZ3RoIG9mIHRoZSBob3Jpem9udGFsIGludGVyc2VjdGlvbiB0aGF0IHRoZSBwb2ludCBiZWxvbmdzIHRvLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5nZXRJbnRlcmlvclBvaW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbmV3IE11bHRpUG9pbnQodGhpcy5nZXRGbGF0SW50ZXJpb3JQb2ludHMoKS5zbGljZSgpLCBHZW9tZXRyeUxheW91dC5YWU0pO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gT3JpZW50ZWQgZmxhdCBjb29yZGluYXRlcy5cbiAgICovXG5cblxuICBNdWx0aVBvbHlnb24ucHJvdG90eXBlLmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLm9yaWVudGVkUmV2aXNpb25fICE9IHRoaXMuZ2V0UmV2aXNpb24oKSkge1xuICAgICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZmxhdENvb3JkaW5hdGVzO1xuXG4gICAgICBpZiAobGluZWFyUmluZ3NzQXJlT3JpZW50ZWQoZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNzXywgdGhpcy5zdHJpZGUpKSB7XG4gICAgICAgIHRoaXMub3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXNfID0gZmxhdENvb3JkaW5hdGVzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc18gPSBmbGF0Q29vcmRpbmF0ZXMuc2xpY2UoKTtcbiAgICAgICAgdGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc18ubGVuZ3RoID0gb3JpZW50TGluZWFyUmluZ3NBcnJheSh0aGlzLm9yaWVudGVkRmxhdENvb3JkaW5hdGVzXywgMCwgdGhpcy5lbmRzc18sIHRoaXMuc3RyaWRlKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5vcmllbnRlZFJldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc187XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICogQHJldHVybiB7TXVsdGlQb2x5Z29ufSBTaW1wbGlmaWVkIE11bHRpUG9seWdvbi5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuZ2V0U2ltcGxpZmllZEdlb21ldHJ5SW50ZXJuYWwgPSBmdW5jdGlvbiAoc3F1YXJlZFRvbGVyYW5jZSkge1xuICAgIHZhciBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzID0gW107XG4gICAgdmFyIHNpbXBsaWZpZWRFbmRzcyA9IFtdO1xuICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMubGVuZ3RoID0gcXVhbnRpemVNdWx0aUFycmF5KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNzXywgdGhpcy5zdHJpZGUsIE1hdGguc3FydChzcXVhcmVkVG9sZXJhbmNlKSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgMCwgc2ltcGxpZmllZEVuZHNzKTtcbiAgICByZXR1cm4gbmV3IE11bHRpUG9seWdvbihzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBHZW9tZXRyeUxheW91dC5YWSwgc2ltcGxpZmllZEVuZHNzKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgcG9seWdvbiBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kZXguXG4gICAqIEByZXR1cm4ge1BvbHlnb259IFBvbHlnb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNdWx0aVBvbHlnb24ucHJvdG90eXBlLmdldFBvbHlnb24gPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICBpZiAoaW5kZXggPCAwIHx8IHRoaXMuZW5kc3NfLmxlbmd0aCA8PSBpbmRleCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIG9mZnNldDtcblxuICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgb2Zmc2V0ID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHByZXZFbmRzID0gdGhpcy5lbmRzc19baW5kZXggLSAxXTtcbiAgICAgIG9mZnNldCA9IHByZXZFbmRzW3ByZXZFbmRzLmxlbmd0aCAtIDFdO1xuICAgIH1cblxuICAgIHZhciBlbmRzID0gdGhpcy5lbmRzc19baW5kZXhdLnNsaWNlKCk7XG4gICAgdmFyIGVuZCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcblxuICAgIGlmIChvZmZzZXQgIT09IDApIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICBlbmRzW2ldIC09IG9mZnNldDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFBvbHlnb24odGhpcy5mbGF0Q29vcmRpbmF0ZXMuc2xpY2Uob2Zmc2V0LCBlbmQpLCB0aGlzLmxheW91dCwgZW5kcyk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHBvbHlnb25zIG9mIHRoaXMgbXVsdGlwb2x5Z29uLlxuICAgKiBAcmV0dXJuIHtBcnJheTxQb2x5Z29uPn0gUG9seWdvbnMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNdWx0aVBvbHlnb24ucHJvdG90eXBlLmdldFBvbHlnb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBsYXlvdXQgPSB0aGlzLmxheW91dDtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgdmFyIGVuZHNzID0gdGhpcy5lbmRzc187XG4gICAgdmFyIHBvbHlnb25zID0gW107XG4gICAgdmFyIG9mZnNldCA9IDA7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgZW5kcyA9IGVuZHNzW2ldLnNsaWNlKCk7XG4gICAgICB2YXIgZW5kID0gZW5kc1tlbmRzLmxlbmd0aCAtIDFdO1xuXG4gICAgICBpZiAob2Zmc2V0ICE9PSAwKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwLCBqaiA9IGVuZHMubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgICAgICAgIGVuZHNbal0gLT0gb2Zmc2V0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBwb2x5Z29uID0gbmV3IFBvbHlnb24oZmxhdENvb3JkaW5hdGVzLnNsaWNlKG9mZnNldCwgZW5kKSwgbGF5b3V0LCBlbmRzKTtcbiAgICAgIHBvbHlnb25zLnB1c2gocG9seWdvbik7XG4gICAgICBvZmZzZXQgPSBlbmQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvbHlnb25zO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB0eXBlIG9mIHRoaXMgZ2VvbWV0cnkuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vR2VvbWV0cnlUeXBlLmpzXCIpLmRlZmF1bHR9IEdlb21ldHJ5IHR5cGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNdWx0aVBvbHlnb24ucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIEdlb21ldHJ5VHlwZS5NVUxUSV9QT0xZR09OO1xuICB9O1xuICAvKipcbiAgICogVGVzdCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBwYXNzZWQgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuaW50ZXJzZWN0c0V4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICByZXR1cm4gaW50ZXJzZWN0c0xpbmVhclJpbmdNdWx0aUFycmF5KHRoaXMuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKSwgMCwgdGhpcy5lbmRzc18sIHRoaXMuc3RyaWRlLCBleHRlbnQpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBjb29yZGluYXRlcyBvZiB0aGUgbXVsdGlwb2x5Z29uLlxuICAgKiBAcGFyYW0geyFBcnJheTxBcnJheTxBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pj59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5zZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uIChjb29yZGluYXRlcywgb3B0X2xheW91dCkge1xuICAgIHRoaXMuc2V0TGF5b3V0KG9wdF9sYXlvdXQsIGNvb3JkaW5hdGVzLCAzKTtcblxuICAgIGlmICghdGhpcy5mbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzID0gW107XG4gICAgfVxuXG4gICAgdmFyIGVuZHNzID0gZGVmbGF0ZU11bHRpQ29vcmRpbmF0ZXNBcnJheSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgY29vcmRpbmF0ZXMsIHRoaXMuc3RyaWRlLCB0aGlzLmVuZHNzXyk7XG5cbiAgICBpZiAoZW5kc3MubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbGFzdEVuZHMgPSBlbmRzc1tlbmRzcy5sZW5ndGggLSAxXTtcbiAgICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IGxhc3RFbmRzLmxlbmd0aCA9PT0gMCA/IDAgOiBsYXN0RW5kc1tsYXN0RW5kcy5sZW5ndGggLSAxXTtcbiAgICB9XG5cbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcblxuICByZXR1cm4gTXVsdGlQb2x5Z29uO1xufShTaW1wbGVHZW9tZXRyeSk7XG5cbmV4cG9ydCBkZWZhdWx0IE11bHRpUG9seWdvbjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL0ZlYXR1cmVcbiAqL1xuaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICcuLi9nZW9tL0dlb21ldHJ5VHlwZS5qcyc7XG5pbXBvcnQgeyBjb21wb3NlIGFzIGNvbXBvc2VUcmFuc2Zvcm0sIGNyZWF0ZSBhcyBjcmVhdGVUcmFuc2Zvcm0gfSBmcm9tICcuLi90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHsgY3JlYXRlT3JVcGRhdGVGcm9tQ29vcmRpbmF0ZSwgY3JlYXRlT3JVcGRhdGVGcm9tRmxhdENvb3JkaW5hdGVzLCBnZXRDZW50ZXIsIGdldEhlaWdodCB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tICcuLi9hcnJheS5qcyc7XG5pbXBvcnQgeyBnZXRJbnRlcmlvclBvaW50T2ZBcnJheSwgZ2V0SW50ZXJpb3JQb2ludHNPZk11bHRpQXJyYXkgfSBmcm9tICcuLi9nZW9tL2ZsYXQvaW50ZXJpb3Jwb2ludC5qcyc7XG5pbXBvcnQgeyBnZXQgYXMgZ2V0UHJvamVjdGlvbiB9IGZyb20gJy4uL3Byb2ouanMnO1xuaW1wb3J0IHsgaW50ZXJwb2xhdGVQb2ludCB9IGZyb20gJy4uL2dlb20vZmxhdC9pbnRlcnBvbGF0ZS5qcyc7XG5pbXBvcnQgeyBsaW5lYXJSaW5nc3MgYXMgbGluZWFyUmluZ3NzQ2VudGVyIH0gZnJvbSAnLi4vZ2VvbS9mbGF0L2NlbnRlci5qcyc7XG5pbXBvcnQgeyB0cmFuc2Zvcm0yRCB9IGZyb20gJy4uL2dlb20vZmxhdC90cmFuc2Zvcm0uanMnO1xuLyoqXG4gKiBAdHlwZSB7aW1wb3J0KFwiLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX1cbiAqL1xuXG52YXIgdG1wVHJhbnNmb3JtID0gY3JlYXRlVHJhbnNmb3JtKCk7XG4vKipcbiAqIExpZ2h0d2VpZ2h0LCByZWFkLW9ubHksIHtAbGluayBtb2R1bGU6b2wvRmVhdHVyZX5GZWF0dXJlfSBhbmQge0BsaW5rIG1vZHVsZTpvbC9nZW9tL0dlb21ldHJ5fkdlb21ldHJ5fSBsaWtlXG4gKiBzdHJ1Y3R1cmUsIG9wdGltaXplZCBmb3IgdmVjdG9yIHRpbGUgcmVuZGVyaW5nIGFuZCBzdHlsaW5nLiBHZW9tZXRyeSBhY2Nlc3NcbiAqIHRocm91Z2ggdGhlIEFQSSBpcyBsaW1pdGVkIHRvIGdldHRpbmcgdGhlIHR5cGUgYW5kIGV4dGVudCBvZiB0aGUgZ2VvbWV0cnkuXG4gKi9cblxudmFyIFJlbmRlckZlYXR1cmUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0fSB0eXBlIEdlb21ldHJ5IHR5cGUuXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuIFRoZXNlIGFsd2F5cyBuZWVkXG4gICAqICAgICB0byBiZSByaWdodC1oYW5kZWQgZm9yIHBvbHlnb25zLlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj58QXJyYXk8QXJyYXk8bnVtYmVyPj59IGVuZHMgRW5kcyBvciBFbmRzcy5cbiAgICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCAqPn0gcHJvcGVydGllcyBQcm9wZXJ0aWVzLlxuICAgKiBAcGFyYW0ge251bWJlcnxzdHJpbmd8dW5kZWZpbmVkfSBpZCBGZWF0dXJlIGlkLlxuICAgKi9cbiAgZnVuY3Rpb24gUmVuZGVyRmVhdHVyZSh0eXBlLCBmbGF0Q29vcmRpbmF0ZXMsIGVuZHMsIHByb3BlcnRpZXMsIGlkKSB7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudHx1bmRlZmluZWR9XG4gICAgICovXG4gICAgdGhpcy5leHRlbnRfO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnxzdHJpbmd8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgdGhpcy5pZF8gPSBpZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgdGhpcy50eXBlXyA9IHR5cGU7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzXyA9IGZsYXRDb29yZGluYXRlcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgdGhpcy5mbGF0SW50ZXJpb3JQb2ludHNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgdGhpcy5mbGF0TWlkcG9pbnRzXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPnxBcnJheTxBcnJheTxudW1iZXI+Pn1cbiAgICAgKi9cblxuICAgIHRoaXMuZW5kc18gPSBlbmRzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsICo+fVxuICAgICAqL1xuXG4gICAgdGhpcy5wcm9wZXJ0aWVzXyA9IHByb3BlcnRpZXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCBhIGZlYXR1cmUgcHJvcGVydHkgYnkgaXRzIGtleS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXlcbiAgICogQHJldHVybiB7Kn0gVmFsdWUgZm9yIHRoZSByZXF1ZXN0ZWQga2V5LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLnByb3BlcnRpZXNfW2tleV07XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGV4dGVudCBvZiB0aGlzIGZlYXR1cmUncyBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0RXh0ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5leHRlbnRfKSB7XG4gICAgICB0aGlzLmV4dGVudF8gPSB0aGlzLnR5cGVfID09PSBHZW9tZXRyeVR5cGUuUE9JTlQgPyBjcmVhdGVPclVwZGF0ZUZyb21Db29yZGluYXRlKHRoaXMuZmxhdENvb3JkaW5hdGVzXykgOiBjcmVhdGVPclVwZGF0ZUZyb21GbGF0Q29vcmRpbmF0ZXModGhpcy5mbGF0Q29vcmRpbmF0ZXNfLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlc18ubGVuZ3RoLCAyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5leHRlbnRfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gRmxhdCBpbnRlcmlvciBwb2ludHMuXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0RmxhdEludGVyaW9yUG9pbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmZsYXRJbnRlcmlvclBvaW50c18pIHtcbiAgICAgIHZhciBmbGF0Q2VudGVyID0gZ2V0Q2VudGVyKHRoaXMuZ2V0RXh0ZW50KCkpO1xuICAgICAgdGhpcy5mbGF0SW50ZXJpb3JQb2ludHNfID0gZ2V0SW50ZXJpb3JQb2ludE9mQXJyYXkodGhpcy5mbGF0Q29vcmRpbmF0ZXNfLCAwLFxuICAgICAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuICAgICAgdGhpcy5lbmRzXywgMiwgZmxhdENlbnRlciwgMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZmxhdEludGVyaW9yUG9pbnRzXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEZsYXQgaW50ZXJpb3IgcG9pbnRzLlxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldEZsYXRJbnRlcmlvclBvaW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuZmxhdEludGVyaW9yUG9pbnRzXykge1xuICAgICAgdmFyIGZsYXRDZW50ZXJzID0gbGluZWFyUmluZ3NzQ2VudGVyKHRoaXMuZmxhdENvb3JkaW5hdGVzXywgMCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59ICovXG4gICAgICB0aGlzLmVuZHNfLCAyKTtcbiAgICAgIHRoaXMuZmxhdEludGVyaW9yUG9pbnRzXyA9IGdldEludGVyaW9yUG9pbnRzT2ZNdWx0aUFycmF5KHRoaXMuZmxhdENvb3JkaW5hdGVzXywgMCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59ICovXG4gICAgICB0aGlzLmVuZHNfLCAyLCBmbGF0Q2VudGVycyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZmxhdEludGVyaW9yUG9pbnRzXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEZsYXQgbWlkcG9pbnQuXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0RmxhdE1pZHBvaW50ID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5mbGF0TWlkcG9pbnRzXykge1xuICAgICAgdGhpcy5mbGF0TWlkcG9pbnRzXyA9IGludGVycG9sYXRlUG9pbnQodGhpcy5mbGF0Q29vcmRpbmF0ZXNfLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlc18ubGVuZ3RoLCAyLCAwLjUpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZsYXRNaWRwb2ludHNfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gRmxhdCBtaWRwb2ludHMuXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0RmxhdE1pZHBvaW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuZmxhdE1pZHBvaW50c18pIHtcbiAgICAgIHRoaXMuZmxhdE1pZHBvaW50c18gPSBbXTtcbiAgICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSB0aGlzLmZsYXRDb29yZGluYXRlc187XG4gICAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICAgIHZhciBlbmRzID1cbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIHRoaXMuZW5kc187XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICAgICAgdmFyIG1pZHBvaW50ID0gaW50ZXJwb2xhdGVQb2ludChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCAyLCAwLjUpO1xuICAgICAgICBleHRlbmQodGhpcy5mbGF0TWlkcG9pbnRzXywgbWlkcG9pbnQpO1xuICAgICAgICBvZmZzZXQgPSBlbmQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZmxhdE1pZHBvaW50c187XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGZlYXR1cmUgaWRlbnRpZmllci4gIFRoaXMgaXMgYSBzdGFibGUgaWRlbnRpZmllciBmb3IgdGhlIGZlYXR1cmUgYW5kXG4gICAqIGlzIHNldCB3aGVuIHJlYWRpbmcgZGF0YSBmcm9tIGEgcmVtb3RlIHNvdXJjZS5cbiAgICogQHJldHVybiB7bnVtYmVyfHN0cmluZ3x1bmRlZmluZWR9IElkLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0SWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaWRfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gRmxhdCBjb29yZGluYXRlcy5cbiAgICovXG5cblxuICBSZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5mbGF0Q29vcmRpbmF0ZXNfO1xuICB9O1xuICAvKipcbiAgICogRm9yIEFQSSBjb21wYXRpYmlsaXR5IHdpdGgge0BsaW5rIG1vZHVsZTpvbC9GZWF0dXJlfkZlYXR1cmV9LCB0aGlzIG1ldGhvZCBpcyB1c2VmdWwgd2hlblxuICAgKiBkZXRlcm1pbmluZyB0aGUgZ2VvbWV0cnkgdHlwZSBpbiBzdHlsZSBmdW5jdGlvbiAoc2VlIHtAbGluayAjZ2V0VHlwZX0pLlxuICAgKiBAcmV0dXJuIHtSZW5kZXJGZWF0dXJlfSBGZWF0dXJlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0R2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICogQHJldHVybiB7UmVuZGVyRmVhdHVyZX0gU2ltcGxpZmllZCBnZW9tZXRyeS5cbiAgICovXG5cblxuICBSZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5nZXRTaW1wbGlmaWVkR2VvbWV0cnkgPSBmdW5jdGlvbiAoc3F1YXJlZFRvbGVyYW5jZSkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICAvKipcbiAgICogR2V0IGEgdHJhbnNmb3JtZWQgYW5kIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiB0aGUgZ2VvbWV0cnkuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufSBbb3B0X3RyYW5zZm9ybV0gT3B0aW9uYWwgdHJhbnNmb3JtIGZ1bmN0aW9uLlxuICAgKiBAcmV0dXJuIHtSZW5kZXJGZWF0dXJlfSBTaW1wbGlmaWVkIGdlb21ldHJ5LlxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLnNpbXBsaWZ5VHJhbnNmb3JtZWQgPSBmdW5jdGlvbiAoc3F1YXJlZFRvbGVyYW5jZSwgb3B0X3RyYW5zZm9ybSkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBmZWF0dXJlIHByb3BlcnRpZXMuXG4gICAqIEByZXR1cm4ge09iamVjdDxzdHJpbmcsICo+fSBGZWF0dXJlIHByb3BlcnRpZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBSZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5nZXRQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnByb3BlcnRpZXNfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBTdHJpZGUuXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0U3RyaWRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAyO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7dW5kZWZpbmVkfVxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldFN0eWxlRnVuY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdHlwZSBvZiB0aGlzIGZlYXR1cmUncyBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkgdHlwZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudHlwZV87XG4gIH07XG4gIC8qKlxuICAgKiBUcmFuc2Zvcm0gZ2VvbWV0cnkgY29vcmRpbmF0ZXMgZnJvbSB0aWxlIHBpeGVsIHNwYWNlIHRvIHByb2plY3RlZC5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBwcm9qZWN0aW9uIFRoZSBkYXRhIHByb2plY3Rpb25cbiAgICovXG5cblxuICBSZW5kZXJGZWF0dXJlLnByb3RvdHlwZS50cmFuc2Zvcm0gPSBmdW5jdGlvbiAocHJvamVjdGlvbikge1xuICAgIHByb2plY3Rpb24gPSBnZXRQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHZhciBwaXhlbEV4dGVudCA9IHByb2plY3Rpb24uZ2V0RXh0ZW50KCk7XG4gICAgdmFyIHByb2plY3RlZEV4dGVudCA9IHByb2plY3Rpb24uZ2V0V29ybGRFeHRlbnQoKTtcblxuICAgIGlmIChwaXhlbEV4dGVudCAmJiBwcm9qZWN0ZWRFeHRlbnQpIHtcbiAgICAgIHZhciBzY2FsZSA9IGdldEhlaWdodChwcm9qZWN0ZWRFeHRlbnQpIC8gZ2V0SGVpZ2h0KHBpeGVsRXh0ZW50KTtcbiAgICAgIGNvbXBvc2VUcmFuc2Zvcm0odG1wVHJhbnNmb3JtLCBwcm9qZWN0ZWRFeHRlbnRbMF0sIHByb2plY3RlZEV4dGVudFszXSwgc2NhbGUsIC1zY2FsZSwgMCwgMCwgMCk7XG4gICAgICB0cmFuc2Zvcm0yRCh0aGlzLmZsYXRDb29yZGluYXRlc18sIDAsIHRoaXMuZmxhdENvb3JkaW5hdGVzXy5sZW5ndGgsIDIsIHRtcFRyYW5zZm9ybSwgdGhpcy5mbGF0Q29vcmRpbmF0ZXNfKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fEFycmF5PEFycmF5PG51bWJlcj4+fSBFbmRzIG9yIGVuZHNzLlxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldEVuZHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZW5kc187XG4gIH07XG5cbiAgcmV0dXJuIFJlbmRlckZlYXR1cmU7XG59KCk7XG5cblJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldEVuZHNzID0gUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0RW5kcztcbi8qKlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gRmxhdCBjb29yZGluYXRlcy5cbiAqL1xuXG5SZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5nZXRGbGF0Q29vcmRpbmF0ZXMgPSBSZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcztcbmV4cG9ydCBkZWZhdWx0IFJlbmRlckZlYXR1cmU7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2Zvcm1hdC9NVlRcbiAqL1xuLy9GSVhNRSBJbXBsZW1lbnQgcHJvamVjdGlvbiBoYW5kbGluZ1xudmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcblxuaW1wb3J0IEZlYXR1cmVGb3JtYXQsIHsgdHJhbnNmb3JtR2VvbWV0cnlXaXRoT3B0aW9ucyB9IGZyb20gJy4vRmVhdHVyZS5qcyc7XG5pbXBvcnQgRm9ybWF0VHlwZSBmcm9tICcuL0Zvcm1hdFR5cGUuanMnO1xuaW1wb3J0IEdlb21ldHJ5TGF5b3V0IGZyb20gJy4uL2dlb20vR2VvbWV0cnlMYXlvdXQuanMnO1xuaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICcuLi9nZW9tL0dlb21ldHJ5VHlwZS5qcyc7XG5pbXBvcnQgTGluZVN0cmluZyBmcm9tICcuLi9nZW9tL0xpbmVTdHJpbmcuanMnO1xuaW1wb3J0IE11bHRpTGluZVN0cmluZyBmcm9tICcuLi9nZW9tL011bHRpTGluZVN0cmluZy5qcyc7XG5pbXBvcnQgTXVsdGlQb2ludCBmcm9tICcuLi9nZW9tL011bHRpUG9pbnQuanMnO1xuaW1wb3J0IE11bHRpUG9seWdvbiBmcm9tICcuLi9nZW9tL011bHRpUG9seWdvbi5qcyc7XG5pbXBvcnQgUEJGIGZyb20gJ3BiZic7XG5pbXBvcnQgUG9pbnQgZnJvbSAnLi4vZ2VvbS9Qb2ludC5qcyc7XG5pbXBvcnQgUG9seWdvbiBmcm9tICcuLi9nZW9tL1BvbHlnb24uanMnO1xuaW1wb3J0IFByb2plY3Rpb24gZnJvbSAnLi4vcHJvai9Qcm9qZWN0aW9uLmpzJztcbmltcG9ydCBSZW5kZXJGZWF0dXJlIGZyb20gJy4uL3JlbmRlci9GZWF0dXJlLmpzJztcbmltcG9ydCBVbml0cyBmcm9tICcuLi9wcm9qL1VuaXRzLmpzJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uL2Fzc2VydHMuanMnO1xuaW1wb3J0IHsgZ2V0IH0gZnJvbSAnLi4vcHJvai5qcyc7XG5pbXBvcnQgeyBsaW5lYXJSaW5nSXNDbG9ja3dpc2UgfSBmcm9tICcuLi9nZW9tL2ZsYXQvb3JpZW50LmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVDbGFzc30gW2ZlYXR1cmVDbGFzc10gQ2xhc3MgZm9yIGZlYXR1cmVzIHJldHVybmVkIGJ5XG4gKiB7QGxpbmsgbW9kdWxlOm9sL2Zvcm1hdC9NVlQjcmVhZEZlYXR1cmVzfS4gU2V0IHRvIHtAbGluayBtb2R1bGU6b2wvRmVhdHVyZX5GZWF0dXJlfSB0byBnZXQgZnVsbCBlZGl0aW5nIGFuZCBnZW9tZXRyeVxuICogc3VwcG9ydCBhdCB0aGUgY29zdCBvZiBkZWNyZWFzZWQgcmVuZGVyaW5nIHBlcmZvcm1hbmNlLiBUaGUgZGVmYXVsdCBpc1xuICoge0BsaW5rIG1vZHVsZTpvbC9yZW5kZXIvRmVhdHVyZX5SZW5kZXJGZWF0dXJlfSwgd2hpY2ggaXMgb3B0aW1pemVkIGZvciByZW5kZXJpbmcgYW5kIGhpdCBkZXRlY3Rpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2dlb21ldHJ5TmFtZT0nZ2VvbWV0cnknXSBHZW9tZXRyeSBuYW1lIHRvIHVzZSB3aGVuIGNyZWF0aW5nIGZlYXR1cmVzLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtsYXllck5hbWU9J2xheWVyJ10gTmFtZSBvZiB0aGUgZmVhdHVyZSBhdHRyaWJ1dGUgdGhhdCBob2xkcyB0aGUgbGF5ZXIgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gW2xheWVyc10gTGF5ZXJzIHRvIHJlYWQgZmVhdHVyZXMgZnJvbS4gSWYgbm90IHByb3ZpZGVkLCBmZWF0dXJlcyB3aWxsIGJlIHJlYWQgZnJvbSBhbGxcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbaWRQcm9wZXJ0eV0gT3B0aW9uYWwgcHJvcGVydHkgdGhhdCB3aWxsIGJlIGFzc2lnbmVkIGFzIHRoZSBmZWF0dXJlIGlkIGFuZCByZW1vdmVkIGZyb20gdGhlIHByb3BlcnRpZXMuXG4gKiBsYXllcnMuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBGZWF0dXJlIGZvcm1hdCBmb3IgcmVhZGluZyBkYXRhIGluIHRoZSBNYXBib3ggTVZUIGZvcm1hdC5cbiAqXG4gKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICogQGFwaVxuICovXG5cbnZhciBNVlQgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoTVZULCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBNVlQob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyA/IG9wdF9vcHRpb25zIDoge307XG4gICAgLyoqXG4gICAgICogQHR5cGUge1Byb2plY3Rpb259XG4gICAgICovXG5cbiAgICBfdGhpcy5kYXRhUHJvamVjdGlvbiA9IG5ldyBQcm9qZWN0aW9uKHtcbiAgICAgIGNvZGU6ICcnLFxuICAgICAgdW5pdHM6IFVuaXRzLlRJTEVfUElYRUxTXG4gICAgfSk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlQ2xhc3N9XG4gICAgICovXG5cbiAgICBfdGhpcy5mZWF0dXJlQ2xhc3NfID0gb3B0aW9ucy5mZWF0dXJlQ2xhc3MgPyBvcHRpb25zLmZlYXR1cmVDbGFzcyA6IFJlbmRlckZlYXR1cmU7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLmdlb21ldHJ5TmFtZV8gPSBvcHRpb25zLmdlb21ldHJ5TmFtZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXllck5hbWVfID0gb3B0aW9ucy5sYXllck5hbWUgPyBvcHRpb25zLmxheWVyTmFtZSA6ICdsYXllcic7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8c3RyaW5nPn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxheWVyc18gPSBvcHRpb25zLmxheWVycyA/IG9wdGlvbnMubGF5ZXJzIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy5pZFByb3BlcnR5XyA9IG9wdGlvbnMuaWRQcm9wZXJ0eTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIFJlYWQgdGhlIHJhdyBnZW9tZXRyeSBmcm9tIHRoZSBwYmYgb2Zmc2V0IHN0b3JlZCBpbiBhIHJhdyBmZWF0dXJlJ3MgZ2VvbWV0cnlcbiAgICogcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7UEJGfSBwYmYgUEJGLlxuICAgKiBAcGFyYW0ge09iamVjdH0gZmVhdHVyZSBSYXcgZmVhdHVyZS5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgQXJyYXkgdG8gc3RvcmUgZmxhdCBjb29yZGluYXRlcyBpbi5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBlbmRzIEFycmF5IHRvIHN0b3JlIGVuZHMgaW4uXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTVZULnByb3RvdHlwZS5yZWFkUmF3R2VvbWV0cnlfID0gZnVuY3Rpb24gKHBiZiwgZmVhdHVyZSwgZmxhdENvb3JkaW5hdGVzLCBlbmRzKSB7XG4gICAgcGJmLnBvcyA9IGZlYXR1cmUuZ2VvbWV0cnk7XG4gICAgdmFyIGVuZCA9IHBiZi5yZWFkVmFyaW50KCkgKyBwYmYucG9zO1xuICAgIHZhciBjbWQgPSAxO1xuICAgIHZhciBsZW5ndGggPSAwO1xuICAgIHZhciB4ID0gMDtcbiAgICB2YXIgeSA9IDA7XG4gICAgdmFyIGNvb3Jkc0xlbiA9IDA7XG4gICAgdmFyIGN1cnJlbnRFbmQgPSAwO1xuXG4gICAgd2hpbGUgKHBiZi5wb3MgPCBlbmQpIHtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHZhciBjbWRMZW4gPSBwYmYucmVhZFZhcmludCgpO1xuICAgICAgICBjbWQgPSBjbWRMZW4gJiAweDc7XG4gICAgICAgIGxlbmd0aCA9IGNtZExlbiA+PiAzO1xuICAgICAgfVxuXG4gICAgICBsZW5ndGgtLTtcblxuICAgICAgaWYgKGNtZCA9PT0gMSB8fCBjbWQgPT09IDIpIHtcbiAgICAgICAgeCArPSBwYmYucmVhZFNWYXJpbnQoKTtcbiAgICAgICAgeSArPSBwYmYucmVhZFNWYXJpbnQoKTtcblxuICAgICAgICBpZiAoY21kID09PSAxKSB7XG4gICAgICAgICAgLy8gbW92ZVRvXG4gICAgICAgICAgaWYgKGNvb3Jkc0xlbiA+IGN1cnJlbnRFbmQpIHtcbiAgICAgICAgICAgIGVuZHMucHVzaChjb29yZHNMZW4pO1xuICAgICAgICAgICAgY3VycmVudEVuZCA9IGNvb3Jkc0xlbjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmbGF0Q29vcmRpbmF0ZXMucHVzaCh4LCB5KTtcbiAgICAgICAgY29vcmRzTGVuICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGNtZCA9PT0gNykge1xuICAgICAgICBpZiAoY29vcmRzTGVuID4gY3VycmVudEVuZCkge1xuICAgICAgICAgIC8vIGNsb3NlIHBvbHlnb25cbiAgICAgICAgICBmbGF0Q29vcmRpbmF0ZXMucHVzaChmbGF0Q29vcmRpbmF0ZXNbY3VycmVudEVuZF0sIGZsYXRDb29yZGluYXRlc1tjdXJyZW50RW5kICsgMV0pO1xuICAgICAgICAgIGNvb3Jkc0xlbiArPSAyO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhc3NlcnQoZmFsc2UsIDU5KTsgLy8gSW52YWxpZCBjb21tYW5kIGZvdW5kIGluIHRoZSBQQkZcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29vcmRzTGVuID4gY3VycmVudEVuZCkge1xuICAgICAgZW5kcy5wdXNoKGNvb3Jkc0xlbik7XG4gICAgICBjdXJyZW50RW5kID0gY29vcmRzTGVuO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7UEJGfSBwYmYgUEJGXG4gICAqIEBwYXJhbSB7T2JqZWN0fSByYXdGZWF0dXJlIFJhdyBNYXBib3ggZmVhdHVyZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuUmVhZE9wdGlvbnN9IG9wdGlvbnMgUmVhZCBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIE1WVC5wcm90b3R5cGUuY3JlYXRlRmVhdHVyZV8gPSBmdW5jdGlvbiAocGJmLCByYXdGZWF0dXJlLCBvcHRpb25zKSB7XG4gICAgdmFyIHR5cGUgPSByYXdGZWF0dXJlLnR5cGU7XG5cbiAgICBpZiAodHlwZSA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGZlYXR1cmU7XG4gICAgdmFyIHZhbHVlcyA9IHJhd0ZlYXR1cmUucHJvcGVydGllcztcbiAgICB2YXIgaWQ7XG5cbiAgICBpZiAoIXRoaXMuaWRQcm9wZXJ0eV8pIHtcbiAgICAgIGlkID0gcmF3RmVhdHVyZS5pZDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWQgPSB2YWx1ZXNbdGhpcy5pZFByb3BlcnR5X107XG4gICAgICBkZWxldGUgdmFsdWVzW3RoaXMuaWRQcm9wZXJ0eV9dO1xuICAgIH1cblxuICAgIHZhbHVlc1t0aGlzLmxheWVyTmFtZV9dID0gcmF3RmVhdHVyZS5sYXllci5uYW1lO1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBbXTtcbiAgICB2YXIgZW5kcyA9IFtdO1xuICAgIHRoaXMucmVhZFJhd0dlb21ldHJ5XyhwYmYsIHJhd0ZlYXR1cmUsIGZsYXRDb29yZGluYXRlcywgZW5kcyk7XG4gICAgdmFyIGdlb21ldHJ5VHlwZSA9IGdldEdlb21ldHJ5VHlwZSh0eXBlLCBlbmRzLmxlbmd0aCk7XG5cbiAgICBpZiAodGhpcy5mZWF0dXJlQ2xhc3NfID09PSBSZW5kZXJGZWF0dXJlKSB7XG4gICAgICBmZWF0dXJlID0gbmV3IHRoaXMuZmVhdHVyZUNsYXNzXyhnZW9tZXRyeVR5cGUsIGZsYXRDb29yZGluYXRlcywgZW5kcywgdmFsdWVzLCBpZCk7XG4gICAgICBmZWF0dXJlLnRyYW5zZm9ybShvcHRpb25zLmRhdGFQcm9qZWN0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGdlb20gPSB2b2lkIDA7XG5cbiAgICAgIGlmIChnZW9tZXRyeVR5cGUgPT0gR2VvbWV0cnlUeXBlLlBPTFlHT04pIHtcbiAgICAgICAgdmFyIGVuZHNzID0gW107XG4gICAgICAgIHZhciBvZmZzZXQgPSAwO1xuICAgICAgICB2YXIgcHJldkVuZEluZGV4ID0gMDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgICB2YXIgZW5kID0gZW5kc1tpXTsgLy8gY2xhc3NpZmllcyBhbiBhcnJheSBvZiByaW5ncyBpbnRvIHBvbHlnb25zIHdpdGggb3V0ZXIgcmluZ3MgYW5kIGhvbGVzXG5cbiAgICAgICAgICBpZiAoIWxpbmVhclJpbmdJc0Nsb2Nrd2lzZShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCAyKSkge1xuICAgICAgICAgICAgZW5kc3MucHVzaChlbmRzLnNsaWNlKHByZXZFbmRJbmRleCwgaSArIDEpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGVuZHNzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZW5kc3NbZW5kc3MubGVuZ3RoIC0gMV0ucHVzaChlbmRzW3ByZXZFbmRJbmRleF0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHByZXZFbmRJbmRleCA9IGkgKyAxO1xuICAgICAgICAgIG9mZnNldCA9IGVuZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbmRzcy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgZ2VvbSA9IG5ldyBNdWx0aVBvbHlnb24oZmxhdENvb3JkaW5hdGVzLCBHZW9tZXRyeUxheW91dC5YWSwgZW5kc3MpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGdlb20gPSBuZXcgUG9seWdvbihmbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZLCBlbmRzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZ2VvbSA9IGdlb21ldHJ5VHlwZSA9PT0gR2VvbWV0cnlUeXBlLlBPSU5UID8gbmV3IFBvaW50KGZsYXRDb29yZGluYXRlcywgR2VvbWV0cnlMYXlvdXQuWFkpIDogZ2VvbWV0cnlUeXBlID09PSBHZW9tZXRyeVR5cGUuTElORV9TVFJJTkcgPyBuZXcgTGluZVN0cmluZyhmbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZKSA6IGdlb21ldHJ5VHlwZSA9PT0gR2VvbWV0cnlUeXBlLlBPTFlHT04gPyBuZXcgUG9seWdvbihmbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZLCBlbmRzKSA6IGdlb21ldHJ5VHlwZSA9PT0gR2VvbWV0cnlUeXBlLk1VTFRJX1BPSU5UID8gbmV3IE11bHRpUG9pbnQoZmxhdENvb3JkaW5hdGVzLCBHZW9tZXRyeUxheW91dC5YWSkgOiBnZW9tZXRyeVR5cGUgPT09IEdlb21ldHJ5VHlwZS5NVUxUSV9MSU5FX1NUUklORyA/IG5ldyBNdWx0aUxpbmVTdHJpbmcoZmxhdENvb3JkaW5hdGVzLCBHZW9tZXRyeUxheW91dC5YWSwgZW5kcykgOiBudWxsO1xuICAgICAgfVxuXG4gICAgICB2YXIgY3RvciA9XG4gICAgICAvKiogQHR5cGUge3R5cGVvZiBpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICB0aGlzLmZlYXR1cmVDbGFzc187XG4gICAgICBmZWF0dXJlID0gbmV3IGN0b3IoKTtcblxuICAgICAgaWYgKHRoaXMuZ2VvbWV0cnlOYW1lXykge1xuICAgICAgICBmZWF0dXJlLnNldEdlb21ldHJ5TmFtZSh0aGlzLmdlb21ldHJ5TmFtZV8pO1xuICAgICAgfVxuXG4gICAgICB2YXIgZ2VvbWV0cnkgPSB0cmFuc2Zvcm1HZW9tZXRyeVdpdGhPcHRpb25zKGdlb20sIGZhbHNlLCBvcHRpb25zKTtcbiAgICAgIGZlYXR1cmUuc2V0R2VvbWV0cnkoZ2VvbWV0cnkpO1xuICAgICAgZmVhdHVyZS5zZXRJZChpZCk7XG4gICAgICBmZWF0dXJlLnNldFByb3BlcnRpZXModmFsdWVzLCB0cnVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmVhdHVyZTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vRm9ybWF0VHlwZS5qc1wiKS5kZWZhdWx0fSBGb3JtYXQuXG4gICAqL1xuXG5cbiAgTVZULnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBGb3JtYXRUeXBlLkFSUkFZX0JVRkZFUjtcbiAgfTtcbiAgLyoqXG4gICAqIFJlYWQgYWxsIGZlYXR1cmVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBzb3VyY2UgU291cmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5SZWFkT3B0aW9ucz19IG9wdF9vcHRpb25zIFJlYWQgb3B0aW9ucy5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZT59IEZlYXR1cmVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTVZULnByb3RvdHlwZS5yZWFkRmVhdHVyZXMgPSBmdW5jdGlvbiAoc291cmNlLCBvcHRfb3B0aW9ucykge1xuICAgIHZhciBsYXllcnMgPSB0aGlzLmxheWVyc187XG4gICAgdmFyIG9wdGlvbnMgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLlJlYWRPcHRpb25zfSAqL1xuICAgIHRoaXMuYWRhcHRPcHRpb25zKG9wdF9vcHRpb25zKTtcbiAgICB2YXIgZGF0YVByb2plY3Rpb24gPSBnZXQob3B0aW9ucy5kYXRhUHJvamVjdGlvbik7XG4gICAgZGF0YVByb2plY3Rpb24uc2V0V29ybGRFeHRlbnQob3B0aW9ucy5leHRlbnQpO1xuICAgIG9wdGlvbnMuZGF0YVByb2plY3Rpb24gPSBkYXRhUHJvamVjdGlvbjtcbiAgICB2YXIgcGJmID0gbmV3IFBCRihcbiAgICAvKiogQHR5cGUge0FycmF5QnVmZmVyfSAqL1xuICAgIHNvdXJjZSk7XG4gICAgdmFyIHBiZkxheWVycyA9IHBiZi5yZWFkRmllbGRzKGxheWVyc1BCRlJlYWRlciwge30pO1xuICAgIHZhciBmZWF0dXJlcyA9IFtdO1xuXG4gICAgZm9yICh2YXIgbmFtZV8xIGluIHBiZkxheWVycykge1xuICAgICAgaWYgKGxheWVycyAmJiBsYXllcnMuaW5kZXhPZihuYW1lXzEpID09IC0xKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgcGJmTGF5ZXIgPSBwYmZMYXllcnNbbmFtZV8xXTtcbiAgICAgIHZhciBleHRlbnQgPSBwYmZMYXllciA/IFswLCAwLCBwYmZMYXllci5leHRlbnQsIHBiZkxheWVyLmV4dGVudF0gOiBudWxsO1xuICAgICAgZGF0YVByb2plY3Rpb24uc2V0RXh0ZW50KGV4dGVudCk7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHBiZkxheWVyLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgdmFyIHJhd0ZlYXR1cmUgPSByZWFkUmF3RmVhdHVyZShwYmYsIHBiZkxheWVyLCBpKTtcbiAgICAgICAgZmVhdHVyZXMucHVzaCh0aGlzLmNyZWF0ZUZlYXR1cmVfKHBiZiwgcmF3RmVhdHVyZSwgb3B0aW9ucykpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmZWF0dXJlcztcbiAgfTtcbiAgLyoqXG4gICAqIFJlYWQgdGhlIHByb2plY3Rpb24gZnJvbSB0aGUgc291cmNlLlxuICAgKlxuICAgKiBAcGFyYW0ge0RvY3VtZW50fEVsZW1lbnR8T2JqZWN0fHN0cmluZ30gc291cmNlIFNvdXJjZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IFByb2plY3Rpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNVlQucHJvdG90eXBlLnJlYWRQcm9qZWN0aW9uID0gZnVuY3Rpb24gKHNvdXJjZSkge1xuICAgIHJldHVybiB0aGlzLmRhdGFQcm9qZWN0aW9uO1xuICB9O1xuICAvKipcbiAgICogU2V0cyB0aGUgbGF5ZXJzIHRoYXQgZmVhdHVyZXMgd2lsbCBiZSByZWFkIGZyb20uXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gbGF5ZXJzIExheWVycy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE1WVC5wcm90b3R5cGUuc2V0TGF5ZXJzID0gZnVuY3Rpb24gKGxheWVycykge1xuICAgIHRoaXMubGF5ZXJzXyA9IGxheWVycztcbiAgfTtcblxuICByZXR1cm4gTVZUO1xufShGZWF0dXJlRm9ybWF0KTtcbi8qKlxuICogUmVhZGVyIGNhbGxiYWNrIGZvciBwYXJzaW5nIGxheWVycy5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0YWcgVGhlIHRhZy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBsYXllcnMgVGhlIGxheWVycyBvYmplY3QuXG4gKiBAcGFyYW0ge1BCRn0gcGJmIFRoZSBQQkYuXG4gKi9cblxuXG5mdW5jdGlvbiBsYXllcnNQQkZSZWFkZXIodGFnLCBsYXllcnMsIHBiZikge1xuICBpZiAodGFnID09PSAzKSB7XG4gICAgdmFyIGxheWVyID0ge1xuICAgICAga2V5czogW10sXG4gICAgICB2YWx1ZXM6IFtdLFxuICAgICAgZmVhdHVyZXM6IFtdXG4gICAgfTtcbiAgICB2YXIgZW5kID0gcGJmLnJlYWRWYXJpbnQoKSArIHBiZi5wb3M7XG4gICAgcGJmLnJlYWRGaWVsZHMobGF5ZXJQQkZSZWFkZXIsIGxheWVyLCBlbmQpO1xuICAgIGxheWVyLmxlbmd0aCA9IGxheWVyLmZlYXR1cmVzLmxlbmd0aDtcblxuICAgIGlmIChsYXllci5sZW5ndGgpIHtcbiAgICAgIGxheWVyc1tsYXllci5uYW1lXSA9IGxheWVyO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBSZWFkZXIgY2FsbGJhY2sgZm9yIHBhcnNpbmcgbGF5ZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gdGFnIFRoZSB0YWcuXG4gKiBAcGFyYW0ge09iamVjdH0gbGF5ZXIgVGhlIGxheWVyIG9iamVjdC5cbiAqIEBwYXJhbSB7UEJGfSBwYmYgVGhlIFBCRi5cbiAqL1xuXG5cbmZ1bmN0aW9uIGxheWVyUEJGUmVhZGVyKHRhZywgbGF5ZXIsIHBiZikge1xuICBpZiAodGFnID09PSAxNSkge1xuICAgIGxheWVyLnZlcnNpb24gPSBwYmYucmVhZFZhcmludCgpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gMSkge1xuICAgIGxheWVyLm5hbWUgPSBwYmYucmVhZFN0cmluZygpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gNSkge1xuICAgIGxheWVyLmV4dGVudCA9IHBiZi5yZWFkVmFyaW50KCk7XG4gIH0gZWxzZSBpZiAodGFnID09PSAyKSB7XG4gICAgbGF5ZXIuZmVhdHVyZXMucHVzaChwYmYucG9zKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09IDMpIHtcbiAgICBsYXllci5rZXlzLnB1c2gocGJmLnJlYWRTdHJpbmcoKSk7XG4gIH0gZWxzZSBpZiAodGFnID09PSA0KSB7XG4gICAgdmFyIHZhbHVlID0gbnVsbDtcbiAgICB2YXIgZW5kID0gcGJmLnJlYWRWYXJpbnQoKSArIHBiZi5wb3M7XG5cbiAgICB3aGlsZSAocGJmLnBvcyA8IGVuZCkge1xuICAgICAgdGFnID0gcGJmLnJlYWRWYXJpbnQoKSA+PiAzO1xuICAgICAgdmFsdWUgPSB0YWcgPT09IDEgPyBwYmYucmVhZFN0cmluZygpIDogdGFnID09PSAyID8gcGJmLnJlYWRGbG9hdCgpIDogdGFnID09PSAzID8gcGJmLnJlYWREb3VibGUoKSA6IHRhZyA9PT0gNCA/IHBiZi5yZWFkVmFyaW50NjQoKSA6IHRhZyA9PT0gNSA/IHBiZi5yZWFkVmFyaW50KCkgOiB0YWcgPT09IDYgPyBwYmYucmVhZFNWYXJpbnQoKSA6IHRhZyA9PT0gNyA/IHBiZi5yZWFkQm9vbGVhbigpIDogbnVsbDtcbiAgICB9XG5cbiAgICBsYXllci52YWx1ZXMucHVzaCh2YWx1ZSk7XG4gIH1cbn1cbi8qKlxuICogUmVhZGVyIGNhbGxiYWNrIGZvciBwYXJzaW5nIGZlYXR1cmUuXG4gKiBAcGFyYW0ge251bWJlcn0gdGFnIFRoZSB0YWcuXG4gKiBAcGFyYW0ge09iamVjdH0gZmVhdHVyZSBUaGUgZmVhdHVyZSBvYmplY3QuXG4gKiBAcGFyYW0ge1BCRn0gcGJmIFRoZSBQQkYuXG4gKi9cblxuXG5mdW5jdGlvbiBmZWF0dXJlUEJGUmVhZGVyKHRhZywgZmVhdHVyZSwgcGJmKSB7XG4gIGlmICh0YWcgPT0gMSkge1xuICAgIGZlYXR1cmUuaWQgPSBwYmYucmVhZFZhcmludCgpO1xuICB9IGVsc2UgaWYgKHRhZyA9PSAyKSB7XG4gICAgdmFyIGVuZCA9IHBiZi5yZWFkVmFyaW50KCkgKyBwYmYucG9zO1xuXG4gICAgd2hpbGUgKHBiZi5wb3MgPCBlbmQpIHtcbiAgICAgIHZhciBrZXkgPSBmZWF0dXJlLmxheWVyLmtleXNbcGJmLnJlYWRWYXJpbnQoKV07XG4gICAgICB2YXIgdmFsdWUgPSBmZWF0dXJlLmxheWVyLnZhbHVlc1twYmYucmVhZFZhcmludCgpXTtcbiAgICAgIGZlYXR1cmUucHJvcGVydGllc1trZXldID0gdmFsdWU7XG4gICAgfVxuICB9IGVsc2UgaWYgKHRhZyA9PSAzKSB7XG4gICAgZmVhdHVyZS50eXBlID0gcGJmLnJlYWRWYXJpbnQoKTtcbiAgfSBlbHNlIGlmICh0YWcgPT0gNCkge1xuICAgIGZlYXR1cmUuZ2VvbWV0cnkgPSBwYmYucG9zO1xuICB9XG59XG4vKipcbiAqIFJlYWQgYSByYXcgZmVhdHVyZSBmcm9tIHRoZSBwYmYgb2Zmc2V0IHN0b3JlZCBhdCBpbmRleCBgaWAgaW4gdGhlIHJhdyBsYXllci5cbiAqIEBwYXJhbSB7UEJGfSBwYmYgUEJGLlxuICogQHBhcmFtIHtPYmplY3R9IGxheWVyIFJhdyBsYXllci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBpIEluZGV4IG9mIHRoZSBmZWF0dXJlIGluIHRoZSByYXcgbGF5ZXIncyBgZmVhdHVyZXNgIGFycmF5LlxuICogQHJldHVybiB7T2JqZWN0fSBSYXcgZmVhdHVyZS5cbiAqL1xuXG5cbmZ1bmN0aW9uIHJlYWRSYXdGZWF0dXJlKHBiZiwgbGF5ZXIsIGkpIHtcbiAgcGJmLnBvcyA9IGxheWVyLmZlYXR1cmVzW2ldO1xuICB2YXIgZW5kID0gcGJmLnJlYWRWYXJpbnQoKSArIHBiZi5wb3M7XG4gIHZhciBmZWF0dXJlID0ge1xuICAgIGxheWVyOiBsYXllcixcbiAgICB0eXBlOiAwLFxuICAgIHByb3BlcnRpZXM6IHt9XG4gIH07XG4gIHBiZi5yZWFkRmllbGRzKGZlYXR1cmVQQkZSZWFkZXIsIGZlYXR1cmUsIGVuZCk7XG4gIHJldHVybiBmZWF0dXJlO1xufVxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdHlwZSBUaGUgcmF3IGZlYXR1cmUncyBnZW9tZXRyeSB0eXBlXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtRW5kcyBOdW1iZXIgb2YgZW5kcyBvZiB0aGUgZmxhdCBjb29yZGluYXRlcyBvZiB0aGVcbiAqIGdlb21ldHJ5LlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gVGhlIGdlb21ldHJ5IHR5cGUuXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRHZW9tZXRyeVR5cGUodHlwZSwgbnVtRW5kcykge1xuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnlUeXBlLmpzXCIpLmRlZmF1bHR9ICovXG4gIHZhciBnZW9tZXRyeVR5cGU7XG5cbiAgaWYgKHR5cGUgPT09IDEpIHtcbiAgICBnZW9tZXRyeVR5cGUgPSBudW1FbmRzID09PSAxID8gR2VvbWV0cnlUeXBlLlBPSU5UIDogR2VvbWV0cnlUeXBlLk1VTFRJX1BPSU5UO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09IDIpIHtcbiAgICBnZW9tZXRyeVR5cGUgPSBudW1FbmRzID09PSAxID8gR2VvbWV0cnlUeXBlLkxJTkVfU1RSSU5HIDogR2VvbWV0cnlUeXBlLk1VTFRJX0xJTkVfU1RSSU5HO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09IDMpIHtcbiAgICBnZW9tZXRyeVR5cGUgPSBHZW9tZXRyeVR5cGUuUE9MWUdPTjsgLy8gTXVsdGlQb2x5Z29uIG5vdCByZWxldmFudCBmb3IgcmVuZGVyaW5nIC0gd2luZGluZyBvcmRlciBkZXRlcm1pbmVzXG4gICAgLy8gb3V0ZXIgcmluZ3Mgb2YgcG9seWdvbnMuXG4gIH1cblxuICByZXR1cm4gZ2VvbWV0cnlUeXBlO1xufVxuXG5leHBvcnQgZGVmYXVsdCBNVlQ7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9JbWFnZVRpbGVcbiAqL1xuXG5cbmltcG9ydCBUaWxlIGZyb20gJy4vVGlsZS5qcyc7XG5pbXBvcnQgVGlsZVN0YXRlIGZyb20gJy4vVGlsZVN0YXRlLmpzJztcbmltcG9ydCB7IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCB9IGZyb20gJy4vZG9tLmpzJztcbmltcG9ydCB7IGxpc3RlbkltYWdlIH0gZnJvbSAnLi9JbWFnZS5qcyc7XG5cbnZhciBJbWFnZVRpbGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoSW1hZ2VUaWxlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UaWxlU3RhdGUuanNcIikuZGVmYXVsdH0gc3RhdGUgU3RhdGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgSW1hZ2Ugc291cmNlIFVSSS5cbiAgICogQHBhcmFtIHs/c3RyaW5nfSBjcm9zc09yaWdpbiBDcm9zcyBvcmlnaW4uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UaWxlLmpzXCIpLkxvYWRGdW5jdGlvbn0gdGlsZUxvYWRGdW5jdGlvbiBUaWxlIGxvYWQgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UaWxlLmpzXCIpLk9wdGlvbnM9fSBvcHRfb3B0aW9ucyBUaWxlIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gSW1hZ2VUaWxlKHRpbGVDb29yZCwgc3RhdGUsIHNyYywgY3Jvc3NPcmlnaW4sIHRpbGVMb2FkRnVuY3Rpb24sIG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdGlsZUNvb3JkLCBzdGF0ZSwgb3B0X29wdGlvbnMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P3N0cmluZ31cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuY3Jvc3NPcmlnaW5fID0gY3Jvc3NPcmlnaW47XG4gICAgLyoqXG4gICAgICogSW1hZ2UgVVJJXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy5zcmNfID0gc3JjO1xuICAgIF90aGlzLmtleSA9IHNyYztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtIVE1MSW1hZ2VFbGVtZW50fEhUTUxDYW52YXNFbGVtZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW1hZ2VfID0gbmV3IEltYWdlKCk7XG5cbiAgICBpZiAoY3Jvc3NPcmlnaW4gIT09IG51bGwpIHtcbiAgICAgIF90aGlzLmltYWdlXy5jcm9zc09yaWdpbiA9IGNyb3NzT3JpZ2luO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/ZnVuY3Rpb24oKTp2b2lkfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy51bmxpc3Rlbl8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vVGlsZS5qc1wiKS5Mb2FkRnVuY3Rpb259XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlTG9hZEZ1bmN0aW9uXyA9IHRpbGVMb2FkRnVuY3Rpb247XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIEhUTUwgaW1hZ2UgZWxlbWVudCBmb3IgdGhpcyB0aWxlIChtYXkgYmUgYSBDYW52YXMsIEltYWdlLCBvciBWaWRlbykuXG4gICAqIEByZXR1cm4ge0hUTUxDYW52YXNFbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR8SFRNTFZpZGVvRWxlbWVudH0gSW1hZ2UuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVRpbGUucHJvdG90eXBlLmdldEltYWdlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmltYWdlXztcbiAgfTtcbiAgLyoqXG4gICAqIFRyYWNrcyBsb2FkaW5nIG9yIHJlYWQgZXJyb3JzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIEltYWdlVGlsZS5wcm90b3R5cGUuaGFuZGxlSW1hZ2VFcnJvcl8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5FUlJPUjtcbiAgICB0aGlzLnVubGlzdGVuSW1hZ2VfKCk7XG4gICAgdGhpcy5pbWFnZV8gPSBnZXRCbGFua0ltYWdlKCk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBUcmFja3Mgc3VjY2Vzc2Z1bCBpbWFnZSBsb2FkLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIEltYWdlVGlsZS5wcm90b3R5cGUuaGFuZGxlSW1hZ2VMb2FkXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaW1hZ2UgPVxuICAgIC8qKiBAdHlwZSB7SFRNTEltYWdlRWxlbWVudH0gKi9cbiAgICB0aGlzLmltYWdlXztcblxuICAgIGlmIChpbWFnZS5uYXR1cmFsV2lkdGggJiYgaW1hZ2UubmF0dXJhbEhlaWdodCkge1xuICAgICAgdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5MT0FERUQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RhdGUgPSBUaWxlU3RhdGUuRU1QVFk7XG4gICAgfVxuXG4gICAgdGhpcy51bmxpc3RlbkltYWdlXygpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTG9hZCBub3QgeWV0IGxvYWRlZCBVUkkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVRpbGUucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUgPT0gVGlsZVN0YXRlLkVSUk9SKSB7XG4gICAgICB0aGlzLnN0YXRlID0gVGlsZVN0YXRlLklETEU7XG4gICAgICB0aGlzLmltYWdlXyA9IG5ldyBJbWFnZSgpO1xuXG4gICAgICBpZiAodGhpcy5jcm9zc09yaWdpbl8gIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5pbWFnZV8uY3Jvc3NPcmlnaW4gPSB0aGlzLmNyb3NzT3JpZ2luXztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZSA9PSBUaWxlU3RhdGUuSURMRSkge1xuICAgICAgdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5MT0FESU5HO1xuICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICB0aGlzLnRpbGVMb2FkRnVuY3Rpb25fKHRoaXMsIHRoaXMuc3JjXyk7XG4gICAgICB0aGlzLnVubGlzdGVuXyA9IGxpc3RlbkltYWdlKHRoaXMuaW1hZ2VfLCB0aGlzLmhhbmRsZUltYWdlTG9hZF8uYmluZCh0aGlzKSwgdGhpcy5oYW5kbGVJbWFnZUVycm9yXy5iaW5kKHRoaXMpKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBEaXNjYXJkcyBldmVudCBoYW5kbGVycyB3aGljaCBsaXN0ZW4gZm9yIGxvYWQgY29tcGxldGlvbiBvciBlcnJvcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgSW1hZ2VUaWxlLnByb3RvdHlwZS51bmxpc3RlbkltYWdlXyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy51bmxpc3Rlbl8pIHtcbiAgICAgIHRoaXMudW5saXN0ZW5fKCk7XG4gICAgICB0aGlzLnVubGlzdGVuXyA9IG51bGw7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBJbWFnZVRpbGU7XG59KFRpbGUpO1xuLyoqXG4gKiBHZXQgYSAxLXBpeGVsIGJsYW5rIGltYWdlLlxuICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR9IEJsYW5rIGltYWdlLlxuICovXG5cblxuZnVuY3Rpb24gZ2V0QmxhbmtJbWFnZSgpIHtcbiAgdmFyIGN0eCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCgxLCAxKTtcbiAgY3R4LmZpbGxTdHlsZSA9ICdyZ2JhKDAsMCwwLDApJztcbiAgY3R4LmZpbGxSZWN0KDAsIDAsIDEsIDEpO1xuICByZXR1cm4gY3R4LmNhbnZhcztcbn1cblxuZXhwb3J0IGRlZmF1bHQgSW1hZ2VUaWxlOyIsIi8qKlxuICogQG1vZHVsZSBvbC9yZXByb2ovY29tbW9uXG4gKi9cblxuLyoqXG4gKiBEZWZhdWx0IG1heGltdW0gYWxsb3dlZCB0aHJlc2hvbGQgIChpbiBwaXhlbHMpIGZvciByZXByb2plY3Rpb25cbiAqIHRyaWFuZ3VsYXRpb24uXG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5leHBvcnQgdmFyIEVSUk9SX1RIUkVTSE9MRCA9IDAuNTtcbi8qKlxuICogRW5hYmxlIGF1dG9tYXRpYyByZXByb2plY3Rpb24gb2YgcmFzdGVyIHNvdXJjZXMuIERlZmF1bHQgaXMgYHRydWVgLlxuICogVE9ETzogZGVjaWRlIGlmIHdlIHdhbnQgdG8gZXhwb3NlIHRoaXMgYXMgYSBidWlsZCBmbGFnIG9yIHJlbW92ZSBpdFxuICogQHR5cGUge2Jvb2xlYW59XG4gKi9cblxuZXhwb3J0IHZhciBFTkFCTEVfUkFTVEVSX1JFUFJPSkVDVElPTiA9IHRydWU7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlcHJvai9Ucmlhbmd1bGF0aW9uXG4gKi9cbmltcG9ydCB7IGJvdW5kaW5nRXh0ZW50LCBjcmVhdGVFbXB0eSwgZXh0ZW5kQ29vcmRpbmF0ZSwgZ2V0QXJlYSwgZ2V0Qm90dG9tTGVmdCwgZ2V0Qm90dG9tUmlnaHQsIGdldFRvcExlZnQsIGdldFRvcFJpZ2h0LCBnZXRXaWR0aCwgaW50ZXJzZWN0cyB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBnZXRUcmFuc2Zvcm0gfSBmcm9tICcuLi9wcm9qLmpzJztcbmltcG9ydCB7IGxvZzIsIG1vZHVsbyB9IGZyb20gJy4uL21hdGguanMnO1xuLyoqXG4gKiBTaW5nbGUgdHJpYW5nbGU7IGNvbnNpc3RzIG9mIDMgc291cmNlIHBvaW50cyBhbmQgMyB0YXJnZXQgcG9pbnRzLlxuICogQHR5cGVkZWYge09iamVjdH0gVHJpYW5nbGVcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn0gc291cmNlXG4gKiBAcHJvcGVydHkge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IHRhcmdldFxuICovXG5cbi8qKlxuICogTWF4aW11bSBudW1iZXIgb2Ygc3ViZGl2aXNpb24gc3RlcHMgZHVyaW5nIHJhc3RlciByZXByb2plY3Rpb24gdHJpYW5ndWxhdGlvbi5cbiAqIFByZXZlbnRzIGhpZ2ggbWVtb3J5IHVzYWdlIGFuZCBsYXJnZSBudW1iZXIgb2YgcHJvajQgY2FsbHMgKGZvciBjZXJ0YWluXG4gKiB0cmFuc2Zvcm1hdGlvbnMgYW5kIGFyZWFzKS4gQXQgbW9zdCBgMiooMl50aGlzKWAgdHJpYW5nbGVzIGFyZSBjcmVhdGVkIGZvclxuICogZWFjaCB0cmlhbmd1bGF0ZWQgZXh0ZW50ICh0aWxlL2ltYWdlKS5cbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cblxudmFyIE1BWF9TVUJESVZJU0lPTiA9IDEwO1xuLyoqXG4gKiBNYXhpbXVtIGFsbG93ZWQgc2l6ZSBvZiB0cmlhbmdsZSByZWxhdGl2ZSB0byB3b3JsZCB3aWR0aC4gV2hlbiB0cmFuc2Zvcm1pbmdcbiAqIGNvcm5lcnMgb2Ygd29ybGQgZXh0ZW50IGJldHdlZW4gY2VydGFpbiBwcm9qZWN0aW9ucywgdGhlIHJlc3VsdGluZ1xuICogdHJpYW5ndWxhdGlvbiBzZWVtcyB0byBoYXZlIHplcm8gZXJyb3IgYW5kIG5vIHN1YmRpdmlzaW9uIGlzIHBlcmZvcm1lZC4gSWZcbiAqIHRoZSB0cmlhbmdsZSB3aWR0aCBpcyBtb3JlIHRoYW4gdGhpcyAocmVsYXRpdmUgdG8gd29ybGQgd2lkdGg7IDAtMSksXG4gKiBzdWJkaXZpc29uIGlzIGZvcmNlZCAodXAgdG8gYE1BWF9TVUJESVZJU0lPTmApLiBEZWZhdWx0IGlzIGAwLjI1YC5cbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cblxudmFyIE1BWF9UUklBTkdMRV9XSURUSCA9IDAuMjU7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIENsYXNzIGNvbnRhaW5pbmcgdHJpYW5ndWxhdGlvbiBvZiB0aGUgZ2l2ZW4gdGFyZ2V0IGV4dGVudC5cbiAqIFVzZWQgZm9yIGRldGVybWluaW5nIHNvdXJjZSBkYXRhIGFuZCB0aGUgcmVwcm9qZWN0aW9uIGl0c2VsZi5cbiAqL1xuXG52YXIgVHJpYW5ndWxhdGlvbiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBzb3VyY2VQcm9qIFNvdXJjZSBwcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSB0YXJnZXRQcm9qIFRhcmdldCBwcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IHRhcmdldEV4dGVudCBUYXJnZXQgZXh0ZW50IHRvIHRyaWFuZ3VsYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IG1heFNvdXJjZUV4dGVudCBNYXhpbWFsIHNvdXJjZSBleHRlbnQgdGhhdCBjYW4gYmUgdXNlZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGVycm9yVGhyZXNob2xkIEFjY2VwdGFibGUgZXJyb3IgKGluIHNvdXJjZSB1bml0cykuXG4gICAqIEBwYXJhbSB7P251bWJlcn0gb3B0X2Rlc3RpbmF0aW9uUmVzb2x1dGlvbiBUaGUgKG9wdGlvbmFsKSByZXNvbHV0aW9uIG9mIHRoZSBkZXN0aW5hdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIFRyaWFuZ3VsYXRpb24oc291cmNlUHJvaiwgdGFyZ2V0UHJvaiwgdGFyZ2V0RXh0ZW50LCBtYXhTb3VyY2VFeHRlbnQsIGVycm9yVGhyZXNob2xkLCBvcHRfZGVzdGluYXRpb25SZXNvbHV0aW9uKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgdGhpcy5zb3VyY2VQcm9qXyA9IHNvdXJjZVByb2o7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLnRhcmdldFByb2pfID0gdGFyZ2V0UHJvajtcbiAgICAvKiogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSAqL1xuXG4gICAgdmFyIHRyYW5zZm9ybUludkNhY2hlID0ge307XG4gICAgdmFyIHRyYW5zZm9ybUludiA9IGdldFRyYW5zZm9ybSh0aGlzLnRhcmdldFByb2pfLCB0aGlzLnNvdXJjZVByb2pfKTtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYyBBIGNvb3JkaW5hdGUuXG4gICAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBUcmFuc2Zvcm1lZCBjb29yZGluYXRlLlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLnRyYW5zZm9ybUludl8gPSBmdW5jdGlvbiAoYykge1xuICAgICAgdmFyIGtleSA9IGNbMF0gKyAnLycgKyBjWzFdO1xuXG4gICAgICBpZiAoIXRyYW5zZm9ybUludkNhY2hlW2tleV0pIHtcbiAgICAgICAgdHJhbnNmb3JtSW52Q2FjaGVba2V5XSA9IHRyYW5zZm9ybUludihjKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRyYW5zZm9ybUludkNhY2hlW2tleV07XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG5cbiAgICB0aGlzLm1heFNvdXJjZUV4dGVudF8gPSBtYXhTb3VyY2VFeHRlbnQ7XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgdGhpcy5lcnJvclRocmVzaG9sZFNxdWFyZWRfID0gZXJyb3JUaHJlc2hvbGQgKiBlcnJvclRocmVzaG9sZDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8VHJpYW5nbGU+fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLnRyaWFuZ2xlc18gPSBbXTtcbiAgICAvKipcbiAgICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgdHJpYW5ndWxhdGlvbiBjcm9zc2VzIGVkZ2Ugb2YgdGhlIHNvdXJjZSBwcm9qZWN0aW9uLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLndyYXBzWEluU291cmNlXyA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLmNhbldyYXBYSW5Tb3VyY2VfID0gdGhpcy5zb3VyY2VQcm9qXy5jYW5XcmFwWCgpICYmICEhbWF4U291cmNlRXh0ZW50ICYmICEhdGhpcy5zb3VyY2VQcm9qXy5nZXRFeHRlbnQoKSAmJiBnZXRXaWR0aChtYXhTb3VyY2VFeHRlbnQpID09IGdldFdpZHRoKHRoaXMuc291cmNlUHJval8uZ2V0RXh0ZW50KCkpO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHs/bnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLnNvdXJjZVdvcmxkV2lkdGhfID0gdGhpcy5zb3VyY2VQcm9qXy5nZXRFeHRlbnQoKSA/IGdldFdpZHRoKHRoaXMuc291cmNlUHJval8uZ2V0RXh0ZW50KCkpIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7P251bWJlcn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgdGhpcy50YXJnZXRXb3JsZFdpZHRoXyA9IHRoaXMudGFyZ2V0UHJval8uZ2V0RXh0ZW50KCkgPyBnZXRXaWR0aCh0aGlzLnRhcmdldFByb2pfLmdldEV4dGVudCgpKSA6IG51bGw7XG4gICAgdmFyIGRlc3RpbmF0aW9uVG9wTGVmdCA9IGdldFRvcExlZnQodGFyZ2V0RXh0ZW50KTtcbiAgICB2YXIgZGVzdGluYXRpb25Ub3BSaWdodCA9IGdldFRvcFJpZ2h0KHRhcmdldEV4dGVudCk7XG4gICAgdmFyIGRlc3RpbmF0aW9uQm90dG9tUmlnaHQgPSBnZXRCb3R0b21SaWdodCh0YXJnZXRFeHRlbnQpO1xuICAgIHZhciBkZXN0aW5hdGlvbkJvdHRvbUxlZnQgPSBnZXRCb3R0b21MZWZ0KHRhcmdldEV4dGVudCk7XG4gICAgdmFyIHNvdXJjZVRvcExlZnQgPSB0aGlzLnRyYW5zZm9ybUludl8oZGVzdGluYXRpb25Ub3BMZWZ0KTtcbiAgICB2YXIgc291cmNlVG9wUmlnaHQgPSB0aGlzLnRyYW5zZm9ybUludl8oZGVzdGluYXRpb25Ub3BSaWdodCk7XG4gICAgdmFyIHNvdXJjZUJvdHRvbVJpZ2h0ID0gdGhpcy50cmFuc2Zvcm1JbnZfKGRlc3RpbmF0aW9uQm90dG9tUmlnaHQpO1xuICAgIHZhciBzb3VyY2VCb3R0b21MZWZ0ID0gdGhpcy50cmFuc2Zvcm1JbnZfKGRlc3RpbmF0aW9uQm90dG9tTGVmdCk7XG4gICAgLypcbiAgICAgKiBUaGUgbWF4U3ViZGl2aXNpb24gY29udHJvbHMgaG93IG1hbnkgc3BsaXR0aW5ncyBvZiB0aGUgdGFyZ2V0IGFyZWEgY2FuXG4gICAgICogYmUgZG9uZS4gVGhlIGlkZWEgaGVyZSBpcyB0byBkbyBhIGxpbmVhciBtYXBwaW5nIG9mIHRoZSB0YXJnZXQgYXJlYXNcbiAgICAgKiBidXQgdGhlIGFjdHVhbCBvdmVyYWwgcmVwcm9qZWN0aW9uIChjYW4gYmUpIGV4dHJlbWVseSBub24tbGluZWFyLiBUaGVcbiAgICAgKiBkZWZhdWx0IHZhbHVlIG9mIE1BWF9TVUJESVZJU0lPTiB3YXMgY2hvc2VuIGJhc2VkIG9uIG1hcHBpbmcgYSAyNTZ4MjU2XG4gICAgICogdGlsZSBzaXplLiBIb3dldmVyIHRoaXMgZnVuY3Rpb24gaXMgYWxzbyBjYWxsZWQgdG8gcmVtYXAgY2FudmFzIHJlbmRlcmVkXG4gICAgICogbGF5ZXJzIHdoaWNoIGNhbiBiZSBtdWNoIGxhcmdlci4gVGhpcyBjYWxjdWxhdGlvbiBpbmNyZWFzZXMgdGhlIG1heFN1YmRpdmlzaW9uXG4gICAgICogdmFsdWUgYnkgdGhlIHJpZ2h0IGZhY3RvciBzbyB0aGF0IGVhY2ggMjU2eDI1NiBwaXhlbCBhcmVhIGhhc1xuICAgICAqIE1BWF9TVUJESVZJU0lPTiBkaXZpc2lvbnMuXG4gICAgICovXG5cbiAgICB2YXIgbWF4U3ViZGl2aXNpb24gPSBNQVhfU1VCRElWSVNJT04gKyAob3B0X2Rlc3RpbmF0aW9uUmVzb2x1dGlvbiA/IE1hdGgubWF4KDAsIE1hdGguY2VpbChsb2cyKGdldEFyZWEodGFyZ2V0RXh0ZW50KSAvIChvcHRfZGVzdGluYXRpb25SZXNvbHV0aW9uICogb3B0X2Rlc3RpbmF0aW9uUmVzb2x1dGlvbiAqIDI1NiAqIDI1NikpKSkgOiAwKTtcbiAgICB0aGlzLmFkZFF1YWRfKGRlc3RpbmF0aW9uVG9wTGVmdCwgZGVzdGluYXRpb25Ub3BSaWdodCwgZGVzdGluYXRpb25Cb3R0b21SaWdodCwgZGVzdGluYXRpb25Cb3R0b21MZWZ0LCBzb3VyY2VUb3BMZWZ0LCBzb3VyY2VUb3BSaWdodCwgc291cmNlQm90dG9tUmlnaHQsIHNvdXJjZUJvdHRvbUxlZnQsIG1heFN1YmRpdmlzaW9uKTtcblxuICAgIGlmICh0aGlzLndyYXBzWEluU291cmNlXykge1xuICAgICAgdmFyIGxlZnRCb3VuZF8xID0gSW5maW5pdHk7XG4gICAgICB0aGlzLnRyaWFuZ2xlc18uZm9yRWFjaChmdW5jdGlvbiAodHJpYW5nbGUsIGksIGFycikge1xuICAgICAgICBsZWZ0Qm91bmRfMSA9IE1hdGgubWluKGxlZnRCb3VuZF8xLCB0cmlhbmdsZS5zb3VyY2VbMF1bMF0sIHRyaWFuZ2xlLnNvdXJjZVsxXVswXSwgdHJpYW5nbGUuc291cmNlWzJdWzBdKTtcbiAgICAgIH0pOyAvLyBTaGlmdCB0cmlhbmdsZXMgdG8gYmUgYXMgY2xvc2UgdG8gYGxlZnRCb3VuZGAgYXMgcG9zc2libGVcbiAgICAgIC8vIChpZiB0aGUgZGlzdGFuY2UgaXMgbW9yZSB0aGFuIGB3b3JsZFdpZHRoIC8gMmAgaXQgY2FuIGJlIGNsb3Nlci5cblxuICAgICAgdGhpcy50cmlhbmdsZXNfLmZvckVhY2goZnVuY3Rpb24gKHRyaWFuZ2xlKSB7XG4gICAgICAgIGlmIChNYXRoLm1heCh0cmlhbmdsZS5zb3VyY2VbMF1bMF0sIHRyaWFuZ2xlLnNvdXJjZVsxXVswXSwgdHJpYW5nbGUuc291cmNlWzJdWzBdKSAtIGxlZnRCb3VuZF8xID4gdGhpcy5zb3VyY2VXb3JsZFdpZHRoXyAvIDIpIHtcbiAgICAgICAgICB2YXIgbmV3VHJpYW5nbGUgPSBbW3RyaWFuZ2xlLnNvdXJjZVswXVswXSwgdHJpYW5nbGUuc291cmNlWzBdWzFdXSwgW3RyaWFuZ2xlLnNvdXJjZVsxXVswXSwgdHJpYW5nbGUuc291cmNlWzFdWzFdXSwgW3RyaWFuZ2xlLnNvdXJjZVsyXVswXSwgdHJpYW5nbGUuc291cmNlWzJdWzFdXV07XG5cbiAgICAgICAgICBpZiAobmV3VHJpYW5nbGVbMF1bMF0gLSBsZWZ0Qm91bmRfMSA+IHRoaXMuc291cmNlV29ybGRXaWR0aF8gLyAyKSB7XG4gICAgICAgICAgICBuZXdUcmlhbmdsZVswXVswXSAtPSB0aGlzLnNvdXJjZVdvcmxkV2lkdGhfO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChuZXdUcmlhbmdsZVsxXVswXSAtIGxlZnRCb3VuZF8xID4gdGhpcy5zb3VyY2VXb3JsZFdpZHRoXyAvIDIpIHtcbiAgICAgICAgICAgIG5ld1RyaWFuZ2xlWzFdWzBdIC09IHRoaXMuc291cmNlV29ybGRXaWR0aF87XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG5ld1RyaWFuZ2xlWzJdWzBdIC0gbGVmdEJvdW5kXzEgPiB0aGlzLnNvdXJjZVdvcmxkV2lkdGhfIC8gMikge1xuICAgICAgICAgICAgbmV3VHJpYW5nbGVbMl1bMF0gLT0gdGhpcy5zb3VyY2VXb3JsZFdpZHRoXztcbiAgICAgICAgICB9IC8vIFJhcmVseSAoaWYgdGhlIGV4dGVudCBjb250YWlucyBib3RoIHRoZSBkYXRlbGluZSBhbmQgcHJpbWUgbWVyaWRpYW4pXG4gICAgICAgICAgLy8gdGhlIHNoaWZ0IGNhbiBpbiB0dXJuIGJyZWFrIHNvbWUgdHJpYW5nbGVzLlxuICAgICAgICAgIC8vIERldGVjdCB0aGlzIGhlcmUgYW5kIGRvbid0IHNoaWZ0IGluIHN1Y2ggY2FzZXMuXG5cblxuICAgICAgICAgIHZhciBtaW5YID0gTWF0aC5taW4obmV3VHJpYW5nbGVbMF1bMF0sIG5ld1RyaWFuZ2xlWzFdWzBdLCBuZXdUcmlhbmdsZVsyXVswXSk7XG4gICAgICAgICAgdmFyIG1heFggPSBNYXRoLm1heChuZXdUcmlhbmdsZVswXVswXSwgbmV3VHJpYW5nbGVbMV1bMF0sIG5ld1RyaWFuZ2xlWzJdWzBdKTtcblxuICAgICAgICAgIGlmIChtYXhYIC0gbWluWCA8IHRoaXMuc291cmNlV29ybGRXaWR0aF8gLyAyKSB7XG4gICAgICAgICAgICB0cmlhbmdsZS5zb3VyY2UgPSBuZXdUcmlhbmdsZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgfVxuXG4gICAgdHJhbnNmb3JtSW52Q2FjaGUgPSB7fTtcbiAgfVxuICAvKipcbiAgICogQWRkcyB0cmlhbmdsZSB0byB0aGUgdHJpYW5ndWxhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGEgVGhlIHRhcmdldCBhIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBiIFRoZSB0YXJnZXQgYiBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYyBUaGUgdGFyZ2V0IGMgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGFTcmMgVGhlIHNvdXJjZSBhIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBiU3JjIFRoZSBzb3VyY2UgYiBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY1NyYyBUaGUgc291cmNlIGMgY29vcmRpbmF0ZS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBUcmlhbmd1bGF0aW9uLnByb3RvdHlwZS5hZGRUcmlhbmdsZV8gPSBmdW5jdGlvbiAoYSwgYiwgYywgYVNyYywgYlNyYywgY1NyYykge1xuICAgIHRoaXMudHJpYW5nbGVzXy5wdXNoKHtcbiAgICAgIHNvdXJjZTogW2FTcmMsIGJTcmMsIGNTcmNdLFxuICAgICAgdGFyZ2V0OiBbYSwgYiwgY11cbiAgICB9KTtcbiAgfTtcbiAgLyoqXG4gICAqIEFkZHMgcXVhZCAocG9pbnRzIGluIGNsb2NrLXdpc2Ugb3JkZXIpIHRvIHRoZSB0cmlhbmd1bGF0aW9uXG4gICAqIChhbmQgcmVwcm9qZWN0cyB0aGUgdmVydGljZXMpIGlmIHZhbGlkLlxuICAgKiBQZXJmb3JtcyBxdWFkIHN1YmRpdmlzaW9uIGlmIG5lZWRlZCB0byBpbmNyZWFzZSBwcmVjaXNpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBhIFRoZSB0YXJnZXQgYSBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYiBUaGUgdGFyZ2V0IGIgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGMgVGhlIHRhcmdldCBjIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBkIFRoZSB0YXJnZXQgZCBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYVNyYyBUaGUgc291cmNlIGEgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGJTcmMgVGhlIHNvdXJjZSBiIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjU3JjIFRoZSBzb3VyY2UgYyBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gZFNyYyBUaGUgc291cmNlIGQgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1heFN1YmRpdmlzaW9uIE1heGltYWwgYWxsb3dlZCBzdWJkaXZpc2lvbiBvZiB0aGUgcXVhZC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBUcmlhbmd1bGF0aW9uLnByb3RvdHlwZS5hZGRRdWFkXyA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkLCBhU3JjLCBiU3JjLCBjU3JjLCBkU3JjLCBtYXhTdWJkaXZpc2lvbikge1xuICAgIHZhciBzb3VyY2VRdWFkRXh0ZW50ID0gYm91bmRpbmdFeHRlbnQoW2FTcmMsIGJTcmMsIGNTcmMsIGRTcmNdKTtcbiAgICB2YXIgc291cmNlQ292ZXJhZ2VYID0gdGhpcy5zb3VyY2VXb3JsZFdpZHRoXyA/IGdldFdpZHRoKHNvdXJjZVF1YWRFeHRlbnQpIC8gdGhpcy5zb3VyY2VXb3JsZFdpZHRoXyA6IG51bGw7XG4gICAgdmFyIHNvdXJjZVdvcmxkV2lkdGggPVxuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuc291cmNlV29ybGRXaWR0aF87IC8vIHdoZW4gdGhlIHF1YWQgaXMgd3JhcHBlZCBpbiB0aGUgc291cmNlIHByb2plY3Rpb25cbiAgICAvLyBpdCBjb3ZlcnMgbW9zdCBvZiB0aGUgcHJvamVjdGlvbiBleHRlbnQsIGJ1dCBub3QgZnVsbHlcblxuICAgIHZhciB3cmFwc1ggPSB0aGlzLnNvdXJjZVByb2pfLmNhbldyYXBYKCkgJiYgc291cmNlQ292ZXJhZ2VYID4gMC41ICYmIHNvdXJjZUNvdmVyYWdlWCA8IDE7XG4gICAgdmFyIG5lZWRzU3ViZGl2aXNpb24gPSBmYWxzZTtcblxuICAgIGlmIChtYXhTdWJkaXZpc2lvbiA+IDApIHtcbiAgICAgIGlmICh0aGlzLnRhcmdldFByb2pfLmlzR2xvYmFsKCkgJiYgdGhpcy50YXJnZXRXb3JsZFdpZHRoXykge1xuICAgICAgICB2YXIgdGFyZ2V0UXVhZEV4dGVudCA9IGJvdW5kaW5nRXh0ZW50KFthLCBiLCBjLCBkXSk7XG4gICAgICAgIHZhciB0YXJnZXRDb3ZlcmFnZVggPSBnZXRXaWR0aCh0YXJnZXRRdWFkRXh0ZW50KSAvIHRoaXMudGFyZ2V0V29ybGRXaWR0aF87XG4gICAgICAgIG5lZWRzU3ViZGl2aXNpb24gPSB0YXJnZXRDb3ZlcmFnZVggPiBNQVhfVFJJQU5HTEVfV0lEVEggfHwgbmVlZHNTdWJkaXZpc2lvbjtcbiAgICAgIH1cblxuICAgICAgaWYgKCF3cmFwc1ggJiYgdGhpcy5zb3VyY2VQcm9qXy5pc0dsb2JhbCgpICYmIHNvdXJjZUNvdmVyYWdlWCkge1xuICAgICAgICBuZWVkc1N1YmRpdmlzaW9uID0gc291cmNlQ292ZXJhZ2VYID4gTUFYX1RSSUFOR0xFX1dJRFRIIHx8IG5lZWRzU3ViZGl2aXNpb247XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFuZWVkc1N1YmRpdmlzaW9uICYmIHRoaXMubWF4U291cmNlRXh0ZW50Xykge1xuICAgICAgaWYgKGlzRmluaXRlKHNvdXJjZVF1YWRFeHRlbnRbMF0pICYmIGlzRmluaXRlKHNvdXJjZVF1YWRFeHRlbnRbMV0pICYmIGlzRmluaXRlKHNvdXJjZVF1YWRFeHRlbnRbMl0pICYmIGlzRmluaXRlKHNvdXJjZVF1YWRFeHRlbnRbM10pKSB7XG4gICAgICAgIGlmICghaW50ZXJzZWN0cyhzb3VyY2VRdWFkRXh0ZW50LCB0aGlzLm1heFNvdXJjZUV4dGVudF8pKSB7XG4gICAgICAgICAgLy8gd2hvbGUgcXVhZCBvdXRzaWRlIHNvdXJjZSBwcm9qZWN0aW9uIGV4dGVudCAtPiBpZ25vcmVcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgaXNOb3RGaW5pdGUgPSAwO1xuXG4gICAgaWYgKCFuZWVkc1N1YmRpdmlzaW9uKSB7XG4gICAgICBpZiAoIWlzRmluaXRlKGFTcmNbMF0pIHx8ICFpc0Zpbml0ZShhU3JjWzFdKSB8fCAhaXNGaW5pdGUoYlNyY1swXSkgfHwgIWlzRmluaXRlKGJTcmNbMV0pIHx8ICFpc0Zpbml0ZShjU3JjWzBdKSB8fCAhaXNGaW5pdGUoY1NyY1sxXSkgfHwgIWlzRmluaXRlKGRTcmNbMF0pIHx8ICFpc0Zpbml0ZShkU3JjWzFdKSkge1xuICAgICAgICBpZiAobWF4U3ViZGl2aXNpb24gPiAwKSB7XG4gICAgICAgICAgbmVlZHNTdWJkaXZpc2lvbiA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gSXQgbWlnaHQgYmUgdGhlIGNhc2UgdGhhdCBvbmx5IDEgb2YgdGhlIHBvaW50cyBpcyBpbmZpbml0ZS4gSW4gdGhpcyBjYXNlXG4gICAgICAgICAgLy8gd2UgY2FuIGRyYXcgYSBzaW5nbGUgdHJpYW5nbGUgd2l0aCB0aGUgb3RoZXIgdGhyZWUgcG9pbnRzXG4gICAgICAgICAgaXNOb3RGaW5pdGUgPSAoIWlzRmluaXRlKGFTcmNbMF0pIHx8ICFpc0Zpbml0ZShhU3JjWzFdKSA/IDggOiAwKSArICghaXNGaW5pdGUoYlNyY1swXSkgfHwgIWlzRmluaXRlKGJTcmNbMV0pID8gNCA6IDApICsgKCFpc0Zpbml0ZShjU3JjWzBdKSB8fCAhaXNGaW5pdGUoY1NyY1sxXSkgPyAyIDogMCkgKyAoIWlzRmluaXRlKGRTcmNbMF0pIHx8ICFpc0Zpbml0ZShkU3JjWzFdKSA/IDEgOiAwKTtcblxuICAgICAgICAgIGlmIChpc05vdEZpbml0ZSAhPSAxICYmIGlzTm90RmluaXRlICE9IDIgJiYgaXNOb3RGaW5pdGUgIT0gNCAmJiBpc05vdEZpbml0ZSAhPSA4KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1heFN1YmRpdmlzaW9uID4gMCkge1xuICAgICAgaWYgKCFuZWVkc1N1YmRpdmlzaW9uKSB7XG4gICAgICAgIHZhciBjZW50ZXIgPSBbKGFbMF0gKyBjWzBdKSAvIDIsIChhWzFdICsgY1sxXSkgLyAyXTtcbiAgICAgICAgdmFyIGNlbnRlclNyYyA9IHRoaXMudHJhbnNmb3JtSW52XyhjZW50ZXIpO1xuICAgICAgICB2YXIgZHggPSB2b2lkIDA7XG5cbiAgICAgICAgaWYgKHdyYXBzWCkge1xuICAgICAgICAgIHZhciBjZW50ZXJTcmNFc3RpbVggPSAobW9kdWxvKGFTcmNbMF0sIHNvdXJjZVdvcmxkV2lkdGgpICsgbW9kdWxvKGNTcmNbMF0sIHNvdXJjZVdvcmxkV2lkdGgpKSAvIDI7XG4gICAgICAgICAgZHggPSBjZW50ZXJTcmNFc3RpbVggLSBtb2R1bG8oY2VudGVyU3JjWzBdLCBzb3VyY2VXb3JsZFdpZHRoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkeCA9IChhU3JjWzBdICsgY1NyY1swXSkgLyAyIC0gY2VudGVyU3JjWzBdO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGR5ID0gKGFTcmNbMV0gKyBjU3JjWzFdKSAvIDIgLSBjZW50ZXJTcmNbMV07XG4gICAgICAgIHZhciBjZW50ZXJTcmNFcnJvclNxdWFyZWQgPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICAgICAgbmVlZHNTdWJkaXZpc2lvbiA9IGNlbnRlclNyY0Vycm9yU3F1YXJlZCA+IHRoaXMuZXJyb3JUaHJlc2hvbGRTcXVhcmVkXztcbiAgICAgIH1cblxuICAgICAgaWYgKG5lZWRzU3ViZGl2aXNpb24pIHtcbiAgICAgICAgaWYgKE1hdGguYWJzKGFbMF0gLSBjWzBdKSA8PSBNYXRoLmFicyhhWzFdIC0gY1sxXSkpIHtcbiAgICAgICAgICAvLyBzcGxpdCBob3Jpem9udGFsbHkgKHRvcCAmIGJvdHRvbSlcbiAgICAgICAgICB2YXIgYmMgPSBbKGJbMF0gKyBjWzBdKSAvIDIsIChiWzFdICsgY1sxXSkgLyAyXTtcbiAgICAgICAgICB2YXIgYmNTcmMgPSB0aGlzLnRyYW5zZm9ybUludl8oYmMpO1xuICAgICAgICAgIHZhciBkYSA9IFsoZFswXSArIGFbMF0pIC8gMiwgKGRbMV0gKyBhWzFdKSAvIDJdO1xuICAgICAgICAgIHZhciBkYVNyYyA9IHRoaXMudHJhbnNmb3JtSW52XyhkYSk7XG4gICAgICAgICAgdGhpcy5hZGRRdWFkXyhhLCBiLCBiYywgZGEsIGFTcmMsIGJTcmMsIGJjU3JjLCBkYVNyYywgbWF4U3ViZGl2aXNpb24gLSAxKTtcbiAgICAgICAgICB0aGlzLmFkZFF1YWRfKGRhLCBiYywgYywgZCwgZGFTcmMsIGJjU3JjLCBjU3JjLCBkU3JjLCBtYXhTdWJkaXZpc2lvbiAtIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHNwbGl0IHZlcnRpY2FsbHkgKGxlZnQgJiByaWdodClcbiAgICAgICAgICB2YXIgYWIgPSBbKGFbMF0gKyBiWzBdKSAvIDIsIChhWzFdICsgYlsxXSkgLyAyXTtcbiAgICAgICAgICB2YXIgYWJTcmMgPSB0aGlzLnRyYW5zZm9ybUludl8oYWIpO1xuICAgICAgICAgIHZhciBjZCA9IFsoY1swXSArIGRbMF0pIC8gMiwgKGNbMV0gKyBkWzFdKSAvIDJdO1xuICAgICAgICAgIHZhciBjZFNyYyA9IHRoaXMudHJhbnNmb3JtSW52XyhjZCk7XG4gICAgICAgICAgdGhpcy5hZGRRdWFkXyhhLCBhYiwgY2QsIGQsIGFTcmMsIGFiU3JjLCBjZFNyYywgZFNyYywgbWF4U3ViZGl2aXNpb24gLSAxKTtcbiAgICAgICAgICB0aGlzLmFkZFF1YWRfKGFiLCBiLCBjLCBjZCwgYWJTcmMsIGJTcmMsIGNTcmMsIGNkU3JjLCBtYXhTdWJkaXZpc2lvbiAtIDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3cmFwc1gpIHtcbiAgICAgIGlmICghdGhpcy5jYW5XcmFwWEluU291cmNlXykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMud3JhcHNYSW5Tb3VyY2VfID0gdHJ1ZTtcbiAgICB9IC8vIEV4YWN0bHkgemVybyBvciBvbmUgb2YgKlNyYyBpcyBub3QgZmluaXRlXG4gICAgLy8gVGhlIHRyaWFuZ2xlcyBtdXN0IGhhdmUgdGhlIGRpYWdvbmFsIGxpbmUgYXMgdGhlIGZpcnN0IHNpZGVcbiAgICAvLyBUaGlzIGlzIHRvIGFsbG93IGVhc3kgY29kZSBpbiByZXByb2oucyB0byBtYWtlIGl0IHN0cmFpZ2h0IGZvciBicm9rZW5cbiAgICAvLyBicm93c2VycyB0aGF0IGNhbid0IGhhbmRsZSBkaWFnb25hbCBjbGlwcGluZ1xuXG5cbiAgICBpZiAoKGlzTm90RmluaXRlICYgMHhiKSA9PSAwKSB7XG4gICAgICB0aGlzLmFkZFRyaWFuZ2xlXyhhLCBjLCBkLCBhU3JjLCBjU3JjLCBkU3JjKTtcbiAgICB9XG5cbiAgICBpZiAoKGlzTm90RmluaXRlICYgMHhlKSA9PSAwKSB7XG4gICAgICB0aGlzLmFkZFRyaWFuZ2xlXyhhLCBjLCBiLCBhU3JjLCBjU3JjLCBiU3JjKTtcbiAgICB9XG5cbiAgICBpZiAoaXNOb3RGaW5pdGUpIHtcbiAgICAgIC8vIFRyeSB0aGUgb3RoZXIgdHdvIHRyaWFuZ2xlc1xuICAgICAgaWYgKChpc05vdEZpbml0ZSAmIDB4ZCkgPT0gMCkge1xuICAgICAgICB0aGlzLmFkZFRyaWFuZ2xlXyhiLCBkLCBhLCBiU3JjLCBkU3JjLCBhU3JjKTtcbiAgICAgIH1cblxuICAgICAgaWYgKChpc05vdEZpbml0ZSAmIDB4NykgPT0gMCkge1xuICAgICAgICB0aGlzLmFkZFRyaWFuZ2xlXyhiLCBkLCBjLCBiU3JjLCBkU3JjLCBjU3JjKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIGV4dGVudCBvZiB0aGUgJ3NvdXJjZScgY29vcmRpbmF0ZXMgZnJvbSBhbGwgdGhlIHRyaWFuZ2xlcy5cbiAgICpcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gQ2FsY3VsYXRlZCBleHRlbnQuXG4gICAqL1xuXG5cbiAgVHJpYW5ndWxhdGlvbi5wcm90b3R5cGUuY2FsY3VsYXRlU291cmNlRXh0ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBleHRlbnQgPSBjcmVhdGVFbXB0eSgpO1xuICAgIHRoaXMudHJpYW5nbGVzXy5mb3JFYWNoKGZ1bmN0aW9uICh0cmlhbmdsZSwgaSwgYXJyKSB7XG4gICAgICB2YXIgc3JjID0gdHJpYW5nbGUuc291cmNlO1xuICAgICAgZXh0ZW5kQ29vcmRpbmF0ZShleHRlbnQsIHNyY1swXSk7XG4gICAgICBleHRlbmRDb29yZGluYXRlKGV4dGVudCwgc3JjWzFdKTtcbiAgICAgIGV4dGVuZENvb3JkaW5hdGUoZXh0ZW50LCBzcmNbMl0pO1xuICAgIH0pO1xuICAgIHJldHVybiBleHRlbnQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxUcmlhbmdsZT59IEFycmF5IG9mIHRoZSBjYWxjdWxhdGVkIHRyaWFuZ2xlcy5cbiAgICovXG5cblxuICBUcmlhbmd1bGF0aW9uLnByb3RvdHlwZS5nZXRUcmlhbmdsZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudHJpYW5nbGVzXztcbiAgfTtcblxuICByZXR1cm4gVHJpYW5ndWxhdGlvbjtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgVHJpYW5ndWxhdGlvbjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvc291cmNlL2NvbW1vblxuICovXG5cbi8qKlxuICogRGVmYXVsdCBXTVMgdmVyc2lvbi5cbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCB2YXIgREVGQVVMVF9XTVNfVkVSU0lPTiA9ICcxLjMuMCc7XG4vKipcbiAqIENvbnRleHQgb3B0aW9ucyB0byBkaXNhYmxlIGltYWdlIHNtb290aGluZy5cbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cblxuZXhwb3J0IHZhciBJTUFHRV9TTU9PVEhJTkdfRElTQUJMRUQgPSB7XG4gIGltYWdlU21vb3RoaW5nRW5hYmxlZDogZmFsc2UsXG4gIG1zSW1hZ2VTbW9vdGhpbmdFbmFibGVkOiBmYWxzZVxufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVwcm9qXG4gKi9cbmltcG9ydCB7IElNQUdFX1NNT09USElOR19ESVNBQkxFRCB9IGZyb20gJy4vc291cmNlL2NvbW1vbi5qcyc7XG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICcuL29iai5qcyc7XG5pbXBvcnQgeyBjb250YWluc0Nvb3JkaW5hdGUsIGNyZWF0ZUVtcHR5LCBleHRlbmQsIGZvckVhY2hDb3JuZXIsIGdldENlbnRlciwgZ2V0SGVpZ2h0LCBnZXRUb3BMZWZ0LCBnZXRXaWR0aCB9IGZyb20gJy4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCB9IGZyb20gJy4vZG9tLmpzJztcbmltcG9ydCB7IGdldFBvaW50UmVzb2x1dGlvbiwgdHJhbnNmb3JtIH0gZnJvbSAnLi9wcm9qLmpzJztcbmltcG9ydCB7IHNvbHZlTGluZWFyU3lzdGVtIH0gZnJvbSAnLi9tYXRoLmpzJztcbnZhciBicm9rZW5EaWFnb25hbFJlbmRlcmluZ187XG4vKipcbiAqIFRoaXMgZHJhd3MgYSBzbWFsbCB0cmlhbmdsZSBpbnRvIGEgY2FudmFzIGJ5IHNldHRpbmcgdGhlIHRyaWFuZ2xlIGFzIHRoZSBjbGlwIHJlZ2lvblxuICogYW5kIHRoZW4gZHJhd2luZyBhICh0b28gbGFyZ2UpIHJlY3RhbmdsZVxuICpcbiAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjdHggVGhlIGNvbnRleHQgaW4gd2hpY2ggdG8gZHJhdyB0aGUgdHJpYW5nbGVcbiAqIEBwYXJhbSB7bnVtYmVyfSB1MSBUaGUgeC1jb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgcG9pbnQuIFRoZSBmaXJzdCBwb2ludCBpcyAwLDAuXG4gKiBAcGFyYW0ge251bWJlcn0gdjEgVGhlIHktY29vcmRpbmF0ZSBvZiB0aGUgc2Vjb25kIHBvaW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHUyIFRoZSB4LWNvb3JkaW5hdGUgb2YgdGhlIHRoaXJkIHBvaW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHYyIFRoZSB5LWNvb3JkaW5hdGUgb2YgdGhlIHRoaXJkIHBvaW50LlxuICovXG5cbmZ1bmN0aW9uIGRyYXdUZXN0VHJpYW5nbGUoY3R4LCB1MSwgdjEsIHUyLCB2Mikge1xuICBjdHguYmVnaW5QYXRoKCk7XG4gIGN0eC5tb3ZlVG8oMCwgMCk7XG4gIGN0eC5saW5lVG8odTEsIHYxKTtcbiAgY3R4LmxpbmVUbyh1MiwgdjIpO1xuICBjdHguY2xvc2VQYXRoKCk7XG4gIGN0eC5zYXZlKCk7XG4gIGN0eC5jbGlwKCk7XG4gIGN0eC5maWxsUmVjdCgwLCAwLCBNYXRoLm1heCh1MSwgdTIpICsgMSwgTWF0aC5tYXgodjEsIHYyKSk7XG4gIGN0eC5yZXN0b3JlKCk7XG59XG4vKipcbiAqIEdpdmVuIHRoZSBkYXRhIGZyb20gZ2V0SW1hZ2VEYXRhLCBzZWUgaWYgdGhlIHJpZ2h0IHZhbHVlcyBhcHBlYXIgYXQgdGhlIHByb3ZpZGVkIG9mZnNldC5cbiAqIFJldHVybnMgdHJ1ZSBpZiBlaXRoZXIgdGhlIGNvbG9yIG9yIHRyYW5zcGFyZW5jeSBpcyBvZmZcbiAqXG4gKiBAcGFyYW0ge1VpbnQ4Q2xhbXBlZEFycmF5fSBkYXRhIFRoZSBkYXRhIHJldHVybmVkIGZyb20gZ2V0SW1hZ2VEYXRhXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IFRoZSBwaXhlbCBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgZGF0YS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgdGhlIGRpYWdvbmFsIHJlbmRlcmluZyBpcyBicm9rZW5cbiAqL1xuXG5cbmZ1bmN0aW9uIHZlcmlmeUJyb2tlbkRpYWdvbmFsUmVuZGVyaW5nKGRhdGEsIG9mZnNldCkge1xuICAvLyB0aGUgdmFsdWVzIG91Z2h0IHRvIGJlIGNsb3NlIHRvIHRoZSByZ2JhKDIxMCwgMCwgMCwgMC43NSlcbiAgcmV0dXJuIE1hdGguYWJzKGRhdGFbb2Zmc2V0ICogNF0gLSAyMTApID4gMiB8fCBNYXRoLmFicyhkYXRhW29mZnNldCAqIDQgKyAzXSAtIDAuNzUgKiAyNTUpID4gMjtcbn1cbi8qKlxuICogRGV0ZXJtaW5lcyBpZiB0aGUgY3VycmVudCBicm93c2VyIGNvbmZpZ3VyYXRpb24gY2FuIHJlbmRlciB0cmlhbmd1bGFyIGNsaXAgcmVnaW9ucyBjb3JyZWN0bHkuXG4gKiBUaGlzIHZhbHVlIGlzIGNhY2hlZCBzbyB0aGUgZnVuY3Rpb24gaXMgb25seSBleHBlbnNpdmUgdGhlIGZpcnN0IHRpbWUgY2FsbGVkLlxuICogRmlyZWZveCBvbiBXaW5kb3dzIChhcyBvZiBub3cpIGRvZXMgbm90IGlmIEhXQSBpcyBlbmFibGVkLiBTZWUgaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTYwNjk3NlxuICogSUUgYWxzbyBkb2Vzbid0LiBDaHJvbWUgd29ya3MsIGFuZCBldmVyeXRoaW5nIHNlZW1zIHRvIHdvcmsgb24gT1NYIGFuZCBBbmRyb2lkLiBUaGlzIGZ1bmN0aW9uIGNhY2hlcyB0aGVcbiAqIHJlc3VsdC4gSSBzdXBwb3NlIHRoYXQgaXQgaXMgY29uY2VpdmFibHkgcG9zc2libGUgdGhhdCBhIGJyb3dzZXIgbWlnaHQgZmxpcCBtb2RlcyB3aGlsZSB0aGUgYXBwIGlzXG4gKiBydW5uaW5nLCBidXQgbGV0cyBob3BlIG5vdC5cbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufSB0cnVlIGlmIHRoZSBEaWFnb25hbCBSZW5kZXJpbmcgaXMgYnJva2VuLlxuICovXG5cblxuZnVuY3Rpb24gaXNCcm9rZW5EaWFnb25hbFJlbmRlcmluZygpIHtcbiAgaWYgKGJyb2tlbkRpYWdvbmFsUmVuZGVyaW5nXyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIGN0eCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJyk7XG4gICAgY3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdsaWdodGVyJztcbiAgICBjdHguZmlsbFN0eWxlID0gJ3JnYmEoMjEwLCAwLCAwLCAwLjc1KSc7XG4gICAgZHJhd1Rlc3RUcmlhbmdsZShjdHgsIDQsIDUsIDQsIDApO1xuICAgIGRyYXdUZXN0VHJpYW5nbGUoY3R4LCA0LCA1LCAwLCA1KTtcbiAgICB2YXIgZGF0YSA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgMywgMykuZGF0YTtcbiAgICBicm9rZW5EaWFnb25hbFJlbmRlcmluZ18gPSB2ZXJpZnlCcm9rZW5EaWFnb25hbFJlbmRlcmluZyhkYXRhLCAwKSB8fCB2ZXJpZnlCcm9rZW5EaWFnb25hbFJlbmRlcmluZyhkYXRhLCA0KSB8fCB2ZXJpZnlCcm9rZW5EaWFnb25hbFJlbmRlcmluZyhkYXRhLCA4KTtcbiAgfVxuXG4gIHJldHVybiBicm9rZW5EaWFnb25hbFJlbmRlcmluZ187XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgaWRlYWwgcmVzb2x1dGlvbiB0byB1c2UgZnJvbSB0aGUgc291cmNlIGluIG9yZGVyIHRvIGFjaGlldmVcbiAqIHBpeGVsIG1hcHBpbmcgYXMgY2xvc2UgYXMgcG9zc2libGUgdG8gMToxIGR1cmluZyByZXByb2plY3Rpb24uXG4gKiBUaGUgcmVzb2x1dGlvbiBpcyBjYWxjdWxhdGVkIHJlZ2FyZGxlc3Mgb2Ygd2hhdCByZXNvbHV0aW9uc1xuICogYXJlIGFjdHVhbGx5IGF2YWlsYWJsZSBpbiB0aGUgZGF0YXNldCAoVGlsZUdyaWQsIEltYWdlLCAuLi4pLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gc291cmNlUHJvaiBTb3VyY2UgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gdGFyZ2V0UHJvaiBUYXJnZXQgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHRhcmdldENlbnRlciBUYXJnZXQgY2VudGVyLlxuICogQHBhcmFtIHtudW1iZXJ9IHRhcmdldFJlc29sdXRpb24gVGFyZ2V0IHJlc29sdXRpb24uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBiZXN0IHJlc29sdXRpb24gdG8gdXNlLiBDYW4gYmUgKy1JbmZpbml0eSwgTmFOIG9yIDAuXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlU291cmNlUmVzb2x1dGlvbihzb3VyY2VQcm9qLCB0YXJnZXRQcm9qLCB0YXJnZXRDZW50ZXIsIHRhcmdldFJlc29sdXRpb24pIHtcbiAgdmFyIHNvdXJjZUNlbnRlciA9IHRyYW5zZm9ybSh0YXJnZXRDZW50ZXIsIHRhcmdldFByb2osIHNvdXJjZVByb2opOyAvLyBjYWxjdWxhdGUgdGhlIGlkZWFsIHJlc29sdXRpb24gb2YgdGhlIHNvdXJjZSBkYXRhXG5cbiAgdmFyIHNvdXJjZVJlc29sdXRpb24gPSBnZXRQb2ludFJlc29sdXRpb24odGFyZ2V0UHJvaiwgdGFyZ2V0UmVzb2x1dGlvbiwgdGFyZ2V0Q2VudGVyKTtcbiAgdmFyIHRhcmdldE1ldGVyc1BlclVuaXQgPSB0YXJnZXRQcm9qLmdldE1ldGVyc1BlclVuaXQoKTtcblxuICBpZiAodGFyZ2V0TWV0ZXJzUGVyVW5pdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgc291cmNlUmVzb2x1dGlvbiAqPSB0YXJnZXRNZXRlcnNQZXJVbml0O1xuICB9XG5cbiAgdmFyIHNvdXJjZU1ldGVyc1BlclVuaXQgPSBzb3VyY2VQcm9qLmdldE1ldGVyc1BlclVuaXQoKTtcblxuICBpZiAoc291cmNlTWV0ZXJzUGVyVW5pdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgc291cmNlUmVzb2x1dGlvbiAvPSBzb3VyY2VNZXRlcnNQZXJVbml0O1xuICB9IC8vIEJhc2VkIG9uIHRoZSBwcm9qZWN0aW9uIHByb3BlcnRpZXMsIHRoZSBwb2ludCByZXNvbHV0aW9uIGF0IHRoZSBzcGVjaWZpZWRcbiAgLy8gY29vcmRpbmF0ZXMgbWF5IGJlIHNsaWdodGx5IGRpZmZlcmVudC4gV2UgbmVlZCB0byByZXZlcnNlLWNvbXBlbnNhdGUgdGhpc1xuICAvLyBpbiBvcmRlciB0byBhY2hpZXZlIG9wdGltYWwgcmVzdWx0cy5cblxuXG4gIHZhciBzb3VyY2VFeHRlbnQgPSBzb3VyY2VQcm9qLmdldEV4dGVudCgpO1xuXG4gIGlmICghc291cmNlRXh0ZW50IHx8IGNvbnRhaW5zQ29vcmRpbmF0ZShzb3VyY2VFeHRlbnQsIHNvdXJjZUNlbnRlcikpIHtcbiAgICB2YXIgY29tcGVuc2F0aW9uRmFjdG9yID0gZ2V0UG9pbnRSZXNvbHV0aW9uKHNvdXJjZVByb2osIHNvdXJjZVJlc29sdXRpb24sIHNvdXJjZUNlbnRlcikgLyBzb3VyY2VSZXNvbHV0aW9uO1xuXG4gICAgaWYgKGlzRmluaXRlKGNvbXBlbnNhdGlvbkZhY3RvcikgJiYgY29tcGVuc2F0aW9uRmFjdG9yID4gMCkge1xuICAgICAgc291cmNlUmVzb2x1dGlvbiAvPSBjb21wZW5zYXRpb25GYWN0b3I7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHNvdXJjZVJlc29sdXRpb247XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgaWRlYWwgcmVzb2x1dGlvbiB0byB1c2UgZnJvbSB0aGUgc291cmNlIGluIG9yZGVyIHRvIGFjaGlldmVcbiAqIHBpeGVsIG1hcHBpbmcgYXMgY2xvc2UgYXMgcG9zc2libGUgdG8gMToxIGR1cmluZyByZXByb2plY3Rpb24uXG4gKiBUaGUgcmVzb2x1dGlvbiBpcyBjYWxjdWxhdGVkIHJlZ2FyZGxlc3Mgb2Ygd2hhdCByZXNvbHV0aW9uc1xuICogYXJlIGFjdHVhbGx5IGF2YWlsYWJsZSBpbiB0aGUgZGF0YXNldCAoVGlsZUdyaWQsIEltYWdlLCAuLi4pLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gc291cmNlUHJvaiBTb3VyY2UgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gdGFyZ2V0UHJvaiBUYXJnZXQgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSB0YXJnZXRFeHRlbnQgVGFyZ2V0IGV4dGVudFxuICogQHBhcmFtIHtudW1iZXJ9IHRhcmdldFJlc29sdXRpb24gVGFyZ2V0IHJlc29sdXRpb24uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBiZXN0IHJlc29sdXRpb24gdG8gdXNlLiBDYW4gYmUgKy1JbmZpbml0eSwgTmFOIG9yIDAuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVNvdXJjZUV4dGVudFJlc29sdXRpb24oc291cmNlUHJvaiwgdGFyZ2V0UHJvaiwgdGFyZ2V0RXh0ZW50LCB0YXJnZXRSZXNvbHV0aW9uKSB7XG4gIHZhciB0YXJnZXRDZW50ZXIgPSBnZXRDZW50ZXIodGFyZ2V0RXh0ZW50KTtcbiAgdmFyIHNvdXJjZVJlc29sdXRpb24gPSBjYWxjdWxhdGVTb3VyY2VSZXNvbHV0aW9uKHNvdXJjZVByb2osIHRhcmdldFByb2osIHRhcmdldENlbnRlciwgdGFyZ2V0UmVzb2x1dGlvbik7XG5cbiAgaWYgKCFpc0Zpbml0ZShzb3VyY2VSZXNvbHV0aW9uKSB8fCBzb3VyY2VSZXNvbHV0aW9uIDw9IDApIHtcbiAgICBmb3JFYWNoQ29ybmVyKHRhcmdldEV4dGVudCwgZnVuY3Rpb24gKGNvcm5lcikge1xuICAgICAgc291cmNlUmVzb2x1dGlvbiA9IGNhbGN1bGF0ZVNvdXJjZVJlc29sdXRpb24oc291cmNlUHJvaiwgdGFyZ2V0UHJvaiwgY29ybmVyLCB0YXJnZXRSZXNvbHV0aW9uKTtcbiAgICAgIHJldHVybiBpc0Zpbml0ZShzb3VyY2VSZXNvbHV0aW9uKSAmJiBzb3VyY2VSZXNvbHV0aW9uID4gMDtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBzb3VyY2VSZXNvbHV0aW9uO1xufVxuLyoqXG4gKiBSZW5kZXJzIHRoZSBzb3VyY2UgZGF0YSBpbnRvIG5ldyBjYW52YXMgYmFzZWQgb24gdGhlIHRyaWFuZ3VsYXRpb24uXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIFdpZHRoIG9mIHRoZSBjYW52YXMuXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IEhlaWdodCBvZiB0aGUgY2FudmFzLlxuICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gKiBAcGFyYW0ge251bWJlcn0gc291cmNlUmVzb2x1dGlvbiBTb3VyY2UgcmVzb2x1dGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBzb3VyY2VFeHRlbnQgRXh0ZW50IG9mIHRoZSBkYXRhIHNvdXJjZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0YXJnZXRSZXNvbHV0aW9uIFRhcmdldCByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IHRhcmdldEV4dGVudCBUYXJnZXQgZXh0ZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3JlcHJvai9Ucmlhbmd1bGF0aW9uLmpzXCIpLmRlZmF1bHR9IHRyaWFuZ3VsYXRpb25cbiAqIENhbGN1bGF0ZWQgdHJpYW5ndWxhdGlvbi5cbiAqIEBwYXJhbSB7QXJyYXk8e2V4dGVudDogaW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50LFxuICogICAgICAgICAgICAgICAgIGltYWdlOiAoSFRNTENhbnZhc0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50KX0+fSBzb3VyY2VzXG4gKiBBcnJheSBvZiBzb3VyY2VzLlxuICogQHBhcmFtIHtudW1iZXJ9IGd1dHRlciBHdXR0ZXIgb2YgdGhlIHNvdXJjZXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfcmVuZGVyRWRnZXMgUmVuZGVyIHJlcHJvamVjdGlvbiBlZGdlcy5cbiAqIEBwYXJhbSB7b2JqZWN0PX0gb3B0X2NvbnRleHRPcHRpb25zIFByb3BlcnRpZXMgdG8gc2V0IG9uIHRoZSBjYW52YXMgY29udGV4dC5cbiAqIEByZXR1cm4ge0hUTUxDYW52YXNFbGVtZW50fSBDYW52YXMgd2l0aCByZXByb2plY3RlZCBkYXRhLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXIod2lkdGgsIGhlaWdodCwgcGl4ZWxSYXRpbywgc291cmNlUmVzb2x1dGlvbiwgc291cmNlRXh0ZW50LCB0YXJnZXRSZXNvbHV0aW9uLCB0YXJnZXRFeHRlbnQsIHRyaWFuZ3VsYXRpb24sIHNvdXJjZXMsIGd1dHRlciwgb3B0X3JlbmRlckVkZ2VzLCBvcHRfY29udGV4dE9wdGlvbnMpIHtcbiAgdmFyIGNvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0MkQoTWF0aC5yb3VuZChwaXhlbFJhdGlvICogd2lkdGgpLCBNYXRoLnJvdW5kKHBpeGVsUmF0aW8gKiBoZWlnaHQpKTtcbiAgYXNzaWduKGNvbnRleHQsIG9wdF9jb250ZXh0T3B0aW9ucyk7XG5cbiAgaWYgKHNvdXJjZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIGNvbnRleHQuY2FudmFzO1xuICB9XG5cbiAgY29udGV4dC5zY2FsZShwaXhlbFJhdGlvLCBwaXhlbFJhdGlvKTtcblxuICBmdW5jdGlvbiBwaXhlbFJvdW5kKHZhbHVlKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQodmFsdWUgKiBwaXhlbFJhdGlvKSAvIHBpeGVsUmF0aW87XG4gIH1cblxuICBjb250ZXh0Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdsaWdodGVyJztcbiAgdmFyIHNvdXJjZURhdGFFeHRlbnQgPSBjcmVhdGVFbXB0eSgpO1xuICBzb3VyY2VzLmZvckVhY2goZnVuY3Rpb24gKHNyYywgaSwgYXJyKSB7XG4gICAgZXh0ZW5kKHNvdXJjZURhdGFFeHRlbnQsIHNyYy5leHRlbnQpO1xuICB9KTtcbiAgdmFyIGNhbnZhc1dpZHRoSW5Vbml0cyA9IGdldFdpZHRoKHNvdXJjZURhdGFFeHRlbnQpO1xuICB2YXIgY2FudmFzSGVpZ2h0SW5Vbml0cyA9IGdldEhlaWdodChzb3VyY2VEYXRhRXh0ZW50KTtcbiAgdmFyIHN0aXRjaENvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0MkQoTWF0aC5yb3VuZChwaXhlbFJhdGlvICogY2FudmFzV2lkdGhJblVuaXRzIC8gc291cmNlUmVzb2x1dGlvbiksIE1hdGgucm91bmQocGl4ZWxSYXRpbyAqIGNhbnZhc0hlaWdodEluVW5pdHMgLyBzb3VyY2VSZXNvbHV0aW9uKSk7XG4gIGFzc2lnbihzdGl0Y2hDb250ZXh0LCBvcHRfY29udGV4dE9wdGlvbnMpO1xuICB2YXIgc3RpdGNoU2NhbGUgPSBwaXhlbFJhdGlvIC8gc291cmNlUmVzb2x1dGlvbjtcbiAgc291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uIChzcmMsIGksIGFycikge1xuICAgIHZhciB4UG9zID0gc3JjLmV4dGVudFswXSAtIHNvdXJjZURhdGFFeHRlbnRbMF07XG4gICAgdmFyIHlQb3MgPSAtKHNyYy5leHRlbnRbM10gLSBzb3VyY2VEYXRhRXh0ZW50WzNdKTtcbiAgICB2YXIgc3JjV2lkdGggPSBnZXRXaWR0aChzcmMuZXh0ZW50KTtcbiAgICB2YXIgc3JjSGVpZ2h0ID0gZ2V0SGVpZ2h0KHNyYy5leHRlbnQpOyAvLyBUaGlzIHRlc3Qgc2hvdWxkIG5ldmVyIGZhaWwgLS0gYnV0IGl0IGRvZXMuIE5lZWQgdG8gZmluZCBhIGZpeCB0aGUgdXBzdHJlYW0gY29uZGl0aW9uXG5cbiAgICBpZiAoc3JjLmltYWdlLndpZHRoID4gMCAmJiBzcmMuaW1hZ2UuaGVpZ2h0ID4gMCkge1xuICAgICAgc3RpdGNoQ29udGV4dC5kcmF3SW1hZ2Uoc3JjLmltYWdlLCBndXR0ZXIsIGd1dHRlciwgc3JjLmltYWdlLndpZHRoIC0gMiAqIGd1dHRlciwgc3JjLmltYWdlLmhlaWdodCAtIDIgKiBndXR0ZXIsIHhQb3MgKiBzdGl0Y2hTY2FsZSwgeVBvcyAqIHN0aXRjaFNjYWxlLCBzcmNXaWR0aCAqIHN0aXRjaFNjYWxlLCBzcmNIZWlnaHQgKiBzdGl0Y2hTY2FsZSk7XG4gICAgfVxuICB9KTtcbiAgdmFyIHRhcmdldFRvcExlZnQgPSBnZXRUb3BMZWZ0KHRhcmdldEV4dGVudCk7XG4gIHRyaWFuZ3VsYXRpb24uZ2V0VHJpYW5nbGVzKCkuZm9yRWFjaChmdW5jdGlvbiAodHJpYW5nbGUsIGksIGFycikge1xuICAgIC8qIENhbGN1bGF0ZSBhZmZpbmUgdHJhbnNmb3JtIChzcmMgLT4gZHN0KVxuICAgICAqIFJlc3VsdGluZyBtYXRyaXggY2FuIGJlIHVzZWQgdG8gdHJhbnNmb3JtIGNvb3JkaW5hdGVcbiAgICAgKiBmcm9tIGBzb3VyY2VQcm9qZWN0aW9uYCB0byBkZXN0aW5hdGlvbiBwaXhlbHMuXG4gICAgICpcbiAgICAgKiBUbyBvcHRpbWl6ZSBudW1iZXIgb2YgY29udGV4dCBjYWxscyBhbmQgaW5jcmVhc2UgbnVtZXJpY2FsIHN0YWJpbGl0eSxcbiAgICAgKiB3ZSBhbHNvIGRvIHRoZSBmb2xsb3dpbmcgb3BlcmF0aW9uczpcbiAgICAgKiB0cmFucygtdG9wTGVmdEV4dGVudENvcm5lciksIHNjYWxlKDEgLyB0YXJnZXRSZXNvbHV0aW9uKSwgc2NhbGUoMSwgLTEpXG4gICAgICogaGVyZSBiZWZvcmUgc29sdmluZyB0aGUgbGluZWFyIHN5c3RlbSBzbyBbdWksIHZpXSBhcmUgcGl4ZWwgY29vcmRpbmF0ZXMuXG4gICAgICpcbiAgICAgKiBTcmMgcG9pbnRzOiB4aSwgeWlcbiAgICAgKiBEc3QgcG9pbnRzOiB1aSwgdmlcbiAgICAgKiBBZmZpbmUgY29lZmZpY2llbnRzOiBhaWpcbiAgICAgKlxuICAgICAqIHwgeDAgeTAgMSAgMCAgMCAwIHwgICB8YTAwfCAgIHx1MHxcbiAgICAgKiB8IHgxIHkxIDEgIDAgIDAgMCB8ICAgfGEwMXwgICB8dTF8XG4gICAgICogfCB4MiB5MiAxICAwICAwIDAgfCB4IHxhMDJ8ID0gfHUyfFxuICAgICAqIHwgIDAgIDAgMCB4MCB5MCAxIHwgICB8YTEwfCAgIHx2MHxcbiAgICAgKiB8ICAwICAwIDAgeDEgeTEgMSB8ICAgfGExMXwgICB8djF8XG4gICAgICogfCAgMCAgMCAwIHgyIHkyIDEgfCAgIHxhMTJ8ICAgfHYyfFxuICAgICAqL1xuICAgIHZhciBzb3VyY2UgPSB0cmlhbmdsZS5zb3VyY2U7XG4gICAgdmFyIHRhcmdldCA9IHRyaWFuZ2xlLnRhcmdldDtcbiAgICB2YXIgeDAgPSBzb3VyY2VbMF1bMF0sXG4gICAgICAgIHkwID0gc291cmNlWzBdWzFdO1xuICAgIHZhciB4MSA9IHNvdXJjZVsxXVswXSxcbiAgICAgICAgeTEgPSBzb3VyY2VbMV1bMV07XG4gICAgdmFyIHgyID0gc291cmNlWzJdWzBdLFxuICAgICAgICB5MiA9IHNvdXJjZVsyXVsxXTsgLy8gTWFrZSBzdXJlIHRoYXQgZXZlcnl0aGluZyBpcyBvbiBwaXhlbCBib3VuZGFyaWVzXG5cbiAgICB2YXIgdTAgPSBwaXhlbFJvdW5kKCh0YXJnZXRbMF1bMF0gLSB0YXJnZXRUb3BMZWZ0WzBdKSAvIHRhcmdldFJlc29sdXRpb24pO1xuICAgIHZhciB2MCA9IHBpeGVsUm91bmQoLSh0YXJnZXRbMF1bMV0gLSB0YXJnZXRUb3BMZWZ0WzFdKSAvIHRhcmdldFJlc29sdXRpb24pO1xuICAgIHZhciB1MSA9IHBpeGVsUm91bmQoKHRhcmdldFsxXVswXSAtIHRhcmdldFRvcExlZnRbMF0pIC8gdGFyZ2V0UmVzb2x1dGlvbik7XG4gICAgdmFyIHYxID0gcGl4ZWxSb3VuZCgtKHRhcmdldFsxXVsxXSAtIHRhcmdldFRvcExlZnRbMV0pIC8gdGFyZ2V0UmVzb2x1dGlvbik7XG4gICAgdmFyIHUyID0gcGl4ZWxSb3VuZCgodGFyZ2V0WzJdWzBdIC0gdGFyZ2V0VG9wTGVmdFswXSkgLyB0YXJnZXRSZXNvbHV0aW9uKTtcbiAgICB2YXIgdjIgPSBwaXhlbFJvdW5kKC0odGFyZ2V0WzJdWzFdIC0gdGFyZ2V0VG9wTGVmdFsxXSkgLyB0YXJnZXRSZXNvbHV0aW9uKTsgLy8gU2hpZnQgYWxsIHRoZSBzb3VyY2UgcG9pbnRzIHRvIGltcHJvdmUgbnVtZXJpY2FsIHN0YWJpbGl0eVxuICAgIC8vIG9mIGFsbCB0aGUgc3Vic2VxdWVudCBjYWxjdWxhdGlvbnMuIFRoZSBbeDAsIHkwXSBpcyB1c2VkIGhlcmUuXG4gICAgLy8gVGhpcyBpcyBhbHNvIHVzZWQgdG8gc2ltcGxpZnkgdGhlIGxpbmVhciBzeXN0ZW0uXG5cbiAgICB2YXIgc291cmNlTnVtZXJpY2FsU2hpZnRYID0geDA7XG4gICAgdmFyIHNvdXJjZU51bWVyaWNhbFNoaWZ0WSA9IHkwO1xuICAgIHgwID0gMDtcbiAgICB5MCA9IDA7XG4gICAgeDEgLT0gc291cmNlTnVtZXJpY2FsU2hpZnRYO1xuICAgIHkxIC09IHNvdXJjZU51bWVyaWNhbFNoaWZ0WTtcbiAgICB4MiAtPSBzb3VyY2VOdW1lcmljYWxTaGlmdFg7XG4gICAgeTIgLT0gc291cmNlTnVtZXJpY2FsU2hpZnRZO1xuICAgIHZhciBhdWdtZW50ZWRNYXRyaXggPSBbW3gxLCB5MSwgMCwgMCwgdTEgLSB1MF0sIFt4MiwgeTIsIDAsIDAsIHUyIC0gdTBdLCBbMCwgMCwgeDEsIHkxLCB2MSAtIHYwXSwgWzAsIDAsIHgyLCB5MiwgdjIgLSB2MF1dO1xuICAgIHZhciBhZmZpbmVDb2VmcyA9IHNvbHZlTGluZWFyU3lzdGVtKGF1Z21lbnRlZE1hdHJpeCk7XG5cbiAgICBpZiAoIWFmZmluZUNvZWZzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29udGV4dC5zYXZlKCk7XG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcblxuICAgIGlmIChpc0Jyb2tlbkRpYWdvbmFsUmVuZGVyaW5nKCkgfHwgb3B0X2NvbnRleHRPcHRpb25zID09PSBJTUFHRV9TTU9PVEhJTkdfRElTQUJMRUQpIHtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IGFsbCBsaW5lcyBhcmUgaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbFxuICAgICAgY29udGV4dC5tb3ZlVG8odTEsIHYxKTsgLy8gVGhpcyBpcyB0aGUgZGlhZ29uYWwgbGluZS4gRG8gaXQgaW4gNCBzdGVwc1xuXG4gICAgICB2YXIgc3RlcHMgPSA0O1xuICAgICAgdmFyIHVkID0gdTAgLSB1MTtcbiAgICAgIHZhciB2ZCA9IHYwIC0gdjE7XG5cbiAgICAgIGZvciAodmFyIHN0ZXAgPSAwOyBzdGVwIDwgc3RlcHM7IHN0ZXArKykge1xuICAgICAgICAvLyBHbyBob3Jpem9udGFsbHlcbiAgICAgICAgY29udGV4dC5saW5lVG8odTEgKyBwaXhlbFJvdW5kKChzdGVwICsgMSkgKiB1ZCAvIHN0ZXBzKSwgdjEgKyBwaXhlbFJvdW5kKHN0ZXAgKiB2ZCAvIChzdGVwcyAtIDEpKSk7IC8vIEdvIHZlcnRpY2FsbHlcblxuICAgICAgICBpZiAoc3RlcCAhPSBzdGVwcyAtIDEpIHtcbiAgICAgICAgICBjb250ZXh0LmxpbmVUbyh1MSArIHBpeGVsUm91bmQoKHN0ZXAgKyAxKSAqIHVkIC8gc3RlcHMpLCB2MSArIHBpeGVsUm91bmQoKHN0ZXAgKyAxKSAqIHZkIC8gKHN0ZXBzIC0gMSkpKTtcbiAgICAgICAgfVxuICAgICAgfSAvLyBXZSBhcmUgYWxtb3N0IGF0IHUwciwgdjByXG5cblxuICAgICAgY29udGV4dC5saW5lVG8odTIsIHYyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dC5tb3ZlVG8odTEsIHYxKTtcbiAgICAgIGNvbnRleHQubGluZVRvKHUwLCB2MCk7XG4gICAgICBjb250ZXh0LmxpbmVUbyh1MiwgdjIpO1xuICAgIH1cblxuICAgIGNvbnRleHQuY2xpcCgpO1xuICAgIGNvbnRleHQudHJhbnNmb3JtKGFmZmluZUNvZWZzWzBdLCBhZmZpbmVDb2Vmc1syXSwgYWZmaW5lQ29lZnNbMV0sIGFmZmluZUNvZWZzWzNdLCB1MCwgdjApO1xuICAgIGNvbnRleHQudHJhbnNsYXRlKHNvdXJjZURhdGFFeHRlbnRbMF0gLSBzb3VyY2VOdW1lcmljYWxTaGlmdFgsIHNvdXJjZURhdGFFeHRlbnRbM10gLSBzb3VyY2VOdW1lcmljYWxTaGlmdFkpO1xuICAgIGNvbnRleHQuc2NhbGUoc291cmNlUmVzb2x1dGlvbiAvIHBpeGVsUmF0aW8sIC1zb3VyY2VSZXNvbHV0aW9uIC8gcGl4ZWxSYXRpbyk7XG4gICAgY29udGV4dC5kcmF3SW1hZ2Uoc3RpdGNoQ29udGV4dC5jYW52YXMsIDAsIDApO1xuICAgIGNvbnRleHQucmVzdG9yZSgpO1xuICB9KTtcblxuICBpZiAob3B0X3JlbmRlckVkZ2VzKSB7XG4gICAgY29udGV4dC5zYXZlKCk7XG4gICAgY29udGV4dC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSAnc291cmNlLW92ZXInO1xuICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSAnYmxhY2snO1xuICAgIGNvbnRleHQubGluZVdpZHRoID0gMTtcbiAgICB0cmlhbmd1bGF0aW9uLmdldFRyaWFuZ2xlcygpLmZvckVhY2goZnVuY3Rpb24gKHRyaWFuZ2xlLCBpLCBhcnIpIHtcbiAgICAgIHZhciB0YXJnZXQgPSB0cmlhbmdsZS50YXJnZXQ7XG4gICAgICB2YXIgdTAgPSAodGFyZ2V0WzBdWzBdIC0gdGFyZ2V0VG9wTGVmdFswXSkgLyB0YXJnZXRSZXNvbHV0aW9uO1xuICAgICAgdmFyIHYwID0gLSh0YXJnZXRbMF1bMV0gLSB0YXJnZXRUb3BMZWZ0WzFdKSAvIHRhcmdldFJlc29sdXRpb247XG4gICAgICB2YXIgdTEgPSAodGFyZ2V0WzFdWzBdIC0gdGFyZ2V0VG9wTGVmdFswXSkgLyB0YXJnZXRSZXNvbHV0aW9uO1xuICAgICAgdmFyIHYxID0gLSh0YXJnZXRbMV1bMV0gLSB0YXJnZXRUb3BMZWZ0WzFdKSAvIHRhcmdldFJlc29sdXRpb247XG4gICAgICB2YXIgdTIgPSAodGFyZ2V0WzJdWzBdIC0gdGFyZ2V0VG9wTGVmdFswXSkgLyB0YXJnZXRSZXNvbHV0aW9uO1xuICAgICAgdmFyIHYyID0gLSh0YXJnZXRbMl1bMV0gLSB0YXJnZXRUb3BMZWZ0WzFdKSAvIHRhcmdldFJlc29sdXRpb247XG4gICAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgICAgY29udGV4dC5tb3ZlVG8odTEsIHYxKTtcbiAgICAgIGNvbnRleHQubGluZVRvKHUwLCB2MCk7XG4gICAgICBjb250ZXh0LmxpbmVUbyh1MiwgdjIpO1xuICAgICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgfSk7XG4gICAgY29udGV4dC5yZXN0b3JlKCk7XG4gIH1cblxuICByZXR1cm4gY29udGV4dC5jYW52YXM7XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9yZXByb2ovVGlsZVxuICovXG5cblxuaW1wb3J0IHsgRVJST1JfVEhSRVNIT0xEIH0gZnJvbSAnLi9jb21tb24uanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBUaWxlIGZyb20gJy4uL1RpbGUuanMnO1xuaW1wb3J0IFRpbGVTdGF0ZSBmcm9tICcuLi9UaWxlU3RhdGUuanMnO1xuaW1wb3J0IFRyaWFuZ3VsYXRpb24gZnJvbSAnLi9Ucmlhbmd1bGF0aW9uLmpzJztcbmltcG9ydCB7IGNhbGN1bGF0ZVNvdXJjZUV4dGVudFJlc29sdXRpb24sIHJlbmRlciBhcyByZW5kZXJSZXByb2plY3RlZCB9IGZyb20gJy4uL3JlcHJvai5qcyc7XG5pbXBvcnQgeyBjbGFtcCB9IGZyb20gJy4uL21hdGguanMnO1xuaW1wb3J0IHsgZ2V0QXJlYSwgZ2V0SW50ZXJzZWN0aW9uIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGxpc3RlbiwgdW5saXN0ZW5CeUtleSB9IGZyb20gJy4uL2V2ZW50cy5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIpIDogaW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0fSBGdW5jdGlvblR5cGVcbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIENsYXNzIGVuY2Fwc3VsYXRpbmcgc2luZ2xlIHJlcHJvamVjdGVkIHRpbGUuXG4gKiBTZWUge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVGlsZUltYWdlflRpbGVJbWFnZX0uXG4gKlxuICovXG5cbnZhciBSZXByb2pUaWxlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFJlcHJvalRpbGUsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBzb3VyY2VQcm9qIFNvdXJjZSBwcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IHNvdXJjZVRpbGVHcmlkIFNvdXJjZSB0aWxlIGdyaWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHRhcmdldFByb2ogVGFyZ2V0IHByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gdGFyZ2V0VGlsZUdyaWQgVGFyZ2V0IHRpbGUgZ3JpZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSB0aWxlQ29vcmQgQ29vcmRpbmF0ZSBvZiB0aGUgdGlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSB3cmFwcGVkVGlsZUNvb3JkIENvb3JkaW5hdGUgb2YgdGhlIHRpbGUgd3JhcHBlZCBpbiBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGd1dHRlciBHdXR0ZXIgb2YgdGhlIHNvdXJjZSB0aWxlcy5cbiAgICogQHBhcmFtIHtGdW5jdGlvblR5cGV9IGdldFRpbGVGdW5jdGlvblxuICAgKiAgICAgRnVuY3Rpb24gcmV0dXJuaW5nIHNvdXJjZSB0aWxlcyAoeiwgeCwgeSwgcGl4ZWxSYXRpbykuXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2Vycm9yVGhyZXNob2xkIEFjY2VwdGFibGUgcmVwcm9qZWN0aW9uIGVycm9yIChpbiBweCkuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yZW5kZXJFZGdlcyBSZW5kZXIgcmVwcm9qZWN0aW9uIGVkZ2VzLlxuICAgKiBAcGFyYW0ge29iamVjdD19IG9wdF9jb250ZXh0T3B0aW9ucyBQcm9wZXJ0aWVzIHRvIHNldCBvbiB0aGUgY2FudmFzIGNvbnRleHQuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gUmVwcm9qVGlsZShzb3VyY2VQcm9qLCBzb3VyY2VUaWxlR3JpZCwgdGFyZ2V0UHJvaiwgdGFyZ2V0VGlsZUdyaWQsIHRpbGVDb29yZCwgd3JhcHBlZFRpbGVDb29yZCwgcGl4ZWxSYXRpbywgZ3V0dGVyLCBnZXRUaWxlRnVuY3Rpb24sIG9wdF9lcnJvclRocmVzaG9sZCwgb3B0X3JlbmRlckVkZ2VzLCBvcHRfY29udGV4dE9wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0aWxlQ29vcmQsIFRpbGVTdGF0ZS5JRExFKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cblxuICAgIF90aGlzLnJlbmRlckVkZ2VzXyA9IG9wdF9yZW5kZXJFZGdlcyAhPT0gdW5kZWZpbmVkID8gb3B0X3JlbmRlckVkZ2VzIDogZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7b2JqZWN0fVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29udGV4dE9wdGlvbnNfID0gb3B0X2NvbnRleHRPcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnBpeGVsUmF0aW9fID0gcGl4ZWxSYXRpbztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5ndXR0ZXJfID0gZ3V0dGVyO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0hUTUxDYW52YXNFbGVtZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMuY2FudmFzXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnNvdXJjZVRpbGVHcmlkXyA9IHNvdXJjZVRpbGVHcmlkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy50YXJnZXRUaWxlR3JpZF8gPSB0YXJnZXRUaWxlR3JpZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfVxuICAgICAqL1xuXG4gICAgX3RoaXMud3JhcHBlZFRpbGVDb29yZF8gPSB3cmFwcGVkVGlsZUNvb3JkID8gd3JhcHBlZFRpbGVDb29yZCA6IHRpbGVDb29yZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshQXJyYXk8aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnNvdXJjZVRpbGVzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9BcnJheTxpbXBvcnQoXCIuLi9ldmVudHMuanNcIikuRXZlbnRzS2V5Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnNvdXJjZXNMaXN0ZW5lcktleXNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5zb3VyY2VaXyA9IDA7XG4gICAgdmFyIHRhcmdldEV4dGVudCA9IHRhcmdldFRpbGVHcmlkLmdldFRpbGVDb29yZEV4dGVudChfdGhpcy53cmFwcGVkVGlsZUNvb3JkXyk7XG5cbiAgICB2YXIgbWF4VGFyZ2V0RXh0ZW50ID0gX3RoaXMudGFyZ2V0VGlsZUdyaWRfLmdldEV4dGVudCgpO1xuXG4gICAgdmFyIG1heFNvdXJjZUV4dGVudCA9IF90aGlzLnNvdXJjZVRpbGVHcmlkXy5nZXRFeHRlbnQoKTtcblxuICAgIHZhciBsaW1pdGVkVGFyZ2V0RXh0ZW50ID0gbWF4VGFyZ2V0RXh0ZW50ID8gZ2V0SW50ZXJzZWN0aW9uKHRhcmdldEV4dGVudCwgbWF4VGFyZ2V0RXh0ZW50KSA6IHRhcmdldEV4dGVudDtcblxuICAgIGlmIChnZXRBcmVhKGxpbWl0ZWRUYXJnZXRFeHRlbnQpID09PSAwKSB7XG4gICAgICAvLyBUaWxlIGlzIGNvbXBsZXRlbHkgb3V0c2lkZSByYW5nZSAtPiBFTVBUWVxuICAgICAgLy8gVE9ETzogaXMgaXQgYWN0dWFsbHkgY29ycmVjdCB0aGF0IHRoZSBzb3VyY2UgZXZlbiBjcmVhdGVzIHRoZSB0aWxlID9cbiAgICAgIF90aGlzLnN0YXRlID0gVGlsZVN0YXRlLkVNUFRZO1xuICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cblxuICAgIHZhciBzb3VyY2VQcm9qRXh0ZW50ID0gc291cmNlUHJvai5nZXRFeHRlbnQoKTtcblxuICAgIGlmIChzb3VyY2VQcm9qRXh0ZW50KSB7XG4gICAgICBpZiAoIW1heFNvdXJjZUV4dGVudCkge1xuICAgICAgICBtYXhTb3VyY2VFeHRlbnQgPSBzb3VyY2VQcm9qRXh0ZW50O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWF4U291cmNlRXh0ZW50ID0gZ2V0SW50ZXJzZWN0aW9uKG1heFNvdXJjZUV4dGVudCwgc291cmNlUHJvakV4dGVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHRhcmdldFJlc29sdXRpb24gPSB0YXJnZXRUaWxlR3JpZC5nZXRSZXNvbHV0aW9uKF90aGlzLndyYXBwZWRUaWxlQ29vcmRfWzBdKTtcbiAgICB2YXIgc291cmNlUmVzb2x1dGlvbiA9IGNhbGN1bGF0ZVNvdXJjZUV4dGVudFJlc29sdXRpb24oc291cmNlUHJvaiwgdGFyZ2V0UHJvaiwgbGltaXRlZFRhcmdldEV4dGVudCwgdGFyZ2V0UmVzb2x1dGlvbik7XG5cbiAgICBpZiAoIWlzRmluaXRlKHNvdXJjZVJlc29sdXRpb24pIHx8IHNvdXJjZVJlc29sdXRpb24gPD0gMCkge1xuICAgICAgLy8gaW52YWxpZCBzb3VyY2VSZXNvbHV0aW9uIC0+IEVNUFRZXG4gICAgICAvLyBwcm9iYWJseSBlZGdlcyBvZiB0aGUgcHJvamVjdGlvbnMgd2hlbiBubyBleHRlbnQgaXMgZGVmaW5lZFxuICAgICAgX3RoaXMuc3RhdGUgPSBUaWxlU3RhdGUuRU1QVFk7XG4gICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuXG4gICAgdmFyIGVycm9yVGhyZXNob2xkSW5QaXhlbHMgPSBvcHRfZXJyb3JUaHJlc2hvbGQgIT09IHVuZGVmaW5lZCA/IG9wdF9lcnJvclRocmVzaG9sZCA6IEVSUk9SX1RIUkVTSE9MRDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshaW1wb3J0KFwiLi9Ucmlhbmd1bGF0aW9uLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy50cmlhbmd1bGF0aW9uXyA9IG5ldyBUcmlhbmd1bGF0aW9uKHNvdXJjZVByb2osIHRhcmdldFByb2osIGxpbWl0ZWRUYXJnZXRFeHRlbnQsIG1heFNvdXJjZUV4dGVudCwgc291cmNlUmVzb2x1dGlvbiAqIGVycm9yVGhyZXNob2xkSW5QaXhlbHMsIHRhcmdldFJlc29sdXRpb24pO1xuXG4gICAgaWYgKF90aGlzLnRyaWFuZ3VsYXRpb25fLmdldFRyaWFuZ2xlcygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgLy8gbm8gdmFsaWQgdHJpYW5nbGVzIC0+IEVNUFRZXG4gICAgICBfdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5FTVBUWTtcbiAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG5cbiAgICBfdGhpcy5zb3VyY2VaXyA9IHNvdXJjZVRpbGVHcmlkLmdldFpGb3JSZXNvbHV0aW9uKHNvdXJjZVJlc29sdXRpb24pO1xuXG4gICAgdmFyIHNvdXJjZUV4dGVudCA9IF90aGlzLnRyaWFuZ3VsYXRpb25fLmNhbGN1bGF0ZVNvdXJjZUV4dGVudCgpO1xuXG4gICAgaWYgKG1heFNvdXJjZUV4dGVudCkge1xuICAgICAgaWYgKHNvdXJjZVByb2ouY2FuV3JhcFgoKSkge1xuICAgICAgICBzb3VyY2VFeHRlbnRbMV0gPSBjbGFtcChzb3VyY2VFeHRlbnRbMV0sIG1heFNvdXJjZUV4dGVudFsxXSwgbWF4U291cmNlRXh0ZW50WzNdKTtcbiAgICAgICAgc291cmNlRXh0ZW50WzNdID0gY2xhbXAoc291cmNlRXh0ZW50WzNdLCBtYXhTb3VyY2VFeHRlbnRbMV0sIG1heFNvdXJjZUV4dGVudFszXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzb3VyY2VFeHRlbnQgPSBnZXRJbnRlcnNlY3Rpb24oc291cmNlRXh0ZW50LCBtYXhTb3VyY2VFeHRlbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghZ2V0QXJlYShzb3VyY2VFeHRlbnQpKSB7XG4gICAgICBfdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5FTVBUWTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHNvdXJjZVJhbmdlID0gc291cmNlVGlsZUdyaWQuZ2V0VGlsZVJhbmdlRm9yRXh0ZW50QW5kWihzb3VyY2VFeHRlbnQsIF90aGlzLnNvdXJjZVpfKTtcblxuICAgICAgZm9yICh2YXIgc3JjWCA9IHNvdXJjZVJhbmdlLm1pblg7IHNyY1ggPD0gc291cmNlUmFuZ2UubWF4WDsgc3JjWCsrKSB7XG4gICAgICAgIGZvciAodmFyIHNyY1kgPSBzb3VyY2VSYW5nZS5taW5ZOyBzcmNZIDw9IHNvdXJjZVJhbmdlLm1heFk7IHNyY1krKykge1xuICAgICAgICAgIHZhciB0aWxlID0gZ2V0VGlsZUZ1bmN0aW9uKF90aGlzLnNvdXJjZVpfLCBzcmNYLCBzcmNZLCBwaXhlbFJhdGlvKTtcblxuICAgICAgICAgIGlmICh0aWxlKSB7XG4gICAgICAgICAgICBfdGhpcy5zb3VyY2VUaWxlc18ucHVzaCh0aWxlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKF90aGlzLnNvdXJjZVRpbGVzXy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgX3RoaXMuc3RhdGUgPSBUaWxlU3RhdGUuRU1QVFk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIEhUTUwgQ2FudmFzIGVsZW1lbnQgZm9yIHRoaXMgdGlsZS5cbiAgICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR9IENhbnZhcy5cbiAgICovXG5cblxuICBSZXByb2pUaWxlLnByb3RvdHlwZS5nZXRJbWFnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jYW52YXNfO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBSZXByb2pUaWxlLnByb3RvdHlwZS5yZXByb2plY3RfID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzb3VyY2VzID0gW107XG4gICAgdGhpcy5zb3VyY2VUaWxlc18uZm9yRWFjaChmdW5jdGlvbiAodGlsZSwgaSwgYXJyKSB7XG4gICAgICBpZiAodGlsZSAmJiB0aWxlLmdldFN0YXRlKCkgPT0gVGlsZVN0YXRlLkxPQURFRCkge1xuICAgICAgICBzb3VyY2VzLnB1c2goe1xuICAgICAgICAgIGV4dGVudDogdGhpcy5zb3VyY2VUaWxlR3JpZF8uZ2V0VGlsZUNvb3JkRXh0ZW50KHRpbGUudGlsZUNvb3JkKSxcbiAgICAgICAgICBpbWFnZTogdGlsZS5nZXRJbWFnZSgpXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0uYmluZCh0aGlzKSk7XG4gICAgdGhpcy5zb3VyY2VUaWxlc18ubGVuZ3RoID0gMDtcblxuICAgIGlmIChzb3VyY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5FUlJPUjtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHogPSB0aGlzLndyYXBwZWRUaWxlQ29vcmRfWzBdO1xuICAgICAgdmFyIHNpemUgPSB0aGlzLnRhcmdldFRpbGVHcmlkXy5nZXRUaWxlU2l6ZSh6KTtcbiAgICAgIHZhciB3aWR0aCA9IHR5cGVvZiBzaXplID09PSAnbnVtYmVyJyA/IHNpemUgOiBzaXplWzBdO1xuICAgICAgdmFyIGhlaWdodCA9IHR5cGVvZiBzaXplID09PSAnbnVtYmVyJyA/IHNpemUgOiBzaXplWzFdO1xuICAgICAgdmFyIHRhcmdldFJlc29sdXRpb24gPSB0aGlzLnRhcmdldFRpbGVHcmlkXy5nZXRSZXNvbHV0aW9uKHopO1xuICAgICAgdmFyIHNvdXJjZVJlc29sdXRpb24gPSB0aGlzLnNvdXJjZVRpbGVHcmlkXy5nZXRSZXNvbHV0aW9uKHRoaXMuc291cmNlWl8pO1xuICAgICAgdmFyIHRhcmdldEV4dGVudCA9IHRoaXMudGFyZ2V0VGlsZUdyaWRfLmdldFRpbGVDb29yZEV4dGVudCh0aGlzLndyYXBwZWRUaWxlQ29vcmRfKTtcbiAgICAgIHRoaXMuY2FudmFzXyA9IHJlbmRlclJlcHJvamVjdGVkKHdpZHRoLCBoZWlnaHQsIHRoaXMucGl4ZWxSYXRpb18sIHNvdXJjZVJlc29sdXRpb24sIHRoaXMuc291cmNlVGlsZUdyaWRfLmdldEV4dGVudCgpLCB0YXJnZXRSZXNvbHV0aW9uLCB0YXJnZXRFeHRlbnQsIHRoaXMudHJpYW5ndWxhdGlvbl8sIHNvdXJjZXMsIHRoaXMuZ3V0dGVyXywgdGhpcy5yZW5kZXJFZGdlc18sIHRoaXMuY29udGV4dE9wdGlvbnNfKTtcbiAgICAgIHRoaXMuc3RhdGUgPSBUaWxlU3RhdGUuTE9BREVEO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTG9hZCBub3QgeWV0IGxvYWRlZCBVUkkuXG4gICAqL1xuXG5cbiAgUmVwcm9qVGlsZS5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZSA9PSBUaWxlU3RhdGUuSURMRSkge1xuICAgICAgdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5MT0FESU5HO1xuICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICB2YXIgbGVmdFRvTG9hZF8xID0gMDtcbiAgICAgIHRoaXMuc291cmNlc0xpc3RlbmVyS2V5c18gPSBbXTtcbiAgICAgIHRoaXMuc291cmNlVGlsZXNfLmZvckVhY2goZnVuY3Rpb24gKHRpbGUsIGksIGFycikge1xuICAgICAgICB2YXIgc3RhdGUgPSB0aWxlLmdldFN0YXRlKCk7XG5cbiAgICAgICAgaWYgKHN0YXRlID09IFRpbGVTdGF0ZS5JRExFIHx8IHN0YXRlID09IFRpbGVTdGF0ZS5MT0FESU5HKSB7XG4gICAgICAgICAgbGVmdFRvTG9hZF8xKys7XG4gICAgICAgICAgdmFyIHNvdXJjZUxpc3RlbktleV8xID0gbGlzdGVuKHRpbGUsIEV2ZW50VHlwZS5DSEFOR0UsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICB2YXIgc3RhdGUgPSB0aWxlLmdldFN0YXRlKCk7XG5cbiAgICAgICAgICAgIGlmIChzdGF0ZSA9PSBUaWxlU3RhdGUuTE9BREVEIHx8IHN0YXRlID09IFRpbGVTdGF0ZS5FUlJPUiB8fCBzdGF0ZSA9PSBUaWxlU3RhdGUuRU1QVFkpIHtcbiAgICAgICAgICAgICAgdW5saXN0ZW5CeUtleShzb3VyY2VMaXN0ZW5LZXlfMSk7XG4gICAgICAgICAgICAgIGxlZnRUb0xvYWRfMS0tO1xuXG4gICAgICAgICAgICAgIGlmIChsZWZ0VG9Mb2FkXzEgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVubGlzdGVuU291cmNlc18oKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlcHJvamVjdF8oKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sIHRoaXMpO1xuICAgICAgICAgIHRoaXMuc291cmNlc0xpc3RlbmVyS2V5c18ucHVzaChzb3VyY2VMaXN0ZW5LZXlfMSk7XG4gICAgICAgIH1cbiAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICB0aGlzLnNvdXJjZVRpbGVzXy5mb3JFYWNoKGZ1bmN0aW9uICh0aWxlLCBpLCBhcnIpIHtcbiAgICAgICAgdmFyIHN0YXRlID0gdGlsZS5nZXRTdGF0ZSgpO1xuXG4gICAgICAgIGlmIChzdGF0ZSA9PSBUaWxlU3RhdGUuSURMRSkge1xuICAgICAgICAgIHRpbGUubG9hZCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKGxlZnRUb0xvYWRfMSA9PT0gMCkge1xuICAgICAgICBzZXRUaW1lb3V0KHRoaXMucmVwcm9qZWN0Xy5iaW5kKHRoaXMpLCAwKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFJlcHJvalRpbGUucHJvdG90eXBlLnVubGlzdGVuU291cmNlc18gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zb3VyY2VzTGlzdGVuZXJLZXlzXy5mb3JFYWNoKHVubGlzdGVuQnlLZXkpO1xuICAgIHRoaXMuc291cmNlc0xpc3RlbmVyS2V5c18gPSBudWxsO1xuICB9O1xuXG4gIHJldHVybiBSZXByb2pUaWxlO1xufShUaWxlKTtcblxuZXhwb3J0IGRlZmF1bHQgUmVwcm9qVGlsZTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3NvdXJjZS9UaWxlSW1hZ2VcbiAqL1xuXG5cbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi4vZXZlbnRzL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgSW1hZ2VUaWxlIGZyb20gJy4uL0ltYWdlVGlsZS5qcyc7XG5pbXBvcnQgUmVwcm9qVGlsZSBmcm9tICcuLi9yZXByb2ovVGlsZS5qcyc7XG5pbXBvcnQgVGlsZUNhY2hlIGZyb20gJy4uL1RpbGVDYWNoZS5qcyc7XG5pbXBvcnQgVGlsZVN0YXRlIGZyb20gJy4uL1RpbGVTdGF0ZS5qcyc7XG5pbXBvcnQgVXJsVGlsZSBmcm9tICcuL1VybFRpbGUuanMnO1xuaW1wb3J0IHsgRU5BQkxFX1JBU1RFUl9SRVBST0pFQ1RJT04gfSBmcm9tICcuLi9yZXByb2ovY29tbW9uLmpzJztcbmltcG9ydCB7IElNQUdFX1NNT09USElOR19ESVNBQkxFRCB9IGZyb20gJy4vY29tbW9uLmpzJztcbmltcG9ydCB7IGVxdWl2YWxlbnQsIGdldCBhcyBnZXRQcm9qZWN0aW9uIH0gZnJvbSAnLi4vcHJvai5qcyc7XG5pbXBvcnQgeyBnZXRLZXksIGdldEtleVpYWSB9IGZyb20gJy4uL3RpbGVjb29yZC5qcyc7XG5pbXBvcnQgeyBnZXRGb3JQcm9qZWN0aW9uIGFzIGdldFRpbGVHcmlkRm9yUHJvamVjdGlvbiB9IGZyb20gJy4uL3RpbGVncmlkLmpzJztcbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJy4uL3V0aWwuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU291cmNlLmpzXCIpLkF0dHJpYnV0aW9uTGlrZX0gW2F0dHJpYnV0aW9uc10gQXR0cmlidXRpb25zLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbYXR0cmlidXRpb25zQ29sbGFwc2libGU9dHJ1ZV0gQXR0cmlidXRpb25zIGFyZSBjb2xsYXBzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbY2FjaGVTaXplXSBJbml0aWFsIHRpbGUgY2FjaGUgc2l6ZS4gV2lsbCBhdXRvLWdyb3cgdG8gaG9sZCBhdCBsZWFzdCB0aGUgbnVtYmVyIG9mIHRpbGVzIGluIHRoZSB2aWV3cG9ydC5cbiAqIEBwcm9wZXJ0eSB7bnVsbHxzdHJpbmd9IFtjcm9zc09yaWdpbl0gVGhlIGBjcm9zc09yaWdpbmAgYXR0cmlidXRlIGZvciBsb2FkZWQgaW1hZ2VzLiAgTm90ZSB0aGF0XG4gKiB5b3UgbXVzdCBwcm92aWRlIGEgYGNyb3NzT3JpZ2luYCB2YWx1ZSBpZiB5b3Ugd2FudCB0byBhY2Nlc3MgcGl4ZWwgZGF0YSB3aXRoIHRoZSBDYW52YXMgcmVuZGVyZXIuXG4gKiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9DT1JTX2VuYWJsZWRfaW1hZ2UgZm9yIG1vcmUgZGV0YWlsLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbaW1hZ2VTbW9vdGhpbmc9dHJ1ZV0gRW5hYmxlIGltYWdlIHNtb290aGluZy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW29wYXF1ZT1mYWxzZV0gV2hldGhlciB0aGUgbGF5ZXIgaXMgb3BhcXVlLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBbcHJvamVjdGlvbl0gUHJvamVjdGlvbi4gRGVmYXVsdCBpcyB0aGUgdmlldyBwcm9qZWN0aW9uLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyZXByb2plY3Rpb25FcnJvclRocmVzaG9sZD0wLjVdIE1heGltdW0gYWxsb3dlZCByZXByb2plY3Rpb24gZXJyb3IgKGluIHBpeGVscykuXG4gKiBIaWdoZXIgdmFsdWVzIGNhbiBpbmNyZWFzZSByZXByb2plY3Rpb24gcGVyZm9ybWFuY2UsIGJ1dCBkZWNyZWFzZSBwcmVjaXNpb24uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU3RhdGUuanNcIikuZGVmYXVsdH0gW3N0YXRlXSBTb3VyY2Ugc3RhdGUuXG4gKiBAcHJvcGVydHkge3R5cGVvZiBpbXBvcnQoXCIuLi9JbWFnZVRpbGUuanNcIikuZGVmYXVsdH0gW3RpbGVDbGFzc10gQ2xhc3MgdXNlZCB0byBpbnN0YW50aWF0ZSBpbWFnZSB0aWxlcy5cbiAqIERlZmF1bHQgaXMge0BsaW5rIG1vZHVsZTpvbC9JbWFnZVRpbGV+SW1hZ2VUaWxlfS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gW3RpbGVHcmlkXSBUaWxlIGdyaWQuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL1RpbGUuanNcIikuTG9hZEZ1bmN0aW9ufSBbdGlsZUxvYWRGdW5jdGlvbl0gT3B0aW9uYWwgZnVuY3Rpb24gdG8gbG9hZCBhIHRpbGUgZ2l2ZW4gYSBVUkwuIFRoZSBkZWZhdWx0IGlzXG4gKiBgYGBqc1xuICogZnVuY3Rpb24oaW1hZ2VUaWxlLCBzcmMpIHtcbiAqICAgaW1hZ2VUaWxlLmdldEltYWdlKCkuc3JjID0gc3JjO1xuICogfTtcbiAqIGBgYFxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt0aWxlUGl4ZWxSYXRpbz0xXSBUaGUgcGl4ZWwgcmF0aW8gdXNlZCBieSB0aGUgdGlsZSBzZXJ2aWNlLiBGb3IgZXhhbXBsZSwgaWYgdGhlIHRpbGVcbiAqIHNlcnZpY2UgYWR2ZXJ0aXplcyAyNTZweCBieSAyNTZweCB0aWxlcyBidXQgYWN0dWFsbHkgc2VuZHMgNTEycHhcbiAqIGJ5IDUxMnB4IGltYWdlcyAoZm9yIHJldGluYS9oaWRwaSBkZXZpY2VzKSB0aGVuIGB0aWxlUGl4ZWxSYXRpb2BcbiAqIHNob3VsZCBiZSBzZXQgdG8gYDJgLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLlVybEZ1bmN0aW9ufSBbdGlsZVVybEZ1bmN0aW9uXSBPcHRpb25hbCBmdW5jdGlvbiB0byBnZXQgdGlsZSBVUkwgZ2l2ZW4gYSB0aWxlIGNvb3JkaW5hdGUgYW5kIHRoZSBwcm9qZWN0aW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFt1cmxdIFVSTCB0ZW1wbGF0ZS4gTXVzdCBpbmNsdWRlIGB7eH1gLCBge3l9YCBvciBgey15fWAsIGFuZCBge3p9YCBwbGFjZWhvbGRlcnMuXG4gKiBBIGB7Py0/fWAgdGVtcGxhdGUgcGF0dGVybiwgZm9yIGV4YW1wbGUgYHN1YmRvbWFpbnthLWZ9LmRvbWFpbi5jb21gLCBtYXkgYmVcbiAqIHVzZWQgaW5zdGVhZCBvZiBkZWZpbmluZyBlYWNoIG9uZSBzZXBhcmF0ZWx5IGluIHRoZSBgdXJsc2Agb3B0aW9uLlxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSBbdXJsc10gQW4gYXJyYXkgb2YgVVJMIHRlbXBsYXRlcy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3dyYXBYXSBXaGV0aGVyIHRvIHdyYXAgdGhlIHdvcmxkIGhvcml6b250YWxseS4gVGhlIGRlZmF1bHQsIGlzIHRvXG4gKiByZXF1ZXN0IG91dC1vZi1ib3VuZHMgdGlsZXMgZnJvbSB0aGUgc2VydmVyLiBXaGVuIHNldCB0byBgZmFsc2VgLCBvbmx5IG9uZVxuICogd29ybGQgd2lsbCBiZSByZW5kZXJlZC4gV2hlbiBzZXQgdG8gYHRydWVgLCB0aWxlcyB3aWxsIGJlIHJlcXVlc3RlZCBmb3Igb25lXG4gKiB3b3JsZCBvbmx5LCBidXQgdGhleSB3aWxsIGJlIHdyYXBwZWQgaG9yaXpvbnRhbGx5IHRvIHJlbmRlciBtdWx0aXBsZSB3b3JsZHMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RyYW5zaXRpb25dIER1cmF0aW9uIG9mIHRoZSBvcGFjaXR5IHRyYW5zaXRpb24gZm9yIHJlbmRlcmluZy5cbiAqIFRvIGRpc2FibGUgdGhlIG9wYWNpdHkgdHJhbnNpdGlvbiwgcGFzcyBgdHJhbnNpdGlvbjogMGAuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2tleV0gT3B0aW9uYWwgdGlsZSBrZXkgZm9yIHByb3BlciBjYWNoZSBmZXRjaGluZ1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6RGlyZWN0aW9uPTBdIEluZGljYXRlIHdoaWNoIHJlc29sdXRpb24gc2hvdWxkIGJlIHVzZWRcbiAqIGJ5IGEgcmVuZGVyZXIgaWYgdGhlIHZpZXcgcmVzb2x1dGlvbiBkb2VzIG5vdCBtYXRjaCBhbnkgcmVzb2x1dGlvbiBvZiB0aGUgdGlsZSBzb3VyY2UuXG4gKiBJZiAwLCB0aGUgbmVhcmVzdCByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC4gSWYgMSwgdGhlIG5lYXJlc3QgbG93ZXIgcmVzb2x1dGlvblxuICogd2lsbCBiZSB1c2VkLiBJZiAtMSwgdGhlIG5lYXJlc3QgaGlnaGVyIHJlc29sdXRpb24gd2lsbCBiZSB1c2VkLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQmFzZSBjbGFzcyBmb3Igc291cmNlcyBwcm92aWRpbmcgaW1hZ2VzIGRpdmlkZWQgaW50byBhIHRpbGUgZ3JpZC5cbiAqXG4gKiBAZmlyZXMgaW1wb3J0KFwiLi9UaWxlLmpzXCIpLlRpbGVTb3VyY2VFdmVudFxuICogQGFwaVxuICovXG5cbnZhciBUaWxlSW1hZ2UgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVGlsZUltYWdlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHshT3B0aW9uc30gb3B0aW9ucyBJbWFnZSB0aWxlIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gVGlsZUltYWdlKG9wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB7XG4gICAgICBhdHRyaWJ1dGlvbnM6IG9wdGlvbnMuYXR0cmlidXRpb25zLFxuICAgICAgY2FjaGVTaXplOiBvcHRpb25zLmNhY2hlU2l6ZSxcbiAgICAgIG9wYXF1ZTogb3B0aW9ucy5vcGFxdWUsXG4gICAgICBwcm9qZWN0aW9uOiBvcHRpb25zLnByb2plY3Rpb24sXG4gICAgICBzdGF0ZTogb3B0aW9ucy5zdGF0ZSxcbiAgICAgIHRpbGVHcmlkOiBvcHRpb25zLnRpbGVHcmlkLFxuICAgICAgdGlsZUxvYWRGdW5jdGlvbjogb3B0aW9ucy50aWxlTG9hZEZ1bmN0aW9uID8gb3B0aW9ucy50aWxlTG9hZEZ1bmN0aW9uIDogZGVmYXVsdFRpbGVMb2FkRnVuY3Rpb24sXG4gICAgICB0aWxlUGl4ZWxSYXRpbzogb3B0aW9ucy50aWxlUGl4ZWxSYXRpbyxcbiAgICAgIHRpbGVVcmxGdW5jdGlvbjogb3B0aW9ucy50aWxlVXJsRnVuY3Rpb24sXG4gICAgICB1cmw6IG9wdGlvbnMudXJsLFxuICAgICAgdXJsczogb3B0aW9ucy51cmxzLFxuICAgICAgd3JhcFg6IG9wdGlvbnMud3JhcFgsXG4gICAgICB0cmFuc2l0aW9uOiBvcHRpb25zLnRyYW5zaXRpb24sXG4gICAgICBrZXk6IG9wdGlvbnMua2V5LFxuICAgICAgYXR0cmlidXRpb25zQ29sbGFwc2libGU6IG9wdGlvbnMuYXR0cmlidXRpb25zQ29sbGFwc2libGUsXG4gICAgICB6RGlyZWN0aW9uOiBvcHRpb25zLnpEaXJlY3Rpb25cbiAgICB9KSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7P3N0cmluZ31cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuY3Jvc3NPcmlnaW4gPSBvcHRpb25zLmNyb3NzT3JpZ2luICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNyb3NzT3JpZ2luIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge3R5cGVvZiBJbWFnZVRpbGV9XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlQ2xhc3MgPSBvcHRpb25zLnRpbGVDbGFzcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy50aWxlQ2xhc3MgOiBJbWFnZVRpbGU7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgVGlsZUNhY2hlPn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVDYWNoZUZvclByb2plY3Rpb24gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVHcmlkRm9yUHJvamVjdGlvbiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZXByb2plY3Rpb25FcnJvclRocmVzaG9sZF8gPSBvcHRpb25zLnJlcHJvamVjdGlvbkVycm9yVGhyZXNob2xkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge29iamVjdHx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5jb250ZXh0T3B0aW9uc18gPSBvcHRpb25zLmltYWdlU21vb3RoaW5nID09PSBmYWxzZSA/IElNQUdFX1NNT09USElOR19ESVNBQkxFRCA6IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyUmVwcm9qZWN0aW9uRWRnZXNfID0gZmFsc2U7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBDYW4gZXhwaXJlIGNhY2hlLlxuICAgKi9cblxuXG4gIFRpbGVJbWFnZS5wcm90b3R5cGUuY2FuRXhwaXJlQ2FjaGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFFTkFCTEVfUkFTVEVSX1JFUFJPSkVDVElPTikge1xuICAgICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUuY2FuRXhwaXJlQ2FjaGUuY2FsbCh0aGlzKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy50aWxlQ2FjaGUuY2FuRXhwaXJlQ2FjaGUoKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiB0aGlzLnRpbGVDYWNoZUZvclByb2plY3Rpb24pIHtcbiAgICAgICAgaWYgKHRoaXMudGlsZUNhY2hlRm9yUHJvamVjdGlvbltrZXldLmNhbkV4cGlyZUNhY2hlKCkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHshT2JqZWN0PHN0cmluZywgYm9vbGVhbj59IHVzZWRUaWxlcyBVc2VkIHRpbGVzLlxuICAgKi9cblxuXG4gIFRpbGVJbWFnZS5wcm90b3R5cGUuZXhwaXJlQ2FjaGUgPSBmdW5jdGlvbiAocHJvamVjdGlvbiwgdXNlZFRpbGVzKSB7XG4gICAgaWYgKCFFTkFCTEVfUkFTVEVSX1JFUFJPSkVDVElPTikge1xuICAgICAgX3N1cGVyLnByb3RvdHlwZS5leHBpcmVDYWNoZS5jYWxsKHRoaXMsIHByb2plY3Rpb24sIHVzZWRUaWxlcyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgdXNlZFRpbGVDYWNoZSA9IHRoaXMuZ2V0VGlsZUNhY2hlRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgICB0aGlzLnRpbGVDYWNoZS5leHBpcmVDYWNoZSh0aGlzLnRpbGVDYWNoZSA9PSB1c2VkVGlsZUNhY2hlID8gdXNlZFRpbGVzIDoge30pO1xuXG4gICAgZm9yICh2YXIgaWQgaW4gdGhpcy50aWxlQ2FjaGVGb3JQcm9qZWN0aW9uKSB7XG4gICAgICB2YXIgdGlsZUNhY2hlID0gdGhpcy50aWxlQ2FjaGVGb3JQcm9qZWN0aW9uW2lkXTtcbiAgICAgIHRpbGVDYWNoZS5leHBpcmVDYWNoZSh0aWxlQ2FjaGUgPT0gdXNlZFRpbGVDYWNoZSA/IHVzZWRUaWxlcyA6IHt9KTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSBDb250ZXh0IG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgVGlsZUltYWdlLnByb3RvdHlwZS5nZXRDb250ZXh0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZXh0T3B0aW9uc187XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge251bWJlcn0gR3V0dGVyLlxuICAgKi9cblxuXG4gIFRpbGVJbWFnZS5wcm90b3R5cGUuZ2V0R3V0dGVyRm9yUHJvamVjdGlvbiA9IGZ1bmN0aW9uIChwcm9qZWN0aW9uKSB7XG4gICAgaWYgKEVOQUJMRV9SQVNURVJfUkVQUk9KRUNUSU9OICYmIHRoaXMuZ2V0UHJvamVjdGlvbigpICYmIHByb2plY3Rpb24gJiYgIWVxdWl2YWxlbnQodGhpcy5nZXRQcm9qZWN0aW9uKCksIHByb2plY3Rpb24pKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0R3V0dGVyKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBHdXR0ZXIuXG4gICAqL1xuXG5cbiAgVGlsZUltYWdlLnByb3RvdHlwZS5nZXRHdXR0ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIDA7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGtleSB0byBiZSB1c2VkIGZvciBhbGwgdGlsZXMgaW4gdGhlIHNvdXJjZS5cbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUga2V5IGZvciBhbGwgdGlsZXMuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBUaWxlSW1hZ2UucHJvdG90eXBlLmdldEtleSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5nZXRLZXkuY2FsbCh0aGlzKSArICh0aGlzLmNvbnRleHRPcHRpb25zXyA/ICdcXG4nICsgSlNPTi5zdHJpbmdpZnkodGhpcy5jb250ZXh0T3B0aW9uc18pIDogJycpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBPcGFxdWUuXG4gICAqL1xuXG5cbiAgVGlsZUltYWdlLnByb3RvdHlwZS5nZXRPcGFxdWUgPSBmdW5jdGlvbiAocHJvamVjdGlvbikge1xuICAgIGlmIChFTkFCTEVfUkFTVEVSX1JFUFJPSkVDVElPTiAmJiB0aGlzLmdldFByb2plY3Rpb24oKSAmJiBwcm9qZWN0aW9uICYmICFlcXVpdmFsZW50KHRoaXMuZ2V0UHJvamVjdGlvbigpLCBwcm9qZWN0aW9uKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5nZXRPcGFxdWUuY2FsbCh0aGlzLCBwcm9qZWN0aW9uKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4geyFpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSBUaWxlIGdyaWQuXG4gICAqL1xuXG5cbiAgVGlsZUltYWdlLnByb3RvdHlwZS5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24gPSBmdW5jdGlvbiAocHJvamVjdGlvbikge1xuICAgIGlmICghRU5BQkxFX1JBU1RFUl9SRVBST0pFQ1RJT04pIHtcbiAgICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLmdldFRpbGVHcmlkRm9yUHJvamVjdGlvbi5jYWxsKHRoaXMsIHByb2plY3Rpb24pO1xuICAgIH1cblxuICAgIHZhciB0aGlzUHJvaiA9IHRoaXMuZ2V0UHJvamVjdGlvbigpO1xuXG4gICAgaWYgKHRoaXMudGlsZUdyaWQgJiYgKCF0aGlzUHJvaiB8fCBlcXVpdmFsZW50KHRoaXNQcm9qLCBwcm9qZWN0aW9uKSkpIHtcbiAgICAgIHJldHVybiB0aGlzLnRpbGVHcmlkO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcHJvaktleSA9IGdldFVpZChwcm9qZWN0aW9uKTtcblxuICAgICAgaWYgKCEocHJvaktleSBpbiB0aGlzLnRpbGVHcmlkRm9yUHJvamVjdGlvbikpIHtcbiAgICAgICAgdGhpcy50aWxlR3JpZEZvclByb2plY3Rpb25bcHJvaktleV0gPSBnZXRUaWxlR3JpZEZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnRpbGVHcmlkRm9yUHJvamVjdGlvbltwcm9qS2V5XTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL1RpbGVDYWNoZS5qc1wiKS5kZWZhdWx0fSBUaWxlIGNhY2hlLlxuICAgKi9cblxuXG4gIFRpbGVJbWFnZS5wcm90b3R5cGUuZ2V0VGlsZUNhY2hlRm9yUHJvamVjdGlvbiA9IGZ1bmN0aW9uIChwcm9qZWN0aW9uKSB7XG4gICAgaWYgKCFFTkFCTEVfUkFTVEVSX1JFUFJPSkVDVElPTikge1xuICAgICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUuZ2V0VGlsZUNhY2hlRm9yUHJvamVjdGlvbi5jYWxsKHRoaXMsIHByb2plY3Rpb24pO1xuICAgIH1cblxuICAgIHZhciB0aGlzUHJvaiA9IHRoaXMuZ2V0UHJvamVjdGlvbigpO1xuXG4gICAgaWYgKCF0aGlzUHJvaiB8fCBlcXVpdmFsZW50KHRoaXNQcm9qLCBwcm9qZWN0aW9uKSkge1xuICAgICAgcmV0dXJuIHRoaXMudGlsZUNhY2hlO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcHJvaktleSA9IGdldFVpZChwcm9qZWN0aW9uKTtcblxuICAgICAgaWYgKCEocHJvaktleSBpbiB0aGlzLnRpbGVDYWNoZUZvclByb2plY3Rpb24pKSB7XG4gICAgICAgIHRoaXMudGlsZUNhY2hlRm9yUHJvamVjdGlvbltwcm9qS2V5XSA9IG5ldyBUaWxlQ2FjaGUodGhpcy50aWxlQ2FjaGUuaGlnaFdhdGVyTWFyayk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnRpbGVDYWNoZUZvclByb2plY3Rpb25bcHJvaktleV07XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHogVGlsZSBjb29yZGluYXRlIHouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFRpbGUgY29vcmRpbmF0ZSB4LlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBUaWxlIGNvb3JkaW5hdGUgeS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IHNldCBvbiB0aGUgdGlsZS5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uL1RpbGUuanNcIikuZGVmYXVsdH0gVGlsZS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBUaWxlSW1hZ2UucHJvdG90eXBlLmNyZWF0ZVRpbGVfID0gZnVuY3Rpb24gKHosIHgsIHksIHBpeGVsUmF0aW8sIHByb2plY3Rpb24sIGtleSkge1xuICAgIHZhciB0aWxlQ29vcmQgPSBbeiwgeCwgeV07XG4gICAgdmFyIHVybFRpbGVDb29yZCA9IHRoaXMuZ2V0VGlsZUNvb3JkRm9yVGlsZVVybEZ1bmN0aW9uKHRpbGVDb29yZCwgcHJvamVjdGlvbik7XG4gICAgdmFyIHRpbGVVcmwgPSB1cmxUaWxlQ29vcmQgPyB0aGlzLnRpbGVVcmxGdW5jdGlvbih1cmxUaWxlQ29vcmQsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIDogdW5kZWZpbmVkO1xuICAgIHZhciB0aWxlID0gbmV3IHRoaXMudGlsZUNsYXNzKHRpbGVDb29yZCwgdGlsZVVybCAhPT0gdW5kZWZpbmVkID8gVGlsZVN0YXRlLklETEUgOiBUaWxlU3RhdGUuRU1QVFksIHRpbGVVcmwgIT09IHVuZGVmaW5lZCA/IHRpbGVVcmwgOiAnJywgdGhpcy5jcm9zc09yaWdpbiwgdGhpcy50aWxlTG9hZEZ1bmN0aW9uLCB0aGlzLnRpbGVPcHRpb25zKTtcbiAgICB0aWxlLmtleSA9IGtleTtcbiAgICB0aWxlLmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5oYW5kbGVUaWxlQ2hhbmdlLmJpbmQodGhpcykpO1xuICAgIHJldHVybiB0aWxlO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHogVGlsZSBjb29yZGluYXRlIHouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFRpbGUgY29vcmRpbmF0ZSB4LlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBUaWxlIGNvb3JkaW5hdGUgeS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uL1RpbGUuanNcIikuZGVmYXVsdH0gVGlsZS5cbiAgICovXG5cblxuICBUaWxlSW1hZ2UucHJvdG90eXBlLmdldFRpbGUgPSBmdW5jdGlvbiAoeiwgeCwgeSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikge1xuICAgIHZhciBzb3VyY2VQcm9qZWN0aW9uID0gdGhpcy5nZXRQcm9qZWN0aW9uKCk7XG5cbiAgICBpZiAoIUVOQUJMRV9SQVNURVJfUkVQUk9KRUNUSU9OIHx8ICFzb3VyY2VQcm9qZWN0aW9uIHx8ICFwcm9qZWN0aW9uIHx8IGVxdWl2YWxlbnQoc291cmNlUHJvamVjdGlvbiwgcHJvamVjdGlvbikpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFRpbGVJbnRlcm5hbCh6LCB4LCB5LCBwaXhlbFJhdGlvLCBzb3VyY2VQcm9qZWN0aW9uIHx8IHByb2plY3Rpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgY2FjaGUgPSB0aGlzLmdldFRpbGVDYWNoZUZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgICB2YXIgdGlsZUNvb3JkID0gW3osIHgsIHldO1xuICAgICAgdmFyIHRpbGUgPSB2b2lkIDA7XG4gICAgICB2YXIgdGlsZUNvb3JkS2V5ID0gZ2V0S2V5KHRpbGVDb29yZCk7XG5cbiAgICAgIGlmIChjYWNoZS5jb250YWluc0tleSh0aWxlQ29vcmRLZXkpKSB7XG4gICAgICAgIHRpbGUgPSBjYWNoZS5nZXQodGlsZUNvb3JkS2V5KTtcbiAgICAgIH1cblxuICAgICAgdmFyIGtleSA9IHRoaXMuZ2V0S2V5KCk7XG5cbiAgICAgIGlmICh0aWxlICYmIHRpbGUua2V5ID09IGtleSkge1xuICAgICAgICByZXR1cm4gdGlsZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBzb3VyY2VUaWxlR3JpZCA9IHRoaXMuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHNvdXJjZVByb2plY3Rpb24pO1xuICAgICAgICB2YXIgdGFyZ2V0VGlsZUdyaWQgPSB0aGlzLmdldFRpbGVHcmlkRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgICAgICAgdmFyIHdyYXBwZWRUaWxlQ29vcmQgPSB0aGlzLmdldFRpbGVDb29yZEZvclRpbGVVcmxGdW5jdGlvbih0aWxlQ29vcmQsIHByb2plY3Rpb24pO1xuICAgICAgICB2YXIgbmV3VGlsZSA9IG5ldyBSZXByb2pUaWxlKHNvdXJjZVByb2plY3Rpb24sIHNvdXJjZVRpbGVHcmlkLCBwcm9qZWN0aW9uLCB0YXJnZXRUaWxlR3JpZCwgdGlsZUNvb3JkLCB3cmFwcGVkVGlsZUNvb3JkLCB0aGlzLmdldFRpbGVQaXhlbFJhdGlvKHBpeGVsUmF0aW8pLCB0aGlzLmdldEd1dHRlcigpLCBmdW5jdGlvbiAoeiwgeCwgeSwgcGl4ZWxSYXRpbykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmdldFRpbGVJbnRlcm5hbCh6LCB4LCB5LCBwaXhlbFJhdGlvLCBzb3VyY2VQcm9qZWN0aW9uKTtcbiAgICAgICAgfS5iaW5kKHRoaXMpLCB0aGlzLnJlcHJvamVjdGlvbkVycm9yVGhyZXNob2xkXywgdGhpcy5yZW5kZXJSZXByb2plY3Rpb25FZGdlc18sIHRoaXMuY29udGV4dE9wdGlvbnNfKTtcbiAgICAgICAgbmV3VGlsZS5rZXkgPSBrZXk7XG5cbiAgICAgICAgaWYgKHRpbGUpIHtcbiAgICAgICAgICBuZXdUaWxlLmludGVyaW1UaWxlID0gdGlsZTtcbiAgICAgICAgICBuZXdUaWxlLnJlZnJlc2hJbnRlcmltQ2hhaW4oKTtcbiAgICAgICAgICBjYWNoZS5yZXBsYWNlKHRpbGVDb29yZEtleSwgbmV3VGlsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2FjaGUuc2V0KHRpbGVDb29yZEtleSwgbmV3VGlsZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3VGlsZTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geiBUaWxlIGNvb3JkaW5hdGUgei5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHggVGlsZSBjb29yZGluYXRlIHguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFRpbGUgY29vcmRpbmF0ZSB5LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHshaW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uL1RpbGUuanNcIikuZGVmYXVsdH0gVGlsZS5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFRpbGVJbWFnZS5wcm90b3R5cGUuZ2V0VGlsZUludGVybmFsID0gZnVuY3Rpb24gKHosIHgsIHksIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIHtcbiAgICB2YXIgdGlsZSA9IG51bGw7XG4gICAgdmFyIHRpbGVDb29yZEtleSA9IGdldEtleVpYWSh6LCB4LCB5KTtcbiAgICB2YXIga2V5ID0gdGhpcy5nZXRLZXkoKTtcblxuICAgIGlmICghdGhpcy50aWxlQ2FjaGUuY29udGFpbnNLZXkodGlsZUNvb3JkS2V5KSkge1xuICAgICAgdGlsZSA9IHRoaXMuY3JlYXRlVGlsZV8oeiwgeCwgeSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbiwga2V5KTtcbiAgICAgIHRoaXMudGlsZUNhY2hlLnNldCh0aWxlQ29vcmRLZXksIHRpbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aWxlID0gdGhpcy50aWxlQ2FjaGUuZ2V0KHRpbGVDb29yZEtleSk7XG5cbiAgICAgIGlmICh0aWxlLmtleSAhPSBrZXkpIHtcbiAgICAgICAgLy8gVGhlIHNvdXJjZSdzIHBhcmFtcyBjaGFuZ2VkLiBJZiB0aGUgdGlsZSBoYXMgYW4gaW50ZXJpbSB0aWxlIGFuZCBpZiB3ZVxuICAgICAgICAvLyBjYW4gdXNlIGl0IHRoZW4gd2UgdXNlIGl0LiBPdGhlcndpc2Ugd2UgY3JlYXRlIGEgbmV3IHRpbGUuICBJbiBib3RoXG4gICAgICAgIC8vIGNhc2VzIHdlIGF0dGVtcHQgdG8gYXNzaWduIGFuIGludGVyaW0gdGlsZSB0byB0aGUgbmV3IHRpbGUuXG4gICAgICAgIHZhciBpbnRlcmltVGlsZSA9IHRpbGU7XG4gICAgICAgIHRpbGUgPSB0aGlzLmNyZWF0ZVRpbGVfKHosIHgsIHksIHBpeGVsUmF0aW8sIHByb2plY3Rpb24sIGtleSk7IC8vbWFrZSB0aGUgbmV3IHRpbGUgdGhlIGhlYWQgb2YgdGhlIGxpc3QsXG5cbiAgICAgICAgaWYgKGludGVyaW1UaWxlLmdldFN0YXRlKCkgPT0gVGlsZVN0YXRlLklETEUpIHtcbiAgICAgICAgICAvL3RoZSBvbGQgdGlsZSBoYXNuJ3QgYmVndW4gbG9hZGluZyB5ZXQsIGFuZCBpcyBub3cgb3V0ZGF0ZWQsIHNvIHdlIGNhbiBzaW1wbHkgZGlzY2FyZCBpdFxuICAgICAgICAgIHRpbGUuaW50ZXJpbVRpbGUgPSBpbnRlcmltVGlsZS5pbnRlcmltVGlsZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aWxlLmludGVyaW1UaWxlID0gaW50ZXJpbVRpbGU7XG4gICAgICAgIH1cblxuICAgICAgICB0aWxlLnJlZnJlc2hJbnRlcmltQ2hhaW4oKTtcbiAgICAgICAgdGhpcy50aWxlQ2FjaGUucmVwbGFjZSh0aWxlQ29vcmRLZXksIHRpbGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aWxlO1xuICB9O1xuICAvKipcbiAgICogU2V0cyB3aGV0aGVyIHRvIHJlbmRlciByZXByb2plY3Rpb24gZWRnZXMgb3Igbm90ICh1c3VhbGx5IGZvciBkZWJ1Z2dpbmcpLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHJlbmRlciBSZW5kZXIgdGhlIGVkZ2VzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZUltYWdlLnByb3RvdHlwZS5zZXRSZW5kZXJSZXByb2plY3Rpb25FZGdlcyA9IGZ1bmN0aW9uIChyZW5kZXIpIHtcbiAgICBpZiAoIUVOQUJMRV9SQVNURVJfUkVQUk9KRUNUSU9OIHx8IHRoaXMucmVuZGVyUmVwcm9qZWN0aW9uRWRnZXNfID09IHJlbmRlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyUmVwcm9qZWN0aW9uRWRnZXNfID0gcmVuZGVyO1xuXG4gICAgZm9yICh2YXIgaWQgaW4gdGhpcy50aWxlQ2FjaGVGb3JQcm9qZWN0aW9uKSB7XG4gICAgICB0aGlzLnRpbGVDYWNoZUZvclByb2plY3Rpb25baWRdLmNsZWFyKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXRzIHRoZSB0aWxlIGdyaWQgdG8gdXNlIHdoZW4gcmVwcm9qZWN0aW5nIHRoZSB0aWxlcyB0byB0aGUgZ2l2ZW5cbiAgICogcHJvamVjdGlvbiBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0IHRpbGUgZ3JpZCBmb3IgdGhlIHByb2plY3Rpb24uXG4gICAqXG4gICAqIFRoaXMgY2FuIGJlIHVzZWZ1bCB3aGVuIHRoZSBkZWZhdWx0IHRpbGUgZ3JpZCBjYW5ub3QgYmUgY3JlYXRlZFxuICAgKiAoZS5nLiBwcm9qZWN0aW9uIGhhcyBubyBleHRlbnQgZGVmaW5lZCkgb3JcbiAgICogZm9yIG9wdGltaXphdGlvbiByZWFzb25zIChjdXN0b20gdGlsZSBzaXplLCByZXNvbHV0aW9ucywgLi4uKS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gdGlsZWdyaWQgVGlsZSBncmlkIHRvIHVzZSBmb3IgdGhlIHByb2plY3Rpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlSW1hZ2UucHJvdG90eXBlLnNldFRpbGVHcmlkRm9yUHJvamVjdGlvbiA9IGZ1bmN0aW9uIChwcm9qZWN0aW9uLCB0aWxlZ3JpZCkge1xuICAgIGlmIChFTkFCTEVfUkFTVEVSX1JFUFJPSkVDVElPTikge1xuICAgICAgdmFyIHByb2ogPSBnZXRQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuXG4gICAgICBpZiAocHJvaikge1xuICAgICAgICB2YXIgcHJvaktleSA9IGdldFVpZChwcm9qKTtcblxuICAgICAgICBpZiAoIShwcm9qS2V5IGluIHRoaXMudGlsZUdyaWRGb3JQcm9qZWN0aW9uKSkge1xuICAgICAgICAgIHRoaXMudGlsZUdyaWRGb3JQcm9qZWN0aW9uW3Byb2pLZXldID0gdGlsZWdyaWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIFRpbGVJbWFnZTtcbn0oVXJsVGlsZSk7XG4vKipcbiAqIEBwYXJhbSB7SW1hZ2VUaWxlfSBpbWFnZVRpbGUgSW1hZ2UgdGlsZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgU291cmNlLlxuICovXG5cblxuZnVuY3Rpb24gZGVmYXVsdFRpbGVMb2FkRnVuY3Rpb24oaW1hZ2VUaWxlLCBzcmMpIHtcbiAgLyoqIEB0eXBlIHtIVE1MSW1hZ2VFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR9ICovXG4gIGltYWdlVGlsZS5nZXRJbWFnZSgpLnNyYyA9IHNyYztcbn1cblxuZXhwb3J0IGRlZmF1bHQgVGlsZUltYWdlOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zb3VyY2UvWFlaXG4gKi9cbnZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG5cbmltcG9ydCBUaWxlSW1hZ2UgZnJvbSAnLi9UaWxlSW1hZ2UuanMnO1xuaW1wb3J0IHsgY3JlYXRlWFlaLCBleHRlbnRGcm9tUHJvamVjdGlvbiB9IGZyb20gJy4uL3RpbGVncmlkLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1NvdXJjZS5qc1wiKS5BdHRyaWJ1dGlvbkxpa2V9IFthdHRyaWJ1dGlvbnNdIEF0dHJpYnV0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2F0dHJpYnV0aW9uc0NvbGxhcHNpYmxlPXRydWVdIEF0dHJpYnV0aW9ucyBhcmUgY29sbGFwc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2NhY2hlU2l6ZV0gSW5pdGlhbCB0aWxlIGNhY2hlIHNpemUuIFdpbGwgYXV0by1ncm93IHRvIGhvbGQgYXQgbGVhc3QgdGhlIG51bWJlciBvZiB0aWxlcyBpbiB0aGUgdmlld3BvcnQuXG4gKiBAcHJvcGVydHkge251bGx8c3RyaW5nfSBbY3Jvc3NPcmlnaW5dIFRoZSBgY3Jvc3NPcmlnaW5gIGF0dHJpYnV0ZSBmb3IgbG9hZGVkIGltYWdlcy4gIE5vdGUgdGhhdFxuICogeW91IG11c3QgcHJvdmlkZSBhIGBjcm9zc09yaWdpbmAgdmFsdWUgaWYgeW91IHdhbnQgdG8gYWNjZXNzIHBpeGVsIGRhdGEgd2l0aCB0aGUgQ2FudmFzIHJlbmRlcmVyLlxuICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvQ09SU19lbmFibGVkX2ltYWdlIGZvciBtb3JlIGRldGFpbC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2ltYWdlU21vb3RoaW5nPXRydWVdIEVuYWJsZSBpbWFnZSBzbW9vdGhpbmcuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtvcGFxdWU9ZmFsc2VdIFdoZXRoZXIgdGhlIGxheWVyIGlzIG9wYXF1ZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gW3Byb2plY3Rpb249J0VQU0c6Mzg1NyddIFByb2plY3Rpb24uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3JlcHJvamVjdGlvbkVycm9yVGhyZXNob2xkPTAuNV0gTWF4aW11bSBhbGxvd2VkIHJlcHJvamVjdGlvbiBlcnJvciAoaW4gcGl4ZWxzKS5cbiAqIEhpZ2hlciB2YWx1ZXMgY2FuIGluY3JlYXNlIHJlcHJvamVjdGlvbiBwZXJmb3JtYW5jZSwgYnV0IGRlY3JlYXNlIHByZWNpc2lvbi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4Wm9vbT00Ml0gT3B0aW9uYWwgbWF4IHpvb20gbGV2ZWwuIE5vdCB1c2VkIGlmIGB0aWxlR3JpZGAgaXMgcHJvdmlkZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblpvb209MF0gT3B0aW9uYWwgbWluIHpvb20gbGV2ZWwuIE5vdCB1c2VkIGlmIGB0aWxlR3JpZGAgaXMgcHJvdmlkZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFJlc29sdXRpb25dIE9wdGlvbmFsIHRpbGUgZ3JpZCByZXNvbHV0aW9uIGF0IGxldmVsIHplcm8uIE5vdCB1c2VkIGlmIGB0aWxlR3JpZGAgaXMgcHJvdmlkZWQuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IFt0aWxlR3JpZF0gVGlsZSBncmlkLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLkxvYWRGdW5jdGlvbn0gW3RpbGVMb2FkRnVuY3Rpb25dIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGxvYWQgYSB0aWxlIGdpdmVuIGEgVVJMLiBUaGUgZGVmYXVsdCBpc1xuICogYGBganNcbiAqIGZ1bmN0aW9uKGltYWdlVGlsZSwgc3JjKSB7XG4gKiAgIGltYWdlVGlsZS5nZXRJbWFnZSgpLnNyYyA9IHNyYztcbiAqIH07XG4gKiBgYGBcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdGlsZVBpeGVsUmF0aW89MV0gVGhlIHBpeGVsIHJhdGlvIHVzZWQgYnkgdGhlIHRpbGUgc2VydmljZS5cbiAqIEZvciBleGFtcGxlLCBpZiB0aGUgdGlsZSBzZXJ2aWNlIGFkdmVydGl6ZXMgMjU2cHggYnkgMjU2cHggdGlsZXMgYnV0IGFjdHVhbGx5IHNlbmRzIDUxMnB4XG4gKiBieSA1MTJweCBpbWFnZXMgKGZvciByZXRpbmEvaGlkcGkgZGV2aWNlcykgdGhlbiBgdGlsZVBpeGVsUmF0aW9gXG4gKiBzaG91bGQgYmUgc2V0IHRvIGAyYC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gW3RpbGVTaXplPVsyNTYsIDI1Nl1dIFRoZSB0aWxlIHNpemUgdXNlZCBieSB0aGUgdGlsZSBzZXJ2aWNlLlxuICogTm90IHVzZWQgaWYgYHRpbGVHcmlkYCBpcyBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5VcmxGdW5jdGlvbn0gW3RpbGVVcmxGdW5jdGlvbl0gT3B0aW9uYWwgZnVuY3Rpb24gdG8gZ2V0XG4gKiB0aWxlIFVSTCBnaXZlbiBhIHRpbGUgY29vcmRpbmF0ZSBhbmQgdGhlIHByb2plY3Rpb24uXG4gKiBSZXF1aXJlZCBpZiBgdXJsYCBvciBgdXJsc2AgYXJlIG5vdCBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdXJsXSBVUkwgdGVtcGxhdGUuIE11c3QgaW5jbHVkZSBge3h9YCwgYHt5fWAgb3IgYHsteX1gLFxuICogYW5kIGB7en1gIHBsYWNlaG9sZGVycy4gQSBgez8tP31gIHRlbXBsYXRlIHBhdHRlcm4sIGZvciBleGFtcGxlIGBzdWJkb21haW57YS1mfS5kb21haW4uY29tYCxcbiAqIG1heSBiZSB1c2VkIGluc3RlYWQgb2YgZGVmaW5pbmcgZWFjaCBvbmUgc2VwYXJhdGVseSBpbiB0aGUgYHVybHNgIG9wdGlvbi5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gW3VybHNdIEFuIGFycmF5IG9mIFVSTCB0ZW1wbGF0ZXMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt3cmFwWD10cnVlXSBXaGV0aGVyIHRvIHdyYXAgdGhlIHdvcmxkIGhvcml6b250YWxseS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdHJhbnNpdGlvbj0yNTBdIER1cmF0aW9uIG9mIHRoZSBvcGFjaXR5IHRyYW5zaXRpb24gZm9yIHJlbmRlcmluZy5cbiAqIFRvIGRpc2FibGUgdGhlIG9wYWNpdHkgdHJhbnNpdGlvbiwgcGFzcyBgdHJhbnNpdGlvbjogMGAuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3pEaXJlY3Rpb249MF0gSW5kaWNhdGUgd2hpY2ggcmVzb2x1dGlvbiBzaG91bGQgYmUgdXNlZFxuICogYnkgYSByZW5kZXJlciBpZiB0aGUgdmlldyByZXNvbHV0aW9uIGRvZXMgbm90IG1hdGNoIGFueSByZXNvbHV0aW9uIG9mIHRoZSB0aWxlIHNvdXJjZS5cbiAqIElmIDAsIHRoZSBuZWFyZXN0IHJlc29sdXRpb24gd2lsbCBiZSB1c2VkLiBJZiAxLCB0aGUgbmVhcmVzdCBsb3dlciByZXNvbHV0aW9uXG4gKiB3aWxsIGJlIHVzZWQuIElmIC0xLCB0aGUgbmVhcmVzdCBoaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBMYXllciBzb3VyY2UgZm9yIHRpbGUgZGF0YSB3aXRoIFVSTHMgaW4gYSBzZXQgWFlaIGZvcm1hdCB0aGF0IGFyZVxuICogZGVmaW5lZCBpbiBhIFVSTCB0ZW1wbGF0ZS4gQnkgZGVmYXVsdCwgdGhpcyBmb2xsb3dzIHRoZSB3aWRlbHktdXNlZFxuICogR29vZ2xlIGdyaWQgd2hlcmUgYHhgIDAgYW5kIGB5YCAwIGFyZSBpbiB0aGUgdG9wIGxlZnQuIEdyaWRzIGxpa2VcbiAqIFRNUyB3aGVyZSBgeGAgMCBhbmQgYHlgIDAgYXJlIGluIHRoZSBib3R0b20gbGVmdCBjYW4gYmUgdXNlZCBieVxuICogdXNpbmcgdGhlIGB7LXl9YCBwbGFjZWhvbGRlciBpbiB0aGUgVVJMIHRlbXBsYXRlLCBzbyBsb25nIGFzIHRoZVxuICogc291cmNlIGRvZXMgbm90IGhhdmUgYSBjdXN0b20gdGlsZSBncmlkLiBJbiB0aGlzIGNhc2VcbiAqIGEgYHRpbGVVcmxGdW5jdGlvbmAgY2FuIGJlIHVzZWQsIHN1Y2ggYXM6XG4gKiBgYGBqc1xuICogIHRpbGVVcmxGdW5jdGlvbjogZnVuY3Rpb24oY29vcmRpbmF0ZSkge1xuICogICAgcmV0dXJuICdodHRwOi8vbWFwc2VydmVyLmNvbS8nICsgY29vcmRpbmF0ZVswXSArICcvJyArXG4gKiAgICAgIGNvb3JkaW5hdGVbMV0gKyAnLycgKyAoLWNvb3JkaW5hdGVbMl0gLSAxKSArICcucG5nJztcbiAqICB9XG4gKiBgYGBcbiAqIEBhcGlcbiAqL1xuXG52YXIgWFlaID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFhZWiwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIFhZWiBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFhZWihvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zIHx8IHt9O1xuICAgIHZhciBwcm9qZWN0aW9uID0gb3B0aW9ucy5wcm9qZWN0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnByb2plY3Rpb24gOiAnRVBTRzozODU3JztcbiAgICB2YXIgdGlsZUdyaWQgPSBvcHRpb25zLnRpbGVHcmlkICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnRpbGVHcmlkIDogY3JlYXRlWFlaKHtcbiAgICAgIGV4dGVudDogZXh0ZW50RnJvbVByb2plY3Rpb24ocHJvamVjdGlvbiksXG4gICAgICBtYXhSZXNvbHV0aW9uOiBvcHRpb25zLm1heFJlc29sdXRpb24sXG4gICAgICBtYXhab29tOiBvcHRpb25zLm1heFpvb20sXG4gICAgICBtaW5ab29tOiBvcHRpb25zLm1pblpvb20sXG4gICAgICB0aWxlU2l6ZTogb3B0aW9ucy50aWxlU2l6ZVxuICAgIH0pO1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgYXR0cmlidXRpb25zOiBvcHRpb25zLmF0dHJpYnV0aW9ucyxcbiAgICAgIGNhY2hlU2l6ZTogb3B0aW9ucy5jYWNoZVNpemUsXG4gICAgICBjcm9zc09yaWdpbjogb3B0aW9ucy5jcm9zc09yaWdpbixcbiAgICAgIGltYWdlU21vb3RoaW5nOiBvcHRpb25zLmltYWdlU21vb3RoaW5nLFxuICAgICAgb3BhcXVlOiBvcHRpb25zLm9wYXF1ZSxcbiAgICAgIHByb2plY3Rpb246IHByb2plY3Rpb24sXG4gICAgICByZXByb2plY3Rpb25FcnJvclRocmVzaG9sZDogb3B0aW9ucy5yZXByb2plY3Rpb25FcnJvclRocmVzaG9sZCxcbiAgICAgIHRpbGVHcmlkOiB0aWxlR3JpZCxcbiAgICAgIHRpbGVMb2FkRnVuY3Rpb246IG9wdGlvbnMudGlsZUxvYWRGdW5jdGlvbixcbiAgICAgIHRpbGVQaXhlbFJhdGlvOiBvcHRpb25zLnRpbGVQaXhlbFJhdGlvLFxuICAgICAgdGlsZVVybEZ1bmN0aW9uOiBvcHRpb25zLnRpbGVVcmxGdW5jdGlvbixcbiAgICAgIHVybDogb3B0aW9ucy51cmwsXG4gICAgICB1cmxzOiBvcHRpb25zLnVybHMsXG4gICAgICB3cmFwWDogb3B0aW9ucy53cmFwWCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy53cmFwWCA6IHRydWUsXG4gICAgICB0cmFuc2l0aW9uOiBvcHRpb25zLnRyYW5zaXRpb24sXG4gICAgICBhdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZTogb3B0aW9ucy5hdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZSxcbiAgICAgIHpEaXJlY3Rpb246IG9wdGlvbnMuekRpcmVjdGlvblxuICAgIH0pIHx8IHRoaXM7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIFhZWjtcbn0oVGlsZUltYWdlKTtcblxuZXhwb3J0IGRlZmF1bHQgWFlaOyIsImZ1bmN0aW9uIG5vbmUoKSB7fVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcbiAgcmV0dXJuIHNlbGVjdG9yID09IG51bGwgPyBub25lIDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICB9O1xufSIsImltcG9ydCB7IFNlbGVjdGlvbiB9IGZyb20gXCIuL2luZGV4LmpzXCI7XG5pbXBvcnQgc2VsZWN0b3IgZnJvbSBcIi4uL3NlbGVjdG9yLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc2VsZWN0KSB7XG4gIGlmICh0eXBlb2Ygc2VsZWN0ICE9PSBcImZ1bmN0aW9uXCIpIHNlbGVjdCA9IHNlbGVjdG9yKHNlbGVjdCk7XG5cbiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBtID0gZ3JvdXBzLmxlbmd0aCwgc3ViZ3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBzdWJncm91cCA9IHN1Ymdyb3Vwc1tqXSA9IG5ldyBBcnJheShuKSwgbm9kZSwgc3Vibm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmICgobm9kZSA9IGdyb3VwW2ldKSAmJiAoc3Vibm9kZSA9IHNlbGVjdC5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKSkpIHtcbiAgICAgICAgaWYgKFwiX19kYXRhX19cIiBpbiBub2RlKSBzdWJub2RlLl9fZGF0YV9fID0gbm9kZS5fX2RhdGFfXztcbiAgICAgICAgc3ViZ3JvdXBbaV0gPSBzdWJub2RlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKHN1Ymdyb3VwcywgdGhpcy5fcGFyZW50cyk7XG59IiwiLy8gR2l2ZW4gc29tZXRoaW5nIGFycmF5IGxpa2UgKG9yIG51bGwpLCByZXR1cm5zIHNvbWV0aGluZyB0aGF0IGlzIHN0cmljdGx5IGFuXG4vLyBhcnJheS4gVGhpcyBpcyB1c2VkIHRvIGVuc3VyZSB0aGF0IGFycmF5LWxpa2Ugb2JqZWN0cyBwYXNzZWQgdG8gZDMuc2VsZWN0QWxsXG4vLyBvciBzZWxlY3Rpb24uc2VsZWN0QWxsIGFyZSBjb252ZXJ0ZWQgaW50byBwcm9wZXIgYXJyYXlzIHdoZW4gY3JlYXRpbmcgYVxuLy8gc2VsZWN0aW9uOyB3ZSBkb27igJl0IGV2ZXIgd2FudCB0byBjcmVhdGUgYSBzZWxlY3Rpb24gYmFja2VkIGJ5IGEgbGl2ZVxuLy8gSFRNTENvbGxlY3Rpb24gb3IgTm9kZUxpc3QuIEhvd2V2ZXIsIG5vdGUgdGhhdCBzZWxlY3Rpb24uc2VsZWN0QWxsIHdpbGwgdXNlIGFcbi8vIHN0YXRpYyBOb2RlTGlzdCBhcyBhIGdyb3VwLCBzaW5jZSBpdCBzYWZlbHkgZGVyaXZlZCBmcm9tIHF1ZXJ5U2VsZWN0b3JBbGwuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBhcnJheSh4KSB7XG4gIHJldHVybiB4ID09IG51bGwgPyBbXSA6IEFycmF5LmlzQXJyYXkoeCkgPyB4IDogQXJyYXkuZnJvbSh4KTtcbn0iLCJmdW5jdGlvbiBlbXB0eSgpIHtcbiAgcmV0dXJuIFtdO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcbiAgcmV0dXJuIHNlbGVjdG9yID09IG51bGwgPyBlbXB0eSA6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcbiAgfTtcbn0iLCJpbXBvcnQgeyBTZWxlY3Rpb24gfSBmcm9tIFwiLi9pbmRleC5qc1wiO1xuaW1wb3J0IGFycmF5IGZyb20gXCIuLi9hcnJheS5qc1wiO1xuaW1wb3J0IHNlbGVjdG9yQWxsIGZyb20gXCIuLi9zZWxlY3RvckFsbC5qc1wiO1xuXG5mdW5jdGlvbiBhcnJheUFsbChzZWxlY3QpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYXJyYXkoc2VsZWN0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc2VsZWN0KSB7XG4gIGlmICh0eXBlb2Ygc2VsZWN0ID09PSBcImZ1bmN0aW9uXCIpIHNlbGVjdCA9IGFycmF5QWxsKHNlbGVjdCk7ZWxzZSBzZWxlY3QgPSBzZWxlY3RvckFsbChzZWxlY3QpO1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIHN1Ymdyb3VwcyA9IFtdLCBwYXJlbnRzID0gW10sIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICAgIHN1Ymdyb3Vwcy5wdXNoKHNlbGVjdC5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKSk7XG4gICAgICAgIHBhcmVudHMucHVzaChub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IFNlbGVjdGlvbihzdWJncm91cHMsIHBhcmVudHMpO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzZWxlY3Rvcikge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm1hdGNoZXMoc2VsZWN0b3IpO1xuICB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNoaWxkTWF0Y2hlcihzZWxlY3Rvcikge1xuICByZXR1cm4gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5tYXRjaGVzKHNlbGVjdG9yKTtcbiAgfTtcbn0iLCJpbXBvcnQgeyBjaGlsZE1hdGNoZXIgfSBmcm9tIFwiLi4vbWF0Y2hlci5qc1wiO1xudmFyIGZpbmQgPSBBcnJheS5wcm90b3R5cGUuZmluZDtcblxuZnVuY3Rpb24gY2hpbGRGaW5kKG1hdGNoKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZpbmQuY2FsbCh0aGlzLmNoaWxkcmVuLCBtYXRjaCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNoaWxkRmlyc3QoKSB7XG4gIHJldHVybiB0aGlzLmZpcnN0RWxlbWVudENoaWxkO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAobWF0Y2gpIHtcbiAgcmV0dXJuIHRoaXMuc2VsZWN0KG1hdGNoID09IG51bGwgPyBjaGlsZEZpcnN0IDogY2hpbGRGaW5kKHR5cGVvZiBtYXRjaCA9PT0gXCJmdW5jdGlvblwiID8gbWF0Y2ggOiBjaGlsZE1hdGNoZXIobWF0Y2gpKSk7XG59IiwiaW1wb3J0IHsgY2hpbGRNYXRjaGVyIH0gZnJvbSBcIi4uL21hdGNoZXIuanNcIjtcbnZhciBmaWx0ZXIgPSBBcnJheS5wcm90b3R5cGUuZmlsdGVyO1xuXG5mdW5jdGlvbiBjaGlsZHJlbigpIHtcbiAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5jaGlsZHJlbik7XG59XG5cbmZ1bmN0aW9uIGNoaWxkcmVuRmlsdGVyKG1hdGNoKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZpbHRlci5jYWxsKHRoaXMuY2hpbGRyZW4sIG1hdGNoKTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG1hdGNoKSB7XG4gIHJldHVybiB0aGlzLnNlbGVjdEFsbChtYXRjaCA9PSBudWxsID8gY2hpbGRyZW4gOiBjaGlsZHJlbkZpbHRlcih0eXBlb2YgbWF0Y2ggPT09IFwiZnVuY3Rpb25cIiA/IG1hdGNoIDogY2hpbGRNYXRjaGVyKG1hdGNoKSkpO1xufSIsImltcG9ydCB7IFNlbGVjdGlvbiB9IGZyb20gXCIuL2luZGV4LmpzXCI7XG5pbXBvcnQgbWF0Y2hlciBmcm9tIFwiLi4vbWF0Y2hlci5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG1hdGNoKSB7XG4gIGlmICh0eXBlb2YgbWF0Y2ggIT09IFwiZnVuY3Rpb25cIikgbWF0Y2ggPSBtYXRjaGVyKG1hdGNoKTtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzdWJncm91cHMgPSBuZXcgQXJyYXkobSksIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIHN1Ymdyb3VwID0gc3ViZ3JvdXBzW2pdID0gW10sIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoKG5vZGUgPSBncm91cFtpXSkgJiYgbWF0Y2guY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkpIHtcbiAgICAgICAgc3ViZ3JvdXAucHVzaChub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IFNlbGVjdGlvbihzdWJncm91cHMsIHRoaXMuX3BhcmVudHMpO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICh1cGRhdGUpIHtcbiAgcmV0dXJuIG5ldyBBcnJheSh1cGRhdGUubGVuZ3RoKTtcbn0iLCJpbXBvcnQgc3BhcnNlIGZyb20gXCIuL3NwYXJzZS5qc1wiO1xuaW1wb3J0IHsgU2VsZWN0aW9uIH0gZnJvbSBcIi4vaW5kZXguanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24odGhpcy5fZW50ZXIgfHwgdGhpcy5fZ3JvdXBzLm1hcChzcGFyc2UpLCB0aGlzLl9wYXJlbnRzKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBFbnRlck5vZGUocGFyZW50LCBkYXR1bSkge1xuICB0aGlzLm93bmVyRG9jdW1lbnQgPSBwYXJlbnQub3duZXJEb2N1bWVudDtcbiAgdGhpcy5uYW1lc3BhY2VVUkkgPSBwYXJlbnQubmFtZXNwYWNlVVJJO1xuICB0aGlzLl9uZXh0ID0gbnVsbDtcbiAgdGhpcy5fcGFyZW50ID0gcGFyZW50O1xuICB0aGlzLl9fZGF0YV9fID0gZGF0dW07XG59XG5FbnRlck5vZGUucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogRW50ZXJOb2RlLFxuICBhcHBlbmRDaGlsZDogZnVuY3Rpb24gYXBwZW5kQ2hpbGQoY2hpbGQpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgdGhpcy5fbmV4dCk7XG4gIH0sXG4gIGluc2VydEJlZm9yZTogZnVuY3Rpb24gaW5zZXJ0QmVmb3JlKGNoaWxkLCBuZXh0KSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhcmVudC5pbnNlcnRCZWZvcmUoY2hpbGQsIG5leHQpO1xuICB9LFxuICBxdWVyeVNlbGVjdG9yOiBmdW5jdGlvbiBxdWVyeVNlbGVjdG9yKHNlbGVjdG9yKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhcmVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbiAgfSxcbiAgcXVlcnlTZWxlY3RvckFsbDogZnVuY3Rpb24gcXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcikge1xuICAgIHJldHVybiB0aGlzLl9wYXJlbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG4gIH1cbn07IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4geDtcbiAgfTtcbn0iLCJpbXBvcnQgeyBTZWxlY3Rpb24gfSBmcm9tIFwiLi9pbmRleC5qc1wiO1xuaW1wb3J0IHsgRW50ZXJOb2RlIH0gZnJvbSBcIi4vZW50ZXIuanNcIjtcbmltcG9ydCBjb25zdGFudCBmcm9tIFwiLi4vY29uc3RhbnQuanNcIjtcblxuZnVuY3Rpb24gYmluZEluZGV4KHBhcmVudCwgZ3JvdXAsIGVudGVyLCB1cGRhdGUsIGV4aXQsIGRhdGEpIHtcbiAgdmFyIGkgPSAwLFxuICAgICAgbm9kZSxcbiAgICAgIGdyb3VwTGVuZ3RoID0gZ3JvdXAubGVuZ3RoLFxuICAgICAgZGF0YUxlbmd0aCA9IGRhdGEubGVuZ3RoOyAvLyBQdXQgYW55IG5vbi1udWxsIG5vZGVzIHRoYXQgZml0IGludG8gdXBkYXRlLlxuICAvLyBQdXQgYW55IG51bGwgbm9kZXMgaW50byBlbnRlci5cbiAgLy8gUHV0IGFueSByZW1haW5pbmcgZGF0YSBpbnRvIGVudGVyLlxuXG4gIGZvciAoOyBpIDwgZGF0YUxlbmd0aDsgKytpKSB7XG4gICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgbm9kZS5fX2RhdGFfXyA9IGRhdGFbaV07XG4gICAgICB1cGRhdGVbaV0gPSBub2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbnRlcltpXSA9IG5ldyBFbnRlck5vZGUocGFyZW50LCBkYXRhW2ldKTtcbiAgICB9XG4gIH0gLy8gUHV0IGFueSBub24tbnVsbCBub2RlcyB0aGF0IGRvbuKAmXQgZml0IGludG8gZXhpdC5cblxuXG4gIGZvciAoOyBpIDwgZ3JvdXBMZW5ndGg7ICsraSkge1xuICAgIGlmIChub2RlID0gZ3JvdXBbaV0pIHtcbiAgICAgIGV4aXRbaV0gPSBub2RlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBiaW5kS2V5KHBhcmVudCwgZ3JvdXAsIGVudGVyLCB1cGRhdGUsIGV4aXQsIGRhdGEsIGtleSkge1xuICB2YXIgaSxcbiAgICAgIG5vZGUsXG4gICAgICBub2RlQnlLZXlWYWx1ZSA9IG5ldyBNYXAoKSxcbiAgICAgIGdyb3VwTGVuZ3RoID0gZ3JvdXAubGVuZ3RoLFxuICAgICAgZGF0YUxlbmd0aCA9IGRhdGEubGVuZ3RoLFxuICAgICAga2V5VmFsdWVzID0gbmV3IEFycmF5KGdyb3VwTGVuZ3RoKSxcbiAgICAgIGtleVZhbHVlOyAvLyBDb21wdXRlIHRoZSBrZXkgZm9yIGVhY2ggbm9kZS5cbiAgLy8gSWYgbXVsdGlwbGUgbm9kZXMgaGF2ZSB0aGUgc2FtZSBrZXksIHRoZSBkdXBsaWNhdGVzIGFyZSBhZGRlZCB0byBleGl0LlxuXG4gIGZvciAoaSA9IDA7IGkgPCBncm91cExlbmd0aDsgKytpKSB7XG4gICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAga2V5VmFsdWVzW2ldID0ga2V5VmFsdWUgPSBrZXkuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkgKyBcIlwiO1xuXG4gICAgICBpZiAobm9kZUJ5S2V5VmFsdWUuaGFzKGtleVZhbHVlKSkge1xuICAgICAgICBleGl0W2ldID0gbm9kZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGVCeUtleVZhbHVlLnNldChrZXlWYWx1ZSwgbm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9IC8vIENvbXB1dGUgdGhlIGtleSBmb3IgZWFjaCBkYXR1bS5cbiAgLy8gSWYgdGhlcmUgYSBub2RlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGtleSwgam9pbiBhbmQgYWRkIGl0IHRvIHVwZGF0ZS5cbiAgLy8gSWYgdGhlcmUgaXMgbm90IChvciB0aGUga2V5IGlzIGEgZHVwbGljYXRlKSwgYWRkIGl0IHRvIGVudGVyLlxuXG5cbiAgZm9yIChpID0gMDsgaSA8IGRhdGFMZW5ndGg7ICsraSkge1xuICAgIGtleVZhbHVlID0ga2V5LmNhbGwocGFyZW50LCBkYXRhW2ldLCBpLCBkYXRhKSArIFwiXCI7XG5cbiAgICBpZiAobm9kZSA9IG5vZGVCeUtleVZhbHVlLmdldChrZXlWYWx1ZSkpIHtcbiAgICAgIHVwZGF0ZVtpXSA9IG5vZGU7XG4gICAgICBub2RlLl9fZGF0YV9fID0gZGF0YVtpXTtcbiAgICAgIG5vZGVCeUtleVZhbHVlLmRlbGV0ZShrZXlWYWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudGVyW2ldID0gbmV3IEVudGVyTm9kZShwYXJlbnQsIGRhdGFbaV0pO1xuICAgIH1cbiAgfSAvLyBBZGQgYW55IHJlbWFpbmluZyBub2RlcyB0aGF0IHdlcmUgbm90IGJvdW5kIHRvIGRhdGEgdG8gZXhpdC5cblxuXG4gIGZvciAoaSA9IDA7IGkgPCBncm91cExlbmd0aDsgKytpKSB7XG4gICAgaWYgKChub2RlID0gZ3JvdXBbaV0pICYmIG5vZGVCeUtleVZhbHVlLmdldChrZXlWYWx1ZXNbaV0pID09PSBub2RlKSB7XG4gICAgICBleGl0W2ldID0gbm9kZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZGF0dW0obm9kZSkge1xuICByZXR1cm4gbm9kZS5fX2RhdGFfXztcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLCBkYXR1bSk7XG4gIHZhciBiaW5kID0ga2V5ID8gYmluZEtleSA6IGJpbmRJbmRleCxcbiAgICAgIHBhcmVudHMgPSB0aGlzLl9wYXJlbnRzLFxuICAgICAgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzO1xuICBpZiAodHlwZW9mIHZhbHVlICE9PSBcImZ1bmN0aW9uXCIpIHZhbHVlID0gY29uc3RhbnQodmFsdWUpO1xuXG4gIGZvciAodmFyIG0gPSBncm91cHMubGVuZ3RoLCB1cGRhdGUgPSBuZXcgQXJyYXkobSksIGVudGVyID0gbmV3IEFycmF5KG0pLCBleGl0ID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIHZhciBwYXJlbnQgPSBwYXJlbnRzW2pdLFxuICAgICAgICBncm91cCA9IGdyb3Vwc1tqXSxcbiAgICAgICAgZ3JvdXBMZW5ndGggPSBncm91cC5sZW5ndGgsXG4gICAgICAgIGRhdGEgPSBhcnJheWxpa2UodmFsdWUuY2FsbChwYXJlbnQsIHBhcmVudCAmJiBwYXJlbnQuX19kYXRhX18sIGosIHBhcmVudHMpKSxcbiAgICAgICAgZGF0YUxlbmd0aCA9IGRhdGEubGVuZ3RoLFxuICAgICAgICBlbnRlckdyb3VwID0gZW50ZXJbal0gPSBuZXcgQXJyYXkoZGF0YUxlbmd0aCksXG4gICAgICAgIHVwZGF0ZUdyb3VwID0gdXBkYXRlW2pdID0gbmV3IEFycmF5KGRhdGFMZW5ndGgpLFxuICAgICAgICBleGl0R3JvdXAgPSBleGl0W2pdID0gbmV3IEFycmF5KGdyb3VwTGVuZ3RoKTtcbiAgICBiaW5kKHBhcmVudCwgZ3JvdXAsIGVudGVyR3JvdXAsIHVwZGF0ZUdyb3VwLCBleGl0R3JvdXAsIGRhdGEsIGtleSk7IC8vIE5vdyBjb25uZWN0IHRoZSBlbnRlciBub2RlcyB0byB0aGVpciBmb2xsb3dpbmcgdXBkYXRlIG5vZGUsIHN1Y2ggdGhhdFxuICAgIC8vIGFwcGVuZENoaWxkIGNhbiBpbnNlcnQgdGhlIG1hdGVyaWFsaXplZCBlbnRlciBub2RlIGJlZm9yZSB0aGlzIG5vZGUsXG4gICAgLy8gcmF0aGVyIHRoYW4gYXQgdGhlIGVuZCBvZiB0aGUgcGFyZW50IG5vZGUuXG5cbiAgICBmb3IgKHZhciBpMCA9IDAsIGkxID0gMCwgcHJldmlvdXMsIG5leHQ7IGkwIDwgZGF0YUxlbmd0aDsgKytpMCkge1xuICAgICAgaWYgKHByZXZpb3VzID0gZW50ZXJHcm91cFtpMF0pIHtcbiAgICAgICAgaWYgKGkwID49IGkxKSBpMSA9IGkwICsgMTtcblxuICAgICAgICB3aGlsZSAoIShuZXh0ID0gdXBkYXRlR3JvdXBbaTFdKSAmJiArK2kxIDwgZGF0YUxlbmd0aCkge1xuICAgICAgICAgIDtcbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZpb3VzLl9uZXh0ID0gbmV4dCB8fCBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZSA9IG5ldyBTZWxlY3Rpb24odXBkYXRlLCBwYXJlbnRzKTtcbiAgdXBkYXRlLl9lbnRlciA9IGVudGVyO1xuICB1cGRhdGUuX2V4aXQgPSBleGl0O1xuICByZXR1cm4gdXBkYXRlO1xufSAvLyBHaXZlbiBzb21lIGRhdGEsIHRoaXMgcmV0dXJucyBhbiBhcnJheS1saWtlIHZpZXcgb2YgaXQ6IGFuIG9iamVjdCB0aGF0XG4vLyBleHBvc2VzIGEgbGVuZ3RoIHByb3BlcnR5IGFuZCBhbGxvd3MgbnVtZXJpYyBpbmRleGluZy4gTm90ZSB0aGF0IHVubGlrZVxuLy8gc2VsZWN0QWxsLCB0aGlzIGlzbuKAmXQgd29ycmllZCBhYm91dCDigJxsaXZl4oCdIGNvbGxlY3Rpb25zIGJlY2F1c2UgdGhlIHJlc3VsdGluZ1xuLy8gYXJyYXkgd2lsbCBvbmx5IGJlIHVzZWQgYnJpZWZseSB3aGlsZSBkYXRhIGlzIGJlaW5nIGJvdW5kLiAoSXQgaXMgcG9zc2libGUgdG9cbi8vIGNhdXNlIHRoZSBkYXRhIHRvIGNoYW5nZSB3aGlsZSBpdGVyYXRpbmcgYnkgdXNpbmcgYSBrZXkgZnVuY3Rpb24sIGJ1dCBwbGVhc2Vcbi8vIGRvbuKAmXQ7IHdl4oCZZCByYXRoZXIgYXZvaWQgYSBncmF0dWl0b3VzIGNvcHkuKVxuXG5mdW5jdGlvbiBhcnJheWxpa2UoZGF0YSkge1xuICByZXR1cm4gdHlwZW9mIGRhdGEgPT09IFwib2JqZWN0XCIgJiYgXCJsZW5ndGhcIiBpbiBkYXRhID8gZGF0YSAvLyBBcnJheSwgVHlwZWRBcnJheSwgTm9kZUxpc3QsIGFycmF5LWxpa2VcbiAgOiBBcnJheS5mcm9tKGRhdGEpOyAvLyBNYXAsIFNldCwgaXRlcmFibGUsIHN0cmluZywgb3IgYW55dGhpbmcgZWxzZVxufSIsImltcG9ydCBzcGFyc2UgZnJvbSBcIi4vc3BhcnNlLmpzXCI7XG5pbXBvcnQgeyBTZWxlY3Rpb24gfSBmcm9tIFwiLi9pbmRleC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gbmV3IFNlbGVjdGlvbih0aGlzLl9leGl0IHx8IHRoaXMuX2dyb3Vwcy5tYXAoc3BhcnNlKSwgdGhpcy5fcGFyZW50cyk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG9uZW50ZXIsIG9udXBkYXRlLCBvbmV4aXQpIHtcbiAgdmFyIGVudGVyID0gdGhpcy5lbnRlcigpLFxuICAgICAgdXBkYXRlID0gdGhpcyxcbiAgICAgIGV4aXQgPSB0aGlzLmV4aXQoKTtcblxuICBpZiAodHlwZW9mIG9uZW50ZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGVudGVyID0gb25lbnRlcihlbnRlcik7XG4gICAgaWYgKGVudGVyKSBlbnRlciA9IGVudGVyLnNlbGVjdGlvbigpO1xuICB9IGVsc2Uge1xuICAgIGVudGVyID0gZW50ZXIuYXBwZW5kKG9uZW50ZXIgKyBcIlwiKTtcbiAgfVxuXG4gIGlmIChvbnVwZGF0ZSAhPSBudWxsKSB7XG4gICAgdXBkYXRlID0gb251cGRhdGUodXBkYXRlKTtcbiAgICBpZiAodXBkYXRlKSB1cGRhdGUgPSB1cGRhdGUuc2VsZWN0aW9uKCk7XG4gIH1cblxuICBpZiAob25leGl0ID09IG51bGwpIGV4aXQucmVtb3ZlKCk7ZWxzZSBvbmV4aXQoZXhpdCk7XG4gIHJldHVybiBlbnRlciAmJiB1cGRhdGUgPyBlbnRlci5tZXJnZSh1cGRhdGUpLm9yZGVyKCkgOiB1cGRhdGU7XG59IiwiaW1wb3J0IHsgU2VsZWN0aW9uIH0gZnJvbSBcIi4vaW5kZXguanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gIHZhciBzZWxlY3Rpb24gPSBjb250ZXh0LnNlbGVjdGlvbiA/IGNvbnRleHQuc2VsZWN0aW9uKCkgOiBjb250ZXh0O1xuXG4gIGZvciAodmFyIGdyb3VwczAgPSB0aGlzLl9ncm91cHMsIGdyb3VwczEgPSBzZWxlY3Rpb24uX2dyb3VwcywgbTAgPSBncm91cHMwLmxlbmd0aCwgbTEgPSBncm91cHMxLmxlbmd0aCwgbSA9IE1hdGgubWluKG0wLCBtMSksIG1lcmdlcyA9IG5ldyBBcnJheShtMCksIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAwID0gZ3JvdXBzMFtqXSwgZ3JvdXAxID0gZ3JvdXBzMVtqXSwgbiA9IGdyb3VwMC5sZW5ndGgsIG1lcmdlID0gbWVyZ2VzW2pdID0gbmV3IEFycmF5KG4pLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cDBbaV0gfHwgZ3JvdXAxW2ldKSB7XG4gICAgICAgIG1lcmdlW2ldID0gbm9kZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3IgKDsgaiA8IG0wOyArK2opIHtcbiAgICBtZXJnZXNbal0gPSBncm91cHMwW2pdO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24obWVyZ2VzLCB0aGlzLl9wYXJlbnRzKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoKSB7XG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgaiA9IC0xLCBtID0gZ3JvdXBzLmxlbmd0aDsgKytqIDwgbTspIHtcbiAgICBmb3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgaSA9IGdyb3VwLmxlbmd0aCAtIDEsIG5leHQgPSBncm91cFtpXSwgbm9kZTsgLS1pID49IDA7KSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICAgIGlmIChuZXh0ICYmIG5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24obmV4dCkgXiA0KSBuZXh0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5vZGUsIG5leHQpO1xuICAgICAgICBuZXh0ID0gbm9kZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn0iLCJpbXBvcnQgeyBTZWxlY3Rpb24gfSBmcm9tIFwiLi9pbmRleC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKGNvbXBhcmUpIHtcbiAgaWYgKCFjb21wYXJlKSBjb21wYXJlID0gYXNjZW5kaW5nO1xuXG4gIGZ1bmN0aW9uIGNvbXBhcmVOb2RlKGEsIGIpIHtcbiAgICByZXR1cm4gYSAmJiBiID8gY29tcGFyZShhLl9fZGF0YV9fLCBiLl9fZGF0YV9fKSA6ICFhIC0gIWI7XG4gIH1cblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzb3J0Z3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBzb3J0Z3JvdXAgPSBzb3J0Z3JvdXBzW2pdID0gbmV3IEFycmF5KG4pLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICBzb3J0Z3JvdXBbaV0gPSBub2RlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHNvcnRncm91cC5zb3J0KGNvbXBhcmVOb2RlKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKHNvcnRncm91cHMsIHRoaXMuX3BhcmVudHMpLm9yZGVyKCk7XG59XG5cbmZ1bmN0aW9uIGFzY2VuZGluZyhhLCBiKSB7XG4gIHJldHVybiBhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogYSA+PSBiID8gMCA6IE5hTjtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoKSB7XG4gIHZhciBjYWxsYmFjayA9IGFyZ3VtZW50c1swXTtcbiAgYXJndW1lbnRzWzBdID0gdGhpcztcbiAgY2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgcmV0dXJuIHRoaXM7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoKSB7XG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgaiA9IDAsIG0gPSBncm91cHMubGVuZ3RoOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIGkgPSAwLCBuID0gZ3JvdXAubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgICB2YXIgbm9kZSA9IGdyb3VwW2ldO1xuICAgICAgaWYgKG5vZGUpIHJldHVybiBub2RlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufSIsImZ1bmN0aW9uIF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyKG8sIGFsbG93QXJyYXlMaWtlKSB7IHZhciBpdCA9IHR5cGVvZiBTeW1ib2wgIT09IFwidW5kZWZpbmVkXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdIHx8IG9bXCJAQGl0ZXJhdG9yXCJdOyBpZiAoIWl0KSB7IGlmIChBcnJheS5pc0FycmF5KG8pIHx8IChpdCA9IF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShvKSkgfHwgYWxsb3dBcnJheUxpa2UgJiYgbyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHsgaWYgKGl0KSBvID0gaXQ7IHZhciBpID0gMDsgdmFyIEYgPSBmdW5jdGlvbiBGKCkge307IHJldHVybiB7IHM6IEYsIG46IGZ1bmN0aW9uIG4oKSB7IGlmIChpID49IG8ubGVuZ3RoKSByZXR1cm4geyBkb25lOiB0cnVlIH07IHJldHVybiB7IGRvbmU6IGZhbHNlLCB2YWx1ZTogb1tpKytdIH07IH0sIGU6IGZ1bmN0aW9uIGUoX2UpIHsgdGhyb3cgX2U7IH0sIGY6IEYgfTsgfSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGl0ZXJhdGUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxcbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC5cIik7IH0gdmFyIG5vcm1hbENvbXBsZXRpb24gPSB0cnVlLCBkaWRFcnIgPSBmYWxzZSwgZXJyOyByZXR1cm4geyBzOiBmdW5jdGlvbiBzKCkgeyBpdCA9IGl0LmNhbGwobyk7IH0sIG46IGZ1bmN0aW9uIG4oKSB7IHZhciBzdGVwID0gaXQubmV4dCgpOyBub3JtYWxDb21wbGV0aW9uID0gc3RlcC5kb25lOyByZXR1cm4gc3RlcDsgfSwgZTogZnVuY3Rpb24gZShfZTIpIHsgZGlkRXJyID0gdHJ1ZTsgZXJyID0gX2UyOyB9LCBmOiBmdW5jdGlvbiBmKCkgeyB0cnkgeyBpZiAoIW5vcm1hbENvbXBsZXRpb24gJiYgaXQucmV0dXJuICE9IG51bGwpIGl0LnJldHVybigpOyB9IGZpbmFsbHkgeyBpZiAoZGlkRXJyKSB0aHJvdyBlcnI7IH0gfSB9OyB9XG5cbmZ1bmN0aW9uIF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShvLCBtaW5MZW4pIHsgaWYgKCFvKSByZXR1cm47IGlmICh0eXBlb2YgbyA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7IHZhciBuID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pLnNsaWNlKDgsIC0xKTsgaWYgKG4gPT09IFwiT2JqZWN0XCIgJiYgby5jb25zdHJ1Y3RvcikgbiA9IG8uY29uc3RydWN0b3IubmFtZTsgaWYgKG4gPT09IFwiTWFwXCIgfHwgbiA9PT0gXCJTZXRcIikgcmV0dXJuIEFycmF5LmZyb20obyk7IGlmIChuID09PSBcIkFyZ3VtZW50c1wiIHx8IC9eKD86VWl8SSludCg/Ojh8MTZ8MzIpKD86Q2xhbXBlZCk/QXJyYXkkLy50ZXN0KG4pKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTsgfVxuXG5mdW5jdGlvbiBfYXJyYXlMaWtlVG9BcnJheShhcnIsIGxlbikgeyBpZiAobGVuID09IG51bGwgfHwgbGVuID4gYXJyLmxlbmd0aCkgbGVuID0gYXJyLmxlbmd0aDsgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBuZXcgQXJyYXkobGVuKTsgaSA8IGxlbjsgaSsrKSB7IGFycjJbaV0gPSBhcnJbaV07IH0gcmV0dXJuIGFycjI7IH1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKCkge1xuICB2YXIgc2l6ZSA9IDA7XG5cbiAgdmFyIF9pdGVyYXRvciA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyKHRoaXMpLFxuICAgICAgX3N0ZXA7XG5cbiAgdHJ5IHtcbiAgICBmb3IgKF9pdGVyYXRvci5zKCk7ICEoX3N0ZXAgPSBfaXRlcmF0b3IubigpKS5kb25lOykge1xuICAgICAgdmFyIG5vZGUgPSBfc3RlcC52YWx1ZTtcbiAgICAgICsrc2l6ZTtcbiAgICB9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcblxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBfaXRlcmF0b3IuZShlcnIpO1xuICB9IGZpbmFsbHkge1xuICAgIF9pdGVyYXRvci5mKCk7XG4gIH1cblxuICByZXR1cm4gc2l6ZTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhdGhpcy5ub2RlKCk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgaiA9IDAsIG0gPSBncm91cHMubGVuZ3RoOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIGkgPSAwLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSBjYWxsYmFjay5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn0iLCJleHBvcnQgdmFyIHhodG1sID0gXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI7XG5leHBvcnQgZGVmYXVsdCB7XG4gIHN2ZzogXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLFxuICB4aHRtbDogeGh0bWwsXG4gIHhsaW5rOiBcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIixcbiAgeG1sOiBcImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZVwiLFxuICB4bWxuczogXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zL1wiXG59OyIsImltcG9ydCBuYW1lc3BhY2VzIGZyb20gXCIuL25hbWVzcGFjZXMuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHZhciBwcmVmaXggPSBuYW1lICs9IFwiXCIsXG4gICAgICBpID0gcHJlZml4LmluZGV4T2YoXCI6XCIpO1xuICBpZiAoaSA+PSAwICYmIChwcmVmaXggPSBuYW1lLnNsaWNlKDAsIGkpKSAhPT0gXCJ4bWxuc1wiKSBuYW1lID0gbmFtZS5zbGljZShpICsgMSk7XG4gIHJldHVybiBuYW1lc3BhY2VzLmhhc093blByb3BlcnR5KHByZWZpeCkgPyB7XG4gICAgc3BhY2U6IG5hbWVzcGFjZXNbcHJlZml4XSxcbiAgICBsb2NhbDogbmFtZVxuICB9IDogbmFtZTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1wcm90b3R5cGUtYnVpbHRpbnNcbn0iLCJpbXBvcnQgbmFtZXNwYWNlIGZyb20gXCIuLi9uYW1lc3BhY2UuanNcIjtcblxuZnVuY3Rpb24gYXR0clJlbW92ZShuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJSZW1vdmVOUyhmdWxsbmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0ckNvbnN0YW50KG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyQ29uc3RhbnROUyhmdWxsbmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCwgdmFsdWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyRnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKHYgPT0gbnVsbCkgdGhpcy5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7ZWxzZSB0aGlzLnNldEF0dHJpYnV0ZShuYW1lLCB2KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0ckZ1bmN0aW9uTlMoZnVsbG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHYgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICh2ID09IG51bGwpIHRoaXMucmVtb3ZlQXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTtlbHNlIHRoaXMuc2V0QXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsLCB2KTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gIHZhciBmdWxsbmFtZSA9IG5hbWVzcGFjZShuYW1lKTtcblxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICB2YXIgbm9kZSA9IHRoaXMubm9kZSgpO1xuICAgIHJldHVybiBmdWxsbmFtZS5sb2NhbCA/IG5vZGUuZ2V0QXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKSA6IG5vZGUuZ2V0QXR0cmlidXRlKGZ1bGxuYW1lKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmVhY2goKHZhbHVlID09IG51bGwgPyBmdWxsbmFtZS5sb2NhbCA/IGF0dHJSZW1vdmVOUyA6IGF0dHJSZW1vdmUgOiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bGxuYW1lLmxvY2FsID8gYXR0ckZ1bmN0aW9uTlMgOiBhdHRyRnVuY3Rpb24gOiBmdWxsbmFtZS5sb2NhbCA/IGF0dHJDb25zdGFudE5TIDogYXR0ckNvbnN0YW50KShmdWxsbmFtZSwgdmFsdWUpKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAobm9kZSkge1xuICByZXR1cm4gbm9kZS5vd25lckRvY3VtZW50ICYmIG5vZGUub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyB8fCAvLyBub2RlIGlzIGEgTm9kZVxuICBub2RlLmRvY3VtZW50ICYmIG5vZGUgLy8gbm9kZSBpcyBhIFdpbmRvd1xuICB8fCBub2RlLmRlZmF1bHRWaWV3OyAvLyBub2RlIGlzIGEgRG9jdW1lbnRcbn0iLCJpbXBvcnQgZGVmYXVsdFZpZXcgZnJvbSBcIi4uL3dpbmRvdy5qc1wiO1xuXG5mdW5jdGlvbiBzdHlsZVJlbW92ZShuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3R5bGVDb25zdGFudChuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnN0eWxlLnNldFByb3BlcnR5KG5hbWUsIHZhbHVlLCBwcmlvcml0eSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHN0eWxlRnVuY3Rpb24obmFtZSwgdmFsdWUsIHByaW9yaXR5KSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHYgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICh2ID09IG51bGwpIHRoaXMuc3R5bGUucmVtb3ZlUHJvcGVydHkobmFtZSk7ZWxzZSB0aGlzLnN0eWxlLnNldFByb3BlcnR5KG5hbWUsIHYsIHByaW9yaXR5KTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyB0aGlzLmVhY2goKHZhbHVlID09IG51bGwgPyBzdHlsZVJlbW92ZSA6IHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gc3R5bGVGdW5jdGlvbiA6IHN0eWxlQ29uc3RhbnQpKG5hbWUsIHZhbHVlLCBwcmlvcml0eSA9PSBudWxsID8gXCJcIiA6IHByaW9yaXR5KSkgOiBzdHlsZVZhbHVlKHRoaXMubm9kZSgpLCBuYW1lKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzdHlsZVZhbHVlKG5vZGUsIG5hbWUpIHtcbiAgcmV0dXJuIG5vZGUuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKSB8fCBkZWZhdWx0Vmlldyhub2RlKS5nZXRDb21wdXRlZFN0eWxlKG5vZGUsIG51bGwpLmdldFByb3BlcnR5VmFsdWUobmFtZSk7XG59IiwiZnVuY3Rpb24gcHJvcGVydHlSZW1vdmUobmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGRlbGV0ZSB0aGlzW25hbWVdO1xuICB9O1xufVxuXG5mdW5jdGlvbiBwcm9wZXJ0eUNvbnN0YW50KG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpc1tuYW1lXSA9IHZhbHVlO1xuICB9O1xufVxuXG5mdW5jdGlvbiBwcm9wZXJ0eUZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHYgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICh2ID09IG51bGwpIGRlbGV0ZSB0aGlzW25hbWVdO2Vsc2UgdGhpc1tuYW1lXSA9IHY7XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyB0aGlzLmVhY2goKHZhbHVlID09IG51bGwgPyBwcm9wZXJ0eVJlbW92ZSA6IHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gcHJvcGVydHlGdW5jdGlvbiA6IHByb3BlcnR5Q29uc3RhbnQpKG5hbWUsIHZhbHVlKSkgOiB0aGlzLm5vZGUoKVtuYW1lXTtcbn0iLCJmdW5jdGlvbiBjbGFzc0FycmF5KHN0cmluZykge1xuICByZXR1cm4gc3RyaW5nLnRyaW0oKS5zcGxpdCgvXnxcXHMrLyk7XG59XG5cbmZ1bmN0aW9uIGNsYXNzTGlzdChub2RlKSB7XG4gIHJldHVybiBub2RlLmNsYXNzTGlzdCB8fCBuZXcgQ2xhc3NMaXN0KG5vZGUpO1xufVxuXG5mdW5jdGlvbiBDbGFzc0xpc3Qobm9kZSkge1xuICB0aGlzLl9ub2RlID0gbm9kZTtcbiAgdGhpcy5fbmFtZXMgPSBjbGFzc0FycmF5KG5vZGUuZ2V0QXR0cmlidXRlKFwiY2xhc3NcIikgfHwgXCJcIik7XG59XG5cbkNsYXNzTGlzdC5wcm90b3R5cGUgPSB7XG4gIGFkZDogZnVuY3Rpb24gYWRkKG5hbWUpIHtcbiAgICB2YXIgaSA9IHRoaXMuX25hbWVzLmluZGV4T2YobmFtZSk7XG5cbiAgICBpZiAoaSA8IDApIHtcbiAgICAgIHRoaXMuX25hbWVzLnB1c2gobmFtZSk7XG5cbiAgICAgIHRoaXMuX25vZGUuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgdGhpcy5fbmFtZXMuam9pbihcIiBcIikpO1xuICAgIH1cbiAgfSxcbiAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUobmFtZSkge1xuICAgIHZhciBpID0gdGhpcy5fbmFtZXMuaW5kZXhPZihuYW1lKTtcblxuICAgIGlmIChpID49IDApIHtcbiAgICAgIHRoaXMuX25hbWVzLnNwbGljZShpLCAxKTtcblxuICAgICAgdGhpcy5fbm9kZS5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCB0aGlzLl9uYW1lcy5qb2luKFwiIFwiKSk7XG4gICAgfVxuICB9LFxuICBjb250YWluczogZnVuY3Rpb24gY29udGFpbnMobmFtZSkge1xuICAgIHJldHVybiB0aGlzLl9uYW1lcy5pbmRleE9mKG5hbWUpID49IDA7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNsYXNzZWRBZGQobm9kZSwgbmFtZXMpIHtcbiAgdmFyIGxpc3QgPSBjbGFzc0xpc3Qobm9kZSksXG4gICAgICBpID0gLTEsXG4gICAgICBuID0gbmFtZXMubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgbGlzdC5hZGQobmFtZXNbaV0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNsYXNzZWRSZW1vdmUobm9kZSwgbmFtZXMpIHtcbiAgdmFyIGxpc3QgPSBjbGFzc0xpc3Qobm9kZSksXG4gICAgICBpID0gLTEsXG4gICAgICBuID0gbmFtZXMubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgbGlzdC5yZW1vdmUobmFtZXNbaV0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNsYXNzZWRUcnVlKG5hbWVzKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgY2xhc3NlZEFkZCh0aGlzLCBuYW1lcyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNsYXNzZWRGYWxzZShuYW1lcykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGNsYXNzZWRSZW1vdmUodGhpcywgbmFtZXMpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBjbGFzc2VkRnVuY3Rpb24obmFtZXMsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgKHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgPyBjbGFzc2VkQWRkIDogY2xhc3NlZFJlbW92ZSkodGhpcywgbmFtZXMpO1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgdmFyIG5hbWVzID0gY2xhc3NBcnJheShuYW1lICsgXCJcIik7XG5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgdmFyIGxpc3QgPSBjbGFzc0xpc3QodGhpcy5ub2RlKCkpLFxuICAgICAgICBpID0gLTEsXG4gICAgICAgIG4gPSBuYW1lcy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaWYgKCFsaXN0LmNvbnRhaW5zKG5hbWVzW2ldKSkgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuZWFjaCgodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBjbGFzc2VkRnVuY3Rpb24gOiB2YWx1ZSA/IGNsYXNzZWRUcnVlIDogY2xhc3NlZEZhbHNlKShuYW1lcywgdmFsdWUpKTtcbn0iLCJmdW5jdGlvbiB0ZXh0UmVtb3ZlKCkge1xuICB0aGlzLnRleHRDb250ZW50ID0gXCJcIjtcbn1cblxuZnVuY3Rpb24gdGV4dENvbnN0YW50KHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy50ZXh0Q29udGVudCA9IHZhbHVlO1xuICB9O1xufVxuXG5mdW5jdGlvbiB0ZXh0RnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy50ZXh0Q29udGVudCA9IHYgPT0gbnVsbCA/IFwiXCIgOiB2O1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLmVhY2godmFsdWUgPT0gbnVsbCA/IHRleHRSZW1vdmUgOiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyB0ZXh0RnVuY3Rpb24gOiB0ZXh0Q29uc3RhbnQpKHZhbHVlKSkgOiB0aGlzLm5vZGUoKS50ZXh0Q29udGVudDtcbn0iLCJmdW5jdGlvbiBodG1sUmVtb3ZlKCkge1xuICB0aGlzLmlubmVySFRNTCA9IFwiXCI7XG59XG5cbmZ1bmN0aW9uIGh0bWxDb25zdGFudCh2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuaW5uZXJIVE1MID0gdmFsdWU7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGh0bWxGdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2ID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0aGlzLmlubmVySFRNTCA9IHYgPT0gbnVsbCA/IFwiXCIgOiB2O1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLmVhY2godmFsdWUgPT0gbnVsbCA/IGh0bWxSZW1vdmUgOiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBodG1sRnVuY3Rpb24gOiBodG1sQ29uc3RhbnQpKHZhbHVlKSkgOiB0aGlzLm5vZGUoKS5pbm5lckhUTUw7XG59IiwiZnVuY3Rpb24gcmFpc2UoKSB7XG4gIGlmICh0aGlzLm5leHRTaWJsaW5nKSB0aGlzLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcyk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaChyYWlzZSk7XG59IiwiZnVuY3Rpb24gbG93ZXIoKSB7XG4gIGlmICh0aGlzLnByZXZpb3VzU2libGluZykgdGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLCB0aGlzLnBhcmVudE5vZGUuZmlyc3RDaGlsZCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaChsb3dlcik7XG59IiwiaW1wb3J0IG5hbWVzcGFjZSBmcm9tIFwiLi9uYW1lc3BhY2UuanNcIjtcbmltcG9ydCB7IHhodG1sIH0gZnJvbSBcIi4vbmFtZXNwYWNlcy5qc1wiO1xuXG5mdW5jdGlvbiBjcmVhdG9ySW5oZXJpdChuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGRvY3VtZW50ID0gdGhpcy5vd25lckRvY3VtZW50LFxuICAgICAgICB1cmkgPSB0aGlzLm5hbWVzcGFjZVVSSTtcbiAgICByZXR1cm4gdXJpID09PSB4aHRtbCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQubmFtZXNwYWNlVVJJID09PSB4aHRtbCA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQobmFtZSkgOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlModXJpLCBuYW1lKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY3JlYXRvckZpeGVkKGZ1bGxuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG5hbWUpIHtcbiAgdmFyIGZ1bGxuYW1lID0gbmFtZXNwYWNlKG5hbWUpO1xuICByZXR1cm4gKGZ1bGxuYW1lLmxvY2FsID8gY3JlYXRvckZpeGVkIDogY3JlYXRvckluaGVyaXQpKGZ1bGxuYW1lKTtcbn0iLCJpbXBvcnQgY3JlYXRvciBmcm9tIFwiLi4vY3JlYXRvci5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG5hbWUpIHtcbiAgdmFyIGNyZWF0ZSA9IHR5cGVvZiBuYW1lID09PSBcImZ1bmN0aW9uXCIgPyBuYW1lIDogY3JlYXRvcihuYW1lKTtcbiAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5hcHBlbmRDaGlsZChjcmVhdGUuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gIH0pO1xufSIsImltcG9ydCBjcmVhdG9yIGZyb20gXCIuLi9jcmVhdG9yLmpzXCI7XG5pbXBvcnQgc2VsZWN0b3IgZnJvbSBcIi4uL3NlbGVjdG9yLmpzXCI7XG5cbmZ1bmN0aW9uIGNvbnN0YW50TnVsbCgpIHtcbiAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChuYW1lLCBiZWZvcmUpIHtcbiAgdmFyIGNyZWF0ZSA9IHR5cGVvZiBuYW1lID09PSBcImZ1bmN0aW9uXCIgPyBuYW1lIDogY3JlYXRvcihuYW1lKSxcbiAgICAgIHNlbGVjdCA9IGJlZm9yZSA9PSBudWxsID8gY29uc3RhbnROdWxsIDogdHlwZW9mIGJlZm9yZSA9PT0gXCJmdW5jdGlvblwiID8gYmVmb3JlIDogc2VsZWN0b3IoYmVmb3JlKTtcbiAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNlcnRCZWZvcmUoY3JlYXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIHNlbGVjdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IG51bGwpO1xuICB9KTtcbn0iLCJmdW5jdGlvbiByZW1vdmUoKSB7XG4gIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7XG4gIGlmIChwYXJlbnQpIHBhcmVudC5yZW1vdmVDaGlsZCh0aGlzKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5lYWNoKHJlbW92ZSk7XG59IiwiZnVuY3Rpb24gc2VsZWN0aW9uX2Nsb25lU2hhbGxvdygpIHtcbiAgdmFyIGNsb25lID0gdGhpcy5jbG9uZU5vZGUoZmFsc2UpLFxuICAgICAgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlO1xuICByZXR1cm4gcGFyZW50ID8gcGFyZW50Lmluc2VydEJlZm9yZShjbG9uZSwgdGhpcy5uZXh0U2libGluZykgOiBjbG9uZTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX2Nsb25lRGVlcCgpIHtcbiAgdmFyIGNsb25lID0gdGhpcy5jbG9uZU5vZGUodHJ1ZSksXG4gICAgICBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7XG4gIHJldHVybiBwYXJlbnQgPyBwYXJlbnQuaW5zZXJ0QmVmb3JlKGNsb25lLCB0aGlzLm5leHRTaWJsaW5nKSA6IGNsb25lO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoZGVlcCkge1xuICByZXR1cm4gdGhpcy5zZWxlY3QoZGVlcCA/IHNlbGVjdGlvbl9jbG9uZURlZXAgOiBzZWxlY3Rpb25fY2xvbmVTaGFsbG93KTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLnByb3BlcnR5KFwiX19kYXRhX19cIiwgdmFsdWUpIDogdGhpcy5ub2RlKCkuX19kYXRhX187XG59IiwiZnVuY3Rpb24gY29udGV4dExpc3RlbmVyKGxpc3RlbmVyKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBsaXN0ZW5lci5jYWxsKHRoaXMsIGV2ZW50LCB0aGlzLl9fZGF0YV9fKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcGFyc2VUeXBlbmFtZXModHlwZW5hbWVzKSB7XG4gIHJldHVybiB0eXBlbmFtZXMudHJpbSgpLnNwbGl0KC9efFxccysvKS5tYXAoZnVuY3Rpb24gKHQpIHtcbiAgICB2YXIgbmFtZSA9IFwiXCIsXG4gICAgICAgIGkgPSB0LmluZGV4T2YoXCIuXCIpO1xuICAgIGlmIChpID49IDApIG5hbWUgPSB0LnNsaWNlKGkgKyAxKSwgdCA9IHQuc2xpY2UoMCwgaSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHQsXG4gICAgICBuYW1lOiBuYW1lXG4gICAgfTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG9uUmVtb3ZlKHR5cGVuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG9uID0gdGhpcy5fX29uO1xuICAgIGlmICghb24pIHJldHVybjtcblxuICAgIGZvciAodmFyIGogPSAwLCBpID0gLTEsIG0gPSBvbi5sZW5ndGgsIG87IGogPCBtOyArK2opIHtcbiAgICAgIGlmIChvID0gb25bal0sICghdHlwZW5hbWUudHlwZSB8fCBvLnR5cGUgPT09IHR5cGVuYW1lLnR5cGUpICYmIG8ubmFtZSA9PT0gdHlwZW5hbWUubmFtZSkge1xuICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoby50eXBlLCBvLmxpc3RlbmVyLCBvLm9wdGlvbnMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb25bKytpXSA9IG87XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCsraSkgb24ubGVuZ3RoID0gaTtlbHNlIGRlbGV0ZSB0aGlzLl9fb247XG4gIH07XG59XG5cbmZ1bmN0aW9uIG9uQWRkKHR5cGVuYW1lLCB2YWx1ZSwgb3B0aW9ucykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBvbiA9IHRoaXMuX19vbixcbiAgICAgICAgbyxcbiAgICAgICAgbGlzdGVuZXIgPSBjb250ZXh0TGlzdGVuZXIodmFsdWUpO1xuICAgIGlmIChvbikgZm9yICh2YXIgaiA9IDAsIG0gPSBvbi5sZW5ndGg7IGogPCBtOyArK2opIHtcbiAgICAgIGlmICgobyA9IG9uW2pdKS50eXBlID09PSB0eXBlbmFtZS50eXBlICYmIG8ubmFtZSA9PT0gdHlwZW5hbWUubmFtZSkge1xuICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoby50eXBlLCBvLmxpc3RlbmVyLCBvLm9wdGlvbnMpO1xuICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoby50eXBlLCBvLmxpc3RlbmVyID0gbGlzdGVuZXIsIG8ub3B0aW9ucyA9IG9wdGlvbnMpO1xuICAgICAgICBvLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKHR5cGVuYW1lLnR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcbiAgICBvID0ge1xuICAgICAgdHlwZTogdHlwZW5hbWUudHlwZSxcbiAgICAgIG5hbWU6IHR5cGVuYW1lLm5hbWUsXG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICBvcHRpb25zOiBvcHRpb25zXG4gICAgfTtcbiAgICBpZiAoIW9uKSB0aGlzLl9fb24gPSBbb107ZWxzZSBvbi5wdXNoKG8pO1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAodHlwZW5hbWUsIHZhbHVlLCBvcHRpb25zKSB7XG4gIHZhciB0eXBlbmFtZXMgPSBwYXJzZVR5cGVuYW1lcyh0eXBlbmFtZSArIFwiXCIpLFxuICAgICAgaSxcbiAgICAgIG4gPSB0eXBlbmFtZXMubGVuZ3RoLFxuICAgICAgdDtcblxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICB2YXIgb24gPSB0aGlzLm5vZGUoKS5fX29uO1xuXG4gICAgaWYgKG9uKSBmb3IgKHZhciBqID0gMCwgbSA9IG9uLmxlbmd0aCwgbzsgaiA8IG07ICsraikge1xuICAgICAgZm9yIChpID0gMCwgbyA9IG9uW2pdOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGlmICgodCA9IHR5cGVuYW1lc1tpXSkudHlwZSA9PT0gby50eXBlICYmIHQubmFtZSA9PT0gby5uYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIG8udmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgb24gPSB2YWx1ZSA/IG9uQWRkIDogb25SZW1vdmU7XG5cbiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgIHRoaXMuZWFjaChvbih0eXBlbmFtZXNbaV0sIHZhbHVlLCBvcHRpb25zKSk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn0iLCJpbXBvcnQgZGVmYXVsdFZpZXcgZnJvbSBcIi4uL3dpbmRvdy5qc1wiO1xuXG5mdW5jdGlvbiBkaXNwYXRjaEV2ZW50KG5vZGUsIHR5cGUsIHBhcmFtcykge1xuICB2YXIgd2luZG93ID0gZGVmYXVsdFZpZXcobm9kZSksXG4gICAgICBldmVudCA9IHdpbmRvdy5DdXN0b21FdmVudDtcblxuICBpZiAodHlwZW9mIGV2ZW50ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICBldmVudCA9IG5ldyBldmVudCh0eXBlLCBwYXJhbXMpO1xuICB9IGVsc2Uge1xuICAgIGV2ZW50ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUV2ZW50KFwiRXZlbnRcIik7XG4gICAgaWYgKHBhcmFtcykgZXZlbnQuaW5pdEV2ZW50KHR5cGUsIHBhcmFtcy5idWJibGVzLCBwYXJhbXMuY2FuY2VsYWJsZSksIGV2ZW50LmRldGFpbCA9IHBhcmFtcy5kZXRhaWw7ZWxzZSBldmVudC5pbml0RXZlbnQodHlwZSwgZmFsc2UsIGZhbHNlKTtcbiAgfVxuXG4gIG5vZGUuZGlzcGF0Y2hFdmVudChldmVudCk7XG59XG5cbmZ1bmN0aW9uIGRpc3BhdGNoQ29uc3RhbnQodHlwZSwgcGFyYW1zKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGRpc3BhdGNoRXZlbnQodGhpcywgdHlwZSwgcGFyYW1zKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hGdW5jdGlvbih0eXBlLCBwYXJhbXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZGlzcGF0Y2hFdmVudCh0aGlzLCB0eXBlLCBwYXJhbXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICh0eXBlLCBwYXJhbXMpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaCgodHlwZW9mIHBhcmFtcyA9PT0gXCJmdW5jdGlvblwiID8gZGlzcGF0Y2hGdW5jdGlvbiA6IGRpc3BhdGNoQ29uc3RhbnQpKHR5cGUsIHBhcmFtcykpO1xufSIsImltcG9ydCBfcmVnZW5lcmF0b3JSdW50aW1lIGZyb20gXCIvaG9tZS9ydW5uZXIvd29yay9qdXN0aWNlNDAtdG9vbC9qdXN0aWNlNDAtdG9vbC9jbGllbnQvbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL3JlZ2VuZXJhdG9yXCI7XG5cbnZhciBfbWFya2VkID0gLyojX19QVVJFX18qL19yZWdlbmVyYXRvclJ1bnRpbWUubWFyayhfY2FsbGVlKTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2NhbGxlZSgpIHtcbiAgdmFyIGdyb3VwcywgaiwgbSwgZ3JvdXAsIGksIG4sIG5vZGU7XG4gIHJldHVybiBfcmVnZW5lcmF0b3JSdW50aW1lLndyYXAoZnVuY3Rpb24gX2NhbGxlZSQoX2NvbnRleHQpIHtcbiAgICB3aGlsZSAoMSkge1xuICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBqID0gMCwgbSA9IGdyb3Vwcy5sZW5ndGg7XG5cbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmICghKGogPCBtKSkge1xuICAgICAgICAgICAgX2NvbnRleHQubmV4dCA9IDEzO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZ3JvdXAgPSBncm91cHNbal0sIGkgPSAwLCBuID0gZ3JvdXAubGVuZ3RoO1xuXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBpZiAoIShpIDwgbikpIHtcbiAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAxMDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghKG5vZGUgPSBncm91cFtpXSkpIHtcbiAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSA3O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgX2NvbnRleHQubmV4dCA9IDc7XG4gICAgICAgICAgcmV0dXJuIG5vZGU7XG5cbiAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICsraTtcbiAgICAgICAgICBfY29udGV4dC5uZXh0ID0gMztcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICsrajtcbiAgICAgICAgICBfY29udGV4dC5uZXh0ID0gMTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDEzOlxuICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgcmV0dXJuIF9jb250ZXh0LnN0b3AoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIF9tYXJrZWQsIHRoaXMpO1xufSIsImltcG9ydCBfZGVmaW5lUHJvcGVydHkgZnJvbSBcIi9ob21lL3J1bm5lci93b3JrL2p1c3RpY2U0MC10b29sL2p1c3RpY2U0MC10b29sL2NsaWVudC9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcbmltcG9ydCBzZWxlY3Rpb25fc2VsZWN0IGZyb20gXCIuL3NlbGVjdC5qc1wiO1xuaW1wb3J0IHNlbGVjdGlvbl9zZWxlY3RBbGwgZnJvbSBcIi4vc2VsZWN0QWxsLmpzXCI7XG5pbXBvcnQgc2VsZWN0aW9uX3NlbGVjdENoaWxkIGZyb20gXCIuL3NlbGVjdENoaWxkLmpzXCI7XG5pbXBvcnQgc2VsZWN0aW9uX3NlbGVjdENoaWxkcmVuIGZyb20gXCIuL3NlbGVjdENoaWxkcmVuLmpzXCI7XG5pbXBvcnQgc2VsZWN0aW9uX2ZpbHRlciBmcm9tIFwiLi9maWx0ZXIuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fZGF0YSBmcm9tIFwiLi9kYXRhLmpzXCI7XG5pbXBvcnQgc2VsZWN0aW9uX2VudGVyIGZyb20gXCIuL2VudGVyLmpzXCI7XG5pbXBvcnQgc2VsZWN0aW9uX2V4aXQgZnJvbSBcIi4vZXhpdC5qc1wiO1xuaW1wb3J0IHNlbGVjdGlvbl9qb2luIGZyb20gXCIuL2pvaW4uanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fbWVyZ2UgZnJvbSBcIi4vbWVyZ2UuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fb3JkZXIgZnJvbSBcIi4vb3JkZXIuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fc29ydCBmcm9tIFwiLi9zb3J0LmpzXCI7XG5pbXBvcnQgc2VsZWN0aW9uX2NhbGwgZnJvbSBcIi4vY2FsbC5qc1wiO1xuaW1wb3J0IHNlbGVjdGlvbl9ub2RlcyBmcm9tIFwiLi9ub2Rlcy5qc1wiO1xuaW1wb3J0IHNlbGVjdGlvbl9ub2RlIGZyb20gXCIuL25vZGUuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fc2l6ZSBmcm9tIFwiLi9zaXplLmpzXCI7XG5pbXBvcnQgc2VsZWN0aW9uX2VtcHR5IGZyb20gXCIuL2VtcHR5LmpzXCI7XG5pbXBvcnQgc2VsZWN0aW9uX2VhY2ggZnJvbSBcIi4vZWFjaC5qc1wiO1xuaW1wb3J0IHNlbGVjdGlvbl9hdHRyIGZyb20gXCIuL2F0dHIuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fc3R5bGUgZnJvbSBcIi4vc3R5bGUuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fcHJvcGVydHkgZnJvbSBcIi4vcHJvcGVydHkuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fY2xhc3NlZCBmcm9tIFwiLi9jbGFzc2VkLmpzXCI7XG5pbXBvcnQgc2VsZWN0aW9uX3RleHQgZnJvbSBcIi4vdGV4dC5qc1wiO1xuaW1wb3J0IHNlbGVjdGlvbl9odG1sIGZyb20gXCIuL2h0bWwuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fcmFpc2UgZnJvbSBcIi4vcmFpc2UuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fbG93ZXIgZnJvbSBcIi4vbG93ZXIuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fYXBwZW5kIGZyb20gXCIuL2FwcGVuZC5qc1wiO1xuaW1wb3J0IHNlbGVjdGlvbl9pbnNlcnQgZnJvbSBcIi4vaW5zZXJ0LmpzXCI7XG5pbXBvcnQgc2VsZWN0aW9uX3JlbW92ZSBmcm9tIFwiLi9yZW1vdmUuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fY2xvbmUgZnJvbSBcIi4vY2xvbmUuanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fZGF0dW0gZnJvbSBcIi4vZGF0dW0uanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fb24gZnJvbSBcIi4vb24uanNcIjtcbmltcG9ydCBzZWxlY3Rpb25fZGlzcGF0Y2ggZnJvbSBcIi4vZGlzcGF0Y2guanNcIjtcbmltcG9ydCBzZWxlY3Rpb25faXRlcmF0b3IgZnJvbSBcIi4vaXRlcmF0b3IuanNcIjtcbmV4cG9ydCB2YXIgcm9vdCA9IFtudWxsXTtcbmV4cG9ydCBmdW5jdGlvbiBTZWxlY3Rpb24oZ3JvdXBzLCBwYXJlbnRzKSB7XG4gIHRoaXMuX2dyb3VwcyA9IGdyb3VwcztcbiAgdGhpcy5fcGFyZW50cyA9IHBhcmVudHM7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24oW1tkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRdXSwgcm9vdCk7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbl9zZWxlY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzO1xufVxuXG5TZWxlY3Rpb24ucHJvdG90eXBlID0gc2VsZWN0aW9uLnByb3RvdHlwZSA9IF9kZWZpbmVQcm9wZXJ0eSh7XG4gIGNvbnN0cnVjdG9yOiBTZWxlY3Rpb24sXG4gIHNlbGVjdDogc2VsZWN0aW9uX3NlbGVjdCxcbiAgc2VsZWN0QWxsOiBzZWxlY3Rpb25fc2VsZWN0QWxsLFxuICBzZWxlY3RDaGlsZDogc2VsZWN0aW9uX3NlbGVjdENoaWxkLFxuICBzZWxlY3RDaGlsZHJlbjogc2VsZWN0aW9uX3NlbGVjdENoaWxkcmVuLFxuICBmaWx0ZXI6IHNlbGVjdGlvbl9maWx0ZXIsXG4gIGRhdGE6IHNlbGVjdGlvbl9kYXRhLFxuICBlbnRlcjogc2VsZWN0aW9uX2VudGVyLFxuICBleGl0OiBzZWxlY3Rpb25fZXhpdCxcbiAgam9pbjogc2VsZWN0aW9uX2pvaW4sXG4gIG1lcmdlOiBzZWxlY3Rpb25fbWVyZ2UsXG4gIHNlbGVjdGlvbjogc2VsZWN0aW9uX3NlbGVjdGlvbixcbiAgb3JkZXI6IHNlbGVjdGlvbl9vcmRlcixcbiAgc29ydDogc2VsZWN0aW9uX3NvcnQsXG4gIGNhbGw6IHNlbGVjdGlvbl9jYWxsLFxuICBub2Rlczogc2VsZWN0aW9uX25vZGVzLFxuICBub2RlOiBzZWxlY3Rpb25fbm9kZSxcbiAgc2l6ZTogc2VsZWN0aW9uX3NpemUsXG4gIGVtcHR5OiBzZWxlY3Rpb25fZW1wdHksXG4gIGVhY2g6IHNlbGVjdGlvbl9lYWNoLFxuICBhdHRyOiBzZWxlY3Rpb25fYXR0cixcbiAgc3R5bGU6IHNlbGVjdGlvbl9zdHlsZSxcbiAgcHJvcGVydHk6IHNlbGVjdGlvbl9wcm9wZXJ0eSxcbiAgY2xhc3NlZDogc2VsZWN0aW9uX2NsYXNzZWQsXG4gIHRleHQ6IHNlbGVjdGlvbl90ZXh0LFxuICBodG1sOiBzZWxlY3Rpb25faHRtbCxcbiAgcmFpc2U6IHNlbGVjdGlvbl9yYWlzZSxcbiAgbG93ZXI6IHNlbGVjdGlvbl9sb3dlcixcbiAgYXBwZW5kOiBzZWxlY3Rpb25fYXBwZW5kLFxuICBpbnNlcnQ6IHNlbGVjdGlvbl9pbnNlcnQsXG4gIHJlbW92ZTogc2VsZWN0aW9uX3JlbW92ZSxcbiAgY2xvbmU6IHNlbGVjdGlvbl9jbG9uZSxcbiAgZGF0dW06IHNlbGVjdGlvbl9kYXR1bSxcbiAgb246IHNlbGVjdGlvbl9vbixcbiAgZGlzcGF0Y2g6IHNlbGVjdGlvbl9kaXNwYXRjaFxufSwgU3ltYm9sLml0ZXJhdG9yLCBzZWxlY3Rpb25faXRlcmF0b3IpO1xuZXhwb3J0IGRlZmF1bHQgc2VsZWN0aW9uOyIsInZhciBub29wID0ge1xuICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUoKSB7fVxufTtcblxuZnVuY3Rpb24gZGlzcGF0Y2goKSB7XG4gIGZvciAodmFyIGkgPSAwLCBuID0gYXJndW1lbnRzLmxlbmd0aCwgXyA9IHt9LCB0OyBpIDwgbjsgKytpKSB7XG4gICAgaWYgKCEodCA9IGFyZ3VtZW50c1tpXSArIFwiXCIpIHx8IHQgaW4gXyB8fCAvW1xccy5dLy50ZXN0KHQpKSB0aHJvdyBuZXcgRXJyb3IoXCJpbGxlZ2FsIHR5cGU6IFwiICsgdCk7XG4gICAgX1t0XSA9IFtdO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBEaXNwYXRjaChfKTtcbn1cblxuZnVuY3Rpb24gRGlzcGF0Y2goXykge1xuICB0aGlzLl8gPSBfO1xufVxuXG5mdW5jdGlvbiBwYXJzZVR5cGVuYW1lcyh0eXBlbmFtZXMsIHR5cGVzKSB7XG4gIHJldHVybiB0eXBlbmFtZXMudHJpbSgpLnNwbGl0KC9efFxccysvKS5tYXAoZnVuY3Rpb24gKHQpIHtcbiAgICB2YXIgbmFtZSA9IFwiXCIsXG4gICAgICAgIGkgPSB0LmluZGV4T2YoXCIuXCIpO1xuICAgIGlmIChpID49IDApIG5hbWUgPSB0LnNsaWNlKGkgKyAxKSwgdCA9IHQuc2xpY2UoMCwgaSk7XG4gICAgaWYgKHQgJiYgIXR5cGVzLmhhc093blByb3BlcnR5KHQpKSB0aHJvdyBuZXcgRXJyb3IoXCJ1bmtub3duIHR5cGU6IFwiICsgdCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHQsXG4gICAgICBuYW1lOiBuYW1lXG4gICAgfTtcbiAgfSk7XG59XG5cbkRpc3BhdGNoLnByb3RvdHlwZSA9IGRpc3BhdGNoLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IERpc3BhdGNoLFxuICBvbjogZnVuY3Rpb24gb24odHlwZW5hbWUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIF8gPSB0aGlzLl8sXG4gICAgICAgIFQgPSBwYXJzZVR5cGVuYW1lcyh0eXBlbmFtZSArIFwiXCIsIF8pLFxuICAgICAgICB0LFxuICAgICAgICBpID0gLTEsXG4gICAgICAgIG4gPSBULmxlbmd0aDsgLy8gSWYgbm8gY2FsbGJhY2sgd2FzIHNwZWNpZmllZCwgcmV0dXJuIHRoZSBjYWxsYmFjayBvZiB0aGUgZ2l2ZW4gdHlwZSBhbmQgbmFtZS5cblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgaWYgKCh0ID0gKHR5cGVuYW1lID0gVFtpXSkudHlwZSkgJiYgKHQgPSBnZXQoX1t0XSwgdHlwZW5hbWUubmFtZSkpKSByZXR1cm4gdDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gSWYgYSB0eXBlIHdhcyBzcGVjaWZpZWQsIHNldCB0aGUgY2FsbGJhY2sgZm9yIHRoZSBnaXZlbiB0eXBlIGFuZCBuYW1lLlxuICAgIC8vIE90aGVyd2lzZSwgaWYgYSBudWxsIGNhbGxiYWNrIHdhcyBzcGVjaWZpZWQsIHJlbW92ZSBjYWxsYmFja3Mgb2YgdGhlIGdpdmVuIG5hbWUuXG5cblxuICAgIGlmIChjYWxsYmFjayAhPSBudWxsICYmIHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIGNhbGxiYWNrOiBcIiArIGNhbGxiYWNrKTtcblxuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBpZiAodCA9ICh0eXBlbmFtZSA9IFRbaV0pLnR5cGUpIF9bdF0gPSBzZXQoX1t0XSwgdHlwZW5hbWUubmFtZSwgY2FsbGJhY2spO2Vsc2UgaWYgKGNhbGxiYWNrID09IG51bGwpIGZvciAodCBpbiBfKSB7XG4gICAgICAgIF9bdF0gPSBzZXQoX1t0XSwgdHlwZW5hbWUubmFtZSwgbnVsbCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIGNvcHk6IGZ1bmN0aW9uIGNvcHkoKSB7XG4gICAgdmFyIGNvcHkgPSB7fSxcbiAgICAgICAgXyA9IHRoaXMuXztcblxuICAgIGZvciAodmFyIHQgaW4gXykge1xuICAgICAgY29weVt0XSA9IF9bdF0uc2xpY2UoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IERpc3BhdGNoKGNvcHkpO1xuICB9LFxuICBjYWxsOiBmdW5jdGlvbiBjYWxsKHR5cGUsIHRoYXQpIHtcbiAgICBpZiAoKG4gPSBhcmd1bWVudHMubGVuZ3RoIC0gMikgPiAwKSBmb3IgKHZhciBhcmdzID0gbmV3IEFycmF5KG4pLCBpID0gMCwgbiwgdDsgaSA8IG47ICsraSkge1xuICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpICsgMl07XG4gICAgfVxuICAgIGlmICghdGhpcy5fLmhhc093blByb3BlcnR5KHR5cGUpKSB0aHJvdyBuZXcgRXJyb3IoXCJ1bmtub3duIHR5cGU6IFwiICsgdHlwZSk7XG5cbiAgICBmb3IgKHQgPSB0aGlzLl9bdHlwZV0sIGkgPSAwLCBuID0gdC5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICAgIHRbaV0udmFsdWUuYXBwbHkodGhhdCwgYXJncyk7XG4gICAgfVxuICB9LFxuICBhcHBseTogZnVuY3Rpb24gYXBwbHkodHlwZSwgdGhhdCwgYXJncykge1xuICAgIGlmICghdGhpcy5fLmhhc093blByb3BlcnR5KHR5cGUpKSB0aHJvdyBuZXcgRXJyb3IoXCJ1bmtub3duIHR5cGU6IFwiICsgdHlwZSk7XG5cbiAgICBmb3IgKHZhciB0ID0gdGhpcy5fW3R5cGVdLCBpID0gMCwgbiA9IHQubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgICB0W2ldLnZhbHVlLmFwcGx5KHRoYXQsIGFyZ3MpO1xuICAgIH1cbiAgfVxufTtcblxuZnVuY3Rpb24gZ2V0KHR5cGUsIG5hbWUpIHtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0eXBlLmxlbmd0aCwgYzsgaSA8IG47ICsraSkge1xuICAgIGlmICgoYyA9IHR5cGVbaV0pLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgIHJldHVybiBjLnZhbHVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzZXQodHlwZSwgbmFtZSwgY2FsbGJhY2spIHtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0eXBlLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgIGlmICh0eXBlW2ldLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgIHR5cGVbaV0gPSBub29wLCB0eXBlID0gdHlwZS5zbGljZSgwLCBpKS5jb25jYXQodHlwZS5zbGljZShpICsgMSkpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHR5cGUucHVzaCh7XG4gICAgbmFtZTogbmFtZSxcbiAgICB2YWx1ZTogY2FsbGJhY2tcbiAgfSk7XG4gIHJldHVybiB0eXBlO1xufVxuXG5leHBvcnQgZGVmYXVsdCBkaXNwYXRjaDsiLCJ2YXIgZnJhbWUgPSAwLFxuICAgIC8vIGlzIGFuIGFuaW1hdGlvbiBmcmFtZSBwZW5kaW5nP1xudGltZW91dCA9IDAsXG4gICAgLy8gaXMgYSB0aW1lb3V0IHBlbmRpbmc/XG5pbnRlcnZhbCA9IDAsXG4gICAgLy8gYXJlIGFueSB0aW1lcnMgYWN0aXZlP1xucG9rZURlbGF5ID0gMTAwMCxcbiAgICAvLyBob3cgZnJlcXVlbnRseSB3ZSBjaGVjayBmb3IgY2xvY2sgc2tld1xudGFza0hlYWQsXG4gICAgdGFza1RhaWwsXG4gICAgY2xvY2tMYXN0ID0gMCxcbiAgICBjbG9ja05vdyA9IDAsXG4gICAgY2xvY2tTa2V3ID0gMCxcbiAgICBjbG9jayA9IHR5cGVvZiBwZXJmb3JtYW5jZSA9PT0gXCJvYmplY3RcIiAmJiBwZXJmb3JtYW5jZS5ub3cgPyBwZXJmb3JtYW5jZSA6IERhdGUsXG4gICAgc2V0RnJhbWUgPSB0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiICYmIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPyB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lLmJpbmQod2luZG93KSA6IGZ1bmN0aW9uIChmKSB7XG4gIHNldFRpbWVvdXQoZiwgMTcpO1xufTtcbmV4cG9ydCBmdW5jdGlvbiBub3coKSB7XG4gIHJldHVybiBjbG9ja05vdyB8fCAoc2V0RnJhbWUoY2xlYXJOb3cpLCBjbG9ja05vdyA9IGNsb2NrLm5vdygpICsgY2xvY2tTa2V3KTtcbn1cblxuZnVuY3Rpb24gY2xlYXJOb3coKSB7XG4gIGNsb2NrTm93ID0gMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFRpbWVyKCkge1xuICB0aGlzLl9jYWxsID0gdGhpcy5fdGltZSA9IHRoaXMuX25leHQgPSBudWxsO1xufVxuVGltZXIucHJvdG90eXBlID0gdGltZXIucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogVGltZXIsXG4gIHJlc3RhcnQ6IGZ1bmN0aW9uIHJlc3RhcnQoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2FsbGJhY2sgaXMgbm90IGEgZnVuY3Rpb25cIik7XG4gICAgdGltZSA9ICh0aW1lID09IG51bGwgPyBub3coKSA6ICt0aW1lKSArIChkZWxheSA9PSBudWxsID8gMCA6ICtkZWxheSk7XG5cbiAgICBpZiAoIXRoaXMuX25leHQgJiYgdGFza1RhaWwgIT09IHRoaXMpIHtcbiAgICAgIGlmICh0YXNrVGFpbCkgdGFza1RhaWwuX25leHQgPSB0aGlzO2Vsc2UgdGFza0hlYWQgPSB0aGlzO1xuICAgICAgdGFza1RhaWwgPSB0aGlzO1xuICAgIH1cblxuICAgIHRoaXMuX2NhbGwgPSBjYWxsYmFjaztcbiAgICB0aGlzLl90aW1lID0gdGltZTtcbiAgICBzbGVlcCgpO1xuICB9LFxuICBzdG9wOiBmdW5jdGlvbiBzdG9wKCkge1xuICAgIGlmICh0aGlzLl9jYWxsKSB7XG4gICAgICB0aGlzLl9jYWxsID0gbnVsbDtcbiAgICAgIHRoaXMuX3RpbWUgPSBJbmZpbml0eTtcbiAgICAgIHNsZWVwKCk7XG4gICAgfVxuICB9XG59O1xuZXhwb3J0IGZ1bmN0aW9uIHRpbWVyKGNhbGxiYWNrLCBkZWxheSwgdGltZSkge1xuICB2YXIgdCA9IG5ldyBUaW1lcigpO1xuICB0LnJlc3RhcnQoY2FsbGJhY2ssIGRlbGF5LCB0aW1lKTtcbiAgcmV0dXJuIHQ7XG59XG5leHBvcnQgZnVuY3Rpb24gdGltZXJGbHVzaCgpIHtcbiAgbm93KCk7IC8vIEdldCB0aGUgY3VycmVudCB0aW1lLCBpZiBub3QgYWxyZWFkeSBzZXQuXG5cbiAgKytmcmFtZTsgLy8gUHJldGVuZCB3ZeKAmXZlIHNldCBhbiBhbGFybSwgaWYgd2UgaGF2ZW7igJl0IGFscmVhZHkuXG5cbiAgdmFyIHQgPSB0YXNrSGVhZCxcbiAgICAgIGU7XG5cbiAgd2hpbGUgKHQpIHtcbiAgICBpZiAoKGUgPSBjbG9ja05vdyAtIHQuX3RpbWUpID49IDApIHQuX2NhbGwuY2FsbCh1bmRlZmluZWQsIGUpO1xuICAgIHQgPSB0Ll9uZXh0O1xuICB9XG5cbiAgLS1mcmFtZTtcbn1cblxuZnVuY3Rpb24gd2FrZSgpIHtcbiAgY2xvY2tOb3cgPSAoY2xvY2tMYXN0ID0gY2xvY2subm93KCkpICsgY2xvY2tTa2V3O1xuICBmcmFtZSA9IHRpbWVvdXQgPSAwO1xuXG4gIHRyeSB7XG4gICAgdGltZXJGbHVzaCgpO1xuICB9IGZpbmFsbHkge1xuICAgIGZyYW1lID0gMDtcbiAgICBuYXAoKTtcbiAgICBjbG9ja05vdyA9IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gcG9rZSgpIHtcbiAgdmFyIG5vdyA9IGNsb2NrLm5vdygpLFxuICAgICAgZGVsYXkgPSBub3cgLSBjbG9ja0xhc3Q7XG4gIGlmIChkZWxheSA+IHBva2VEZWxheSkgY2xvY2tTa2V3IC09IGRlbGF5LCBjbG9ja0xhc3QgPSBub3c7XG59XG5cbmZ1bmN0aW9uIG5hcCgpIHtcbiAgdmFyIHQwLFxuICAgICAgdDEgPSB0YXNrSGVhZCxcbiAgICAgIHQyLFxuICAgICAgdGltZSA9IEluZmluaXR5O1xuXG4gIHdoaWxlICh0MSkge1xuICAgIGlmICh0MS5fY2FsbCkge1xuICAgICAgaWYgKHRpbWUgPiB0MS5fdGltZSkgdGltZSA9IHQxLl90aW1lO1xuICAgICAgdDAgPSB0MSwgdDEgPSB0MS5fbmV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgdDIgPSB0MS5fbmV4dCwgdDEuX25leHQgPSBudWxsO1xuICAgICAgdDEgPSB0MCA/IHQwLl9uZXh0ID0gdDIgOiB0YXNrSGVhZCA9IHQyO1xuICAgIH1cbiAgfVxuXG4gIHRhc2tUYWlsID0gdDA7XG4gIHNsZWVwKHRpbWUpO1xufVxuXG5mdW5jdGlvbiBzbGVlcCh0aW1lKSB7XG4gIGlmIChmcmFtZSkgcmV0dXJuOyAvLyBTb29uZXN0IGFsYXJtIGFscmVhZHkgc2V0LCBvciB3aWxsIGJlLlxuXG4gIGlmICh0aW1lb3V0KSB0aW1lb3V0ID0gY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICB2YXIgZGVsYXkgPSB0aW1lIC0gY2xvY2tOb3c7IC8vIFN0cmljdGx5IGxlc3MgdGhhbiBpZiB3ZSByZWNvbXB1dGVkIGNsb2NrTm93LlxuXG4gIGlmIChkZWxheSA+IDI0KSB7XG4gICAgaWYgKHRpbWUgPCBJbmZpbml0eSkgdGltZW91dCA9IHNldFRpbWVvdXQod2FrZSwgdGltZSAtIGNsb2NrLm5vdygpIC0gY2xvY2tTa2V3KTtcbiAgICBpZiAoaW50ZXJ2YWwpIGludGVydmFsID0gY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFpbnRlcnZhbCkgY2xvY2tMYXN0ID0gY2xvY2subm93KCksIGludGVydmFsID0gc2V0SW50ZXJ2YWwocG9rZSwgcG9rZURlbGF5KTtcbiAgICBmcmFtZSA9IDEsIHNldEZyYW1lKHdha2UpO1xuICB9XG59IiwiaW1wb3J0IHsgVGltZXIgfSBmcm9tIFwiLi90aW1lci5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKGNhbGxiYWNrLCBkZWxheSwgdGltZSkge1xuICB2YXIgdCA9IG5ldyBUaW1lcigpO1xuICBkZWxheSA9IGRlbGF5ID09IG51bGwgPyAwIDogK2RlbGF5O1xuICB0LnJlc3RhcnQoZnVuY3Rpb24gKGVsYXBzZWQpIHtcbiAgICB0LnN0b3AoKTtcbiAgICBjYWxsYmFjayhlbGFwc2VkICsgZGVsYXkpO1xuICB9LCBkZWxheSwgdGltZSk7XG4gIHJldHVybiB0O1xufSIsImltcG9ydCB7IGRpc3BhdGNoIH0gZnJvbSBcImQzLWRpc3BhdGNoXCI7XG5pbXBvcnQgeyB0aW1lciwgdGltZW91dCB9IGZyb20gXCJkMy10aW1lclwiO1xudmFyIGVtcHR5T24gPSBkaXNwYXRjaChcInN0YXJ0XCIsIFwiZW5kXCIsIFwiY2FuY2VsXCIsIFwiaW50ZXJydXB0XCIpO1xudmFyIGVtcHR5VHdlZW4gPSBbXTtcbmV4cG9ydCB2YXIgQ1JFQVRFRCA9IDA7XG5leHBvcnQgdmFyIFNDSEVEVUxFRCA9IDE7XG5leHBvcnQgdmFyIFNUQVJUSU5HID0gMjtcbmV4cG9ydCB2YXIgU1RBUlRFRCA9IDM7XG5leHBvcnQgdmFyIFJVTk5JTkcgPSA0O1xuZXhwb3J0IHZhciBFTkRJTkcgPSA1O1xuZXhwb3J0IHZhciBFTkRFRCA9IDY7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAobm9kZSwgbmFtZSwgaWQsIGluZGV4LCBncm91cCwgdGltaW5nKSB7XG4gIHZhciBzY2hlZHVsZXMgPSBub2RlLl9fdHJhbnNpdGlvbjtcbiAgaWYgKCFzY2hlZHVsZXMpIG5vZGUuX190cmFuc2l0aW9uID0ge307ZWxzZSBpZiAoaWQgaW4gc2NoZWR1bGVzKSByZXR1cm47XG4gIGNyZWF0ZShub2RlLCBpZCwge1xuICAgIG5hbWU6IG5hbWUsXG4gICAgaW5kZXg6IGluZGV4LFxuICAgIC8vIEZvciBjb250ZXh0IGR1cmluZyBjYWxsYmFjay5cbiAgICBncm91cDogZ3JvdXAsXG4gICAgLy8gRm9yIGNvbnRleHQgZHVyaW5nIGNhbGxiYWNrLlxuICAgIG9uOiBlbXB0eU9uLFxuICAgIHR3ZWVuOiBlbXB0eVR3ZWVuLFxuICAgIHRpbWU6IHRpbWluZy50aW1lLFxuICAgIGRlbGF5OiB0aW1pbmcuZGVsYXksXG4gICAgZHVyYXRpb246IHRpbWluZy5kdXJhdGlvbixcbiAgICBlYXNlOiB0aW1pbmcuZWFzZSxcbiAgICB0aW1lcjogbnVsbCxcbiAgICBzdGF0ZTogQ1JFQVRFRFxuICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBpbml0KG5vZGUsIGlkKSB7XG4gIHZhciBzY2hlZHVsZSA9IGdldChub2RlLCBpZCk7XG4gIGlmIChzY2hlZHVsZS5zdGF0ZSA+IENSRUFURUQpIHRocm93IG5ldyBFcnJvcihcInRvbyBsYXRlOyBhbHJlYWR5IHNjaGVkdWxlZFwiKTtcbiAgcmV0dXJuIHNjaGVkdWxlO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNldChub2RlLCBpZCkge1xuICB2YXIgc2NoZWR1bGUgPSBnZXQobm9kZSwgaWQpO1xuICBpZiAoc2NoZWR1bGUuc3RhdGUgPiBTVEFSVEVEKSB0aHJvdyBuZXcgRXJyb3IoXCJ0b28gbGF0ZTsgYWxyZWFkeSBydW5uaW5nXCIpO1xuICByZXR1cm4gc2NoZWR1bGU7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0KG5vZGUsIGlkKSB7XG4gIHZhciBzY2hlZHVsZSA9IG5vZGUuX190cmFuc2l0aW9uO1xuICBpZiAoIXNjaGVkdWxlIHx8ICEoc2NoZWR1bGUgPSBzY2hlZHVsZVtpZF0pKSB0aHJvdyBuZXcgRXJyb3IoXCJ0cmFuc2l0aW9uIG5vdCBmb3VuZFwiKTtcbiAgcmV0dXJuIHNjaGVkdWxlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGUobm9kZSwgaWQsIHNlbGYpIHtcbiAgdmFyIHNjaGVkdWxlcyA9IG5vZGUuX190cmFuc2l0aW9uLFxuICAgICAgdHdlZW47IC8vIEluaXRpYWxpemUgdGhlIHNlbGYgdGltZXIgd2hlbiB0aGUgdHJhbnNpdGlvbiBpcyBjcmVhdGVkLlxuICAvLyBOb3RlIHRoZSBhY3R1YWwgZGVsYXkgaXMgbm90IGtub3duIHVudGlsIHRoZSBmaXJzdCBjYWxsYmFjayFcblxuICBzY2hlZHVsZXNbaWRdID0gc2VsZjtcbiAgc2VsZi50aW1lciA9IHRpbWVyKHNjaGVkdWxlLCAwLCBzZWxmLnRpbWUpO1xuXG4gIGZ1bmN0aW9uIHNjaGVkdWxlKGVsYXBzZWQpIHtcbiAgICBzZWxmLnN0YXRlID0gU0NIRURVTEVEO1xuICAgIHNlbGYudGltZXIucmVzdGFydChzdGFydCwgc2VsZi5kZWxheSwgc2VsZi50aW1lKTsgLy8gSWYgdGhlIGVsYXBzZWQgZGVsYXkgaXMgbGVzcyB0aGFuIG91ciBmaXJzdCBzbGVlcCwgc3RhcnQgaW1tZWRpYXRlbHkuXG5cbiAgICBpZiAoc2VsZi5kZWxheSA8PSBlbGFwc2VkKSBzdGFydChlbGFwc2VkIC0gc2VsZi5kZWxheSk7XG4gIH1cblxuICBmdW5jdGlvbiBzdGFydChlbGFwc2VkKSB7XG4gICAgdmFyIGksIGosIG4sIG87IC8vIElmIHRoZSBzdGF0ZSBpcyBub3QgU0NIRURVTEVELCB0aGVuIHdlIHByZXZpb3VzbHkgZXJyb3JlZCBvbiBzdGFydC5cblxuICAgIGlmIChzZWxmLnN0YXRlICE9PSBTQ0hFRFVMRUQpIHJldHVybiBzdG9wKCk7XG5cbiAgICBmb3IgKGkgaW4gc2NoZWR1bGVzKSB7XG4gICAgICBvID0gc2NoZWR1bGVzW2ldO1xuICAgICAgaWYgKG8ubmFtZSAhPT0gc2VsZi5uYW1lKSBjb250aW51ZTsgLy8gV2hpbGUgdGhpcyBlbGVtZW50IGFscmVhZHkgaGFzIGEgc3RhcnRpbmcgdHJhbnNpdGlvbiBkdXJpbmcgdGhpcyBmcmFtZSxcbiAgICAgIC8vIGRlZmVyIHN0YXJ0aW5nIGFuIGludGVycnVwdGluZyB0cmFuc2l0aW9uIHVudGlsIHRoYXQgdHJhbnNpdGlvbiBoYXMgYVxuICAgICAgLy8gY2hhbmNlIHRvIHRpY2sgKGFuZCBwb3NzaWJseSBlbmQpOyBzZWUgZDMvZDMtdHJhbnNpdGlvbiM1NCFcblxuICAgICAgaWYgKG8uc3RhdGUgPT09IFNUQVJURUQpIHJldHVybiB0aW1lb3V0KHN0YXJ0KTsgLy8gSW50ZXJydXB0IHRoZSBhY3RpdmUgdHJhbnNpdGlvbiwgaWYgYW55LlxuXG4gICAgICBpZiAoby5zdGF0ZSA9PT0gUlVOTklORykge1xuICAgICAgICBvLnN0YXRlID0gRU5ERUQ7XG4gICAgICAgIG8udGltZXIuc3RvcCgpO1xuICAgICAgICBvLm9uLmNhbGwoXCJpbnRlcnJ1cHRcIiwgbm9kZSwgbm9kZS5fX2RhdGFfXywgby5pbmRleCwgby5ncm91cCk7XG4gICAgICAgIGRlbGV0ZSBzY2hlZHVsZXNbaV07XG4gICAgICB9IC8vIENhbmNlbCBhbnkgcHJlLWVtcHRlZCB0cmFuc2l0aW9ucy5cbiAgICAgIGVsc2UgaWYgKCtpIDwgaWQpIHtcbiAgICAgICAgICBvLnN0YXRlID0gRU5ERUQ7XG4gICAgICAgICAgby50aW1lci5zdG9wKCk7XG4gICAgICAgICAgby5vbi5jYWxsKFwiY2FuY2VsXCIsIG5vZGUsIG5vZGUuX19kYXRhX18sIG8uaW5kZXgsIG8uZ3JvdXApO1xuICAgICAgICAgIGRlbGV0ZSBzY2hlZHVsZXNbaV07XG4gICAgICAgIH1cbiAgICB9IC8vIERlZmVyIHRoZSBmaXJzdCB0aWNrIHRvIGVuZCBvZiB0aGUgY3VycmVudCBmcmFtZTsgc2VlIGQzL2QzIzE1NzYuXG4gICAgLy8gTm90ZSB0aGUgdHJhbnNpdGlvbiBtYXkgYmUgY2FuY2VsZWQgYWZ0ZXIgc3RhcnQgYW5kIGJlZm9yZSB0aGUgZmlyc3QgdGljayFcbiAgICAvLyBOb3RlIHRoaXMgbXVzdCBiZSBzY2hlZHVsZWQgYmVmb3JlIHRoZSBzdGFydCBldmVudDsgc2VlIGQzL2QzLXRyYW5zaXRpb24jMTYhXG4gICAgLy8gQXNzdW1pbmcgdGhpcyBpcyBzdWNjZXNzZnVsLCBzdWJzZXF1ZW50IGNhbGxiYWNrcyBnbyBzdHJhaWdodCB0byB0aWNrLlxuXG5cbiAgICB0aW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLnN0YXRlID09PSBTVEFSVEVEKSB7XG4gICAgICAgIHNlbGYuc3RhdGUgPSBSVU5OSU5HO1xuICAgICAgICBzZWxmLnRpbWVyLnJlc3RhcnQodGljaywgc2VsZi5kZWxheSwgc2VsZi50aW1lKTtcbiAgICAgICAgdGljayhlbGFwc2VkKTtcbiAgICAgIH1cbiAgICB9KTsgLy8gRGlzcGF0Y2ggdGhlIHN0YXJ0IGV2ZW50LlxuICAgIC8vIE5vdGUgdGhpcyBtdXN0IGJlIGRvbmUgYmVmb3JlIHRoZSB0d2VlbiBhcmUgaW5pdGlhbGl6ZWQuXG5cbiAgICBzZWxmLnN0YXRlID0gU1RBUlRJTkc7XG4gICAgc2VsZi5vbi5jYWxsKFwic3RhcnRcIiwgbm9kZSwgbm9kZS5fX2RhdGFfXywgc2VsZi5pbmRleCwgc2VsZi5ncm91cCk7XG4gICAgaWYgKHNlbGYuc3RhdGUgIT09IFNUQVJUSU5HKSByZXR1cm47IC8vIGludGVycnVwdGVkXG5cbiAgICBzZWxmLnN0YXRlID0gU1RBUlRFRDsgLy8gSW5pdGlhbGl6ZSB0aGUgdHdlZW4sIGRlbGV0aW5nIG51bGwgdHdlZW4uXG5cbiAgICB0d2VlbiA9IG5ldyBBcnJheShuID0gc2VsZi50d2Vlbi5sZW5ndGgpO1xuXG4gICAgZm9yIChpID0gMCwgaiA9IC0xOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobyA9IHNlbGYudHdlZW5baV0udmFsdWUuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBzZWxmLmluZGV4LCBzZWxmLmdyb3VwKSkge1xuICAgICAgICB0d2VlblsrK2pdID0gbztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0d2Vlbi5sZW5ndGggPSBqICsgMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRpY2soZWxhcHNlZCkge1xuICAgIHZhciB0ID0gZWxhcHNlZCA8IHNlbGYuZHVyYXRpb24gPyBzZWxmLmVhc2UuY2FsbChudWxsLCBlbGFwc2VkIC8gc2VsZi5kdXJhdGlvbikgOiAoc2VsZi50aW1lci5yZXN0YXJ0KHN0b3ApLCBzZWxmLnN0YXRlID0gRU5ESU5HLCAxKSxcbiAgICAgICAgaSA9IC0xLFxuICAgICAgICBuID0gdHdlZW4ubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIHR3ZWVuW2ldLmNhbGwobm9kZSwgdCk7XG4gICAgfSAvLyBEaXNwYXRjaCB0aGUgZW5kIGV2ZW50LlxuXG5cbiAgICBpZiAoc2VsZi5zdGF0ZSA9PT0gRU5ESU5HKSB7XG4gICAgICBzZWxmLm9uLmNhbGwoXCJlbmRcIiwgbm9kZSwgbm9kZS5fX2RhdGFfXywgc2VsZi5pbmRleCwgc2VsZi5ncm91cCk7XG4gICAgICBzdG9wKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc3RvcCgpIHtcbiAgICBzZWxmLnN0YXRlID0gRU5ERUQ7XG4gICAgc2VsZi50aW1lci5zdG9wKCk7XG4gICAgZGVsZXRlIHNjaGVkdWxlc1tpZF07XG5cbiAgICBmb3IgKHZhciBpIGluIHNjaGVkdWxlcykge1xuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuXG5cbiAgICBkZWxldGUgbm9kZS5fX3RyYW5zaXRpb247XG4gIH1cbn0iLCJpbXBvcnQgeyBTVEFSVElORywgRU5ESU5HLCBFTkRFRCB9IGZyb20gXCIuL3RyYW5zaXRpb24vc2NoZWR1bGUuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChub2RlLCBuYW1lKSB7XG4gIHZhciBzY2hlZHVsZXMgPSBub2RlLl9fdHJhbnNpdGlvbixcbiAgICAgIHNjaGVkdWxlLFxuICAgICAgYWN0aXZlLFxuICAgICAgZW1wdHkgPSB0cnVlLFxuICAgICAgaTtcbiAgaWYgKCFzY2hlZHVsZXMpIHJldHVybjtcbiAgbmFtZSA9IG5hbWUgPT0gbnVsbCA/IG51bGwgOiBuYW1lICsgXCJcIjtcblxuICBmb3IgKGkgaW4gc2NoZWR1bGVzKSB7XG4gICAgaWYgKChzY2hlZHVsZSA9IHNjaGVkdWxlc1tpXSkubmFtZSAhPT0gbmFtZSkge1xuICAgICAgZW1wdHkgPSBmYWxzZTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGFjdGl2ZSA9IHNjaGVkdWxlLnN0YXRlID4gU1RBUlRJTkcgJiYgc2NoZWR1bGUuc3RhdGUgPCBFTkRJTkc7XG4gICAgc2NoZWR1bGUuc3RhdGUgPSBFTkRFRDtcbiAgICBzY2hlZHVsZS50aW1lci5zdG9wKCk7XG4gICAgc2NoZWR1bGUub24uY2FsbChhY3RpdmUgPyBcImludGVycnVwdFwiIDogXCJjYW5jZWxcIiwgbm9kZSwgbm9kZS5fX2RhdGFfXywgc2NoZWR1bGUuaW5kZXgsIHNjaGVkdWxlLmdyb3VwKTtcbiAgICBkZWxldGUgc2NoZWR1bGVzW2ldO1xuICB9XG5cbiAgaWYgKGVtcHR5KSBkZWxldGUgbm9kZS5fX3RyYW5zaXRpb247XG59IiwiaW1wb3J0IGludGVycnVwdCBmcm9tIFwiLi4vaW50ZXJydXB0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBpbnRlcnJ1cHQodGhpcywgbmFtZSk7XG4gIH0pO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChhLCBiKSB7XG4gIHJldHVybiBhID0gK2EsIGIgPSArYiwgZnVuY3Rpb24gKHQpIHtcbiAgICByZXR1cm4gYSAqICgxIC0gdCkgKyBiICogdDtcbiAgfTtcbn0iLCJ2YXIgZGVncmVlcyA9IDE4MCAvIE1hdGguUEk7XG5leHBvcnQgdmFyIGlkZW50aXR5ID0ge1xuICB0cmFuc2xhdGVYOiAwLFxuICB0cmFuc2xhdGVZOiAwLFxuICByb3RhdGU6IDAsXG4gIHNrZXdYOiAwLFxuICBzY2FsZVg6IDEsXG4gIHNjYWxlWTogMVxufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChhLCBiLCBjLCBkLCBlLCBmKSB7XG4gIHZhciBzY2FsZVgsIHNjYWxlWSwgc2tld1g7XG4gIGlmIChzY2FsZVggPSBNYXRoLnNxcnQoYSAqIGEgKyBiICogYikpIGEgLz0gc2NhbGVYLCBiIC89IHNjYWxlWDtcbiAgaWYgKHNrZXdYID0gYSAqIGMgKyBiICogZCkgYyAtPSBhICogc2tld1gsIGQgLT0gYiAqIHNrZXdYO1xuICBpZiAoc2NhbGVZID0gTWF0aC5zcXJ0KGMgKiBjICsgZCAqIGQpKSBjIC89IHNjYWxlWSwgZCAvPSBzY2FsZVksIHNrZXdYIC89IHNjYWxlWTtcbiAgaWYgKGEgKiBkIDwgYiAqIGMpIGEgPSAtYSwgYiA9IC1iLCBza2V3WCA9IC1za2V3WCwgc2NhbGVYID0gLXNjYWxlWDtcbiAgcmV0dXJuIHtcbiAgICB0cmFuc2xhdGVYOiBlLFxuICAgIHRyYW5zbGF0ZVk6IGYsXG4gICAgcm90YXRlOiBNYXRoLmF0YW4yKGIsIGEpICogZGVncmVlcyxcbiAgICBza2V3WDogTWF0aC5hdGFuKHNrZXdYKSAqIGRlZ3JlZXMsXG4gICAgc2NhbGVYOiBzY2FsZVgsXG4gICAgc2NhbGVZOiBzY2FsZVlcbiAgfTtcbn0iLCJpbXBvcnQgZGVjb21wb3NlLCB7IGlkZW50aXR5IH0gZnJvbSBcIi4vZGVjb21wb3NlLmpzXCI7XG52YXIgc3ZnTm9kZTtcbi8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUNzcyh2YWx1ZSkge1xuICB2YXIgbSA9IG5ldyAodHlwZW9mIERPTU1hdHJpeCA9PT0gXCJmdW5jdGlvblwiID8gRE9NTWF0cml4IDogV2ViS2l0Q1NTTWF0cml4KSh2YWx1ZSArIFwiXCIpO1xuICByZXR1cm4gbS5pc0lkZW50aXR5ID8gaWRlbnRpdHkgOiBkZWNvbXBvc2UobS5hLCBtLmIsIG0uYywgbS5kLCBtLmUsIG0uZik7XG59XG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTdmcodmFsdWUpIHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBpZGVudGl0eTtcbiAgaWYgKCFzdmdOb2RlKSBzdmdOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiwgXCJnXCIpO1xuICBzdmdOb2RlLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCB2YWx1ZSk7XG4gIGlmICghKHZhbHVlID0gc3ZnTm9kZS50cmFuc2Zvcm0uYmFzZVZhbC5jb25zb2xpZGF0ZSgpKSkgcmV0dXJuIGlkZW50aXR5O1xuICB2YWx1ZSA9IHZhbHVlLm1hdHJpeDtcbiAgcmV0dXJuIGRlY29tcG9zZSh2YWx1ZS5hLCB2YWx1ZS5iLCB2YWx1ZS5jLCB2YWx1ZS5kLCB2YWx1ZS5lLCB2YWx1ZS5mKTtcbn0iLCJpbXBvcnQgbnVtYmVyIGZyb20gXCIuLi9udW1iZXIuanNcIjtcbmltcG9ydCB7IHBhcnNlQ3NzLCBwYXJzZVN2ZyB9IGZyb20gXCIuL3BhcnNlLmpzXCI7XG5cbmZ1bmN0aW9uIGludGVycG9sYXRlVHJhbnNmb3JtKHBhcnNlLCBweENvbW1hLCBweFBhcmVuLCBkZWdQYXJlbikge1xuICBmdW5jdGlvbiBwb3Aocykge1xuICAgIHJldHVybiBzLmxlbmd0aCA/IHMucG9wKCkgKyBcIiBcIiA6IFwiXCI7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFuc2xhdGUoeGEsIHlhLCB4YiwgeWIsIHMsIHEpIHtcbiAgICBpZiAoeGEgIT09IHhiIHx8IHlhICE9PSB5Yikge1xuICAgICAgdmFyIGkgPSBzLnB1c2goXCJ0cmFuc2xhdGUoXCIsIG51bGwsIHB4Q29tbWEsIG51bGwsIHB4UGFyZW4pO1xuICAgICAgcS5wdXNoKHtcbiAgICAgICAgaTogaSAtIDQsXG4gICAgICAgIHg6IG51bWJlcih4YSwgeGIpXG4gICAgICB9LCB7XG4gICAgICAgIGk6IGkgLSAyLFxuICAgICAgICB4OiBudW1iZXIoeWEsIHliKVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh4YiB8fCB5Yikge1xuICAgICAgcy5wdXNoKFwidHJhbnNsYXRlKFwiICsgeGIgKyBweENvbW1hICsgeWIgKyBweFBhcmVuKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByb3RhdGUoYSwgYiwgcywgcSkge1xuICAgIGlmIChhICE9PSBiKSB7XG4gICAgICBpZiAoYSAtIGIgPiAxODApIGIgKz0gMzYwO2Vsc2UgaWYgKGIgLSBhID4gMTgwKSBhICs9IDM2MDsgLy8gc2hvcnRlc3QgcGF0aFxuXG4gICAgICBxLnB1c2goe1xuICAgICAgICBpOiBzLnB1c2gocG9wKHMpICsgXCJyb3RhdGUoXCIsIG51bGwsIGRlZ1BhcmVuKSAtIDIsXG4gICAgICAgIHg6IG51bWJlcihhLCBiKVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChiKSB7XG4gICAgICBzLnB1c2gocG9wKHMpICsgXCJyb3RhdGUoXCIgKyBiICsgZGVnUGFyZW4pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNrZXdYKGEsIGIsIHMsIHEpIHtcbiAgICBpZiAoYSAhPT0gYikge1xuICAgICAgcS5wdXNoKHtcbiAgICAgICAgaTogcy5wdXNoKHBvcChzKSArIFwic2tld1goXCIsIG51bGwsIGRlZ1BhcmVuKSAtIDIsXG4gICAgICAgIHg6IG51bWJlcihhLCBiKVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChiKSB7XG4gICAgICBzLnB1c2gocG9wKHMpICsgXCJza2V3WChcIiArIGIgKyBkZWdQYXJlbik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2NhbGUoeGEsIHlhLCB4YiwgeWIsIHMsIHEpIHtcbiAgICBpZiAoeGEgIT09IHhiIHx8IHlhICE9PSB5Yikge1xuICAgICAgdmFyIGkgPSBzLnB1c2gocG9wKHMpICsgXCJzY2FsZShcIiwgbnVsbCwgXCIsXCIsIG51bGwsIFwiKVwiKTtcbiAgICAgIHEucHVzaCh7XG4gICAgICAgIGk6IGkgLSA0LFxuICAgICAgICB4OiBudW1iZXIoeGEsIHhiKVxuICAgICAgfSwge1xuICAgICAgICBpOiBpIC0gMixcbiAgICAgICAgeDogbnVtYmVyKHlhLCB5YilcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoeGIgIT09IDEgfHwgeWIgIT09IDEpIHtcbiAgICAgIHMucHVzaChwb3AocykgKyBcInNjYWxlKFwiICsgeGIgKyBcIixcIiArIHliICsgXCIpXCIpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoYSwgYikge1xuICAgIHZhciBzID0gW10sXG4gICAgICAgIC8vIHN0cmluZyBjb25zdGFudHMgYW5kIHBsYWNlaG9sZGVyc1xuICAgIHEgPSBbXTsgLy8gbnVtYmVyIGludGVycG9sYXRvcnNcblxuICAgIGEgPSBwYXJzZShhKSwgYiA9IHBhcnNlKGIpO1xuICAgIHRyYW5zbGF0ZShhLnRyYW5zbGF0ZVgsIGEudHJhbnNsYXRlWSwgYi50cmFuc2xhdGVYLCBiLnRyYW5zbGF0ZVksIHMsIHEpO1xuICAgIHJvdGF0ZShhLnJvdGF0ZSwgYi5yb3RhdGUsIHMsIHEpO1xuICAgIHNrZXdYKGEuc2tld1gsIGIuc2tld1gsIHMsIHEpO1xuICAgIHNjYWxlKGEuc2NhbGVYLCBhLnNjYWxlWSwgYi5zY2FsZVgsIGIuc2NhbGVZLCBzLCBxKTtcbiAgICBhID0gYiA9IG51bGw7IC8vIGdjXG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKHQpIHtcbiAgICAgIHZhciBpID0gLTEsXG4gICAgICAgICAgbiA9IHEubGVuZ3RoLFxuICAgICAgICAgIG87XG5cbiAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgIHNbKG8gPSBxW2ldKS5pXSA9IG8ueCh0KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHMuam9pbihcIlwiKTtcbiAgICB9O1xuICB9O1xufVxuXG5leHBvcnQgdmFyIGludGVycG9sYXRlVHJhbnNmb3JtQ3NzID0gaW50ZXJwb2xhdGVUcmFuc2Zvcm0ocGFyc2VDc3MsIFwicHgsIFwiLCBcInB4KVwiLCBcImRlZylcIik7XG5leHBvcnQgdmFyIGludGVycG9sYXRlVHJhbnNmb3JtU3ZnID0gaW50ZXJwb2xhdGVUcmFuc2Zvcm0ocGFyc2VTdmcsIFwiLCBcIiwgXCIpXCIsIFwiKVwiKTsiLCJpbXBvcnQgeyBnZXQsIHNldCB9IGZyb20gXCIuL3NjaGVkdWxlLmpzXCI7XG5cbmZ1bmN0aW9uIHR3ZWVuUmVtb3ZlKGlkLCBuYW1lKSB7XG4gIHZhciB0d2VlbjAsIHR3ZWVuMTtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2NoZWR1bGUgPSBzZXQodGhpcywgaWQpLFxuICAgICAgICB0d2VlbiA9IHNjaGVkdWxlLnR3ZWVuOyAvLyBJZiB0aGlzIG5vZGUgc2hhcmVkIHR3ZWVuIHdpdGggdGhlIHByZXZpb3VzIG5vZGUsXG4gICAgLy8ganVzdCBhc3NpZ24gdGhlIHVwZGF0ZWQgc2hhcmVkIHR3ZWVuIGFuZCB3ZeKAmXJlIGRvbmUhXG4gICAgLy8gT3RoZXJ3aXNlLCBjb3B5LW9uLXdyaXRlLlxuXG4gICAgaWYgKHR3ZWVuICE9PSB0d2VlbjApIHtcbiAgICAgIHR3ZWVuMSA9IHR3ZWVuMCA9IHR3ZWVuO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbiA9IHR3ZWVuMS5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgaWYgKHR3ZWVuMVtpXS5uYW1lID09PSBuYW1lKSB7XG4gICAgICAgICAgdHdlZW4xID0gdHdlZW4xLnNsaWNlKCk7XG4gICAgICAgICAgdHdlZW4xLnNwbGljZShpLCAxKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHNjaGVkdWxlLnR3ZWVuID0gdHdlZW4xO1xuICB9O1xufVxuXG5mdW5jdGlvbiB0d2VlbkZ1bmN0aW9uKGlkLCBuYW1lLCB2YWx1ZSkge1xuICB2YXIgdHdlZW4wLCB0d2VlbjE7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IEVycm9yKCk7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNjaGVkdWxlID0gc2V0KHRoaXMsIGlkKSxcbiAgICAgICAgdHdlZW4gPSBzY2hlZHVsZS50d2VlbjsgLy8gSWYgdGhpcyBub2RlIHNoYXJlZCB0d2VlbiB3aXRoIHRoZSBwcmV2aW91cyBub2RlLFxuICAgIC8vIGp1c3QgYXNzaWduIHRoZSB1cGRhdGVkIHNoYXJlZCB0d2VlbiBhbmQgd2XigJlyZSBkb25lIVxuICAgIC8vIE90aGVyd2lzZSwgY29weS1vbi13cml0ZS5cblxuICAgIGlmICh0d2VlbiAhPT0gdHdlZW4wKSB7XG4gICAgICB0d2VlbjEgPSAodHdlZW4wID0gdHdlZW4pLnNsaWNlKCk7XG5cbiAgICAgIGZvciAodmFyIHQgPSB7XG4gICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfSwgaSA9IDAsIG4gPSB0d2VlbjEubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGlmICh0d2VlbjFbaV0ubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICAgIHR3ZWVuMVtpXSA9IHQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGkgPT09IG4pIHR3ZWVuMS5wdXNoKHQpO1xuICAgIH1cblxuICAgIHNjaGVkdWxlLnR3ZWVuID0gdHdlZW4xO1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgdmFyIGlkID0gdGhpcy5faWQ7XG4gIG5hbWUgKz0gXCJcIjtcblxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICB2YXIgdHdlZW4gPSBnZXQodGhpcy5ub2RlKCksIGlkKS50d2VlbjtcblxuICAgIGZvciAodmFyIGkgPSAwLCBuID0gdHdlZW4ubGVuZ3RoLCB0OyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoKHQgPSB0d2VlbltpXSkubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICByZXR1cm4gdC52YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmVhY2goKHZhbHVlID09IG51bGwgPyB0d2VlblJlbW92ZSA6IHR3ZWVuRnVuY3Rpb24pKGlkLCBuYW1lLCB2YWx1ZSkpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHR3ZWVuVmFsdWUodHJhbnNpdGlvbiwgbmFtZSwgdmFsdWUpIHtcbiAgdmFyIGlkID0gdHJhbnNpdGlvbi5faWQ7XG4gIHRyYW5zaXRpb24uZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNjaGVkdWxlID0gc2V0KHRoaXMsIGlkKTtcbiAgICAoc2NoZWR1bGUudmFsdWUgfHwgKHNjaGVkdWxlLnZhbHVlID0ge30pKVtuYW1lXSA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH0pO1xuICByZXR1cm4gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICByZXR1cm4gZ2V0KG5vZGUsIGlkKS52YWx1ZVtuYW1lXTtcbiAgfTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoY29uc3RydWN0b3IsIGZhY3RvcnksIHByb3RvdHlwZSkge1xuICBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBmYWN0b3J5LnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgcHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY29uc3RydWN0b3I7XG59XG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kKHBhcmVudCwgZGVmaW5pdGlvbikge1xuICB2YXIgcHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShwYXJlbnQucHJvdG90eXBlKTtcblxuICBmb3IgKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuICAgIHByb3RvdHlwZVtrZXldID0gZGVmaW5pdGlvbltrZXldO1xuICB9XG5cbiAgcmV0dXJuIHByb3RvdHlwZTtcbn0iLCJpbXBvcnQgZGVmaW5lLCB7IGV4dGVuZCB9IGZyb20gXCIuL2RlZmluZS5qc1wiO1xuZXhwb3J0IGZ1bmN0aW9uIENvbG9yKCkge31cbnZhciBfZGFya2VyID0gMC43O1xuZXhwb3J0IHsgX2RhcmtlciBhcyBkYXJrZXIgfTtcblxudmFyIF9icmlnaHRlciA9IDEgLyBfZGFya2VyO1xuXG5leHBvcnQgeyBfYnJpZ2h0ZXIgYXMgYnJpZ2h0ZXIgfTtcbnZhciByZUkgPSBcIlxcXFxzKihbKy1dP1xcXFxkKylcXFxccypcIixcbiAgICByZU4gPSBcIlxcXFxzKihbKy1dP1xcXFxkKlxcXFwuP1xcXFxkKyg/OltlRV1bKy1dP1xcXFxkKyk/KVxcXFxzKlwiLFxuICAgIHJlUCA9IFwiXFxcXHMqKFsrLV0/XFxcXGQqXFxcXC4/XFxcXGQrKD86W2VFXVsrLV0/XFxcXGQrKT8pJVxcXFxzKlwiLFxuICAgIHJlSGV4ID0gL14jKFswLTlhLWZdezMsOH0pJC8sXG4gICAgcmVSZ2JJbnRlZ2VyID0gbmV3IFJlZ0V4cChcIl5yZ2JcXFxcKFwiICsgW3JlSSwgcmVJLCByZUldICsgXCJcXFxcKSRcIiksXG4gICAgcmVSZ2JQZXJjZW50ID0gbmV3IFJlZ0V4cChcIl5yZ2JcXFxcKFwiICsgW3JlUCwgcmVQLCByZVBdICsgXCJcXFxcKSRcIiksXG4gICAgcmVSZ2JhSW50ZWdlciA9IG5ldyBSZWdFeHAoXCJecmdiYVxcXFwoXCIgKyBbcmVJLCByZUksIHJlSSwgcmVOXSArIFwiXFxcXCkkXCIpLFxuICAgIHJlUmdiYVBlcmNlbnQgPSBuZXcgUmVnRXhwKFwiXnJnYmFcXFxcKFwiICsgW3JlUCwgcmVQLCByZVAsIHJlTl0gKyBcIlxcXFwpJFwiKSxcbiAgICByZUhzbFBlcmNlbnQgPSBuZXcgUmVnRXhwKFwiXmhzbFxcXFwoXCIgKyBbcmVOLCByZVAsIHJlUF0gKyBcIlxcXFwpJFwiKSxcbiAgICByZUhzbGFQZXJjZW50ID0gbmV3IFJlZ0V4cChcIl5oc2xhXFxcXChcIiArIFtyZU4sIHJlUCwgcmVQLCByZU5dICsgXCJcXFxcKSRcIik7XG52YXIgbmFtZWQgPSB7XG4gIGFsaWNlYmx1ZTogMHhmMGY4ZmYsXG4gIGFudGlxdWV3aGl0ZTogMHhmYWViZDcsXG4gIGFxdWE6IDB4MDBmZmZmLFxuICBhcXVhbWFyaW5lOiAweDdmZmZkNCxcbiAgYXp1cmU6IDB4ZjBmZmZmLFxuICBiZWlnZTogMHhmNWY1ZGMsXG4gIGJpc3F1ZTogMHhmZmU0YzQsXG4gIGJsYWNrOiAweDAwMDAwMCxcbiAgYmxhbmNoZWRhbG1vbmQ6IDB4ZmZlYmNkLFxuICBibHVlOiAweDAwMDBmZixcbiAgYmx1ZXZpb2xldDogMHg4YTJiZTIsXG4gIGJyb3duOiAweGE1MmEyYSxcbiAgYnVybHl3b29kOiAweGRlYjg4NyxcbiAgY2FkZXRibHVlOiAweDVmOWVhMCxcbiAgY2hhcnRyZXVzZTogMHg3ZmZmMDAsXG4gIGNob2NvbGF0ZTogMHhkMjY5MWUsXG4gIGNvcmFsOiAweGZmN2Y1MCxcbiAgY29ybmZsb3dlcmJsdWU6IDB4NjQ5NWVkLFxuICBjb3Juc2lsazogMHhmZmY4ZGMsXG4gIGNyaW1zb246IDB4ZGMxNDNjLFxuICBjeWFuOiAweDAwZmZmZixcbiAgZGFya2JsdWU6IDB4MDAwMDhiLFxuICBkYXJrY3lhbjogMHgwMDhiOGIsXG4gIGRhcmtnb2xkZW5yb2Q6IDB4Yjg4NjBiLFxuICBkYXJrZ3JheTogMHhhOWE5YTksXG4gIGRhcmtncmVlbjogMHgwMDY0MDAsXG4gIGRhcmtncmV5OiAweGE5YTlhOSxcbiAgZGFya2toYWtpOiAweGJkYjc2YixcbiAgZGFya21hZ2VudGE6IDB4OGIwMDhiLFxuICBkYXJrb2xpdmVncmVlbjogMHg1NTZiMmYsXG4gIGRhcmtvcmFuZ2U6IDB4ZmY4YzAwLFxuICBkYXJrb3JjaGlkOiAweDk5MzJjYyxcbiAgZGFya3JlZDogMHg4YjAwMDAsXG4gIGRhcmtzYWxtb246IDB4ZTk5NjdhLFxuICBkYXJrc2VhZ3JlZW46IDB4OGZiYzhmLFxuICBkYXJrc2xhdGVibHVlOiAweDQ4M2Q4YixcbiAgZGFya3NsYXRlZ3JheTogMHgyZjRmNGYsXG4gIGRhcmtzbGF0ZWdyZXk6IDB4MmY0ZjRmLFxuICBkYXJrdHVycXVvaXNlOiAweDAwY2VkMSxcbiAgZGFya3Zpb2xldDogMHg5NDAwZDMsXG4gIGRlZXBwaW5rOiAweGZmMTQ5MyxcbiAgZGVlcHNreWJsdWU6IDB4MDBiZmZmLFxuICBkaW1ncmF5OiAweDY5Njk2OSxcbiAgZGltZ3JleTogMHg2OTY5NjksXG4gIGRvZGdlcmJsdWU6IDB4MWU5MGZmLFxuICBmaXJlYnJpY2s6IDB4YjIyMjIyLFxuICBmbG9yYWx3aGl0ZTogMHhmZmZhZjAsXG4gIGZvcmVzdGdyZWVuOiAweDIyOGIyMixcbiAgZnVjaHNpYTogMHhmZjAwZmYsXG4gIGdhaW5zYm9ybzogMHhkY2RjZGMsXG4gIGdob3N0d2hpdGU6IDB4ZjhmOGZmLFxuICBnb2xkOiAweGZmZDcwMCxcbiAgZ29sZGVucm9kOiAweGRhYTUyMCxcbiAgZ3JheTogMHg4MDgwODAsXG4gIGdyZWVuOiAweDAwODAwMCxcbiAgZ3JlZW55ZWxsb3c6IDB4YWRmZjJmLFxuICBncmV5OiAweDgwODA4MCxcbiAgaG9uZXlkZXc6IDB4ZjBmZmYwLFxuICBob3RwaW5rOiAweGZmNjliNCxcbiAgaW5kaWFucmVkOiAweGNkNWM1YyxcbiAgaW5kaWdvOiAweDRiMDA4MixcbiAgaXZvcnk6IDB4ZmZmZmYwLFxuICBraGFraTogMHhmMGU2OGMsXG4gIGxhdmVuZGVyOiAweGU2ZTZmYSxcbiAgbGF2ZW5kZXJibHVzaDogMHhmZmYwZjUsXG4gIGxhd25ncmVlbjogMHg3Y2ZjMDAsXG4gIGxlbW9uY2hpZmZvbjogMHhmZmZhY2QsXG4gIGxpZ2h0Ymx1ZTogMHhhZGQ4ZTYsXG4gIGxpZ2h0Y29yYWw6IDB4ZjA4MDgwLFxuICBsaWdodGN5YW46IDB4ZTBmZmZmLFxuICBsaWdodGdvbGRlbnJvZHllbGxvdzogMHhmYWZhZDIsXG4gIGxpZ2h0Z3JheTogMHhkM2QzZDMsXG4gIGxpZ2h0Z3JlZW46IDB4OTBlZTkwLFxuICBsaWdodGdyZXk6IDB4ZDNkM2QzLFxuICBsaWdodHBpbms6IDB4ZmZiNmMxLFxuICBsaWdodHNhbG1vbjogMHhmZmEwN2EsXG4gIGxpZ2h0c2VhZ3JlZW46IDB4MjBiMmFhLFxuICBsaWdodHNreWJsdWU6IDB4ODdjZWZhLFxuICBsaWdodHNsYXRlZ3JheTogMHg3Nzg4OTksXG4gIGxpZ2h0c2xhdGVncmV5OiAweDc3ODg5OSxcbiAgbGlnaHRzdGVlbGJsdWU6IDB4YjBjNGRlLFxuICBsaWdodHllbGxvdzogMHhmZmZmZTAsXG4gIGxpbWU6IDB4MDBmZjAwLFxuICBsaW1lZ3JlZW46IDB4MzJjZDMyLFxuICBsaW5lbjogMHhmYWYwZTYsXG4gIG1hZ2VudGE6IDB4ZmYwMGZmLFxuICBtYXJvb246IDB4ODAwMDAwLFxuICBtZWRpdW1hcXVhbWFyaW5lOiAweDY2Y2RhYSxcbiAgbWVkaXVtYmx1ZTogMHgwMDAwY2QsXG4gIG1lZGl1bW9yY2hpZDogMHhiYTU1ZDMsXG4gIG1lZGl1bXB1cnBsZTogMHg5MzcwZGIsXG4gIG1lZGl1bXNlYWdyZWVuOiAweDNjYjM3MSxcbiAgbWVkaXVtc2xhdGVibHVlOiAweDdiNjhlZSxcbiAgbWVkaXVtc3ByaW5nZ3JlZW46IDB4MDBmYTlhLFxuICBtZWRpdW10dXJxdW9pc2U6IDB4NDhkMWNjLFxuICBtZWRpdW12aW9sZXRyZWQ6IDB4YzcxNTg1LFxuICBtaWRuaWdodGJsdWU6IDB4MTkxOTcwLFxuICBtaW50Y3JlYW06IDB4ZjVmZmZhLFxuICBtaXN0eXJvc2U6IDB4ZmZlNGUxLFxuICBtb2NjYXNpbjogMHhmZmU0YjUsXG4gIG5hdmFqb3doaXRlOiAweGZmZGVhZCxcbiAgbmF2eTogMHgwMDAwODAsXG4gIG9sZGxhY2U6IDB4ZmRmNWU2LFxuICBvbGl2ZTogMHg4MDgwMDAsXG4gIG9saXZlZHJhYjogMHg2YjhlMjMsXG4gIG9yYW5nZTogMHhmZmE1MDAsXG4gIG9yYW5nZXJlZDogMHhmZjQ1MDAsXG4gIG9yY2hpZDogMHhkYTcwZDYsXG4gIHBhbGVnb2xkZW5yb2Q6IDB4ZWVlOGFhLFxuICBwYWxlZ3JlZW46IDB4OThmYjk4LFxuICBwYWxldHVycXVvaXNlOiAweGFmZWVlZSxcbiAgcGFsZXZpb2xldHJlZDogMHhkYjcwOTMsXG4gIHBhcGF5YXdoaXA6IDB4ZmZlZmQ1LFxuICBwZWFjaHB1ZmY6IDB4ZmZkYWI5LFxuICBwZXJ1OiAweGNkODUzZixcbiAgcGluazogMHhmZmMwY2IsXG4gIHBsdW06IDB4ZGRhMGRkLFxuICBwb3dkZXJibHVlOiAweGIwZTBlNixcbiAgcHVycGxlOiAweDgwMDA4MCxcbiAgcmViZWNjYXB1cnBsZTogMHg2NjMzOTksXG4gIHJlZDogMHhmZjAwMDAsXG4gIHJvc3licm93bjogMHhiYzhmOGYsXG4gIHJveWFsYmx1ZTogMHg0MTY5ZTEsXG4gIHNhZGRsZWJyb3duOiAweDhiNDUxMyxcbiAgc2FsbW9uOiAweGZhODA3MixcbiAgc2FuZHlicm93bjogMHhmNGE0NjAsXG4gIHNlYWdyZWVuOiAweDJlOGI1NyxcbiAgc2Vhc2hlbGw6IDB4ZmZmNWVlLFxuICBzaWVubmE6IDB4YTA1MjJkLFxuICBzaWx2ZXI6IDB4YzBjMGMwLFxuICBza3libHVlOiAweDg3Y2VlYixcbiAgc2xhdGVibHVlOiAweDZhNWFjZCxcbiAgc2xhdGVncmF5OiAweDcwODA5MCxcbiAgc2xhdGVncmV5OiAweDcwODA5MCxcbiAgc25vdzogMHhmZmZhZmEsXG4gIHNwcmluZ2dyZWVuOiAweDAwZmY3ZixcbiAgc3RlZWxibHVlOiAweDQ2ODJiNCxcbiAgdGFuOiAweGQyYjQ4YyxcbiAgdGVhbDogMHgwMDgwODAsXG4gIHRoaXN0bGU6IDB4ZDhiZmQ4LFxuICB0b21hdG86IDB4ZmY2MzQ3LFxuICB0dXJxdW9pc2U6IDB4NDBlMGQwLFxuICB2aW9sZXQ6IDB4ZWU4MmVlLFxuICB3aGVhdDogMHhmNWRlYjMsXG4gIHdoaXRlOiAweGZmZmZmZixcbiAgd2hpdGVzbW9rZTogMHhmNWY1ZjUsXG4gIHllbGxvdzogMHhmZmZmMDAsXG4gIHllbGxvd2dyZWVuOiAweDlhY2QzMlxufTtcbmRlZmluZShDb2xvciwgY29sb3IsIHtcbiAgY29weTogZnVuY3Rpb24gY29weShjaGFubmVscykge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyB0aGlzLmNvbnN0cnVjdG9yKCksIHRoaXMsIGNoYW5uZWxzKTtcbiAgfSxcbiAgZGlzcGxheWFibGU6IGZ1bmN0aW9uIGRpc3BsYXlhYmxlKCkge1xuICAgIHJldHVybiB0aGlzLnJnYigpLmRpc3BsYXlhYmxlKCk7XG4gIH0sXG4gIGhleDogY29sb3JfZm9ybWF0SGV4LFxuICAvLyBEZXByZWNhdGVkISBVc2UgY29sb3IuZm9ybWF0SGV4LlxuICBmb3JtYXRIZXg6IGNvbG9yX2Zvcm1hdEhleCxcbiAgZm9ybWF0SHNsOiBjb2xvcl9mb3JtYXRIc2wsXG4gIGZvcm1hdFJnYjogY29sb3JfZm9ybWF0UmdiLFxuICB0b1N0cmluZzogY29sb3JfZm9ybWF0UmdiXG59KTtcblxuZnVuY3Rpb24gY29sb3JfZm9ybWF0SGV4KCkge1xuICByZXR1cm4gdGhpcy5yZ2IoKS5mb3JtYXRIZXgoKTtcbn1cblxuZnVuY3Rpb24gY29sb3JfZm9ybWF0SHNsKCkge1xuICByZXR1cm4gaHNsQ29udmVydCh0aGlzKS5mb3JtYXRIc2woKTtcbn1cblxuZnVuY3Rpb24gY29sb3JfZm9ybWF0UmdiKCkge1xuICByZXR1cm4gdGhpcy5yZ2IoKS5mb3JtYXRSZ2IoKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29sb3IoZm9ybWF0KSB7XG4gIHZhciBtLCBsO1xuICBmb3JtYXQgPSAoZm9ybWF0ICsgXCJcIikudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiAobSA9IHJlSGV4LmV4ZWMoZm9ybWF0KSkgPyAobCA9IG1bMV0ubGVuZ3RoLCBtID0gcGFyc2VJbnQobVsxXSwgMTYpLCBsID09PSA2ID8gcmdibihtKSAvLyAjZmYwMDAwXG4gIDogbCA9PT0gMyA/IG5ldyBSZ2IobSA+PiA4ICYgMHhmIHwgbSA+PiA0ICYgMHhmMCwgbSA+PiA0ICYgMHhmIHwgbSAmIDB4ZjAsIChtICYgMHhmKSA8PCA0IHwgbSAmIDB4ZiwgMSkgLy8gI2YwMFxuICA6IGwgPT09IDggPyByZ2JhKG0gPj4gMjQgJiAweGZmLCBtID4+IDE2ICYgMHhmZiwgbSA+PiA4ICYgMHhmZiwgKG0gJiAweGZmKSAvIDB4ZmYpIC8vICNmZjAwMDAwMFxuICA6IGwgPT09IDQgPyByZ2JhKG0gPj4gMTIgJiAweGYgfCBtID4+IDggJiAweGYwLCBtID4+IDggJiAweGYgfCBtID4+IDQgJiAweGYwLCBtID4+IDQgJiAweGYgfCBtICYgMHhmMCwgKChtICYgMHhmKSA8PCA0IHwgbSAmIDB4ZikgLyAweGZmKSAvLyAjZjAwMFxuICA6IG51bGwgLy8gaW52YWxpZCBoZXhcbiAgKSA6IChtID0gcmVSZ2JJbnRlZ2VyLmV4ZWMoZm9ybWF0KSkgPyBuZXcgUmdiKG1bMV0sIG1bMl0sIG1bM10sIDEpIC8vIHJnYigyNTUsIDAsIDApXG4gIDogKG0gPSByZVJnYlBlcmNlbnQuZXhlYyhmb3JtYXQpKSA/IG5ldyBSZ2IobVsxXSAqIDI1NSAvIDEwMCwgbVsyXSAqIDI1NSAvIDEwMCwgbVszXSAqIDI1NSAvIDEwMCwgMSkgLy8gcmdiKDEwMCUsIDAlLCAwJSlcbiAgOiAobSA9IHJlUmdiYUludGVnZXIuZXhlYyhmb3JtYXQpKSA/IHJnYmEobVsxXSwgbVsyXSwgbVszXSwgbVs0XSkgLy8gcmdiYSgyNTUsIDAsIDAsIDEpXG4gIDogKG0gPSByZVJnYmFQZXJjZW50LmV4ZWMoZm9ybWF0KSkgPyByZ2JhKG1bMV0gKiAyNTUgLyAxMDAsIG1bMl0gKiAyNTUgLyAxMDAsIG1bM10gKiAyNTUgLyAxMDAsIG1bNF0pIC8vIHJnYigxMDAlLCAwJSwgMCUsIDEpXG4gIDogKG0gPSByZUhzbFBlcmNlbnQuZXhlYyhmb3JtYXQpKSA/IGhzbGEobVsxXSwgbVsyXSAvIDEwMCwgbVszXSAvIDEwMCwgMSkgLy8gaHNsKDEyMCwgNTAlLCA1MCUpXG4gIDogKG0gPSByZUhzbGFQZXJjZW50LmV4ZWMoZm9ybWF0KSkgPyBoc2xhKG1bMV0sIG1bMl0gLyAxMDAsIG1bM10gLyAxMDAsIG1bNF0pIC8vIGhzbGEoMTIwLCA1MCUsIDUwJSwgMSlcbiAgOiBuYW1lZC5oYXNPd25Qcm9wZXJ0eShmb3JtYXQpID8gcmdibihuYW1lZFtmb3JtYXRdKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXByb3RvdHlwZS1idWlsdGluc1xuICA6IGZvcm1hdCA9PT0gXCJ0cmFuc3BhcmVudFwiID8gbmV3IFJnYihOYU4sIE5hTiwgTmFOLCAwKSA6IG51bGw7XG59XG5cbmZ1bmN0aW9uIHJnYm4obikge1xuICByZXR1cm4gbmV3IFJnYihuID4+IDE2ICYgMHhmZiwgbiA+PiA4ICYgMHhmZiwgbiAmIDB4ZmYsIDEpO1xufVxuXG5mdW5jdGlvbiByZ2JhKHIsIGcsIGIsIGEpIHtcbiAgaWYgKGEgPD0gMCkgciA9IGcgPSBiID0gTmFOO1xuICByZXR1cm4gbmV3IFJnYihyLCBnLCBiLCBhKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJnYkNvbnZlcnQobykge1xuICBpZiAoIShvIGluc3RhbmNlb2YgQ29sb3IpKSBvID0gY29sb3Iobyk7XG4gIGlmICghbykgcmV0dXJuIG5ldyBSZ2IoKTtcbiAgbyA9IG8ucmdiKCk7XG4gIHJldHVybiBuZXcgUmdiKG8uciwgby5nLCBvLmIsIG8ub3BhY2l0eSk7XG59XG5leHBvcnQgZnVuY3Rpb24gcmdiKHIsIGcsIGIsIG9wYWNpdHkpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyByZ2JDb252ZXJ0KHIpIDogbmV3IFJnYihyLCBnLCBiLCBvcGFjaXR5ID09IG51bGwgPyAxIDogb3BhY2l0eSk7XG59XG5leHBvcnQgZnVuY3Rpb24gUmdiKHIsIGcsIGIsIG9wYWNpdHkpIHtcbiAgdGhpcy5yID0gK3I7XG4gIHRoaXMuZyA9ICtnO1xuICB0aGlzLmIgPSArYjtcbiAgdGhpcy5vcGFjaXR5ID0gK29wYWNpdHk7XG59XG5kZWZpbmUoUmdiLCByZ2IsIGV4dGVuZChDb2xvciwge1xuICBicmlnaHRlcjogZnVuY3Rpb24gYnJpZ2h0ZXIoaykge1xuICAgIGsgPSBrID09IG51bGwgPyBfYnJpZ2h0ZXIgOiBNYXRoLnBvdyhfYnJpZ2h0ZXIsIGspO1xuICAgIHJldHVybiBuZXcgUmdiKHRoaXMuciAqIGssIHRoaXMuZyAqIGssIHRoaXMuYiAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRhcmtlcjogZnVuY3Rpb24gZGFya2VyKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gX2RhcmtlciA6IE1hdGgucG93KF9kYXJrZXIsIGspO1xuICAgIHJldHVybiBuZXcgUmdiKHRoaXMuciAqIGssIHRoaXMuZyAqIGssIHRoaXMuYiAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIHJnYjogZnVuY3Rpb24gcmdiKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBkaXNwbGF5YWJsZTogZnVuY3Rpb24gZGlzcGxheWFibGUoKSB7XG4gICAgcmV0dXJuIC0wLjUgPD0gdGhpcy5yICYmIHRoaXMuciA8IDI1NS41ICYmIC0wLjUgPD0gdGhpcy5nICYmIHRoaXMuZyA8IDI1NS41ICYmIC0wLjUgPD0gdGhpcy5iICYmIHRoaXMuYiA8IDI1NS41ICYmIDAgPD0gdGhpcy5vcGFjaXR5ICYmIHRoaXMub3BhY2l0eSA8PSAxO1xuICB9LFxuICBoZXg6IHJnYl9mb3JtYXRIZXgsXG4gIC8vIERlcHJlY2F0ZWQhIFVzZSBjb2xvci5mb3JtYXRIZXguXG4gIGZvcm1hdEhleDogcmdiX2Zvcm1hdEhleCxcbiAgZm9ybWF0UmdiOiByZ2JfZm9ybWF0UmdiLFxuICB0b1N0cmluZzogcmdiX2Zvcm1hdFJnYlxufSkpO1xuXG5mdW5jdGlvbiByZ2JfZm9ybWF0SGV4KCkge1xuICByZXR1cm4gXCIjXCIgKyBoZXgodGhpcy5yKSArIGhleCh0aGlzLmcpICsgaGV4KHRoaXMuYik7XG59XG5cbmZ1bmN0aW9uIHJnYl9mb3JtYXRSZ2IoKSB7XG4gIHZhciBhID0gdGhpcy5vcGFjaXR5O1xuICBhID0gaXNOYU4oYSkgPyAxIDogTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgYSkpO1xuICByZXR1cm4gKGEgPT09IDEgPyBcInJnYihcIiA6IFwicmdiYShcIikgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIE1hdGgucm91bmQodGhpcy5yKSB8fCAwKSkgKyBcIiwgXCIgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIE1hdGgucm91bmQodGhpcy5nKSB8fCAwKSkgKyBcIiwgXCIgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIE1hdGgucm91bmQodGhpcy5iKSB8fCAwKSkgKyAoYSA9PT0gMSA/IFwiKVwiIDogXCIsIFwiICsgYSArIFwiKVwiKTtcbn1cblxuZnVuY3Rpb24gaGV4KHZhbHVlKSB7XG4gIHZhbHVlID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMjU1LCBNYXRoLnJvdW5kKHZhbHVlKSB8fCAwKSk7XG4gIHJldHVybiAodmFsdWUgPCAxNiA/IFwiMFwiIDogXCJcIikgKyB2YWx1ZS50b1N0cmluZygxNik7XG59XG5cbmZ1bmN0aW9uIGhzbGEoaCwgcywgbCwgYSkge1xuICBpZiAoYSA8PSAwKSBoID0gcyA9IGwgPSBOYU47ZWxzZSBpZiAobCA8PSAwIHx8IGwgPj0gMSkgaCA9IHMgPSBOYU47ZWxzZSBpZiAocyA8PSAwKSBoID0gTmFOO1xuICByZXR1cm4gbmV3IEhzbChoLCBzLCBsLCBhKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhzbENvbnZlcnQobykge1xuICBpZiAobyBpbnN0YW5jZW9mIEhzbCkgcmV0dXJuIG5ldyBIc2woby5oLCBvLnMsIG8ubCwgby5vcGFjaXR5KTtcbiAgaWYgKCEobyBpbnN0YW5jZW9mIENvbG9yKSkgbyA9IGNvbG9yKG8pO1xuICBpZiAoIW8pIHJldHVybiBuZXcgSHNsKCk7XG4gIGlmIChvIGluc3RhbmNlb2YgSHNsKSByZXR1cm4gbztcbiAgbyA9IG8ucmdiKCk7XG4gIHZhciByID0gby5yIC8gMjU1LFxuICAgICAgZyA9IG8uZyAvIDI1NSxcbiAgICAgIGIgPSBvLmIgLyAyNTUsXG4gICAgICBtaW4gPSBNYXRoLm1pbihyLCBnLCBiKSxcbiAgICAgIG1heCA9IE1hdGgubWF4KHIsIGcsIGIpLFxuICAgICAgaCA9IE5hTixcbiAgICAgIHMgPSBtYXggLSBtaW4sXG4gICAgICBsID0gKG1heCArIG1pbikgLyAyO1xuXG4gIGlmIChzKSB7XG4gICAgaWYgKHIgPT09IG1heCkgaCA9IChnIC0gYikgLyBzICsgKGcgPCBiKSAqIDY7ZWxzZSBpZiAoZyA9PT0gbWF4KSBoID0gKGIgLSByKSAvIHMgKyAyO2Vsc2UgaCA9IChyIC0gZykgLyBzICsgNDtcbiAgICBzIC89IGwgPCAwLjUgPyBtYXggKyBtaW4gOiAyIC0gbWF4IC0gbWluO1xuICAgIGggKj0gNjA7XG4gIH0gZWxzZSB7XG4gICAgcyA9IGwgPiAwICYmIGwgPCAxID8gMCA6IGg7XG4gIH1cblxuICByZXR1cm4gbmV3IEhzbChoLCBzLCBsLCBvLm9wYWNpdHkpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGhzbChoLCBzLCBsLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gaHNsQ29udmVydChoKSA6IG5ldyBIc2woaCwgcywgbCwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBIc2woaCwgcywgbCwgb3BhY2l0eSkge1xuICB0aGlzLmggPSAraDtcbiAgdGhpcy5zID0gK3M7XG4gIHRoaXMubCA9ICtsO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKEhzbCwgaHNsLCBleHRlbmQoQ29sb3IsIHtcbiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uIGJyaWdodGVyKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gX2JyaWdodGVyIDogTWF0aC5wb3coX2JyaWdodGVyLCBrKTtcbiAgICByZXR1cm4gbmV3IEhzbCh0aGlzLmgsIHRoaXMucywgdGhpcy5sICogaywgdGhpcy5vcGFjaXR5KTtcbiAgfSxcbiAgZGFya2VyOiBmdW5jdGlvbiBkYXJrZXIoaykge1xuICAgIGsgPSBrID09IG51bGwgPyBfZGFya2VyIDogTWF0aC5wb3coX2Rhcmtlciwgayk7XG4gICAgcmV0dXJuIG5ldyBIc2wodGhpcy5oLCB0aGlzLnMsIHRoaXMubCAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIHJnYjogZnVuY3Rpb24gcmdiKCkge1xuICAgIHZhciBoID0gdGhpcy5oICUgMzYwICsgKHRoaXMuaCA8IDApICogMzYwLFxuICAgICAgICBzID0gaXNOYU4oaCkgfHwgaXNOYU4odGhpcy5zKSA/IDAgOiB0aGlzLnMsXG4gICAgICAgIGwgPSB0aGlzLmwsXG4gICAgICAgIG0yID0gbCArIChsIDwgMC41ID8gbCA6IDEgLSBsKSAqIHMsXG4gICAgICAgIG0xID0gMiAqIGwgLSBtMjtcbiAgICByZXR1cm4gbmV3IFJnYihoc2wycmdiKGggPj0gMjQwID8gaCAtIDI0MCA6IGggKyAxMjAsIG0xLCBtMiksIGhzbDJyZ2IoaCwgbTEsIG0yKSwgaHNsMnJnYihoIDwgMTIwID8gaCArIDI0MCA6IGggLSAxMjAsIG0xLCBtMiksIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRpc3BsYXlhYmxlOiBmdW5jdGlvbiBkaXNwbGF5YWJsZSgpIHtcbiAgICByZXR1cm4gKDAgPD0gdGhpcy5zICYmIHRoaXMucyA8PSAxIHx8IGlzTmFOKHRoaXMucykpICYmIDAgPD0gdGhpcy5sICYmIHRoaXMubCA8PSAxICYmIDAgPD0gdGhpcy5vcGFjaXR5ICYmIHRoaXMub3BhY2l0eSA8PSAxO1xuICB9LFxuICBmb3JtYXRIc2w6IGZ1bmN0aW9uIGZvcm1hdEhzbCgpIHtcbiAgICB2YXIgYSA9IHRoaXMub3BhY2l0eTtcbiAgICBhID0gaXNOYU4oYSkgPyAxIDogTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgYSkpO1xuICAgIHJldHVybiAoYSA9PT0gMSA/IFwiaHNsKFwiIDogXCJoc2xhKFwiKSArICh0aGlzLmggfHwgMCkgKyBcIiwgXCIgKyAodGhpcy5zIHx8IDApICogMTAwICsgXCIlLCBcIiArICh0aGlzLmwgfHwgMCkgKiAxMDAgKyBcIiVcIiArIChhID09PSAxID8gXCIpXCIgOiBcIiwgXCIgKyBhICsgXCIpXCIpO1xuICB9XG59KSk7XG4vKiBGcm9tIEZ2RCAxMy4zNywgQ1NTIENvbG9yIE1vZHVsZSBMZXZlbCAzICovXG5cbmZ1bmN0aW9uIGhzbDJyZ2IoaCwgbTEsIG0yKSB7XG4gIHJldHVybiAoaCA8IDYwID8gbTEgKyAobTIgLSBtMSkgKiBoIC8gNjAgOiBoIDwgMTgwID8gbTIgOiBoIDwgMjQwID8gbTEgKyAobTIgLSBtMSkgKiAoMjQwIC0gaCkgLyA2MCA6IG0xKSAqIDI1NTtcbn0iLCJleHBvcnQgZnVuY3Rpb24gYmFzaXModDEsIHYwLCB2MSwgdjIsIHYzKSB7XG4gIHZhciB0MiA9IHQxICogdDEsXG4gICAgICB0MyA9IHQyICogdDE7XG4gIHJldHVybiAoKDEgLSAzICogdDEgKyAzICogdDIgLSB0MykgKiB2MCArICg0IC0gNiAqIHQyICsgMyAqIHQzKSAqIHYxICsgKDEgKyAzICogdDEgKyAzICogdDIgLSAzICogdDMpICogdjIgKyB0MyAqIHYzKSAvIDY7XG59XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAodmFsdWVzKSB7XG4gIHZhciBuID0gdmFsdWVzLmxlbmd0aCAtIDE7XG4gIHJldHVybiBmdW5jdGlvbiAodCkge1xuICAgIHZhciBpID0gdCA8PSAwID8gdCA9IDAgOiB0ID49IDEgPyAodCA9IDEsIG4gLSAxKSA6IE1hdGguZmxvb3IodCAqIG4pLFxuICAgICAgICB2MSA9IHZhbHVlc1tpXSxcbiAgICAgICAgdjIgPSB2YWx1ZXNbaSArIDFdLFxuICAgICAgICB2MCA9IGkgPiAwID8gdmFsdWVzW2kgLSAxXSA6IDIgKiB2MSAtIHYyLFxuICAgICAgICB2MyA9IGkgPCBuIC0gMSA/IHZhbHVlc1tpICsgMl0gOiAyICogdjIgLSB2MTtcbiAgICByZXR1cm4gYmFzaXMoKHQgLSBpIC8gbikgKiBuLCB2MCwgdjEsIHYyLCB2Myk7XG4gIH07XG59IiwiaW1wb3J0IHsgYmFzaXMgfSBmcm9tIFwiLi9iYXNpcy5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHZhbHVlcykge1xuICB2YXIgbiA9IHZhbHVlcy5sZW5ndGg7XG4gIHJldHVybiBmdW5jdGlvbiAodCkge1xuICAgIHZhciBpID0gTWF0aC5mbG9vcigoKHQgJT0gMSkgPCAwID8gKyt0IDogdCkgKiBuKSxcbiAgICAgICAgdjAgPSB2YWx1ZXNbKGkgKyBuIC0gMSkgJSBuXSxcbiAgICAgICAgdjEgPSB2YWx1ZXNbaSAlIG5dLFxuICAgICAgICB2MiA9IHZhbHVlc1soaSArIDEpICUgbl0sXG4gICAgICAgIHYzID0gdmFsdWVzWyhpICsgMikgJSBuXTtcbiAgICByZXR1cm4gYmFzaXMoKHQgLSBpIC8gbikgKiBuLCB2MCwgdjEsIHYyLCB2Myk7XG4gIH07XG59IiwiZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uICh4KSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59KTsiLCJpbXBvcnQgY29uc3RhbnQgZnJvbSBcIi4vY29uc3RhbnQuanNcIjtcblxuZnVuY3Rpb24gbGluZWFyKGEsIGQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh0KSB7XG4gICAgcmV0dXJuIGEgKyB0ICogZDtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZXhwb25lbnRpYWwoYSwgYiwgeSkge1xuICByZXR1cm4gYSA9IE1hdGgucG93KGEsIHkpLCBiID0gTWF0aC5wb3coYiwgeSkgLSBhLCB5ID0gMSAvIHksIGZ1bmN0aW9uICh0KSB7XG4gICAgcmV0dXJuIE1hdGgucG93KGEgKyB0ICogYiwgeSk7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBodWUoYSwgYikge1xuICB2YXIgZCA9IGIgLSBhO1xuICByZXR1cm4gZCA/IGxpbmVhcihhLCBkID4gMTgwIHx8IGQgPCAtMTgwID8gZCAtIDM2MCAqIE1hdGgucm91bmQoZCAvIDM2MCkgOiBkKSA6IGNvbnN0YW50KGlzTmFOKGEpID8gYiA6IGEpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdhbW1hKHkpIHtcbiAgcmV0dXJuICh5ID0gK3kpID09PSAxID8gbm9nYW1tYSA6IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIGIgLSBhID8gZXhwb25lbnRpYWwoYSwgYiwgeSkgOiBjb25zdGFudChpc05hTihhKSA/IGIgOiBhKTtcbiAgfTtcbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG5vZ2FtbWEoYSwgYikge1xuICB2YXIgZCA9IGIgLSBhO1xuICByZXR1cm4gZCA/IGxpbmVhcihhLCBkKSA6IGNvbnN0YW50KGlzTmFOKGEpID8gYiA6IGEpO1xufSIsImltcG9ydCB7IHJnYiBhcyBjb2xvclJnYiB9IGZyb20gXCJkMy1jb2xvclwiO1xuaW1wb3J0IGJhc2lzIGZyb20gXCIuL2Jhc2lzLmpzXCI7XG5pbXBvcnQgYmFzaXNDbG9zZWQgZnJvbSBcIi4vYmFzaXNDbG9zZWQuanNcIjtcbmltcG9ydCBub2dhbW1hLCB7IGdhbW1hIH0gZnJvbSBcIi4vY29sb3IuanNcIjtcbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiByZ2JHYW1tYSh5KSB7XG4gIHZhciBjb2xvciA9IGdhbW1hKHkpO1xuXG4gIGZ1bmN0aW9uIHJnYihzdGFydCwgZW5kKSB7XG4gICAgdmFyIHIgPSBjb2xvcigoc3RhcnQgPSBjb2xvclJnYihzdGFydCkpLnIsIChlbmQgPSBjb2xvclJnYihlbmQpKS5yKSxcbiAgICAgICAgZyA9IGNvbG9yKHN0YXJ0LmcsIGVuZC5nKSxcbiAgICAgICAgYiA9IGNvbG9yKHN0YXJ0LmIsIGVuZC5iKSxcbiAgICAgICAgb3BhY2l0eSA9IG5vZ2FtbWEoc3RhcnQub3BhY2l0eSwgZW5kLm9wYWNpdHkpO1xuICAgIHJldHVybiBmdW5jdGlvbiAodCkge1xuICAgICAgc3RhcnQuciA9IHIodCk7XG4gICAgICBzdGFydC5nID0gZyh0KTtcbiAgICAgIHN0YXJ0LmIgPSBiKHQpO1xuICAgICAgc3RhcnQub3BhY2l0eSA9IG9wYWNpdHkodCk7XG4gICAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICAgIH07XG4gIH1cblxuICByZ2IuZ2FtbWEgPSByZ2JHYW1tYTtcbiAgcmV0dXJuIHJnYjtcbn0pKDEpO1xuXG5mdW5jdGlvbiByZ2JTcGxpbmUoc3BsaW5lKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoY29sb3JzKSB7XG4gICAgdmFyIG4gPSBjb2xvcnMubGVuZ3RoLFxuICAgICAgICByID0gbmV3IEFycmF5KG4pLFxuICAgICAgICBnID0gbmV3IEFycmF5KG4pLFxuICAgICAgICBiID0gbmV3IEFycmF5KG4pLFxuICAgICAgICBpLFxuICAgICAgICBjb2xvcjtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGNvbG9yID0gY29sb3JSZ2IoY29sb3JzW2ldKTtcbiAgICAgIHJbaV0gPSBjb2xvci5yIHx8IDA7XG4gICAgICBnW2ldID0gY29sb3IuZyB8fCAwO1xuICAgICAgYltpXSA9IGNvbG9yLmIgfHwgMDtcbiAgICB9XG5cbiAgICByID0gc3BsaW5lKHIpO1xuICAgIGcgPSBzcGxpbmUoZyk7XG4gICAgYiA9IHNwbGluZShiKTtcbiAgICBjb2xvci5vcGFjaXR5ID0gMTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHQpIHtcbiAgICAgIGNvbG9yLnIgPSByKHQpO1xuICAgICAgY29sb3IuZyA9IGcodCk7XG4gICAgICBjb2xvci5iID0gYih0KTtcbiAgICAgIHJldHVybiBjb2xvciArIFwiXCI7XG4gICAgfTtcbiAgfTtcbn1cblxuZXhwb3J0IHZhciByZ2JCYXNpcyA9IHJnYlNwbGluZShiYXNpcyk7XG5leHBvcnQgdmFyIHJnYkJhc2lzQ2xvc2VkID0gcmdiU3BsaW5lKGJhc2lzQ2xvc2VkKTsiLCJpbXBvcnQgbnVtYmVyIGZyb20gXCIuL251bWJlci5qc1wiO1xudmFyIHJlQSA9IC9bLStdPyg/OlxcZCtcXC4/XFxkKnxcXC4/XFxkKykoPzpbZUVdWy0rXT9cXGQrKT8vZyxcbiAgICByZUIgPSBuZXcgUmVnRXhwKHJlQS5zb3VyY2UsIFwiZ1wiKTtcblxuZnVuY3Rpb24gemVybyhiKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGI7XG4gIH07XG59XG5cbmZ1bmN0aW9uIG9uZShiKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodCkge1xuICAgIHJldHVybiBiKHQpICsgXCJcIjtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKGEsIGIpIHtcbiAgdmFyIGJpID0gcmVBLmxhc3RJbmRleCA9IHJlQi5sYXN0SW5kZXggPSAwLFxuICAgICAgLy8gc2NhbiBpbmRleCBmb3IgbmV4dCBudW1iZXIgaW4gYlxuICBhbSxcbiAgICAgIC8vIGN1cnJlbnQgbWF0Y2ggaW4gYVxuICBibSxcbiAgICAgIC8vIGN1cnJlbnQgbWF0Y2ggaW4gYlxuICBicyxcbiAgICAgIC8vIHN0cmluZyBwcmVjZWRpbmcgY3VycmVudCBudW1iZXIgaW4gYiwgaWYgYW55XG4gIGkgPSAtMSxcbiAgICAgIC8vIGluZGV4IGluIHNcbiAgcyA9IFtdLFxuICAgICAgLy8gc3RyaW5nIGNvbnN0YW50cyBhbmQgcGxhY2Vob2xkZXJzXG4gIHEgPSBbXTsgLy8gbnVtYmVyIGludGVycG9sYXRvcnNcbiAgLy8gQ29lcmNlIGlucHV0cyB0byBzdHJpbmdzLlxuXG4gIGEgPSBhICsgXCJcIiwgYiA9IGIgKyBcIlwiOyAvLyBJbnRlcnBvbGF0ZSBwYWlycyBvZiBudW1iZXJzIGluIGEgJiBiLlxuXG4gIHdoaWxlICgoYW0gPSByZUEuZXhlYyhhKSkgJiYgKGJtID0gcmVCLmV4ZWMoYikpKSB7XG4gICAgaWYgKChicyA9IGJtLmluZGV4KSA+IGJpKSB7XG4gICAgICAvLyBhIHN0cmluZyBwcmVjZWRlcyB0aGUgbmV4dCBudW1iZXIgaW4gYlxuICAgICAgYnMgPSBiLnNsaWNlKGJpLCBicyk7XG4gICAgICBpZiAoc1tpXSkgc1tpXSArPSBiczsgLy8gY29hbGVzY2Ugd2l0aCBwcmV2aW91cyBzdHJpbmdcbiAgICAgIGVsc2Ugc1srK2ldID0gYnM7XG4gICAgfVxuXG4gICAgaWYgKChhbSA9IGFtWzBdKSA9PT0gKGJtID0gYm1bMF0pKSB7XG4gICAgICAvLyBudW1iZXJzIGluIGEgJiBiIG1hdGNoXG4gICAgICBpZiAoc1tpXSkgc1tpXSArPSBibTsgLy8gY29hbGVzY2Ugd2l0aCBwcmV2aW91cyBzdHJpbmdcbiAgICAgIGVsc2Ugc1srK2ldID0gYm07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGludGVycG9sYXRlIG5vbi1tYXRjaGluZyBudW1iZXJzXG4gICAgICBzWysraV0gPSBudWxsO1xuICAgICAgcS5wdXNoKHtcbiAgICAgICAgaTogaSxcbiAgICAgICAgeDogbnVtYmVyKGFtLCBibSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGJpID0gcmVCLmxhc3RJbmRleDtcbiAgfSAvLyBBZGQgcmVtYWlucyBvZiBiLlxuXG5cbiAgaWYgKGJpIDwgYi5sZW5ndGgpIHtcbiAgICBicyA9IGIuc2xpY2UoYmkpO1xuICAgIGlmIChzW2ldKSBzW2ldICs9IGJzOyAvLyBjb2FsZXNjZSB3aXRoIHByZXZpb3VzIHN0cmluZ1xuICAgIGVsc2Ugc1srK2ldID0gYnM7XG4gIH0gLy8gU3BlY2lhbCBvcHRpbWl6YXRpb24gZm9yIG9ubHkgYSBzaW5nbGUgbWF0Y2guXG4gIC8vIE90aGVyd2lzZSwgaW50ZXJwb2xhdGUgZWFjaCBvZiB0aGUgbnVtYmVycyBhbmQgcmVqb2luIHRoZSBzdHJpbmcuXG5cblxuICByZXR1cm4gcy5sZW5ndGggPCAyID8gcVswXSA/IG9uZShxWzBdLngpIDogemVybyhiKSA6IChiID0gcS5sZW5ndGgsIGZ1bmN0aW9uICh0KSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIG87IGkgPCBiOyArK2kpIHtcbiAgICAgIHNbKG8gPSBxW2ldKS5pXSA9IG8ueCh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcy5qb2luKFwiXCIpO1xuICB9KTtcbn0iLCJpbXBvcnQgeyBjb2xvciB9IGZyb20gXCJkMy1jb2xvclwiO1xuaW1wb3J0IHsgaW50ZXJwb2xhdGVOdW1iZXIsIGludGVycG9sYXRlUmdiLCBpbnRlcnBvbGF0ZVN0cmluZyB9IGZyb20gXCJkMy1pbnRlcnBvbGF0ZVwiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKGEsIGIpIHtcbiAgdmFyIGM7XG4gIHJldHVybiAodHlwZW9mIGIgPT09IFwibnVtYmVyXCIgPyBpbnRlcnBvbGF0ZU51bWJlciA6IGIgaW5zdGFuY2VvZiBjb2xvciA/IGludGVycG9sYXRlUmdiIDogKGMgPSBjb2xvcihiKSkgPyAoYiA9IGMsIGludGVycG9sYXRlUmdiKSA6IGludGVycG9sYXRlU3RyaW5nKShhLCBiKTtcbn0iLCJpbXBvcnQgeyBpbnRlcnBvbGF0ZVRyYW5zZm9ybVN2ZyBhcyBpbnRlcnBvbGF0ZVRyYW5zZm9ybSB9IGZyb20gXCJkMy1pbnRlcnBvbGF0ZVwiO1xuaW1wb3J0IHsgbmFtZXNwYWNlIH0gZnJvbSBcImQzLXNlbGVjdGlvblwiO1xuaW1wb3J0IHsgdHdlZW5WYWx1ZSB9IGZyb20gXCIuL3R3ZWVuLmpzXCI7XG5pbXBvcnQgaW50ZXJwb2xhdGUgZnJvbSBcIi4vaW50ZXJwb2xhdGUuanNcIjtcblxuZnVuY3Rpb24gYXR0clJlbW92ZShuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJSZW1vdmVOUyhmdWxsbmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0ckNvbnN0YW50KG5hbWUsIGludGVycG9sYXRlLCB2YWx1ZTEpIHtcbiAgdmFyIHN0cmluZzAwLFxuICAgICAgc3RyaW5nMSA9IHZhbHVlMSArIFwiXCIsXG4gICAgICBpbnRlcnBvbGF0ZTA7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0cmluZzAgPSB0aGlzLmdldEF0dHJpYnV0ZShuYW1lKTtcbiAgICByZXR1cm4gc3RyaW5nMCA9PT0gc3RyaW5nMSA/IG51bGwgOiBzdHJpbmcwID09PSBzdHJpbmcwMCA/IGludGVycG9sYXRlMCA6IGludGVycG9sYXRlMCA9IGludGVycG9sYXRlKHN0cmluZzAwID0gc3RyaW5nMCwgdmFsdWUxKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0ckNvbnN0YW50TlMoZnVsbG5hbWUsIGludGVycG9sYXRlLCB2YWx1ZTEpIHtcbiAgdmFyIHN0cmluZzAwLFxuICAgICAgc3RyaW5nMSA9IHZhbHVlMSArIFwiXCIsXG4gICAgICBpbnRlcnBvbGF0ZTA7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0cmluZzAgPSB0aGlzLmdldEF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCk7XG4gICAgcmV0dXJuIHN0cmluZzAgPT09IHN0cmluZzEgPyBudWxsIDogc3RyaW5nMCA9PT0gc3RyaW5nMDAgPyBpbnRlcnBvbGF0ZTAgOiBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0ZShzdHJpbmcwMCA9IHN0cmluZzAsIHZhbHVlMSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJGdW5jdGlvbihuYW1lLCBpbnRlcnBvbGF0ZSwgdmFsdWUpIHtcbiAgdmFyIHN0cmluZzAwLCBzdHJpbmcxMCwgaW50ZXJwb2xhdGUwO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdHJpbmcwLFxuICAgICAgICB2YWx1ZTEgPSB2YWx1ZSh0aGlzKSxcbiAgICAgICAgc3RyaW5nMTtcbiAgICBpZiAodmFsdWUxID09IG51bGwpIHJldHVybiB2b2lkIHRoaXMucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgIHN0cmluZzAgPSB0aGlzLmdldEF0dHJpYnV0ZShuYW1lKTtcbiAgICBzdHJpbmcxID0gdmFsdWUxICsgXCJcIjtcbiAgICByZXR1cm4gc3RyaW5nMCA9PT0gc3RyaW5nMSA/IG51bGwgOiBzdHJpbmcwID09PSBzdHJpbmcwMCAmJiBzdHJpbmcxID09PSBzdHJpbmcxMCA/IGludGVycG9sYXRlMCA6IChzdHJpbmcxMCA9IHN0cmluZzEsIGludGVycG9sYXRlMCA9IGludGVycG9sYXRlKHN0cmluZzAwID0gc3RyaW5nMCwgdmFsdWUxKSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJGdW5jdGlvbk5TKGZ1bGxuYW1lLCBpbnRlcnBvbGF0ZSwgdmFsdWUpIHtcbiAgdmFyIHN0cmluZzAwLCBzdHJpbmcxMCwgaW50ZXJwb2xhdGUwO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdHJpbmcwLFxuICAgICAgICB2YWx1ZTEgPSB2YWx1ZSh0aGlzKSxcbiAgICAgICAgc3RyaW5nMTtcbiAgICBpZiAodmFsdWUxID09IG51bGwpIHJldHVybiB2b2lkIHRoaXMucmVtb3ZlQXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTtcbiAgICBzdHJpbmcwID0gdGhpcy5nZXRBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5hbWUubG9jYWwpO1xuICAgIHN0cmluZzEgPSB2YWx1ZTEgKyBcIlwiO1xuICAgIHJldHVybiBzdHJpbmcwID09PSBzdHJpbmcxID8gbnVsbCA6IHN0cmluZzAgPT09IHN0cmluZzAwICYmIHN0cmluZzEgPT09IHN0cmluZzEwID8gaW50ZXJwb2xhdGUwIDogKHN0cmluZzEwID0gc3RyaW5nMSwgaW50ZXJwb2xhdGUwID0gaW50ZXJwb2xhdGUoc3RyaW5nMDAgPSBzdHJpbmcwLCB2YWx1ZTEpKTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gIHZhciBmdWxsbmFtZSA9IG5hbWVzcGFjZShuYW1lKSxcbiAgICAgIGkgPSBmdWxsbmFtZSA9PT0gXCJ0cmFuc2Zvcm1cIiA/IGludGVycG9sYXRlVHJhbnNmb3JtIDogaW50ZXJwb2xhdGU7XG4gIHJldHVybiB0aGlzLmF0dHJUd2VlbihuYW1lLCB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIiA/IChmdWxsbmFtZS5sb2NhbCA/IGF0dHJGdW5jdGlvbk5TIDogYXR0ckZ1bmN0aW9uKShmdWxsbmFtZSwgaSwgdHdlZW5WYWx1ZSh0aGlzLCBcImF0dHIuXCIgKyBuYW1lLCB2YWx1ZSkpIDogdmFsdWUgPT0gbnVsbCA/IChmdWxsbmFtZS5sb2NhbCA/IGF0dHJSZW1vdmVOUyA6IGF0dHJSZW1vdmUpKGZ1bGxuYW1lKSA6IChmdWxsbmFtZS5sb2NhbCA/IGF0dHJDb25zdGFudE5TIDogYXR0ckNvbnN0YW50KShmdWxsbmFtZSwgaSwgdmFsdWUpKTtcbn0iLCJpbXBvcnQgeyBuYW1lc3BhY2UgfSBmcm9tIFwiZDMtc2VsZWN0aW9uXCI7XG5cbmZ1bmN0aW9uIGF0dHJJbnRlcnBvbGF0ZShuYW1lLCBpKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodCkge1xuICAgIHRoaXMuc2V0QXR0cmlidXRlKG5hbWUsIGkuY2FsbCh0aGlzLCB0KSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJJbnRlcnBvbGF0ZU5TKGZ1bGxuYW1lLCBpKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodCkge1xuICAgIHRoaXMuc2V0QXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsLCBpLmNhbGwodGhpcywgdCkpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyVHdlZW5OUyhmdWxsbmFtZSwgdmFsdWUpIHtcbiAgdmFyIHQwLCBpMDtcblxuICBmdW5jdGlvbiB0d2VlbigpIHtcbiAgICB2YXIgaSA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKGkgIT09IGkwKSB0MCA9IChpMCA9IGkpICYmIGF0dHJJbnRlcnBvbGF0ZU5TKGZ1bGxuYW1lLCBpKTtcbiAgICByZXR1cm4gdDA7XG4gIH1cblxuICB0d2Vlbi5fdmFsdWUgPSB2YWx1ZTtcbiAgcmV0dXJuIHR3ZWVuO1xufVxuXG5mdW5jdGlvbiBhdHRyVHdlZW4obmFtZSwgdmFsdWUpIHtcbiAgdmFyIHQwLCBpMDtcblxuICBmdW5jdGlvbiB0d2VlbigpIHtcbiAgICB2YXIgaSA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKGkgIT09IGkwKSB0MCA9IChpMCA9IGkpICYmIGF0dHJJbnRlcnBvbGF0ZShuYW1lLCBpKTtcbiAgICByZXR1cm4gdDA7XG4gIH1cblxuICB0d2Vlbi5fdmFsdWUgPSB2YWx1ZTtcbiAgcmV0dXJuIHR3ZWVuO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgdmFyIGtleSA9IFwiYXR0ci5cIiArIG5hbWU7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikgcmV0dXJuIChrZXkgPSB0aGlzLnR3ZWVuKGtleSkpICYmIGtleS5fdmFsdWU7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSByZXR1cm4gdGhpcy50d2VlbihrZXksIG51bGwpO1xuICBpZiAodHlwZW9mIHZhbHVlICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBFcnJvcigpO1xuICB2YXIgZnVsbG5hbWUgPSBuYW1lc3BhY2UobmFtZSk7XG4gIHJldHVybiB0aGlzLnR3ZWVuKGtleSwgKGZ1bGxuYW1lLmxvY2FsID8gYXR0clR3ZWVuTlMgOiBhdHRyVHdlZW4pKGZ1bGxuYW1lLCB2YWx1ZSkpO1xufSIsImltcG9ydCB7IGdldCwgaW5pdCB9IGZyb20gXCIuL3NjaGVkdWxlLmpzXCI7XG5cbmZ1bmN0aW9uIGRlbGF5RnVuY3Rpb24oaWQsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgaW5pdCh0aGlzLCBpZCkuZGVsYXkgPSArdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGVsYXlDb25zdGFudChpZCwgdmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID0gK3ZhbHVlLCBmdW5jdGlvbiAoKSB7XG4gICAgaW5pdCh0aGlzLCBpZCkuZGVsYXkgPSB2YWx1ZTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHZhbHVlKSB7XG4gIHZhciBpZCA9IHRoaXMuX2lkO1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHRoaXMuZWFjaCgodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIgPyBkZWxheUZ1bmN0aW9uIDogZGVsYXlDb25zdGFudCkoaWQsIHZhbHVlKSkgOiBnZXQodGhpcy5ub2RlKCksIGlkKS5kZWxheTtcbn0iLCJpbXBvcnQgeyBnZXQsIHNldCB9IGZyb20gXCIuL3NjaGVkdWxlLmpzXCI7XG5cbmZ1bmN0aW9uIGR1cmF0aW9uRnVuY3Rpb24oaWQsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgc2V0KHRoaXMsIGlkKS5kdXJhdGlvbiA9ICt2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBkdXJhdGlvbkNvbnN0YW50KGlkLCB2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPSArdmFsdWUsIGZ1bmN0aW9uICgpIHtcbiAgICBzZXQodGhpcywgaWQpLmR1cmF0aW9uID0gdmFsdWU7XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB2YXIgaWQgPSB0aGlzLl9pZDtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLmVhY2goKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gZHVyYXRpb25GdW5jdGlvbiA6IGR1cmF0aW9uQ29uc3RhbnQpKGlkLCB2YWx1ZSkpIDogZ2V0KHRoaXMubm9kZSgpLCBpZCkuZHVyYXRpb247XG59IiwiaW1wb3J0IHsgZ2V0LCBzZXQgfSBmcm9tIFwiLi9zY2hlZHVsZS5qc1wiO1xuXG5mdW5jdGlvbiBlYXNlQ29uc3RhbnQoaWQsIHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IEVycm9yKCk7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgc2V0KHRoaXMsIGlkKS5lYXNlID0gdmFsdWU7XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB2YXIgaWQgPSB0aGlzLl9pZDtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLmVhY2goZWFzZUNvbnN0YW50KGlkLCB2YWx1ZSkpIDogZ2V0KHRoaXMubm9kZSgpLCBpZCkuZWFzZTtcbn0iLCJpbXBvcnQgeyBzZXQgfSBmcm9tIFwiLi9zY2hlZHVsZS5qc1wiO1xuXG5mdW5jdGlvbiBlYXNlVmFyeWluZyhpZCwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKHR5cGVvZiB2ICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBFcnJvcigpO1xuICAgIHNldCh0aGlzLCBpZCkuZWFzZSA9IHY7XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICh2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBFcnJvcigpO1xuICByZXR1cm4gdGhpcy5lYWNoKGVhc2VWYXJ5aW5nKHRoaXMuX2lkLCB2YWx1ZSkpO1xufSIsImltcG9ydCB7IG1hdGNoZXIgfSBmcm9tIFwiZDMtc2VsZWN0aW9uXCI7XG5pbXBvcnQgeyBUcmFuc2l0aW9uIH0gZnJvbSBcIi4vaW5kZXguanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChtYXRjaCkge1xuICBpZiAodHlwZW9mIG1hdGNoICE9PSBcImZ1bmN0aW9uXCIpIG1hdGNoID0gbWF0Y2hlcihtYXRjaCk7XG5cbiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBtID0gZ3JvdXBzLmxlbmd0aCwgc3ViZ3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBzdWJncm91cCA9IHN1Ymdyb3Vwc1tqXSA9IFtdLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKChub2RlID0gZ3JvdXBbaV0pICYmIG1hdGNoLmNhbGwobm9kZSwgbm9kZS5fX2RhdGFfXywgaSwgZ3JvdXApKSB7XG4gICAgICAgIHN1Ymdyb3VwLnB1c2gobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKHN1Ymdyb3VwcywgdGhpcy5fcGFyZW50cywgdGhpcy5fbmFtZSwgdGhpcy5faWQpO1xufSIsImltcG9ydCB7IFRyYW5zaXRpb24gfSBmcm9tIFwiLi9pbmRleC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHRyYW5zaXRpb24pIHtcbiAgaWYgKHRyYW5zaXRpb24uX2lkICE9PSB0aGlzLl9pZCkgdGhyb3cgbmV3IEVycm9yKCk7XG5cbiAgZm9yICh2YXIgZ3JvdXBzMCA9IHRoaXMuX2dyb3VwcywgZ3JvdXBzMSA9IHRyYW5zaXRpb24uX2dyb3VwcywgbTAgPSBncm91cHMwLmxlbmd0aCwgbTEgPSBncm91cHMxLmxlbmd0aCwgbSA9IE1hdGgubWluKG0wLCBtMSksIG1lcmdlcyA9IG5ldyBBcnJheShtMCksIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAwID0gZ3JvdXBzMFtqXSwgZ3JvdXAxID0gZ3JvdXBzMVtqXSwgbiA9IGdyb3VwMC5sZW5ndGgsIG1lcmdlID0gbWVyZ2VzW2pdID0gbmV3IEFycmF5KG4pLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cDBbaV0gfHwgZ3JvdXAxW2ldKSB7XG4gICAgICAgIG1lcmdlW2ldID0gbm9kZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3IgKDsgaiA8IG0wOyArK2opIHtcbiAgICBtZXJnZXNbal0gPSBncm91cHMwW2pdO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKG1lcmdlcywgdGhpcy5fcGFyZW50cywgdGhpcy5fbmFtZSwgdGhpcy5faWQpO1xufSIsImltcG9ydCB7IGdldCwgc2V0LCBpbml0IH0gZnJvbSBcIi4vc2NoZWR1bGUuanNcIjtcblxuZnVuY3Rpb24gc3RhcnQobmFtZSkge1xuICByZXR1cm4gKG5hbWUgKyBcIlwiKS50cmltKCkuc3BsaXQoL158XFxzKy8pLmV2ZXJ5KGZ1bmN0aW9uICh0KSB7XG4gICAgdmFyIGkgPSB0LmluZGV4T2YoXCIuXCIpO1xuICAgIGlmIChpID49IDApIHQgPSB0LnNsaWNlKDAsIGkpO1xuICAgIHJldHVybiAhdCB8fCB0ID09PSBcInN0YXJ0XCI7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBvbkZ1bmN0aW9uKGlkLCBuYW1lLCBsaXN0ZW5lcikge1xuICB2YXIgb24wLFxuICAgICAgb24xLFxuICAgICAgc2l0ID0gc3RhcnQobmFtZSkgPyBpbml0IDogc2V0O1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzY2hlZHVsZSA9IHNpdCh0aGlzLCBpZCksXG4gICAgICAgIG9uID0gc2NoZWR1bGUub247IC8vIElmIHRoaXMgbm9kZSBzaGFyZWQgYSBkaXNwYXRjaCB3aXRoIHRoZSBwcmV2aW91cyBub2RlLFxuICAgIC8vIGp1c3QgYXNzaWduIHRoZSB1cGRhdGVkIHNoYXJlZCBkaXNwYXRjaCBhbmQgd2XigJlyZSBkb25lIVxuICAgIC8vIE90aGVyd2lzZSwgY29weS1vbi13cml0ZS5cblxuICAgIGlmIChvbiAhPT0gb24wKSAob24xID0gKG9uMCA9IG9uKS5jb3B5KCkpLm9uKG5hbWUsIGxpc3RlbmVyKTtcbiAgICBzY2hlZHVsZS5vbiA9IG9uMTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG5hbWUsIGxpc3RlbmVyKSB7XG4gIHZhciBpZCA9IHRoaXMuX2lkO1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA8IDIgPyBnZXQodGhpcy5ub2RlKCksIGlkKS5vbi5vbihuYW1lKSA6IHRoaXMuZWFjaChvbkZ1bmN0aW9uKGlkLCBuYW1lLCBsaXN0ZW5lcikpO1xufSIsImZ1bmN0aW9uIHJlbW92ZUZ1bmN0aW9uKGlkKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50Tm9kZTtcblxuICAgIGZvciAodmFyIGkgaW4gdGhpcy5fX3RyYW5zaXRpb24pIHtcbiAgICAgIGlmICgraSAhPT0gaWQpIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFyZW50KSBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcyk7XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMub24oXCJlbmQucmVtb3ZlXCIsIHJlbW92ZUZ1bmN0aW9uKHRoaXMuX2lkKSk7XG59IiwiaW1wb3J0IHsgc2VsZWN0b3IgfSBmcm9tIFwiZDMtc2VsZWN0aW9uXCI7XG5pbXBvcnQgeyBUcmFuc2l0aW9uIH0gZnJvbSBcIi4vaW5kZXguanNcIjtcbmltcG9ydCBzY2hlZHVsZSwgeyBnZXQgfSBmcm9tIFwiLi9zY2hlZHVsZS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHNlbGVjdCkge1xuICB2YXIgbmFtZSA9IHRoaXMuX25hbWUsXG4gICAgICBpZCA9IHRoaXMuX2lkO1xuICBpZiAodHlwZW9mIHNlbGVjdCAhPT0gXCJmdW5jdGlvblwiKSBzZWxlY3QgPSBzZWxlY3RvcihzZWxlY3QpO1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIHN1Ymdyb3VwcyA9IG5ldyBBcnJheShtKSwgaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICBmb3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgbiA9IGdyb3VwLmxlbmd0aCwgc3ViZ3JvdXAgPSBzdWJncm91cHNbal0gPSBuZXcgQXJyYXkobiksIG5vZGUsIHN1Ym5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAoKG5vZGUgPSBncm91cFtpXSkgJiYgKHN1Ym5vZGUgPSBzZWxlY3QuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkpKSB7XG4gICAgICAgIGlmIChcIl9fZGF0YV9fXCIgaW4gbm9kZSkgc3Vibm9kZS5fX2RhdGFfXyA9IG5vZGUuX19kYXRhX187XG4gICAgICAgIHN1Ymdyb3VwW2ldID0gc3Vibm9kZTtcbiAgICAgICAgc2NoZWR1bGUoc3ViZ3JvdXBbaV0sIG5hbWUsIGlkLCBpLCBzdWJncm91cCwgZ2V0KG5vZGUsIGlkKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKHN1Ymdyb3VwcywgdGhpcy5fcGFyZW50cywgbmFtZSwgaWQpO1xufSIsImltcG9ydCB7IHNlbGVjdG9yQWxsIH0gZnJvbSBcImQzLXNlbGVjdGlvblwiO1xuaW1wb3J0IHsgVHJhbnNpdGlvbiB9IGZyb20gXCIuL2luZGV4LmpzXCI7XG5pbXBvcnQgc2NoZWR1bGUsIHsgZ2V0IH0gZnJvbSBcIi4vc2NoZWR1bGUuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzZWxlY3QpIHtcbiAgdmFyIG5hbWUgPSB0aGlzLl9uYW1lLFxuICAgICAgaWQgPSB0aGlzLl9pZDtcbiAgaWYgKHR5cGVvZiBzZWxlY3QgIT09IFwiZnVuY3Rpb25cIikgc2VsZWN0ID0gc2VsZWN0b3JBbGwoc2VsZWN0KTtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzdWJncm91cHMgPSBbXSwgcGFyZW50cyA9IFtdLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICBmb3IgKHZhciBjaGlsZHJlbiA9IHNlbGVjdC5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKSwgY2hpbGQsIGluaGVyaXQgPSBnZXQobm9kZSwgaWQpLCBrID0gMCwgbCA9IGNoaWxkcmVuLmxlbmd0aDsgayA8IGw7ICsraykge1xuICAgICAgICAgIGlmIChjaGlsZCA9IGNoaWxkcmVuW2tdKSB7XG4gICAgICAgICAgICBzY2hlZHVsZShjaGlsZCwgbmFtZSwgaWQsIGssIGNoaWxkcmVuLCBpbmhlcml0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzdWJncm91cHMucHVzaChjaGlsZHJlbik7XG4gICAgICAgIHBhcmVudHMucHVzaChub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IFRyYW5zaXRpb24oc3ViZ3JvdXBzLCBwYXJlbnRzLCBuYW1lLCBpZCk7XG59IiwiaW1wb3J0IHsgc2VsZWN0aW9uIH0gZnJvbSBcImQzLXNlbGVjdGlvblwiO1xudmFyIFNlbGVjdGlvbiA9IHNlbGVjdGlvbi5wcm90b3R5cGUuY29uc3RydWN0b3I7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKHRoaXMuX2dyb3VwcywgdGhpcy5fcGFyZW50cyk7XG59IiwiaW1wb3J0IHsgaW50ZXJwb2xhdGVUcmFuc2Zvcm1Dc3MgYXMgaW50ZXJwb2xhdGVUcmFuc2Zvcm0gfSBmcm9tIFwiZDMtaW50ZXJwb2xhdGVcIjtcbmltcG9ydCB7IHN0eWxlIH0gZnJvbSBcImQzLXNlbGVjdGlvblwiO1xuaW1wb3J0IHsgc2V0IH0gZnJvbSBcIi4vc2NoZWR1bGUuanNcIjtcbmltcG9ydCB7IHR3ZWVuVmFsdWUgfSBmcm9tIFwiLi90d2Vlbi5qc1wiO1xuaW1wb3J0IGludGVycG9sYXRlIGZyb20gXCIuL2ludGVycG9sYXRlLmpzXCI7XG5cbmZ1bmN0aW9uIHN0eWxlTnVsbChuYW1lLCBpbnRlcnBvbGF0ZSkge1xuICB2YXIgc3RyaW5nMDAsIHN0cmluZzEwLCBpbnRlcnBvbGF0ZTA7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0cmluZzAgPSBzdHlsZSh0aGlzLCBuYW1lKSxcbiAgICAgICAgc3RyaW5nMSA9ICh0aGlzLnN0eWxlLnJlbW92ZVByb3BlcnR5KG5hbWUpLCBzdHlsZSh0aGlzLCBuYW1lKSk7XG4gICAgcmV0dXJuIHN0cmluZzAgPT09IHN0cmluZzEgPyBudWxsIDogc3RyaW5nMCA9PT0gc3RyaW5nMDAgJiYgc3RyaW5nMSA9PT0gc3RyaW5nMTAgPyBpbnRlcnBvbGF0ZTAgOiBpbnRlcnBvbGF0ZTAgPSBpbnRlcnBvbGF0ZShzdHJpbmcwMCA9IHN0cmluZzAsIHN0cmluZzEwID0gc3RyaW5nMSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHN0eWxlUmVtb3ZlKG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnN0eWxlLnJlbW92ZVByb3BlcnR5KG5hbWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdHlsZUNvbnN0YW50KG5hbWUsIGludGVycG9sYXRlLCB2YWx1ZTEpIHtcbiAgdmFyIHN0cmluZzAwLFxuICAgICAgc3RyaW5nMSA9IHZhbHVlMSArIFwiXCIsXG4gICAgICBpbnRlcnBvbGF0ZTA7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0cmluZzAgPSBzdHlsZSh0aGlzLCBuYW1lKTtcbiAgICByZXR1cm4gc3RyaW5nMCA9PT0gc3RyaW5nMSA/IG51bGwgOiBzdHJpbmcwID09PSBzdHJpbmcwMCA/IGludGVycG9sYXRlMCA6IGludGVycG9sYXRlMCA9IGludGVycG9sYXRlKHN0cmluZzAwID0gc3RyaW5nMCwgdmFsdWUxKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3R5bGVGdW5jdGlvbihuYW1lLCBpbnRlcnBvbGF0ZSwgdmFsdWUpIHtcbiAgdmFyIHN0cmluZzAwLCBzdHJpbmcxMCwgaW50ZXJwb2xhdGUwO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdHJpbmcwID0gc3R5bGUodGhpcywgbmFtZSksXG4gICAgICAgIHZhbHVlMSA9IHZhbHVlKHRoaXMpLFxuICAgICAgICBzdHJpbmcxID0gdmFsdWUxICsgXCJcIjtcbiAgICBpZiAodmFsdWUxID09IG51bGwpIHN0cmluZzEgPSB2YWx1ZTEgPSAodGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKSwgc3R5bGUodGhpcywgbmFtZSkpO1xuICAgIHJldHVybiBzdHJpbmcwID09PSBzdHJpbmcxID8gbnVsbCA6IHN0cmluZzAgPT09IHN0cmluZzAwICYmIHN0cmluZzEgPT09IHN0cmluZzEwID8gaW50ZXJwb2xhdGUwIDogKHN0cmluZzEwID0gc3RyaW5nMSwgaW50ZXJwb2xhdGUwID0gaW50ZXJwb2xhdGUoc3RyaW5nMDAgPSBzdHJpbmcwLCB2YWx1ZTEpKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3R5bGVNYXliZVJlbW92ZShpZCwgbmFtZSkge1xuICB2YXIgb24wLFxuICAgICAgb24xLFxuICAgICAgbGlzdGVuZXIwLFxuICAgICAga2V5ID0gXCJzdHlsZS5cIiArIG5hbWUsXG4gICAgICBldmVudCA9IFwiZW5kLlwiICsga2V5LFxuICAgICAgcmVtb3ZlO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzY2hlZHVsZSA9IHNldCh0aGlzLCBpZCksXG4gICAgICAgIG9uID0gc2NoZWR1bGUub24sXG4gICAgICAgIGxpc3RlbmVyID0gc2NoZWR1bGUudmFsdWVba2V5XSA9PSBudWxsID8gcmVtb3ZlIHx8IChyZW1vdmUgPSBzdHlsZVJlbW92ZShuYW1lKSkgOiB1bmRlZmluZWQ7IC8vIElmIHRoaXMgbm9kZSBzaGFyZWQgYSBkaXNwYXRjaCB3aXRoIHRoZSBwcmV2aW91cyBub2RlLFxuICAgIC8vIGp1c3QgYXNzaWduIHRoZSB1cGRhdGVkIHNoYXJlZCBkaXNwYXRjaCBhbmQgd2XigJlyZSBkb25lIVxuICAgIC8vIE90aGVyd2lzZSwgY29weS1vbi13cml0ZS5cblxuICAgIGlmIChvbiAhPT0gb24wIHx8IGxpc3RlbmVyMCAhPT0gbGlzdGVuZXIpIChvbjEgPSAob24wID0gb24pLmNvcHkoKSkub24oZXZlbnQsIGxpc3RlbmVyMCA9IGxpc3RlbmVyKTtcbiAgICBzY2hlZHVsZS5vbiA9IG9uMTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG5hbWUsIHZhbHVlLCBwcmlvcml0eSkge1xuICB2YXIgaSA9IChuYW1lICs9IFwiXCIpID09PSBcInRyYW5zZm9ybVwiID8gaW50ZXJwb2xhdGVUcmFuc2Zvcm0gOiBpbnRlcnBvbGF0ZTtcbiAgcmV0dXJuIHZhbHVlID09IG51bGwgPyB0aGlzLnN0eWxlVHdlZW4obmFtZSwgc3R5bGVOdWxsKG5hbWUsIGkpKS5vbihcImVuZC5zdHlsZS5cIiArIG5hbWUsIHN0eWxlUmVtb3ZlKG5hbWUpKSA6IHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gdGhpcy5zdHlsZVR3ZWVuKG5hbWUsIHN0eWxlRnVuY3Rpb24obmFtZSwgaSwgdHdlZW5WYWx1ZSh0aGlzLCBcInN0eWxlLlwiICsgbmFtZSwgdmFsdWUpKSkuZWFjaChzdHlsZU1heWJlUmVtb3ZlKHRoaXMuX2lkLCBuYW1lKSkgOiB0aGlzLnN0eWxlVHdlZW4obmFtZSwgc3R5bGVDb25zdGFudChuYW1lLCBpLCB2YWx1ZSksIHByaW9yaXR5KS5vbihcImVuZC5zdHlsZS5cIiArIG5hbWUsIG51bGwpO1xufSIsImZ1bmN0aW9uIHN0eWxlSW50ZXJwb2xhdGUobmFtZSwgaSwgcHJpb3JpdHkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh0KSB7XG4gICAgdGhpcy5zdHlsZS5zZXRQcm9wZXJ0eShuYW1lLCBpLmNhbGwodGhpcywgdCksIHByaW9yaXR5KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3R5bGVUd2VlbihuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpIHtcbiAgdmFyIHQsIGkwO1xuXG4gIGZ1bmN0aW9uIHR3ZWVuKCkge1xuICAgIHZhciBpID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBpZiAoaSAhPT0gaTApIHQgPSAoaTAgPSBpKSAmJiBzdHlsZUludGVycG9sYXRlKG5hbWUsIGksIHByaW9yaXR5KTtcbiAgICByZXR1cm4gdDtcbiAgfVxuXG4gIHR3ZWVuLl92YWx1ZSA9IHZhbHVlO1xuICByZXR1cm4gdHdlZW47XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgcHJpb3JpdHkpIHtcbiAgdmFyIGtleSA9IFwic3R5bGUuXCIgKyAobmFtZSArPSBcIlwiKTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSByZXR1cm4gKGtleSA9IHRoaXMudHdlZW4oa2V5KSkgJiYga2V5Ll92YWx1ZTtcbiAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiB0aGlzLnR3ZWVuKGtleSwgbnVsbCk7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IEVycm9yKCk7XG4gIHJldHVybiB0aGlzLnR3ZWVuKGtleSwgc3R5bGVUd2VlbihuYW1lLCB2YWx1ZSwgcHJpb3JpdHkgPT0gbnVsbCA/IFwiXCIgOiBwcmlvcml0eSkpO1xufSIsImltcG9ydCB7IHR3ZWVuVmFsdWUgfSBmcm9tIFwiLi90d2Vlbi5qc1wiO1xuXG5mdW5jdGlvbiB0ZXh0Q29uc3RhbnQodmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRleHRDb250ZW50ID0gdmFsdWU7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHRleHRGdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZTEgPSB2YWx1ZSh0aGlzKTtcbiAgICB0aGlzLnRleHRDb250ZW50ID0gdmFsdWUxID09IG51bGwgPyBcIlwiIDogdmFsdWUxO1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMudHdlZW4oXCJ0ZXh0XCIsIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiID8gdGV4dEZ1bmN0aW9uKHR3ZWVuVmFsdWUodGhpcywgXCJ0ZXh0XCIsIHZhbHVlKSkgOiB0ZXh0Q29uc3RhbnQodmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSArIFwiXCIpKTtcbn0iLCJmdW5jdGlvbiB0ZXh0SW50ZXJwb2xhdGUoaSkge1xuICByZXR1cm4gZnVuY3Rpb24gKHQpIHtcbiAgICB0aGlzLnRleHRDb250ZW50ID0gaS5jYWxsKHRoaXMsIHQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiB0ZXh0VHdlZW4odmFsdWUpIHtcbiAgdmFyIHQwLCBpMDtcblxuICBmdW5jdGlvbiB0d2VlbigpIHtcbiAgICB2YXIgaSA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKGkgIT09IGkwKSB0MCA9IChpMCA9IGkpICYmIHRleHRJbnRlcnBvbGF0ZShpKTtcbiAgICByZXR1cm4gdDA7XG4gIH1cblxuICB0d2Vlbi5fdmFsdWUgPSB2YWx1ZTtcbiAgcmV0dXJuIHR3ZWVuO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgdmFyIGtleSA9IFwidGV4dFwiO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDEpIHJldHVybiAoa2V5ID0gdGhpcy50d2VlbihrZXkpKSAmJiBrZXkuX3ZhbHVlO1xuICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIHRoaXMudHdlZW4oa2V5LCBudWxsKTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgcmV0dXJuIHRoaXMudHdlZW4oa2V5LCB0ZXh0VHdlZW4odmFsdWUpKTtcbn0iLCJpbXBvcnQgeyBUcmFuc2l0aW9uLCBuZXdJZCB9IGZyb20gXCIuL2luZGV4LmpzXCI7XG5pbXBvcnQgc2NoZWR1bGUsIHsgZ2V0IH0gZnJvbSBcIi4vc2NoZWR1bGUuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5hbWUgPSB0aGlzLl9uYW1lLFxuICAgICAgaWQwID0gdGhpcy5faWQsXG4gICAgICBpZDEgPSBuZXdJZCgpO1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICAgIHZhciBpbmhlcml0ID0gZ2V0KG5vZGUsIGlkMCk7XG4gICAgICAgIHNjaGVkdWxlKG5vZGUsIG5hbWUsIGlkMSwgaSwgZ3JvdXAsIHtcbiAgICAgICAgICB0aW1lOiBpbmhlcml0LnRpbWUgKyBpbmhlcml0LmRlbGF5ICsgaW5oZXJpdC5kdXJhdGlvbixcbiAgICAgICAgICBkZWxheTogMCxcbiAgICAgICAgICBkdXJhdGlvbjogaW5oZXJpdC5kdXJhdGlvbixcbiAgICAgICAgICBlYXNlOiBpbmhlcml0LmVhc2VcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKGdyb3VwcywgdGhpcy5fcGFyZW50cywgbmFtZSwgaWQxKTtcbn0iLCJpbXBvcnQgeyBzZXQgfSBmcm9tIFwiLi9zY2hlZHVsZS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKCkge1xuICB2YXIgb24wLFxuICAgICAgb24xLFxuICAgICAgdGhhdCA9IHRoaXMsXG4gICAgICBpZCA9IHRoYXQuX2lkLFxuICAgICAgc2l6ZSA9IHRoYXQuc2l6ZSgpO1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciBjYW5jZWwgPSB7XG4gICAgICB2YWx1ZTogcmVqZWN0XG4gICAgfSxcbiAgICAgICAgZW5kID0ge1xuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKCkge1xuICAgICAgICBpZiAoLS1zaXplID09PSAwKSByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfTtcbiAgICB0aGF0LmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHNjaGVkdWxlID0gc2V0KHRoaXMsIGlkKSxcbiAgICAgICAgICBvbiA9IHNjaGVkdWxlLm9uOyAvLyBJZiB0aGlzIG5vZGUgc2hhcmVkIGEgZGlzcGF0Y2ggd2l0aCB0aGUgcHJldmlvdXMgbm9kZSxcbiAgICAgIC8vIGp1c3QgYXNzaWduIHRoZSB1cGRhdGVkIHNoYXJlZCBkaXNwYXRjaCBhbmQgd2XigJlyZSBkb25lIVxuICAgICAgLy8gT3RoZXJ3aXNlLCBjb3B5LW9uLXdyaXRlLlxuXG4gICAgICBpZiAob24gIT09IG9uMCkge1xuICAgICAgICBvbjEgPSAob24wID0gb24pLmNvcHkoKTtcblxuICAgICAgICBvbjEuXy5jYW5jZWwucHVzaChjYW5jZWwpO1xuXG4gICAgICAgIG9uMS5fLmludGVycnVwdC5wdXNoKGNhbmNlbCk7XG5cbiAgICAgICAgb24xLl8uZW5kLnB1c2goZW5kKTtcbiAgICAgIH1cblxuICAgICAgc2NoZWR1bGUub24gPSBvbjE7XG4gICAgfSk7IC8vIFRoZSBzZWxlY3Rpb24gd2FzIGVtcHR5LCByZXNvbHZlIGVuZCBpbW1lZGlhdGVseVxuXG4gICAgaWYgKHNpemUgPT09IDApIHJlc29sdmUoKTtcbiAgfSk7XG59IiwiaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiL2hvbWUvcnVubmVyL3dvcmsvanVzdGljZTQwLXRvb2wvanVzdGljZTQwLXRvb2wvY2xpZW50L25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuaW1wb3J0IHsgc2VsZWN0aW9uIH0gZnJvbSBcImQzLXNlbGVjdGlvblwiO1xuaW1wb3J0IHRyYW5zaXRpb25fYXR0ciBmcm9tIFwiLi9hdHRyLmpzXCI7XG5pbXBvcnQgdHJhbnNpdGlvbl9hdHRyVHdlZW4gZnJvbSBcIi4vYXR0clR3ZWVuLmpzXCI7XG5pbXBvcnQgdHJhbnNpdGlvbl9kZWxheSBmcm9tIFwiLi9kZWxheS5qc1wiO1xuaW1wb3J0IHRyYW5zaXRpb25fZHVyYXRpb24gZnJvbSBcIi4vZHVyYXRpb24uanNcIjtcbmltcG9ydCB0cmFuc2l0aW9uX2Vhc2UgZnJvbSBcIi4vZWFzZS5qc1wiO1xuaW1wb3J0IHRyYW5zaXRpb25fZWFzZVZhcnlpbmcgZnJvbSBcIi4vZWFzZVZhcnlpbmcuanNcIjtcbmltcG9ydCB0cmFuc2l0aW9uX2ZpbHRlciBmcm9tIFwiLi9maWx0ZXIuanNcIjtcbmltcG9ydCB0cmFuc2l0aW9uX21lcmdlIGZyb20gXCIuL21lcmdlLmpzXCI7XG5pbXBvcnQgdHJhbnNpdGlvbl9vbiBmcm9tIFwiLi9vbi5qc1wiO1xuaW1wb3J0IHRyYW5zaXRpb25fcmVtb3ZlIGZyb20gXCIuL3JlbW92ZS5qc1wiO1xuaW1wb3J0IHRyYW5zaXRpb25fc2VsZWN0IGZyb20gXCIuL3NlbGVjdC5qc1wiO1xuaW1wb3J0IHRyYW5zaXRpb25fc2VsZWN0QWxsIGZyb20gXCIuL3NlbGVjdEFsbC5qc1wiO1xuaW1wb3J0IHRyYW5zaXRpb25fc2VsZWN0aW9uIGZyb20gXCIuL3NlbGVjdGlvbi5qc1wiO1xuaW1wb3J0IHRyYW5zaXRpb25fc3R5bGUgZnJvbSBcIi4vc3R5bGUuanNcIjtcbmltcG9ydCB0cmFuc2l0aW9uX3N0eWxlVHdlZW4gZnJvbSBcIi4vc3R5bGVUd2Vlbi5qc1wiO1xuaW1wb3J0IHRyYW5zaXRpb25fdGV4dCBmcm9tIFwiLi90ZXh0LmpzXCI7XG5pbXBvcnQgdHJhbnNpdGlvbl90ZXh0VHdlZW4gZnJvbSBcIi4vdGV4dFR3ZWVuLmpzXCI7XG5pbXBvcnQgdHJhbnNpdGlvbl90cmFuc2l0aW9uIGZyb20gXCIuL3RyYW5zaXRpb24uanNcIjtcbmltcG9ydCB0cmFuc2l0aW9uX3R3ZWVuIGZyb20gXCIuL3R3ZWVuLmpzXCI7XG5pbXBvcnQgdHJhbnNpdGlvbl9lbmQgZnJvbSBcIi4vZW5kLmpzXCI7XG52YXIgaWQgPSAwO1xuZXhwb3J0IGZ1bmN0aW9uIFRyYW5zaXRpb24oZ3JvdXBzLCBwYXJlbnRzLCBuYW1lLCBpZCkge1xuICB0aGlzLl9ncm91cHMgPSBncm91cHM7XG4gIHRoaXMuX3BhcmVudHMgPSBwYXJlbnRzO1xuICB0aGlzLl9uYW1lID0gbmFtZTtcbiAgdGhpcy5faWQgPSBpZDtcbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRyYW5zaXRpb24obmFtZSkge1xuICByZXR1cm4gc2VsZWN0aW9uKCkudHJhbnNpdGlvbihuYW1lKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBuZXdJZCgpIHtcbiAgcmV0dXJuICsraWQ7XG59XG52YXIgc2VsZWN0aW9uX3Byb3RvdHlwZSA9IHNlbGVjdGlvbi5wcm90b3R5cGU7XG5UcmFuc2l0aW9uLnByb3RvdHlwZSA9IHRyYW5zaXRpb24ucHJvdG90eXBlID0gX2RlZmluZVByb3BlcnR5KHtcbiAgY29uc3RydWN0b3I6IFRyYW5zaXRpb24sXG4gIHNlbGVjdDogdHJhbnNpdGlvbl9zZWxlY3QsXG4gIHNlbGVjdEFsbDogdHJhbnNpdGlvbl9zZWxlY3RBbGwsXG4gIHNlbGVjdENoaWxkOiBzZWxlY3Rpb25fcHJvdG90eXBlLnNlbGVjdENoaWxkLFxuICBzZWxlY3RDaGlsZHJlbjogc2VsZWN0aW9uX3Byb3RvdHlwZS5zZWxlY3RDaGlsZHJlbixcbiAgZmlsdGVyOiB0cmFuc2l0aW9uX2ZpbHRlcixcbiAgbWVyZ2U6IHRyYW5zaXRpb25fbWVyZ2UsXG4gIHNlbGVjdGlvbjogdHJhbnNpdGlvbl9zZWxlY3Rpb24sXG4gIHRyYW5zaXRpb246IHRyYW5zaXRpb25fdHJhbnNpdGlvbixcbiAgY2FsbDogc2VsZWN0aW9uX3Byb3RvdHlwZS5jYWxsLFxuICBub2Rlczogc2VsZWN0aW9uX3Byb3RvdHlwZS5ub2RlcyxcbiAgbm9kZTogc2VsZWN0aW9uX3Byb3RvdHlwZS5ub2RlLFxuICBzaXplOiBzZWxlY3Rpb25fcHJvdG90eXBlLnNpemUsXG4gIGVtcHR5OiBzZWxlY3Rpb25fcHJvdG90eXBlLmVtcHR5LFxuICBlYWNoOiBzZWxlY3Rpb25fcHJvdG90eXBlLmVhY2gsXG4gIG9uOiB0cmFuc2l0aW9uX29uLFxuICBhdHRyOiB0cmFuc2l0aW9uX2F0dHIsXG4gIGF0dHJUd2VlbjogdHJhbnNpdGlvbl9hdHRyVHdlZW4sXG4gIHN0eWxlOiB0cmFuc2l0aW9uX3N0eWxlLFxuICBzdHlsZVR3ZWVuOiB0cmFuc2l0aW9uX3N0eWxlVHdlZW4sXG4gIHRleHQ6IHRyYW5zaXRpb25fdGV4dCxcbiAgdGV4dFR3ZWVuOiB0cmFuc2l0aW9uX3RleHRUd2VlbixcbiAgcmVtb3ZlOiB0cmFuc2l0aW9uX3JlbW92ZSxcbiAgdHdlZW46IHRyYW5zaXRpb25fdHdlZW4sXG4gIGRlbGF5OiB0cmFuc2l0aW9uX2RlbGF5LFxuICBkdXJhdGlvbjogdHJhbnNpdGlvbl9kdXJhdGlvbixcbiAgZWFzZTogdHJhbnNpdGlvbl9lYXNlLFxuICBlYXNlVmFyeWluZzogdHJhbnNpdGlvbl9lYXNlVmFyeWluZyxcbiAgZW5kOiB0cmFuc2l0aW9uX2VuZFxufSwgU3ltYm9sLml0ZXJhdG9yLCBzZWxlY3Rpb25fcHJvdG90eXBlW1N5bWJvbC5pdGVyYXRvcl0pOyIsImV4cG9ydCBmdW5jdGlvbiBjdWJpY0luKHQpIHtcbiAgcmV0dXJuIHQgKiB0ICogdDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjdWJpY091dCh0KSB7XG4gIHJldHVybiAtLXQgKiB0ICogdCArIDE7XG59XG5leHBvcnQgZnVuY3Rpb24gY3ViaWNJbk91dCh0KSB7XG4gIHJldHVybiAoKHQgKj0gMikgPD0gMSA/IHQgKiB0ICogdCA6ICh0IC09IDIpICogdCAqIHQgKyAyKSAvIDI7XG59IiwiaW1wb3J0IHsgVHJhbnNpdGlvbiwgbmV3SWQgfSBmcm9tIFwiLi4vdHJhbnNpdGlvbi9pbmRleC5qc1wiO1xuaW1wb3J0IHNjaGVkdWxlIGZyb20gXCIuLi90cmFuc2l0aW9uL3NjaGVkdWxlLmpzXCI7XG5pbXBvcnQgeyBlYXNlQ3ViaWNJbk91dCB9IGZyb20gXCJkMy1lYXNlXCI7XG5pbXBvcnQgeyBub3cgfSBmcm9tIFwiZDMtdGltZXJcIjtcbnZhciBkZWZhdWx0VGltaW5nID0ge1xuICB0aW1lOiBudWxsLFxuICAvLyBTZXQgb24gdXNlLlxuICBkZWxheTogMCxcbiAgZHVyYXRpb246IDI1MCxcbiAgZWFzZTogZWFzZUN1YmljSW5PdXRcbn07XG5cbmZ1bmN0aW9uIGluaGVyaXQobm9kZSwgaWQpIHtcbiAgdmFyIHRpbWluZztcblxuICB3aGlsZSAoISh0aW1pbmcgPSBub2RlLl9fdHJhbnNpdGlvbikgfHwgISh0aW1pbmcgPSB0aW1pbmdbaWRdKSkge1xuICAgIGlmICghKG5vZGUgPSBub2RlLnBhcmVudE5vZGUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0cmFuc2l0aW9uIFwiLmNvbmNhdChpZCwgXCIgbm90IGZvdW5kXCIpKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGltaW5nO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAobmFtZSkge1xuICB2YXIgaWQsIHRpbWluZztcblxuICBpZiAobmFtZSBpbnN0YW5jZW9mIFRyYW5zaXRpb24pIHtcbiAgICBpZCA9IG5hbWUuX2lkLCBuYW1lID0gbmFtZS5fbmFtZTtcbiAgfSBlbHNlIHtcbiAgICBpZCA9IG5ld0lkKCksICh0aW1pbmcgPSBkZWZhdWx0VGltaW5nKS50aW1lID0gbm93KCksIG5hbWUgPSBuYW1lID09IG51bGwgPyBudWxsIDogbmFtZSArIFwiXCI7XG4gIH1cblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICBzY2hlZHVsZShub2RlLCBuYW1lLCBpZCwgaSwgZ3JvdXAsIHRpbWluZyB8fCBpbmhlcml0KG5vZGUsIGlkKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBUcmFuc2l0aW9uKGdyb3VwcywgdGhpcy5fcGFyZW50cywgbmFtZSwgaWQpO1xufSIsImltcG9ydCB7IHNlbGVjdGlvbiB9IGZyb20gXCJkMy1zZWxlY3Rpb25cIjtcbmltcG9ydCBzZWxlY3Rpb25faW50ZXJydXB0IGZyb20gXCIuL2ludGVycnVwdC5qc1wiO1xuaW1wb3J0IHNlbGVjdGlvbl90cmFuc2l0aW9uIGZyb20gXCIuL3RyYW5zaXRpb24uanNcIjtcbnNlbGVjdGlvbi5wcm90b3R5cGUuaW50ZXJydXB0ID0gc2VsZWN0aW9uX2ludGVycnVwdDtcbnNlbGVjdGlvbi5wcm90b3R5cGUudHJhbnNpdGlvbiA9IHNlbGVjdGlvbl90cmFuc2l0aW9uOyIsImltcG9ydCBcIi4vc2VsZWN0aW9uL2luZGV4LmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHRyYW5zaXRpb24gfSBmcm9tIFwiLi90cmFuc2l0aW9uL2luZGV4LmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGFjdGl2ZSB9IGZyb20gXCIuL2FjdGl2ZS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnJ1cHQgfSBmcm9tIFwiLi9pbnRlcnJ1cHQuanNcIjsiLCJmdW5jdGlvbiBfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlcihvLCBhbGxvd0FycmF5TGlrZSkgeyB2YXIgaXQgPSB0eXBlb2YgU3ltYm9sICE9PSBcInVuZGVmaW5lZFwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXSB8fCBvW1wiQEBpdGVyYXRvclwiXTsgaWYgKCFpdCkgeyBpZiAoQXJyYXkuaXNBcnJheShvKSB8fCAoaXQgPSBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobykpIHx8IGFsbG93QXJyYXlMaWtlICYmIG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSB7IGlmIChpdCkgbyA9IGl0OyB2YXIgaSA9IDA7IHZhciBGID0gZnVuY3Rpb24gRigpIHt9OyByZXR1cm4geyBzOiBGLCBuOiBmdW5jdGlvbiBuKCkgeyBpZiAoaSA+PSBvLmxlbmd0aCkgcmV0dXJuIHsgZG9uZTogdHJ1ZSB9OyByZXR1cm4geyBkb25lOiBmYWxzZSwgdmFsdWU6IG9baSsrXSB9OyB9LCBlOiBmdW5jdGlvbiBlKF9lKSB7IHRocm93IF9lOyB9LCBmOiBGIH07IH0gdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBpdGVyYXRlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpOyB9IHZhciBub3JtYWxDb21wbGV0aW9uID0gdHJ1ZSwgZGlkRXJyID0gZmFsc2UsIGVycjsgcmV0dXJuIHsgczogZnVuY3Rpb24gcygpIHsgaXQgPSBpdC5jYWxsKG8pOyB9LCBuOiBmdW5jdGlvbiBuKCkgeyB2YXIgc3RlcCA9IGl0Lm5leHQoKTsgbm9ybWFsQ29tcGxldGlvbiA9IHN0ZXAuZG9uZTsgcmV0dXJuIHN0ZXA7IH0sIGU6IGZ1bmN0aW9uIGUoX2UyKSB7IGRpZEVyciA9IHRydWU7IGVyciA9IF9lMjsgfSwgZjogZnVuY3Rpb24gZigpIHsgdHJ5IHsgaWYgKCFub3JtYWxDb21wbGV0aW9uICYmIGl0LnJldHVybiAhPSBudWxsKSBpdC5yZXR1cm4oKTsgfSBmaW5hbGx5IHsgaWYgKGRpZEVycikgdGhyb3cgZXJyOyB9IH0gfTsgfVxuXG5mdW5jdGlvbiBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobywgbWluTGVuKSB7IGlmICghbykgcmV0dXJuOyBpZiAodHlwZW9mIG8gPT09IFwic3RyaW5nXCIpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pOyB2YXIgbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSk7IGlmIChuID09PSBcIk9iamVjdFwiICYmIG8uY29uc3RydWN0b3IpIG4gPSBvLmNvbnN0cnVjdG9yLm5hbWU7IGlmIChuID09PSBcIk1hcFwiIHx8IG4gPT09IFwiU2V0XCIpIHJldHVybiBBcnJheS5mcm9tKG8pOyBpZiAobiA9PT0gXCJBcmd1bWVudHNcIiB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdChuKSkgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7IH1cblxuZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHsgaWYgKGxlbiA9PSBudWxsIHx8IGxlbiA+IGFyci5sZW5ndGgpIGxlbiA9IGFyci5sZW5ndGg7IGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykgeyBhcnIyW2ldID0gYXJyW2ldOyB9IHJldHVybiBhcnIyOyB9XG5cbmltcG9ydCB7IGRpc3BhdGNoIH0gZnJvbSBcImQzLWRpc3BhdGNoXCI7XG5pbXBvcnQgeyBkcmFnRGlzYWJsZSwgZHJhZ0VuYWJsZSB9IGZyb20gXCJkMy1kcmFnXCI7XG5pbXBvcnQgeyBpbnRlcnBvbGF0ZSB9IGZyb20gXCJkMy1pbnRlcnBvbGF0ZVwiO1xuaW1wb3J0IHsgcG9pbnRlciwgc2VsZWN0IH0gZnJvbSBcImQzLXNlbGVjdGlvblwiO1xuaW1wb3J0IHsgaW50ZXJydXB0IH0gZnJvbSBcImQzLXRyYW5zaXRpb25cIjtcbmltcG9ydCBjb25zdGFudCBmcm9tIFwiLi9jb25zdGFudC5qc1wiO1xuaW1wb3J0IEJydXNoRXZlbnQgZnJvbSBcIi4vZXZlbnQuanNcIjtcbmltcG9ydCBub2V2ZW50LCB7IG5vcHJvcGFnYXRpb24gfSBmcm9tIFwiLi9ub2V2ZW50LmpzXCI7XG52YXIgTU9ERV9EUkFHID0ge1xuICBuYW1lOiBcImRyYWdcIlxufSxcbiAgICBNT0RFX1NQQUNFID0ge1xuICBuYW1lOiBcInNwYWNlXCJcbn0sXG4gICAgTU9ERV9IQU5ETEUgPSB7XG4gIG5hbWU6IFwiaGFuZGxlXCJcbn0sXG4gICAgTU9ERV9DRU5URVIgPSB7XG4gIG5hbWU6IFwiY2VudGVyXCJcbn07XG52YXIgYWJzID0gTWF0aC5hYnMsXG4gICAgbWF4ID0gTWF0aC5tYXgsXG4gICAgbWluID0gTWF0aC5taW47XG5cbmZ1bmN0aW9uIG51bWJlcjEoZSkge1xuICByZXR1cm4gWytlWzBdLCArZVsxXV07XG59XG5cbmZ1bmN0aW9uIG51bWJlcjIoZSkge1xuICByZXR1cm4gW251bWJlcjEoZVswXSksIG51bWJlcjEoZVsxXSldO1xufVxuXG52YXIgWCA9IHtcbiAgbmFtZTogXCJ4XCIsXG4gIGhhbmRsZXM6IFtcIndcIiwgXCJlXCJdLm1hcCh0eXBlKSxcbiAgaW5wdXQ6IGZ1bmN0aW9uIGlucHV0KHgsIGUpIHtcbiAgICByZXR1cm4geCA9PSBudWxsID8gbnVsbCA6IFtbK3hbMF0sIGVbMF1bMV1dLCBbK3hbMV0sIGVbMV1bMV1dXTtcbiAgfSxcbiAgb3V0cHV0OiBmdW5jdGlvbiBvdXRwdXQoeHkpIHtcbiAgICByZXR1cm4geHkgJiYgW3h5WzBdWzBdLCB4eVsxXVswXV07XG4gIH1cbn07XG52YXIgWSA9IHtcbiAgbmFtZTogXCJ5XCIsXG4gIGhhbmRsZXM6IFtcIm5cIiwgXCJzXCJdLm1hcCh0eXBlKSxcbiAgaW5wdXQ6IGZ1bmN0aW9uIGlucHV0KHksIGUpIHtcbiAgICByZXR1cm4geSA9PSBudWxsID8gbnVsbCA6IFtbZVswXVswXSwgK3lbMF1dLCBbZVsxXVswXSwgK3lbMV1dXTtcbiAgfSxcbiAgb3V0cHV0OiBmdW5jdGlvbiBvdXRwdXQoeHkpIHtcbiAgICByZXR1cm4geHkgJiYgW3h5WzBdWzFdLCB4eVsxXVsxXV07XG4gIH1cbn07XG52YXIgWFkgPSB7XG4gIG5hbWU6IFwieHlcIixcbiAgaGFuZGxlczogW1wiblwiLCBcIndcIiwgXCJlXCIsIFwic1wiLCBcIm53XCIsIFwibmVcIiwgXCJzd1wiLCBcInNlXCJdLm1hcCh0eXBlKSxcbiAgaW5wdXQ6IGZ1bmN0aW9uIGlucHV0KHh5KSB7XG4gICAgcmV0dXJuIHh5ID09IG51bGwgPyBudWxsIDogbnVtYmVyMih4eSk7XG4gIH0sXG4gIG91dHB1dDogZnVuY3Rpb24gb3V0cHV0KHh5KSB7XG4gICAgcmV0dXJuIHh5O1xuICB9XG59O1xudmFyIGN1cnNvcnMgPSB7XG4gIG92ZXJsYXk6IFwiY3Jvc3NoYWlyXCIsXG4gIHNlbGVjdGlvbjogXCJtb3ZlXCIsXG4gIG46IFwibnMtcmVzaXplXCIsXG4gIGU6IFwiZXctcmVzaXplXCIsXG4gIHM6IFwibnMtcmVzaXplXCIsXG4gIHc6IFwiZXctcmVzaXplXCIsXG4gIG53OiBcIm53c2UtcmVzaXplXCIsXG4gIG5lOiBcIm5lc3ctcmVzaXplXCIsXG4gIHNlOiBcIm53c2UtcmVzaXplXCIsXG4gIHN3OiBcIm5lc3ctcmVzaXplXCJcbn07XG52YXIgZmxpcFggPSB7XG4gIGU6IFwid1wiLFxuICB3OiBcImVcIixcbiAgbnc6IFwibmVcIixcbiAgbmU6IFwibndcIixcbiAgc2U6IFwic3dcIixcbiAgc3c6IFwic2VcIlxufTtcbnZhciBmbGlwWSA9IHtcbiAgbjogXCJzXCIsXG4gIHM6IFwiblwiLFxuICBudzogXCJzd1wiLFxuICBuZTogXCJzZVwiLFxuICBzZTogXCJuZVwiLFxuICBzdzogXCJud1wiXG59O1xudmFyIHNpZ25zWCA9IHtcbiAgb3ZlcmxheTogKzEsXG4gIHNlbGVjdGlvbjogKzEsXG4gIG46IG51bGwsXG4gIGU6ICsxLFxuICBzOiBudWxsLFxuICB3OiAtMSxcbiAgbnc6IC0xLFxuICBuZTogKzEsXG4gIHNlOiArMSxcbiAgc3c6IC0xXG59O1xudmFyIHNpZ25zWSA9IHtcbiAgb3ZlcmxheTogKzEsXG4gIHNlbGVjdGlvbjogKzEsXG4gIG46IC0xLFxuICBlOiBudWxsLFxuICBzOiArMSxcbiAgdzogbnVsbCxcbiAgbnc6IC0xLFxuICBuZTogLTEsXG4gIHNlOiArMSxcbiAgc3c6ICsxXG59O1xuXG5mdW5jdGlvbiB0eXBlKHQpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiB0XG4gIH07XG59IC8vIElnbm9yZSByaWdodC1jbGljaywgc2luY2UgdGhhdCBzaG91bGQgb3BlbiB0aGUgY29udGV4dCBtZW51LlxuXG5cbmZ1bmN0aW9uIGRlZmF1bHRGaWx0ZXIoZXZlbnQpIHtcbiAgcmV0dXJuICFldmVudC5jdHJsS2V5ICYmICFldmVudC5idXR0b247XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRFeHRlbnQoKSB7XG4gIHZhciBzdmcgPSB0aGlzLm93bmVyU1ZHRWxlbWVudCB8fCB0aGlzO1xuXG4gIGlmIChzdmcuaGFzQXR0cmlidXRlKFwidmlld0JveFwiKSkge1xuICAgIHN2ZyA9IHN2Zy52aWV3Qm94LmJhc2VWYWw7XG4gICAgcmV0dXJuIFtbc3ZnLngsIHN2Zy55XSwgW3N2Zy54ICsgc3ZnLndpZHRoLCBzdmcueSArIHN2Zy5oZWlnaHRdXTtcbiAgfVxuXG4gIHJldHVybiBbWzAsIDBdLCBbc3ZnLndpZHRoLmJhc2VWYWwudmFsdWUsIHN2Zy5oZWlnaHQuYmFzZVZhbC52YWx1ZV1dO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0VG91Y2hhYmxlKCkge1xuICByZXR1cm4gbmF2aWdhdG9yLm1heFRvdWNoUG9pbnRzIHx8IFwib250b3VjaHN0YXJ0XCIgaW4gdGhpcztcbn0gLy8gTGlrZSBkMy5sb2NhbCwgYnV0IHdpdGggdGhlIG5hbWUg4oCcX19icnVzaOKAnSByYXRoZXIgdGhhbiBhdXRvLWdlbmVyYXRlZC5cblxuXG5mdW5jdGlvbiBsb2NhbChub2RlKSB7XG4gIHdoaWxlICghbm9kZS5fX2JydXNoKSB7XG4gICAgaWYgKCEobm9kZSA9IG5vZGUucGFyZW50Tm9kZSkpIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiBub2RlLl9fYnJ1c2g7XG59XG5cbmZ1bmN0aW9uIGVtcHR5KGV4dGVudCkge1xuICByZXR1cm4gZXh0ZW50WzBdWzBdID09PSBleHRlbnRbMV1bMF0gfHwgZXh0ZW50WzBdWzFdID09PSBleHRlbnRbMV1bMV07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBicnVzaFNlbGVjdGlvbihub2RlKSB7XG4gIHZhciBzdGF0ZSA9IG5vZGUuX19icnVzaDtcbiAgcmV0dXJuIHN0YXRlID8gc3RhdGUuZGltLm91dHB1dChzdGF0ZS5zZWxlY3Rpb24pIDogbnVsbDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBicnVzaFgoKSB7XG4gIHJldHVybiBicnVzaChYKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBicnVzaFkoKSB7XG4gIHJldHVybiBicnVzaChZKTtcbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGJydXNoKFhZKTtcbn1cblxuZnVuY3Rpb24gYnJ1c2goZGltKSB7XG4gIHZhciBleHRlbnQgPSBkZWZhdWx0RXh0ZW50LFxuICAgICAgZmlsdGVyID0gZGVmYXVsdEZpbHRlcixcbiAgICAgIHRvdWNoYWJsZSA9IGRlZmF1bHRUb3VjaGFibGUsXG4gICAgICBrZXlzID0gdHJ1ZSxcbiAgICAgIGxpc3RlbmVycyA9IGRpc3BhdGNoKFwic3RhcnRcIiwgXCJicnVzaFwiLCBcImVuZFwiKSxcbiAgICAgIGhhbmRsZVNpemUgPSA2LFxuICAgICAgdG91Y2hlbmRpbmc7XG5cbiAgZnVuY3Rpb24gYnJ1c2goZ3JvdXApIHtcbiAgICB2YXIgb3ZlcmxheSA9IGdyb3VwLnByb3BlcnR5KFwiX19icnVzaFwiLCBpbml0aWFsaXplKS5zZWxlY3RBbGwoXCIub3ZlcmxheVwiKS5kYXRhKFt0eXBlKFwib3ZlcmxheVwiKV0pO1xuICAgIG92ZXJsYXkuZW50ZXIoKS5hcHBlbmQoXCJyZWN0XCIpLmF0dHIoXCJjbGFzc1wiLCBcIm92ZXJsYXlcIikuYXR0cihcInBvaW50ZXItZXZlbnRzXCIsIFwiYWxsXCIpLmF0dHIoXCJjdXJzb3JcIiwgY3Vyc29ycy5vdmVybGF5KS5tZXJnZShvdmVybGF5KS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBleHRlbnQgPSBsb2NhbCh0aGlzKS5leHRlbnQ7XG4gICAgICBzZWxlY3QodGhpcykuYXR0cihcInhcIiwgZXh0ZW50WzBdWzBdKS5hdHRyKFwieVwiLCBleHRlbnRbMF1bMV0pLmF0dHIoXCJ3aWR0aFwiLCBleHRlbnRbMV1bMF0gLSBleHRlbnRbMF1bMF0pLmF0dHIoXCJoZWlnaHRcIiwgZXh0ZW50WzFdWzFdIC0gZXh0ZW50WzBdWzFdKTtcbiAgICB9KTtcbiAgICBncm91cC5zZWxlY3RBbGwoXCIuc2VsZWN0aW9uXCIpLmRhdGEoW3R5cGUoXCJzZWxlY3Rpb25cIildKS5lbnRlcigpLmFwcGVuZChcInJlY3RcIikuYXR0cihcImNsYXNzXCIsIFwic2VsZWN0aW9uXCIpLmF0dHIoXCJjdXJzb3JcIiwgY3Vyc29ycy5zZWxlY3Rpb24pLmF0dHIoXCJmaWxsXCIsIFwiIzc3N1wiKS5hdHRyKFwiZmlsbC1vcGFjaXR5XCIsIDAuMykuYXR0cihcInN0cm9rZVwiLCBcIiNmZmZcIikuYXR0cihcInNoYXBlLXJlbmRlcmluZ1wiLCBcImNyaXNwRWRnZXNcIik7XG4gICAgdmFyIGhhbmRsZSA9IGdyb3VwLnNlbGVjdEFsbChcIi5oYW5kbGVcIikuZGF0YShkaW0uaGFuZGxlcywgZnVuY3Rpb24gKGQpIHtcbiAgICAgIHJldHVybiBkLnR5cGU7XG4gICAgfSk7XG4gICAgaGFuZGxlLmV4aXQoKS5yZW1vdmUoKTtcbiAgICBoYW5kbGUuZW50ZXIoKS5hcHBlbmQoXCJyZWN0XCIpLmF0dHIoXCJjbGFzc1wiLCBmdW5jdGlvbiAoZCkge1xuICAgICAgcmV0dXJuIFwiaGFuZGxlIGhhbmRsZS0tXCIgKyBkLnR5cGU7XG4gICAgfSkuYXR0cihcImN1cnNvclwiLCBmdW5jdGlvbiAoZCkge1xuICAgICAgcmV0dXJuIGN1cnNvcnNbZC50eXBlXTtcbiAgICB9KTtcbiAgICBncm91cC5lYWNoKHJlZHJhdykuYXR0cihcImZpbGxcIiwgXCJub25lXCIpLmF0dHIoXCJwb2ludGVyLWV2ZW50c1wiLCBcImFsbFwiKS5vbihcIm1vdXNlZG93bi5icnVzaFwiLCBzdGFydGVkKS5maWx0ZXIodG91Y2hhYmxlKS5vbihcInRvdWNoc3RhcnQuYnJ1c2hcIiwgc3RhcnRlZCkub24oXCJ0b3VjaG1vdmUuYnJ1c2hcIiwgdG91Y2htb3ZlZCkub24oXCJ0b3VjaGVuZC5icnVzaCB0b3VjaGNhbmNlbC5icnVzaFwiLCB0b3VjaGVuZGVkKS5zdHlsZShcInRvdWNoLWFjdGlvblwiLCBcIm5vbmVcIikuc3R5bGUoXCItd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3JcIiwgXCJyZ2JhKDAsMCwwLDApXCIpO1xuICB9XG5cbiAgYnJ1c2gubW92ZSA9IGZ1bmN0aW9uIChncm91cCwgc2VsZWN0aW9uLCBldmVudCkge1xuICAgIGlmIChncm91cC50d2Vlbikge1xuICAgICAgZ3JvdXAub24oXCJzdGFydC5icnVzaFwiLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgZW1pdHRlcih0aGlzLCBhcmd1bWVudHMpLmJlZm9yZXN0YXJ0KCkuc3RhcnQoZXZlbnQpO1xuICAgICAgfSkub24oXCJpbnRlcnJ1cHQuYnJ1c2ggZW5kLmJydXNoXCIsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBlbWl0dGVyKHRoaXMsIGFyZ3VtZW50cykuZW5kKGV2ZW50KTtcbiAgICAgIH0pLnR3ZWVuKFwiYnJ1c2hcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGhhdCA9IHRoaXMsXG4gICAgICAgICAgICBzdGF0ZSA9IHRoYXQuX19icnVzaCxcbiAgICAgICAgICAgIGVtaXQgPSBlbWl0dGVyKHRoYXQsIGFyZ3VtZW50cyksXG4gICAgICAgICAgICBzZWxlY3Rpb24wID0gc3RhdGUuc2VsZWN0aW9uLFxuICAgICAgICAgICAgc2VsZWN0aW9uMSA9IGRpbS5pbnB1dCh0eXBlb2Ygc2VsZWN0aW9uID09PSBcImZ1bmN0aW9uXCIgPyBzZWxlY3Rpb24uYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IHNlbGVjdGlvbiwgc3RhdGUuZXh0ZW50KSxcbiAgICAgICAgICAgIGkgPSBpbnRlcnBvbGF0ZShzZWxlY3Rpb24wLCBzZWxlY3Rpb24xKTtcblxuICAgICAgICBmdW5jdGlvbiB0d2Vlbih0KSB7XG4gICAgICAgICAgc3RhdGUuc2VsZWN0aW9uID0gdCA9PT0gMSAmJiBzZWxlY3Rpb24xID09PSBudWxsID8gbnVsbCA6IGkodCk7XG4gICAgICAgICAgcmVkcmF3LmNhbGwodGhhdCk7XG4gICAgICAgICAgZW1pdC5icnVzaCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNlbGVjdGlvbjAgIT09IG51bGwgJiYgc2VsZWN0aW9uMSAhPT0gbnVsbCA/IHR3ZWVuIDogdHdlZW4oMSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ3JvdXAuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgICBzdGF0ZSA9IHRoYXQuX19icnVzaCxcbiAgICAgICAgICAgIHNlbGVjdGlvbjEgPSBkaW0uaW5wdXQodHlwZW9mIHNlbGVjdGlvbiA9PT0gXCJmdW5jdGlvblwiID8gc2VsZWN0aW9uLmFwcGx5KHRoYXQsIGFyZ3MpIDogc2VsZWN0aW9uLCBzdGF0ZS5leHRlbnQpLFxuICAgICAgICAgICAgZW1pdCA9IGVtaXR0ZXIodGhhdCwgYXJncykuYmVmb3Jlc3RhcnQoKTtcbiAgICAgICAgaW50ZXJydXB0KHRoYXQpO1xuICAgICAgICBzdGF0ZS5zZWxlY3Rpb24gPSBzZWxlY3Rpb24xID09PSBudWxsID8gbnVsbCA6IHNlbGVjdGlvbjE7XG4gICAgICAgIHJlZHJhdy5jYWxsKHRoYXQpO1xuICAgICAgICBlbWl0LnN0YXJ0KGV2ZW50KS5icnVzaChldmVudCkuZW5kKGV2ZW50KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBicnVzaC5jbGVhciA9IGZ1bmN0aW9uIChncm91cCwgZXZlbnQpIHtcbiAgICBicnVzaC5tb3ZlKGdyb3VwLCBudWxsLCBldmVudCk7XG4gIH07XG5cbiAgZnVuY3Rpb24gcmVkcmF3KCkge1xuICAgIHZhciBncm91cCA9IHNlbGVjdCh0aGlzKSxcbiAgICAgICAgc2VsZWN0aW9uID0gbG9jYWwodGhpcykuc2VsZWN0aW9uO1xuXG4gICAgaWYgKHNlbGVjdGlvbikge1xuICAgICAgZ3JvdXAuc2VsZWN0QWxsKFwiLnNlbGVjdGlvblwiKS5zdHlsZShcImRpc3BsYXlcIiwgbnVsbCkuYXR0cihcInhcIiwgc2VsZWN0aW9uWzBdWzBdKS5hdHRyKFwieVwiLCBzZWxlY3Rpb25bMF1bMV0pLmF0dHIoXCJ3aWR0aFwiLCBzZWxlY3Rpb25bMV1bMF0gLSBzZWxlY3Rpb25bMF1bMF0pLmF0dHIoXCJoZWlnaHRcIiwgc2VsZWN0aW9uWzFdWzFdIC0gc2VsZWN0aW9uWzBdWzFdKTtcbiAgICAgIGdyb3VwLnNlbGVjdEFsbChcIi5oYW5kbGVcIikuc3R5bGUoXCJkaXNwbGF5XCIsIG51bGwpLmF0dHIoXCJ4XCIsIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIHJldHVybiBkLnR5cGVbZC50eXBlLmxlbmd0aCAtIDFdID09PSBcImVcIiA/IHNlbGVjdGlvblsxXVswXSAtIGhhbmRsZVNpemUgLyAyIDogc2VsZWN0aW9uWzBdWzBdIC0gaGFuZGxlU2l6ZSAvIDI7XG4gICAgICB9KS5hdHRyKFwieVwiLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICByZXR1cm4gZC50eXBlWzBdID09PSBcInNcIiA/IHNlbGVjdGlvblsxXVsxXSAtIGhhbmRsZVNpemUgLyAyIDogc2VsZWN0aW9uWzBdWzFdIC0gaGFuZGxlU2l6ZSAvIDI7XG4gICAgICB9KS5hdHRyKFwid2lkdGhcIiwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgcmV0dXJuIGQudHlwZSA9PT0gXCJuXCIgfHwgZC50eXBlID09PSBcInNcIiA/IHNlbGVjdGlvblsxXVswXSAtIHNlbGVjdGlvblswXVswXSArIGhhbmRsZVNpemUgOiBoYW5kbGVTaXplO1xuICAgICAgfSkuYXR0cihcImhlaWdodFwiLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICByZXR1cm4gZC50eXBlID09PSBcImVcIiB8fCBkLnR5cGUgPT09IFwid1wiID8gc2VsZWN0aW9uWzFdWzFdIC0gc2VsZWN0aW9uWzBdWzFdICsgaGFuZGxlU2l6ZSA6IGhhbmRsZVNpemU7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZ3JvdXAuc2VsZWN0QWxsKFwiLnNlbGVjdGlvbiwuaGFuZGxlXCIpLnN0eWxlKFwiZGlzcGxheVwiLCBcIm5vbmVcIikuYXR0cihcInhcIiwgbnVsbCkuYXR0cihcInlcIiwgbnVsbCkuYXR0cihcIndpZHRoXCIsIG51bGwpLmF0dHIoXCJoZWlnaHRcIiwgbnVsbCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZW1pdHRlcih0aGF0LCBhcmdzLCBjbGVhbikge1xuICAgIHZhciBlbWl0ID0gdGhhdC5fX2JydXNoLmVtaXR0ZXI7XG4gICAgcmV0dXJuIGVtaXQgJiYgKCFjbGVhbiB8fCAhZW1pdC5jbGVhbikgPyBlbWl0IDogbmV3IEVtaXR0ZXIodGhhdCwgYXJncywgY2xlYW4pO1xuICB9XG5cbiAgZnVuY3Rpb24gRW1pdHRlcih0aGF0LCBhcmdzLCBjbGVhbikge1xuICAgIHRoaXMudGhhdCA9IHRoYXQ7XG4gICAgdGhpcy5hcmdzID0gYXJncztcbiAgICB0aGlzLnN0YXRlID0gdGhhdC5fX2JydXNoO1xuICAgIHRoaXMuYWN0aXZlID0gMDtcbiAgICB0aGlzLmNsZWFuID0gY2xlYW47XG4gIH1cblxuICBFbWl0dGVyLnByb3RvdHlwZSA9IHtcbiAgICBiZWZvcmVzdGFydDogZnVuY3Rpb24gYmVmb3Jlc3RhcnQoKSB7XG4gICAgICBpZiAoKyt0aGlzLmFjdGl2ZSA9PT0gMSkgdGhpcy5zdGF0ZS5lbWl0dGVyID0gdGhpcywgdGhpcy5zdGFydGluZyA9IHRydWU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIHN0YXJ0OiBmdW5jdGlvbiBzdGFydChldmVudCwgbW9kZSkge1xuICAgICAgaWYgKHRoaXMuc3RhcnRpbmcpIHRoaXMuc3RhcnRpbmcgPSBmYWxzZSwgdGhpcy5lbWl0KFwic3RhcnRcIiwgZXZlbnQsIG1vZGUpO2Vsc2UgdGhpcy5lbWl0KFwiYnJ1c2hcIiwgZXZlbnQpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBicnVzaDogZnVuY3Rpb24gYnJ1c2goZXZlbnQsIG1vZGUpIHtcbiAgICAgIHRoaXMuZW1pdChcImJydXNoXCIsIGV2ZW50LCBtb2RlKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgZW5kOiBmdW5jdGlvbiBlbmQoZXZlbnQsIG1vZGUpIHtcbiAgICAgIGlmICgtLXRoaXMuYWN0aXZlID09PSAwKSBkZWxldGUgdGhpcy5zdGF0ZS5lbWl0dGVyLCB0aGlzLmVtaXQoXCJlbmRcIiwgZXZlbnQsIG1vZGUpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBlbWl0OiBmdW5jdGlvbiBlbWl0KHR5cGUsIGV2ZW50LCBtb2RlKSB7XG4gICAgICB2YXIgZCA9IHNlbGVjdCh0aGlzLnRoYXQpLmRhdHVtKCk7XG4gICAgICBsaXN0ZW5lcnMuY2FsbCh0eXBlLCB0aGlzLnRoYXQsIG5ldyBCcnVzaEV2ZW50KHR5cGUsIHtcbiAgICAgICAgc291cmNlRXZlbnQ6IGV2ZW50LFxuICAgICAgICB0YXJnZXQ6IGJydXNoLFxuICAgICAgICBzZWxlY3Rpb246IGRpbS5vdXRwdXQodGhpcy5zdGF0ZS5zZWxlY3Rpb24pLFxuICAgICAgICBtb2RlOiBtb2RlLFxuICAgICAgICBkaXNwYXRjaDogbGlzdGVuZXJzXG4gICAgICB9KSwgZCk7XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIHN0YXJ0ZWQoZXZlbnQpIHtcbiAgICBpZiAodG91Y2hlbmRpbmcgJiYgIWV2ZW50LnRvdWNoZXMpIHJldHVybjtcbiAgICBpZiAoIWZpbHRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSByZXR1cm47XG4gICAgdmFyIHRoYXQgPSB0aGlzLFxuICAgICAgICB0eXBlID0gZXZlbnQudGFyZ2V0Ll9fZGF0YV9fLnR5cGUsXG4gICAgICAgIG1vZGUgPSAoa2V5cyAmJiBldmVudC5tZXRhS2V5ID8gdHlwZSA9IFwib3ZlcmxheVwiIDogdHlwZSkgPT09IFwic2VsZWN0aW9uXCIgPyBNT0RFX0RSQUcgOiBrZXlzICYmIGV2ZW50LmFsdEtleSA/IE1PREVfQ0VOVEVSIDogTU9ERV9IQU5ETEUsXG4gICAgICAgIHNpZ25YID0gZGltID09PSBZID8gbnVsbCA6IHNpZ25zWFt0eXBlXSxcbiAgICAgICAgc2lnblkgPSBkaW0gPT09IFggPyBudWxsIDogc2lnbnNZW3R5cGVdLFxuICAgICAgICBzdGF0ZSA9IGxvY2FsKHRoYXQpLFxuICAgICAgICBleHRlbnQgPSBzdGF0ZS5leHRlbnQsXG4gICAgICAgIHNlbGVjdGlvbiA9IHN0YXRlLnNlbGVjdGlvbixcbiAgICAgICAgVyA9IGV4dGVudFswXVswXSxcbiAgICAgICAgdzAsXG4gICAgICAgIHcxLFxuICAgICAgICBOID0gZXh0ZW50WzBdWzFdLFxuICAgICAgICBuMCxcbiAgICAgICAgbjEsXG4gICAgICAgIEUgPSBleHRlbnRbMV1bMF0sXG4gICAgICAgIGUwLFxuICAgICAgICBlMSxcbiAgICAgICAgUyA9IGV4dGVudFsxXVsxXSxcbiAgICAgICAgczAsXG4gICAgICAgIHMxLFxuICAgICAgICBkeCA9IDAsXG4gICAgICAgIGR5ID0gMCxcbiAgICAgICAgbW92aW5nLFxuICAgICAgICBzaGlmdGluZyA9IHNpZ25YICYmIHNpZ25ZICYmIGtleXMgJiYgZXZlbnQuc2hpZnRLZXksXG4gICAgICAgIGxvY2tYLFxuICAgICAgICBsb2NrWSxcbiAgICAgICAgcG9pbnRzID0gQXJyYXkuZnJvbShldmVudC50b3VjaGVzIHx8IFtldmVudF0sIGZ1bmN0aW9uICh0KSB7XG4gICAgICB2YXIgaSA9IHQuaWRlbnRpZmllcjtcbiAgICAgIHQgPSBwb2ludGVyKHQsIHRoYXQpO1xuICAgICAgdC5wb2ludDAgPSB0LnNsaWNlKCk7XG4gICAgICB0LmlkZW50aWZpZXIgPSBpO1xuICAgICAgcmV0dXJuIHQ7XG4gICAgfSk7XG4gICAgaW50ZXJydXB0KHRoYXQpO1xuICAgIHZhciBlbWl0ID0gZW1pdHRlcih0aGF0LCBhcmd1bWVudHMsIHRydWUpLmJlZm9yZXN0YXJ0KCk7XG5cbiAgICBpZiAodHlwZSA9PT0gXCJvdmVybGF5XCIpIHtcbiAgICAgIGlmIChzZWxlY3Rpb24pIG1vdmluZyA9IHRydWU7XG4gICAgICB2YXIgcHRzID0gW3BvaW50c1swXSwgcG9pbnRzWzFdIHx8IHBvaW50c1swXV07XG4gICAgICBzdGF0ZS5zZWxlY3Rpb24gPSBzZWxlY3Rpb24gPSBbW3cwID0gZGltID09PSBZID8gVyA6IG1pbihwdHNbMF1bMF0sIHB0c1sxXVswXSksIG4wID0gZGltID09PSBYID8gTiA6IG1pbihwdHNbMF1bMV0sIHB0c1sxXVsxXSldLCBbZTAgPSBkaW0gPT09IFkgPyBFIDogbWF4KHB0c1swXVswXSwgcHRzWzFdWzBdKSwgczAgPSBkaW0gPT09IFggPyBTIDogbWF4KHB0c1swXVsxXSwgcHRzWzFdWzFdKV1dO1xuICAgICAgaWYgKHBvaW50cy5sZW5ndGggPiAxKSBtb3ZlKGV2ZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdzAgPSBzZWxlY3Rpb25bMF1bMF07XG4gICAgICBuMCA9IHNlbGVjdGlvblswXVsxXTtcbiAgICAgIGUwID0gc2VsZWN0aW9uWzFdWzBdO1xuICAgICAgczAgPSBzZWxlY3Rpb25bMV1bMV07XG4gICAgfVxuXG4gICAgdzEgPSB3MDtcbiAgICBuMSA9IG4wO1xuICAgIGUxID0gZTA7XG4gICAgczEgPSBzMDtcbiAgICB2YXIgZ3JvdXAgPSBzZWxlY3QodGhhdCkuYXR0cihcInBvaW50ZXItZXZlbnRzXCIsIFwibm9uZVwiKTtcbiAgICB2YXIgb3ZlcmxheSA9IGdyb3VwLnNlbGVjdEFsbChcIi5vdmVybGF5XCIpLmF0dHIoXCJjdXJzb3JcIiwgY3Vyc29yc1t0eXBlXSk7XG5cbiAgICBpZiAoZXZlbnQudG91Y2hlcykge1xuICAgICAgZW1pdC5tb3ZlZCA9IG1vdmVkO1xuICAgICAgZW1pdC5lbmRlZCA9IGVuZGVkO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdmlldyA9IHNlbGVjdChldmVudC52aWV3KS5vbihcIm1vdXNlbW92ZS5icnVzaFwiLCBtb3ZlZCwgdHJ1ZSkub24oXCJtb3VzZXVwLmJydXNoXCIsIGVuZGVkLCB0cnVlKTtcbiAgICAgIGlmIChrZXlzKSB2aWV3Lm9uKFwia2V5ZG93bi5icnVzaFwiLCBrZXlkb3duZWQsIHRydWUpLm9uKFwia2V5dXAuYnJ1c2hcIiwga2V5dXBwZWQsIHRydWUpO1xuICAgICAgZHJhZ0Rpc2FibGUoZXZlbnQudmlldyk7XG4gICAgfVxuXG4gICAgcmVkcmF3LmNhbGwodGhhdCk7XG4gICAgZW1pdC5zdGFydChldmVudCwgbW9kZS5uYW1lKTtcblxuICAgIGZ1bmN0aW9uIG1vdmVkKGV2ZW50KSB7XG4gICAgICB2YXIgX2l0ZXJhdG9yID0gX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIoZXZlbnQuY2hhbmdlZFRvdWNoZXMgfHwgW2V2ZW50XSksXG4gICAgICAgICAgX3N0ZXA7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAoX2l0ZXJhdG9yLnMoKTsgIShfc3RlcCA9IF9pdGVyYXRvci5uKCkpLmRvbmU7KSB7XG4gICAgICAgICAgdmFyIHAgPSBfc3RlcC52YWx1ZTtcblxuICAgICAgICAgIHZhciBfaXRlcmF0b3IzID0gX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIocG9pbnRzKSxcbiAgICAgICAgICAgICAgX3N0ZXAzO1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZvciAoX2l0ZXJhdG9yMy5zKCk7ICEoX3N0ZXAzID0gX2l0ZXJhdG9yMy5uKCkpLmRvbmU7KSB7XG4gICAgICAgICAgICAgIHZhciBkID0gX3N0ZXAzLnZhbHVlO1xuICAgICAgICAgICAgICBpZiAoZC5pZGVudGlmaWVyID09PSBwLmlkZW50aWZpZXIpIGQuY3VyID0gcG9pbnRlcihwLCB0aGF0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIF9pdGVyYXRvcjMuZShlcnIpO1xuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBfaXRlcmF0b3IzLmYoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBfaXRlcmF0b3IuZShlcnIpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgX2l0ZXJhdG9yLmYoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNoaWZ0aW5nICYmICFsb2NrWCAmJiAhbG9ja1kgJiYgcG9pbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNbMF07XG4gICAgICAgIGlmIChhYnMocG9pbnQuY3VyWzBdIC0gcG9pbnRbMF0pID4gYWJzKHBvaW50LmN1clsxXSAtIHBvaW50WzFdKSkgbG9ja1kgPSB0cnVlO2Vsc2UgbG9ja1ggPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgX2l0ZXJhdG9yMiA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyKHBvaW50cyksXG4gICAgICAgICAgX3N0ZXAyO1xuXG4gICAgICB0cnkge1xuICAgICAgICBmb3IgKF9pdGVyYXRvcjIucygpOyAhKF9zdGVwMiA9IF9pdGVyYXRvcjIubigpKS5kb25lOykge1xuICAgICAgICAgIHZhciBfcG9pbnQgPSBfc3RlcDIudmFsdWU7XG4gICAgICAgICAgaWYgKF9wb2ludC5jdXIpIF9wb2ludFswXSA9IF9wb2ludC5jdXJbMF0sIF9wb2ludFsxXSA9IF9wb2ludC5jdXJbMV07XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBfaXRlcmF0b3IyLmUoZXJyKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIF9pdGVyYXRvcjIuZigpO1xuICAgICAgfVxuXG4gICAgICBtb3ZpbmcgPSB0cnVlO1xuICAgICAgbm9ldmVudChldmVudCk7XG4gICAgICBtb3ZlKGV2ZW50KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb3ZlKGV2ZW50KSB7XG4gICAgICB2YXIgcG9pbnQgPSBwb2ludHNbMF0sXG4gICAgICAgICAgcG9pbnQwID0gcG9pbnQucG9pbnQwO1xuICAgICAgdmFyIHQ7XG4gICAgICBkeCA9IHBvaW50WzBdIC0gcG9pbnQwWzBdO1xuICAgICAgZHkgPSBwb2ludFsxXSAtIHBvaW50MFsxXTtcblxuICAgICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICAgIGNhc2UgTU9ERV9TUEFDRTpcbiAgICAgICAgY2FzZSBNT0RFX0RSQUc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKHNpZ25YKSBkeCA9IG1heChXIC0gdzAsIG1pbihFIC0gZTAsIGR4KSksIHcxID0gdzAgKyBkeCwgZTEgPSBlMCArIGR4O1xuICAgICAgICAgICAgaWYgKHNpZ25ZKSBkeSA9IG1heChOIC0gbjAsIG1pbihTIC0gczAsIGR5KSksIG4xID0gbjAgKyBkeSwgczEgPSBzMCArIGR5O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgTU9ERV9IQU5ETEU6XG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKHBvaW50c1sxXSkge1xuICAgICAgICAgICAgICBpZiAoc2lnblgpIHcxID0gbWF4KFcsIG1pbihFLCBwb2ludHNbMF1bMF0pKSwgZTEgPSBtYXgoVywgbWluKEUsIHBvaW50c1sxXVswXSkpLCBzaWduWCA9IDE7XG4gICAgICAgICAgICAgIGlmIChzaWduWSkgbjEgPSBtYXgoTiwgbWluKFMsIHBvaW50c1swXVsxXSkpLCBzMSA9IG1heChOLCBtaW4oUywgcG9pbnRzWzFdWzFdKSksIHNpZ25ZID0gMTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChzaWduWCA8IDApIGR4ID0gbWF4KFcgLSB3MCwgbWluKEUgLSB3MCwgZHgpKSwgdzEgPSB3MCArIGR4LCBlMSA9IGUwO2Vsc2UgaWYgKHNpZ25YID4gMCkgZHggPSBtYXgoVyAtIGUwLCBtaW4oRSAtIGUwLCBkeCkpLCB3MSA9IHcwLCBlMSA9IGUwICsgZHg7XG4gICAgICAgICAgICAgIGlmIChzaWduWSA8IDApIGR5ID0gbWF4KE4gLSBuMCwgbWluKFMgLSBuMCwgZHkpKSwgbjEgPSBuMCArIGR5LCBzMSA9IHMwO2Vsc2UgaWYgKHNpZ25ZID4gMCkgZHkgPSBtYXgoTiAtIHMwLCBtaW4oUyAtIHMwLCBkeSkpLCBuMSA9IG4wLCBzMSA9IHMwICsgZHk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIE1PREVfQ0VOVEVSOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmIChzaWduWCkgdzEgPSBtYXgoVywgbWluKEUsIHcwIC0gZHggKiBzaWduWCkpLCBlMSA9IG1heChXLCBtaW4oRSwgZTAgKyBkeCAqIHNpZ25YKSk7XG4gICAgICAgICAgICBpZiAoc2lnblkpIG4xID0gbWF4KE4sIG1pbihTLCBuMCAtIGR5ICogc2lnblkpKSwgczEgPSBtYXgoTiwgbWluKFMsIHMwICsgZHkgKiBzaWduWSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZTEgPCB3MSkge1xuICAgICAgICBzaWduWCAqPSAtMTtcbiAgICAgICAgdCA9IHcwLCB3MCA9IGUwLCBlMCA9IHQ7XG4gICAgICAgIHQgPSB3MSwgdzEgPSBlMSwgZTEgPSB0O1xuICAgICAgICBpZiAodHlwZSBpbiBmbGlwWCkgb3ZlcmxheS5hdHRyKFwiY3Vyc29yXCIsIGN1cnNvcnNbdHlwZSA9IGZsaXBYW3R5cGVdXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzMSA8IG4xKSB7XG4gICAgICAgIHNpZ25ZICo9IC0xO1xuICAgICAgICB0ID0gbjAsIG4wID0gczAsIHMwID0gdDtcbiAgICAgICAgdCA9IG4xLCBuMSA9IHMxLCBzMSA9IHQ7XG4gICAgICAgIGlmICh0eXBlIGluIGZsaXBZKSBvdmVybGF5LmF0dHIoXCJjdXJzb3JcIiwgY3Vyc29yc1t0eXBlID0gZmxpcFlbdHlwZV1dKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXRlLnNlbGVjdGlvbikgc2VsZWN0aW9uID0gc3RhdGUuc2VsZWN0aW9uOyAvLyBNYXkgYmUgc2V0IGJ5IGJydXNoLm1vdmUhXG5cbiAgICAgIGlmIChsb2NrWCkgdzEgPSBzZWxlY3Rpb25bMF1bMF0sIGUxID0gc2VsZWN0aW9uWzFdWzBdO1xuICAgICAgaWYgKGxvY2tZKSBuMSA9IHNlbGVjdGlvblswXVsxXSwgczEgPSBzZWxlY3Rpb25bMV1bMV07XG5cbiAgICAgIGlmIChzZWxlY3Rpb25bMF1bMF0gIT09IHcxIHx8IHNlbGVjdGlvblswXVsxXSAhPT0gbjEgfHwgc2VsZWN0aW9uWzFdWzBdICE9PSBlMSB8fCBzZWxlY3Rpb25bMV1bMV0gIT09IHMxKSB7XG4gICAgICAgIHN0YXRlLnNlbGVjdGlvbiA9IFtbdzEsIG4xXSwgW2UxLCBzMV1dO1xuICAgICAgICByZWRyYXcuY2FsbCh0aGF0KTtcbiAgICAgICAgZW1pdC5icnVzaChldmVudCwgbW9kZS5uYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBlbmRlZChldmVudCkge1xuICAgICAgbm9wcm9wYWdhdGlvbihldmVudCk7XG5cbiAgICAgIGlmIChldmVudC50b3VjaGVzKSB7XG4gICAgICAgIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCkgcmV0dXJuO1xuICAgICAgICBpZiAodG91Y2hlbmRpbmcpIGNsZWFyVGltZW91dCh0b3VjaGVuZGluZyk7XG4gICAgICAgIHRvdWNoZW5kaW5nID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdG91Y2hlbmRpbmcgPSBudWxsO1xuICAgICAgICB9LCA1MDApOyAvLyBHaG9zdCBjbGlja3MgYXJlIGRlbGF5ZWQhXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkcmFnRW5hYmxlKGV2ZW50LnZpZXcsIG1vdmluZyk7XG4gICAgICAgIHZpZXcub24oXCJrZXlkb3duLmJydXNoIGtleXVwLmJydXNoIG1vdXNlbW92ZS5icnVzaCBtb3VzZXVwLmJydXNoXCIsIG51bGwpO1xuICAgICAgfVxuXG4gICAgICBncm91cC5hdHRyKFwicG9pbnRlci1ldmVudHNcIiwgXCJhbGxcIik7XG4gICAgICBvdmVybGF5LmF0dHIoXCJjdXJzb3JcIiwgY3Vyc29ycy5vdmVybGF5KTtcbiAgICAgIGlmIChzdGF0ZS5zZWxlY3Rpb24pIHNlbGVjdGlvbiA9IHN0YXRlLnNlbGVjdGlvbjsgLy8gTWF5IGJlIHNldCBieSBicnVzaC5tb3ZlIChvbiBzdGFydCkhXG5cbiAgICAgIGlmIChlbXB0eShzZWxlY3Rpb24pKSBzdGF0ZS5zZWxlY3Rpb24gPSBudWxsLCByZWRyYXcuY2FsbCh0aGF0KTtcbiAgICAgIGVtaXQuZW5kKGV2ZW50LCBtb2RlLm5hbWUpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGtleWRvd25lZChldmVudCkge1xuICAgICAgc3dpdGNoIChldmVudC5rZXlDb2RlKSB7XG4gICAgICAgIGNhc2UgMTY6XG4gICAgICAgICAge1xuICAgICAgICAgICAgLy8gU0hJRlRcbiAgICAgICAgICAgIHNoaWZ0aW5nID0gc2lnblggJiYgc2lnblk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSAxODpcbiAgICAgICAgICB7XG4gICAgICAgICAgICAvLyBBTFRcbiAgICAgICAgICAgIGlmIChtb2RlID09PSBNT0RFX0hBTkRMRSkge1xuICAgICAgICAgICAgICBpZiAoc2lnblgpIGUwID0gZTEgLSBkeCAqIHNpZ25YLCB3MCA9IHcxICsgZHggKiBzaWduWDtcbiAgICAgICAgICAgICAgaWYgKHNpZ25ZKSBzMCA9IHMxIC0gZHkgKiBzaWduWSwgbjAgPSBuMSArIGR5ICogc2lnblk7XG4gICAgICAgICAgICAgIG1vZGUgPSBNT0RFX0NFTlRFUjtcbiAgICAgICAgICAgICAgbW92ZShldmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIDMyOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC8vIFNQQUNFOyB0YWtlcyBwcmlvcml0eSBvdmVyIEFMVFxuICAgICAgICAgICAgaWYgKG1vZGUgPT09IE1PREVfSEFORExFIHx8IG1vZGUgPT09IE1PREVfQ0VOVEVSKSB7XG4gICAgICAgICAgICAgIGlmIChzaWduWCA8IDApIGUwID0gZTEgLSBkeDtlbHNlIGlmIChzaWduWCA+IDApIHcwID0gdzEgLSBkeDtcbiAgICAgICAgICAgICAgaWYgKHNpZ25ZIDwgMCkgczAgPSBzMSAtIGR5O2Vsc2UgaWYgKHNpZ25ZID4gMCkgbjAgPSBuMSAtIGR5O1xuICAgICAgICAgICAgICBtb2RlID0gTU9ERV9TUEFDRTtcbiAgICAgICAgICAgICAgb3ZlcmxheS5hdHRyKFwiY3Vyc29yXCIsIGN1cnNvcnMuc2VsZWN0aW9uKTtcbiAgICAgICAgICAgICAgbW92ZShldmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbm9ldmVudChldmVudCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24ga2V5dXBwZWQoZXZlbnQpIHtcbiAgICAgIHN3aXRjaCAoZXZlbnQua2V5Q29kZSkge1xuICAgICAgICBjYXNlIDE2OlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC8vIFNISUZUXG4gICAgICAgICAgICBpZiAoc2hpZnRpbmcpIHtcbiAgICAgICAgICAgICAgbG9ja1ggPSBsb2NrWSA9IHNoaWZ0aW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgIG1vdmUoZXZlbnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSAxODpcbiAgICAgICAgICB7XG4gICAgICAgICAgICAvLyBBTFRcbiAgICAgICAgICAgIGlmIChtb2RlID09PSBNT0RFX0NFTlRFUikge1xuICAgICAgICAgICAgICBpZiAoc2lnblggPCAwKSBlMCA9IGUxO2Vsc2UgaWYgKHNpZ25YID4gMCkgdzAgPSB3MTtcbiAgICAgICAgICAgICAgaWYgKHNpZ25ZIDwgMCkgczAgPSBzMTtlbHNlIGlmIChzaWduWSA+IDApIG4wID0gbjE7XG4gICAgICAgICAgICAgIG1vZGUgPSBNT0RFX0hBTkRMRTtcbiAgICAgICAgICAgICAgbW92ZShldmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIDMyOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC8vIFNQQUNFXG4gICAgICAgICAgICBpZiAobW9kZSA9PT0gTU9ERV9TUEFDRSkge1xuICAgICAgICAgICAgICBpZiAoZXZlbnQuYWx0S2V5KSB7XG4gICAgICAgICAgICAgICAgaWYgKHNpZ25YKSBlMCA9IGUxIC0gZHggKiBzaWduWCwgdzAgPSB3MSArIGR4ICogc2lnblg7XG4gICAgICAgICAgICAgICAgaWYgKHNpZ25ZKSBzMCA9IHMxIC0gZHkgKiBzaWduWSwgbjAgPSBuMSArIGR5ICogc2lnblk7XG4gICAgICAgICAgICAgICAgbW9kZSA9IE1PREVfQ0VOVEVSO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChzaWduWCA8IDApIGUwID0gZTE7ZWxzZSBpZiAoc2lnblggPiAwKSB3MCA9IHcxO1xuICAgICAgICAgICAgICAgIGlmIChzaWduWSA8IDApIHMwID0gczE7ZWxzZSBpZiAoc2lnblkgPiAwKSBuMCA9IG4xO1xuICAgICAgICAgICAgICAgIG1vZGUgPSBNT0RFX0hBTkRMRTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIG92ZXJsYXkuYXR0cihcImN1cnNvclwiLCBjdXJzb3JzW3R5cGVdKTtcbiAgICAgICAgICAgICAgbW92ZShldmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbm9ldmVudChldmVudCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdG91Y2htb3ZlZChldmVudCkge1xuICAgIGVtaXR0ZXIodGhpcywgYXJndW1lbnRzKS5tb3ZlZChldmVudCk7XG4gIH1cblxuICBmdW5jdGlvbiB0b3VjaGVuZGVkKGV2ZW50KSB7XG4gICAgZW1pdHRlcih0aGlzLCBhcmd1bWVudHMpLmVuZGVkKGV2ZW50KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5fX2JydXNoIHx8IHtcbiAgICAgIHNlbGVjdGlvbjogbnVsbFxuICAgIH07XG4gICAgc3RhdGUuZXh0ZW50ID0gbnVtYmVyMihleHRlbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gICAgc3RhdGUuZGltID0gZGltO1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIGJydXNoLmV4dGVudCA9IGZ1bmN0aW9uIChfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZXh0ZW50ID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudChudW1iZXIyKF8pKSwgYnJ1c2gpIDogZXh0ZW50O1xuICB9O1xuXG4gIGJydXNoLmZpbHRlciA9IGZ1bmN0aW9uIChfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZmlsdGVyID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCghIV8pLCBicnVzaCkgOiBmaWx0ZXI7XG4gIH07XG5cbiAgYnJ1c2gudG91Y2hhYmxlID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0b3VjaGFibGUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50KCEhXyksIGJydXNoKSA6IHRvdWNoYWJsZTtcbiAgfTtcblxuICBicnVzaC5oYW5kbGVTaXplID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChoYW5kbGVTaXplID0gK18sIGJydXNoKSA6IGhhbmRsZVNpemU7XG4gIH07XG5cbiAgYnJ1c2gua2V5TW9kaWZpZXJzID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChrZXlzID0gISFfLCBicnVzaCkgOiBrZXlzO1xuICB9O1xuXG4gIGJydXNoLm9uID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IGxpc3RlbmVycy5vbi5hcHBseShsaXN0ZW5lcnMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHZhbHVlID09PSBsaXN0ZW5lcnMgPyBicnVzaCA6IHZhbHVlO1xuICB9O1xuXG4gIHJldHVybiBicnVzaDtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfYXJyYXlXaXRoSG9sZXMoYXJyKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGFycikpIHJldHVybiBhcnI7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkge1xuICB2YXIgX2kgPSBhcnIgPT0gbnVsbCA/IG51bGwgOiB0eXBlb2YgU3ltYm9sICE9PSBcInVuZGVmaW5lZFwiICYmIGFycltTeW1ib2wuaXRlcmF0b3JdIHx8IGFycltcIkBAaXRlcmF0b3JcIl07XG5cbiAgaWYgKF9pID09IG51bGwpIHJldHVybjtcbiAgdmFyIF9hcnIgPSBbXTtcbiAgdmFyIF9uID0gdHJ1ZTtcbiAgdmFyIF9kID0gZmFsc2U7XG5cbiAgdmFyIF9zLCBfZTtcblxuICB0cnkge1xuICAgIGZvciAoX2kgPSBfaS5jYWxsKGFycik7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHtcbiAgICAgIF9hcnIucHVzaChfcy52YWx1ZSk7XG5cbiAgICAgIGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhaztcbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIF9kID0gdHJ1ZTtcbiAgICBfZSA9IGVycjtcbiAgfSBmaW5hbGx5IHtcbiAgICB0cnkge1xuICAgICAgaWYgKCFfbiAmJiBfaVtcInJldHVyblwiXSAhPSBudWxsKSBfaVtcInJldHVyblwiXSgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAoX2QpIHRocm93IF9lO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBfYXJyO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9ub25JdGVyYWJsZVJlc3QoKSB7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gZGVzdHJ1Y3R1cmUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxcbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC5cIik7XG59IiwiaW1wb3J0IGFycmF5V2l0aEhvbGVzIGZyb20gXCIuL2FycmF5V2l0aEhvbGVzLmpzXCI7XG5pbXBvcnQgaXRlcmFibGVUb0FycmF5TGltaXQgZnJvbSBcIi4vaXRlcmFibGVUb0FycmF5TGltaXQuanNcIjtcbmltcG9ydCB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSBmcm9tIFwiLi91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheS5qc1wiO1xuaW1wb3J0IG5vbkl0ZXJhYmxlUmVzdCBmcm9tIFwiLi9ub25JdGVyYWJsZVJlc3QuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KGFyciwgaSkge1xuICByZXR1cm4gYXJyYXlXaXRoSG9sZXMoYXJyKSB8fCBpdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHx8IHVuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KGFyciwgaSkgfHwgbm9uSXRlcmFibGVSZXN0KCk7XG59IiwiaW1wb3J0IHZhbHVlIGZyb20gXCIuL3ZhbHVlLmpzXCI7XG5pbXBvcnQgbnVtYmVyQXJyYXksIHsgaXNOdW1iZXJBcnJheSB9IGZyb20gXCIuL251bWJlckFycmF5LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoYSwgYikge1xuICByZXR1cm4gKGlzTnVtYmVyQXJyYXkoYikgPyBudW1iZXJBcnJheSA6IGdlbmVyaWNBcnJheSkoYSwgYik7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJpY0FycmF5KGEsIGIpIHtcbiAgdmFyIG5iID0gYiA/IGIubGVuZ3RoIDogMCxcbiAgICAgIG5hID0gYSA/IE1hdGgubWluKG5iLCBhLmxlbmd0aCkgOiAwLFxuICAgICAgeCA9IG5ldyBBcnJheShuYSksXG4gICAgICBjID0gbmV3IEFycmF5KG5iKSxcbiAgICAgIGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IG5hOyArK2kpIHtcbiAgICB4W2ldID0gdmFsdWUoYVtpXSwgYltpXSk7XG4gIH1cblxuICBmb3IgKDsgaSA8IG5iOyArK2kpIHtcbiAgICBjW2ldID0gYltpXTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAodCkge1xuICAgIGZvciAoaSA9IDA7IGkgPCBuYTsgKytpKSB7XG4gICAgICBjW2ldID0geFtpXSh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYztcbiAgfTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoYSwgYikge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHJldHVybiBhID0gK2EsIGIgPSArYiwgZnVuY3Rpb24gKHQpIHtcbiAgICByZXR1cm4gZC5zZXRUaW1lKGEgKiAoMSAtIHQpICsgYiAqIHQpLCBkO1xuICB9O1xufSIsImltcG9ydCB2YWx1ZSBmcm9tIFwiLi92YWx1ZS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKGEsIGIpIHtcbiAgdmFyIGkgPSB7fSxcbiAgICAgIGMgPSB7fSxcbiAgICAgIGs7XG4gIGlmIChhID09PSBudWxsIHx8IHR5cGVvZiBhICE9PSBcIm9iamVjdFwiKSBhID0ge307XG4gIGlmIChiID09PSBudWxsIHx8IHR5cGVvZiBiICE9PSBcIm9iamVjdFwiKSBiID0ge307XG5cbiAgZm9yIChrIGluIGIpIHtcbiAgICBpZiAoayBpbiBhKSB7XG4gICAgICBpW2tdID0gdmFsdWUoYVtrXSwgYltrXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNba10gPSBiW2tdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAodCkge1xuICAgIGZvciAoayBpbiBpKSB7XG4gICAgICBjW2tdID0gaVtrXSh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYztcbiAgfTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoYSwgYikge1xuICBpZiAoIWIpIGIgPSBbXTtcbiAgdmFyIG4gPSBhID8gTWF0aC5taW4oYi5sZW5ndGgsIGEubGVuZ3RoKSA6IDAsXG4gICAgICBjID0gYi5zbGljZSgpLFxuICAgICAgaTtcbiAgcmV0dXJuIGZ1bmN0aW9uICh0KSB7XG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgY1tpXSA9IGFbaV0gKiAoMSAtIHQpICsgYltpXSAqIHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGM7XG4gIH07XG59XG5leHBvcnQgZnVuY3Rpb24gaXNOdW1iZXJBcnJheSh4KSB7XG4gIHJldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoeCkgJiYgISh4IGluc3RhbmNlb2YgRGF0YVZpZXcpO1xufSIsImltcG9ydCB7IGNvbG9yIH0gZnJvbSBcImQzLWNvbG9yXCI7XG5pbXBvcnQgcmdiIGZyb20gXCIuL3JnYi5qc1wiO1xuaW1wb3J0IHsgZ2VuZXJpY0FycmF5IH0gZnJvbSBcIi4vYXJyYXkuanNcIjtcbmltcG9ydCBkYXRlIGZyb20gXCIuL2RhdGUuanNcIjtcbmltcG9ydCBudW1iZXIgZnJvbSBcIi4vbnVtYmVyLmpzXCI7XG5pbXBvcnQgb2JqZWN0IGZyb20gXCIuL29iamVjdC5qc1wiO1xuaW1wb3J0IHN0cmluZyBmcm9tIFwiLi9zdHJpbmcuanNcIjtcbmltcG9ydCBjb25zdGFudCBmcm9tIFwiLi9jb25zdGFudC5qc1wiO1xuaW1wb3J0IG51bWJlckFycmF5LCB7IGlzTnVtYmVyQXJyYXkgfSBmcm9tIFwiLi9udW1iZXJBcnJheS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKGEsIGIpIHtcbiAgdmFyIHQgPSB0eXBlb2YgYixcbiAgICAgIGM7XG4gIHJldHVybiBiID09IG51bGwgfHwgdCA9PT0gXCJib29sZWFuXCIgPyBjb25zdGFudChiKSA6ICh0ID09PSBcIm51bWJlclwiID8gbnVtYmVyIDogdCA9PT0gXCJzdHJpbmdcIiA/IChjID0gY29sb3IoYikpID8gKGIgPSBjLCByZ2IpIDogc3RyaW5nIDogYiBpbnN0YW5jZW9mIGNvbG9yID8gcmdiIDogYiBpbnN0YW5jZW9mIERhdGUgPyBkYXRlIDogaXNOdW1iZXJBcnJheShiKSA/IG51bWJlckFycmF5IDogQXJyYXkuaXNBcnJheShiKSA/IGdlbmVyaWNBcnJheSA6IHR5cGVvZiBiLnZhbHVlT2YgIT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgYi50b1N0cmluZyAhPT0gXCJmdW5jdGlvblwiIHx8IGlzTmFOKGIpID8gb2JqZWN0IDogbnVtYmVyKShhLCBiKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoYSwgYikge1xuICByZXR1cm4gYSA9ICthLCBiID0gK2IsIGZ1bmN0aW9uICh0KSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoYSAqICgxIC0gdCkgKyBiICogdCk7XG4gIH07XG59IiwiaW1wb3J0IHsgYmlzZWN0IH0gZnJvbSBcImQzLWFycmF5XCI7XG5pbXBvcnQgeyBpbnRlcnBvbGF0ZSBhcyBpbnRlcnBvbGF0ZVZhbHVlLCBpbnRlcnBvbGF0ZU51bWJlciwgaW50ZXJwb2xhdGVSb3VuZCB9IGZyb20gXCJkMy1pbnRlcnBvbGF0ZVwiO1xuaW1wb3J0IGNvbnN0YW50IGZyb20gXCIuL2NvbnN0YW50LmpzXCI7XG5pbXBvcnQgbnVtYmVyIGZyb20gXCIuL251bWJlci5qc1wiO1xudmFyIHVuaXQgPSBbMCwgMV07XG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpdHkoeCkge1xuICByZXR1cm4geDtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplKGEsIGIpIHtcbiAgcmV0dXJuIChiIC09IGEgPSArYSkgPyBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiAoeCAtIGEpIC8gYjtcbiAgfSA6IGNvbnN0YW50KGlzTmFOKGIpID8gTmFOIDogMC41KTtcbn1cblxuZnVuY3Rpb24gY2xhbXBlcihhLCBiKSB7XG4gIHZhciB0O1xuICBpZiAoYSA+IGIpIHQgPSBhLCBhID0gYiwgYiA9IHQ7XG4gIHJldHVybiBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiBNYXRoLm1heChhLCBNYXRoLm1pbihiLCB4KSk7XG4gIH07XG59IC8vIG5vcm1hbGl6ZShhLCBiKSh4KSB0YWtlcyBhIGRvbWFpbiB2YWx1ZSB4IGluIFthLGJdIGFuZCByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHBhcmFtZXRlciB0IGluIFswLDFdLlxuLy8gaW50ZXJwb2xhdGUoYSwgYikodCkgdGFrZXMgYSBwYXJhbWV0ZXIgdCBpbiBbMCwxXSBhbmQgcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyByYW5nZSB2YWx1ZSB4IGluIFthLGJdLlxuXG5cbmZ1bmN0aW9uIGJpbWFwKGRvbWFpbiwgcmFuZ2UsIGludGVycG9sYXRlKSB7XG4gIHZhciBkMCA9IGRvbWFpblswXSxcbiAgICAgIGQxID0gZG9tYWluWzFdLFxuICAgICAgcjAgPSByYW5nZVswXSxcbiAgICAgIHIxID0gcmFuZ2VbMV07XG4gIGlmIChkMSA8IGQwKSBkMCA9IG5vcm1hbGl6ZShkMSwgZDApLCByMCA9IGludGVycG9sYXRlKHIxLCByMCk7ZWxzZSBkMCA9IG5vcm1hbGl6ZShkMCwgZDEpLCByMCA9IGludGVycG9sYXRlKHIwLCByMSk7XG4gIHJldHVybiBmdW5jdGlvbiAoeCkge1xuICAgIHJldHVybiByMChkMCh4KSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHBvbHltYXAoZG9tYWluLCByYW5nZSwgaW50ZXJwb2xhdGUpIHtcbiAgdmFyIGogPSBNYXRoLm1pbihkb21haW4ubGVuZ3RoLCByYW5nZS5sZW5ndGgpIC0gMSxcbiAgICAgIGQgPSBuZXcgQXJyYXkoaiksXG4gICAgICByID0gbmV3IEFycmF5KGopLFxuICAgICAgaSA9IC0xOyAvLyBSZXZlcnNlIGRlc2NlbmRpbmcgZG9tYWlucy5cblxuICBpZiAoZG9tYWluW2pdIDwgZG9tYWluWzBdKSB7XG4gICAgZG9tYWluID0gZG9tYWluLnNsaWNlKCkucmV2ZXJzZSgpO1xuICAgIHJhbmdlID0gcmFuZ2Uuc2xpY2UoKS5yZXZlcnNlKCk7XG4gIH1cblxuICB3aGlsZSAoKytpIDwgaikge1xuICAgIGRbaV0gPSBub3JtYWxpemUoZG9tYWluW2ldLCBkb21haW5baSArIDFdKTtcbiAgICByW2ldID0gaW50ZXJwb2xhdGUocmFuZ2VbaV0sIHJhbmdlW2kgKyAxXSk7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gKHgpIHtcbiAgICB2YXIgaSA9IGJpc2VjdChkb21haW4sIHgsIDEsIGopIC0gMTtcbiAgICByZXR1cm4gcltpXShkW2ldKHgpKTtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvcHkoc291cmNlLCB0YXJnZXQpIHtcbiAgcmV0dXJuIHRhcmdldC5kb21haW4oc291cmNlLmRvbWFpbigpKS5yYW5nZShzb3VyY2UucmFuZ2UoKSkuaW50ZXJwb2xhdGUoc291cmNlLmludGVycG9sYXRlKCkpLmNsYW1wKHNvdXJjZS5jbGFtcCgpKS51bmtub3duKHNvdXJjZS51bmtub3duKCkpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybWVyKCkge1xuICB2YXIgZG9tYWluID0gdW5pdCxcbiAgICAgIHJhbmdlID0gdW5pdCxcbiAgICAgIGludGVycG9sYXRlID0gaW50ZXJwb2xhdGVWYWx1ZSxcbiAgICAgIHRyYW5zZm9ybSxcbiAgICAgIHVudHJhbnNmb3JtLFxuICAgICAgdW5rbm93bixcbiAgICAgIGNsYW1wID0gaWRlbnRpdHksXG4gICAgICBwaWVjZXdpc2UsXG4gICAgICBvdXRwdXQsXG4gICAgICBpbnB1dDtcblxuICBmdW5jdGlvbiByZXNjYWxlKCkge1xuICAgIHZhciBuID0gTWF0aC5taW4oZG9tYWluLmxlbmd0aCwgcmFuZ2UubGVuZ3RoKTtcbiAgICBpZiAoY2xhbXAgIT09IGlkZW50aXR5KSBjbGFtcCA9IGNsYW1wZXIoZG9tYWluWzBdLCBkb21haW5bbiAtIDFdKTtcbiAgICBwaWVjZXdpc2UgPSBuID4gMiA/IHBvbHltYXAgOiBiaW1hcDtcbiAgICBvdXRwdXQgPSBpbnB1dCA9IG51bGw7XG4gICAgcmV0dXJuIHNjYWxlO1xuICB9XG5cbiAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgIHJldHVybiB4ID09IG51bGwgfHwgaXNOYU4oeCA9ICt4KSA/IHVua25vd24gOiAob3V0cHV0IHx8IChvdXRwdXQgPSBwaWVjZXdpc2UoZG9tYWluLm1hcCh0cmFuc2Zvcm0pLCByYW5nZSwgaW50ZXJwb2xhdGUpKSkodHJhbnNmb3JtKGNsYW1wKHgpKSk7XG4gIH1cblxuICBzY2FsZS5pbnZlcnQgPSBmdW5jdGlvbiAoeSkge1xuICAgIHJldHVybiBjbGFtcCh1bnRyYW5zZm9ybSgoaW5wdXQgfHwgKGlucHV0ID0gcGllY2V3aXNlKHJhbmdlLCBkb21haW4ubWFwKHRyYW5zZm9ybSksIGludGVycG9sYXRlTnVtYmVyKSkpKHkpKSk7XG4gIH07XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkb21haW4gPSBBcnJheS5mcm9tKF8sIG51bWJlciksIHJlc2NhbGUoKSkgOiBkb21haW4uc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uIChfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocmFuZ2UgPSBBcnJheS5mcm9tKF8pLCByZXNjYWxlKCkpIDogcmFuZ2Uuc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZVJvdW5kID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gcmFuZ2UgPSBBcnJheS5mcm9tKF8pLCBpbnRlcnBvbGF0ZSA9IGludGVycG9sYXRlUm91bmQsIHJlc2NhbGUoKTtcbiAgfTtcblxuICBzY2FsZS5jbGFtcCA9IGZ1bmN0aW9uIChfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoY2xhbXAgPSBfID8gdHJ1ZSA6IGlkZW50aXR5LCByZXNjYWxlKCkpIDogY2xhbXAgIT09IGlkZW50aXR5O1xuICB9O1xuXG4gIHNjYWxlLmludGVycG9sYXRlID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChpbnRlcnBvbGF0ZSA9IF8sIHJlc2NhbGUoKSkgOiBpbnRlcnBvbGF0ZTtcbiAgfTtcblxuICBzY2FsZS51bmtub3duID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh1bmtub3duID0gXywgc2NhbGUpIDogdW5rbm93bjtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKHQsIHUpIHtcbiAgICB0cmFuc2Zvcm0gPSB0LCB1bnRyYW5zZm9ybSA9IHU7XG4gICAgcmV0dXJuIHJlc2NhbGUoKTtcbiAgfTtcbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbnRpbnVvdXMoKSB7XG4gIHJldHVybiB0cmFuc2Zvcm1lcigpKGlkZW50aXR5LCBpZGVudGl0eSk7XG59IiwiZXhwb3J0IGZ1bmN0aW9uIGluaXRSYW5nZShkb21haW4sIHJhbmdlKSB7XG4gIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIGNhc2UgMDpcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAxOlxuICAgICAgdGhpcy5yYW5nZShkb21haW4pO1xuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhpcy5yYW5nZShyYW5nZSkuZG9tYWluKGRvbWFpbik7XG4gICAgICBicmVhaztcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGluaXRJbnRlcnBvbGF0b3IoZG9tYWluLCBpbnRlcnBvbGF0b3IpIHtcbiAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgY2FzZSAwOlxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIDE6XG4gICAgICB7XG4gICAgICAgIGlmICh0eXBlb2YgZG9tYWluID09PSBcImZ1bmN0aW9uXCIpIHRoaXMuaW50ZXJwb2xhdG9yKGRvbWFpbik7ZWxzZSB0aGlzLnJhbmdlKGRvbWFpbik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHtcbiAgICAgICAgdGhpcy5kb21haW4oZG9tYWluKTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbnRlcnBvbGF0b3IgPT09IFwiZnVuY3Rpb25cIikgdGhpcy5pbnRlcnBvbGF0b3IoaW50ZXJwb2xhdG9yKTtlbHNlIHRoaXMucmFuZ2UoaW50ZXJwb2xhdG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn0iLCJ2YXIgZTEwID0gTWF0aC5zcXJ0KDUwKSxcbiAgICBlNSA9IE1hdGguc3FydCgxMCksXG4gICAgZTIgPSBNYXRoLnNxcnQoMik7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RhcnQsIHN0b3AsIGNvdW50KSB7XG4gIHZhciByZXZlcnNlLFxuICAgICAgaSA9IC0xLFxuICAgICAgbixcbiAgICAgIHRpY2tzLFxuICAgICAgc3RlcDtcbiAgc3RvcCA9ICtzdG9wLCBzdGFydCA9ICtzdGFydCwgY291bnQgPSArY291bnQ7XG4gIGlmIChzdGFydCA9PT0gc3RvcCAmJiBjb3VudCA+IDApIHJldHVybiBbc3RhcnRdO1xuICBpZiAocmV2ZXJzZSA9IHN0b3AgPCBzdGFydCkgbiA9IHN0YXJ0LCBzdGFydCA9IHN0b3AsIHN0b3AgPSBuO1xuICBpZiAoKHN0ZXAgPSB0aWNrSW5jcmVtZW50KHN0YXJ0LCBzdG9wLCBjb3VudCkpID09PSAwIHx8ICFpc0Zpbml0ZShzdGVwKSkgcmV0dXJuIFtdO1xuXG4gIGlmIChzdGVwID4gMCkge1xuICAgIHZhciByMCA9IE1hdGgucm91bmQoc3RhcnQgLyBzdGVwKSxcbiAgICAgICAgcjEgPSBNYXRoLnJvdW5kKHN0b3AgLyBzdGVwKTtcbiAgICBpZiAocjAgKiBzdGVwIDwgc3RhcnQpICsrcjA7XG4gICAgaWYgKHIxICogc3RlcCA+IHN0b3ApIC0tcjE7XG4gICAgdGlja3MgPSBuZXcgQXJyYXkobiA9IHIxIC0gcjAgKyAxKTtcblxuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICB0aWNrc1tpXSA9IChyMCArIGkpICogc3RlcDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc3RlcCA9IC1zdGVwO1xuXG4gICAgdmFyIF9yID0gTWF0aC5yb3VuZChzdGFydCAqIHN0ZXApLFxuICAgICAgICBfcjIgPSBNYXRoLnJvdW5kKHN0b3AgKiBzdGVwKTtcblxuICAgIGlmIChfciAvIHN0ZXAgPCBzdGFydCkgKytfcjtcbiAgICBpZiAoX3IyIC8gc3RlcCA+IHN0b3ApIC0tX3IyO1xuICAgIHRpY2tzID0gbmV3IEFycmF5KG4gPSBfcjIgLSBfciArIDEpO1xuXG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIHRpY2tzW2ldID0gKF9yICsgaSkgLyBzdGVwO1xuICAgIH1cbiAgfVxuXG4gIGlmIChyZXZlcnNlKSB0aWNrcy5yZXZlcnNlKCk7XG4gIHJldHVybiB0aWNrcztcbn1cbmV4cG9ydCBmdW5jdGlvbiB0aWNrSW5jcmVtZW50KHN0YXJ0LCBzdG9wLCBjb3VudCkge1xuICB2YXIgc3RlcCA9IChzdG9wIC0gc3RhcnQpIC8gTWF0aC5tYXgoMCwgY291bnQpLFxuICAgICAgcG93ZXIgPSBNYXRoLmZsb29yKE1hdGgubG9nKHN0ZXApIC8gTWF0aC5MTjEwKSxcbiAgICAgIGVycm9yID0gc3RlcCAvIE1hdGgucG93KDEwLCBwb3dlcik7XG4gIHJldHVybiBwb3dlciA+PSAwID8gKGVycm9yID49IGUxMCA/IDEwIDogZXJyb3IgPj0gZTUgPyA1IDogZXJyb3IgPj0gZTIgPyAyIDogMSkgKiBNYXRoLnBvdygxMCwgcG93ZXIpIDogLU1hdGgucG93KDEwLCAtcG93ZXIpIC8gKGVycm9yID49IGUxMCA/IDEwIDogZXJyb3IgPj0gZTUgPyA1IDogZXJyb3IgPj0gZTIgPyAyIDogMSk7XG59XG5leHBvcnQgZnVuY3Rpb24gdGlja1N0ZXAoc3RhcnQsIHN0b3AsIGNvdW50KSB7XG4gIHZhciBzdGVwMCA9IE1hdGguYWJzKHN0b3AgLSBzdGFydCkgLyBNYXRoLm1heCgwLCBjb3VudCksXG4gICAgICBzdGVwMSA9IE1hdGgucG93KDEwLCBNYXRoLmZsb29yKE1hdGgubG9nKHN0ZXAwKSAvIE1hdGguTE4xMCkpLFxuICAgICAgZXJyb3IgPSBzdGVwMCAvIHN0ZXAxO1xuICBpZiAoZXJyb3IgPj0gZTEwKSBzdGVwMSAqPSAxMDtlbHNlIGlmIChlcnJvciA+PSBlNSkgc3RlcDEgKj0gNTtlbHNlIGlmIChlcnJvciA+PSBlMikgc3RlcDEgKj0gMjtcbiAgcmV0dXJuIHN0b3AgPCBzdGFydCA/IC1zdGVwMSA6IHN0ZXAxO1xufSIsIi8vIFtbZmlsbF1hbGlnbl1bc2lnbl1bc3ltYm9sXVswXVt3aWR0aF1bLF1bLnByZWNpc2lvbl1bfl1bdHlwZV1cbnZhciByZSA9IC9eKD86KC4pPyhbPD49Xl0pKT8oWytcXC0oIF0pPyhbJCNdKT8oMCk/KFxcZCspPygsKT8oXFwuXFxkKyk/KH4pPyhbYS16JV0pPyQvaTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpIHtcbiAgaWYgKCEobWF0Y2ggPSByZS5leGVjKHNwZWNpZmllcikpKSB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIGZvcm1hdDogXCIgKyBzcGVjaWZpZXIpO1xuICB2YXIgbWF0Y2g7XG4gIHJldHVybiBuZXcgRm9ybWF0U3BlY2lmaWVyKHtcbiAgICBmaWxsOiBtYXRjaFsxXSxcbiAgICBhbGlnbjogbWF0Y2hbMl0sXG4gICAgc2lnbjogbWF0Y2hbM10sXG4gICAgc3ltYm9sOiBtYXRjaFs0XSxcbiAgICB6ZXJvOiBtYXRjaFs1XSxcbiAgICB3aWR0aDogbWF0Y2hbNl0sXG4gICAgY29tbWE6IG1hdGNoWzddLFxuICAgIHByZWNpc2lvbjogbWF0Y2hbOF0gJiYgbWF0Y2hbOF0uc2xpY2UoMSksXG4gICAgdHJpbTogbWF0Y2hbOV0sXG4gICAgdHlwZTogbWF0Y2hbMTBdXG4gIH0pO1xufVxuZm9ybWF0U3BlY2lmaWVyLnByb3RvdHlwZSA9IEZvcm1hdFNwZWNpZmllci5wcm90b3R5cGU7IC8vIGluc3RhbmNlb2ZcblxuZXhwb3J0IGZ1bmN0aW9uIEZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpIHtcbiAgdGhpcy5maWxsID0gc3BlY2lmaWVyLmZpbGwgPT09IHVuZGVmaW5lZCA/IFwiIFwiIDogc3BlY2lmaWVyLmZpbGwgKyBcIlwiO1xuICB0aGlzLmFsaWduID0gc3BlY2lmaWVyLmFsaWduID09PSB1bmRlZmluZWQgPyBcIj5cIiA6IHNwZWNpZmllci5hbGlnbiArIFwiXCI7XG4gIHRoaXMuc2lnbiA9IHNwZWNpZmllci5zaWduID09PSB1bmRlZmluZWQgPyBcIi1cIiA6IHNwZWNpZmllci5zaWduICsgXCJcIjtcbiAgdGhpcy5zeW1ib2wgPSBzcGVjaWZpZXIuc3ltYm9sID09PSB1bmRlZmluZWQgPyBcIlwiIDogc3BlY2lmaWVyLnN5bWJvbCArIFwiXCI7XG4gIHRoaXMuemVybyA9ICEhc3BlY2lmaWVyLnplcm87XG4gIHRoaXMud2lkdGggPSBzcGVjaWZpZXIud2lkdGggPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6ICtzcGVjaWZpZXIud2lkdGg7XG4gIHRoaXMuY29tbWEgPSAhIXNwZWNpZmllci5jb21tYTtcbiAgdGhpcy5wcmVjaXNpb24gPSBzcGVjaWZpZXIucHJlY2lzaW9uID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiArc3BlY2lmaWVyLnByZWNpc2lvbjtcbiAgdGhpcy50cmltID0gISFzcGVjaWZpZXIudHJpbTtcbiAgdGhpcy50eXBlID0gc3BlY2lmaWVyLnR5cGUgPT09IHVuZGVmaW5lZCA/IFwiXCIgOiBzcGVjaWZpZXIudHlwZSArIFwiXCI7XG59XG5cbkZvcm1hdFNwZWNpZmllci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLmZpbGwgKyB0aGlzLmFsaWduICsgdGhpcy5zaWduICsgdGhpcy5zeW1ib2wgKyAodGhpcy56ZXJvID8gXCIwXCIgOiBcIlwiKSArICh0aGlzLndpZHRoID09PSB1bmRlZmluZWQgPyBcIlwiIDogTWF0aC5tYXgoMSwgdGhpcy53aWR0aCB8IDApKSArICh0aGlzLmNvbW1hID8gXCIsXCIgOiBcIlwiKSArICh0aGlzLnByZWNpc2lvbiA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IFwiLlwiICsgTWF0aC5tYXgoMCwgdGhpcy5wcmVjaXNpb24gfCAwKSkgKyAodGhpcy50cmltID8gXCJ+XCIgOiBcIlwiKSArIHRoaXMudHlwZTtcbn07IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHgpIHtcbiAgcmV0dXJuIE1hdGguYWJzKHggPSBNYXRoLnJvdW5kKHgpKSA+PSAxZTIxID8geC50b0xvY2FsZVN0cmluZyhcImVuXCIpLnJlcGxhY2UoLywvZywgXCJcIikgOiB4LnRvU3RyaW5nKDEwKTtcbn0gLy8gQ29tcHV0ZXMgdGhlIGRlY2ltYWwgY29lZmZpY2llbnQgYW5kIGV4cG9uZW50IG9mIHRoZSBzcGVjaWZpZWQgbnVtYmVyIHggd2l0aFxuLy8gc2lnbmlmaWNhbnQgZGlnaXRzIHAsIHdoZXJlIHggaXMgcG9zaXRpdmUgYW5kIHAgaXMgaW4gWzEsIDIxXSBvciB1bmRlZmluZWQuXG4vLyBGb3IgZXhhbXBsZSwgZm9ybWF0RGVjaW1hbFBhcnRzKDEuMjMpIHJldHVybnMgW1wiMTIzXCIsIDBdLlxuXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0RGVjaW1hbFBhcnRzKHgsIHApIHtcbiAgaWYgKChpID0gKHggPSBwID8geC50b0V4cG9uZW50aWFsKHAgLSAxKSA6IHgudG9FeHBvbmVudGlhbCgpKS5pbmRleE9mKFwiZVwiKSkgPCAwKSByZXR1cm4gbnVsbDsgLy8gTmFOLCDCsUluZmluaXR5XG5cbiAgdmFyIGksXG4gICAgICBjb2VmZmljaWVudCA9IHguc2xpY2UoMCwgaSk7IC8vIFRoZSBzdHJpbmcgcmV0dXJuZWQgYnkgdG9FeHBvbmVudGlhbCBlaXRoZXIgaGFzIHRoZSBmb3JtIFxcZFxcLlxcZCtlWy0rXVxcZCtcbiAgLy8gKGUuZy4sIDEuMmUrMykgb3IgdGhlIGZvcm0gXFxkZVstK11cXGQrIChlLmcuLCAxZSszKS5cblxuICByZXR1cm4gW2NvZWZmaWNpZW50Lmxlbmd0aCA+IDEgPyBjb2VmZmljaWVudFswXSArIGNvZWZmaWNpZW50LnNsaWNlKDIpIDogY29lZmZpY2llbnQsICt4LnNsaWNlKGkgKyAxKV07XG59IiwiaW1wb3J0IHsgZm9ybWF0RGVjaW1hbFBhcnRzIH0gZnJvbSBcIi4vZm9ybWF0RGVjaW1hbC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHgpIHtcbiAgcmV0dXJuIHggPSBmb3JtYXREZWNpbWFsUGFydHMoTWF0aC5hYnMoeCkpLCB4ID8geFsxXSA6IE5hTjtcbn0iLCJpbXBvcnQgZXhwb25lbnQgZnJvbSBcIi4vZXhwb25lbnQuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzdGVwLCB2YWx1ZSkge1xuICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5tYXgoLTgsIE1hdGgubWluKDgsIE1hdGguZmxvb3IoZXhwb25lbnQodmFsdWUpIC8gMykpKSAqIDMgLSBleHBvbmVudChNYXRoLmFicyhzdGVwKSkpO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChncm91cGluZywgdGhvdXNhbmRzKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIHdpZHRoKSB7XG4gICAgdmFyIGkgPSB2YWx1ZS5sZW5ndGgsXG4gICAgICAgIHQgPSBbXSxcbiAgICAgICAgaiA9IDAsXG4gICAgICAgIGcgPSBncm91cGluZ1swXSxcbiAgICAgICAgbGVuZ3RoID0gMDtcblxuICAgIHdoaWxlIChpID4gMCAmJiBnID4gMCkge1xuICAgICAgaWYgKGxlbmd0aCArIGcgKyAxID4gd2lkdGgpIGcgPSBNYXRoLm1heCgxLCB3aWR0aCAtIGxlbmd0aCk7XG4gICAgICB0LnB1c2godmFsdWUuc3Vic3RyaW5nKGkgLT0gZywgaSArIGcpKTtcbiAgICAgIGlmICgobGVuZ3RoICs9IGcgKyAxKSA+IHdpZHRoKSBicmVhaztcbiAgICAgIGcgPSBncm91cGluZ1tqID0gKGogKyAxKSAlIGdyb3VwaW5nLmxlbmd0aF07XG4gICAgfVxuXG4gICAgcmV0dXJuIHQucmV2ZXJzZSgpLmpvaW4odGhvdXNhbmRzKTtcbiAgfTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAobnVtZXJhbHMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZS5yZXBsYWNlKC9bMC05XS9nLCBmdW5jdGlvbiAoaSkge1xuICAgICAgcmV0dXJuIG51bWVyYWxzWytpXTtcbiAgICB9KTtcbiAgfTtcbn0iLCIvLyBUcmltcyBpbnNpZ25pZmljYW50IHplcm9zLCBlLmcuLCByZXBsYWNlcyAxLjIwMDBrIHdpdGggMS4yay5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzKSB7XG4gIG91dDogZm9yICh2YXIgbiA9IHMubGVuZ3RoLCBpID0gMSwgaTAgPSAtMSwgaTE7IGkgPCBuOyArK2kpIHtcbiAgICBzd2l0Y2ggKHNbaV0pIHtcbiAgICAgIGNhc2UgXCIuXCI6XG4gICAgICAgIGkwID0gaTEgPSBpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcIjBcIjpcbiAgICAgICAgaWYgKGkwID09PSAwKSBpMCA9IGk7XG4gICAgICAgIGkxID0gaTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmICghK3NbaV0pIGJyZWFrIG91dDtcbiAgICAgICAgaWYgKGkwID4gMCkgaTAgPSAwO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaTAgPiAwID8gcy5zbGljZSgwLCBpMCkgKyBzLnNsaWNlKGkxICsgMSkgOiBzO1xufSIsImltcG9ydCB7IGZvcm1hdERlY2ltYWxQYXJ0cyB9IGZyb20gXCIuL2Zvcm1hdERlY2ltYWwuanNcIjtcbmV4cG9ydCB2YXIgcHJlZml4RXhwb25lbnQ7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoeCwgcCkge1xuICB2YXIgZCA9IGZvcm1hdERlY2ltYWxQYXJ0cyh4LCBwKTtcbiAgaWYgKCFkKSByZXR1cm4geCArIFwiXCI7XG4gIHZhciBjb2VmZmljaWVudCA9IGRbMF0sXG4gICAgICBleHBvbmVudCA9IGRbMV0sXG4gICAgICBpID0gZXhwb25lbnQgLSAocHJlZml4RXhwb25lbnQgPSBNYXRoLm1heCgtOCwgTWF0aC5taW4oOCwgTWF0aC5mbG9vcihleHBvbmVudCAvIDMpKSkgKiAzKSArIDEsXG4gICAgICBuID0gY29lZmZpY2llbnQubGVuZ3RoO1xuICByZXR1cm4gaSA9PT0gbiA/IGNvZWZmaWNpZW50IDogaSA+IG4gPyBjb2VmZmljaWVudCArIG5ldyBBcnJheShpIC0gbiArIDEpLmpvaW4oXCIwXCIpIDogaSA+IDAgPyBjb2VmZmljaWVudC5zbGljZSgwLCBpKSArIFwiLlwiICsgY29lZmZpY2llbnQuc2xpY2UoaSkgOiBcIjAuXCIgKyBuZXcgQXJyYXkoMSAtIGkpLmpvaW4oXCIwXCIpICsgZm9ybWF0RGVjaW1hbFBhcnRzKHgsIE1hdGgubWF4KDAsIHAgKyBpIC0gMSkpWzBdOyAvLyBsZXNzIHRoYW4gMXkhXG59IiwiaW1wb3J0IHsgZm9ybWF0RGVjaW1hbFBhcnRzIH0gZnJvbSBcIi4vZm9ybWF0RGVjaW1hbC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHgsIHApIHtcbiAgdmFyIGQgPSBmb3JtYXREZWNpbWFsUGFydHMoeCwgcCk7XG4gIGlmICghZCkgcmV0dXJuIHggKyBcIlwiO1xuICB2YXIgY29lZmZpY2llbnQgPSBkWzBdLFxuICAgICAgZXhwb25lbnQgPSBkWzFdO1xuICByZXR1cm4gZXhwb25lbnQgPCAwID8gXCIwLlwiICsgbmV3IEFycmF5KC1leHBvbmVudCkuam9pbihcIjBcIikgKyBjb2VmZmljaWVudCA6IGNvZWZmaWNpZW50Lmxlbmd0aCA+IGV4cG9uZW50ICsgMSA/IGNvZWZmaWNpZW50LnNsaWNlKDAsIGV4cG9uZW50ICsgMSkgKyBcIi5cIiArIGNvZWZmaWNpZW50LnNsaWNlKGV4cG9uZW50ICsgMSkgOiBjb2VmZmljaWVudCArIG5ldyBBcnJheShleHBvbmVudCAtIGNvZWZmaWNpZW50Lmxlbmd0aCArIDIpLmpvaW4oXCIwXCIpO1xufSIsImltcG9ydCBmb3JtYXREZWNpbWFsIGZyb20gXCIuL2Zvcm1hdERlY2ltYWwuanNcIjtcbmltcG9ydCBmb3JtYXRQcmVmaXhBdXRvIGZyb20gXCIuL2Zvcm1hdFByZWZpeEF1dG8uanNcIjtcbmltcG9ydCBmb3JtYXRSb3VuZGVkIGZyb20gXCIuL2Zvcm1hdFJvdW5kZWQuanNcIjtcbmV4cG9ydCBkZWZhdWx0IHtcbiAgXCIlXCI6IGZ1bmN0aW9uIF8oeCwgcCkge1xuICAgIHJldHVybiAoeCAqIDEwMCkudG9GaXhlZChwKTtcbiAgfSxcbiAgXCJiXCI6IGZ1bmN0aW9uIGIoeCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKHgpLnRvU3RyaW5nKDIpO1xuICB9LFxuICBcImNcIjogZnVuY3Rpb24gYyh4KSB7XG4gICAgcmV0dXJuIHggKyBcIlwiO1xuICB9LFxuICBcImRcIjogZm9ybWF0RGVjaW1hbCxcbiAgXCJlXCI6IGZ1bmN0aW9uIGUoeCwgcCkge1xuICAgIHJldHVybiB4LnRvRXhwb25lbnRpYWwocCk7XG4gIH0sXG4gIFwiZlwiOiBmdW5jdGlvbiBmKHgsIHApIHtcbiAgICByZXR1cm4geC50b0ZpeGVkKHApO1xuICB9LFxuICBcImdcIjogZnVuY3Rpb24gZyh4LCBwKSB7XG4gICAgcmV0dXJuIHgudG9QcmVjaXNpb24ocCk7XG4gIH0sXG4gIFwib1wiOiBmdW5jdGlvbiBvKHgpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZCh4KS50b1N0cmluZyg4KTtcbiAgfSxcbiAgXCJwXCI6IGZ1bmN0aW9uIHAoeCwgX3ApIHtcbiAgICByZXR1cm4gZm9ybWF0Um91bmRlZCh4ICogMTAwLCBfcCk7XG4gIH0sXG4gIFwiclwiOiBmb3JtYXRSb3VuZGVkLFxuICBcInNcIjogZm9ybWF0UHJlZml4QXV0byxcbiAgXCJYXCI6IGZ1bmN0aW9uIFgoeCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKHgpLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xuICB9LFxuICBcInhcIjogZnVuY3Rpb24geChfeCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKF94KS50b1N0cmluZygxNik7XG4gIH1cbn07IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHgpIHtcbiAgcmV0dXJuIHg7XG59IiwiaW1wb3J0IGV4cG9uZW50IGZyb20gXCIuL2V4cG9uZW50LmpzXCI7XG5pbXBvcnQgZm9ybWF0R3JvdXAgZnJvbSBcIi4vZm9ybWF0R3JvdXAuanNcIjtcbmltcG9ydCBmb3JtYXROdW1lcmFscyBmcm9tIFwiLi9mb3JtYXROdW1lcmFscy5qc1wiO1xuaW1wb3J0IGZvcm1hdFNwZWNpZmllciBmcm9tIFwiLi9mb3JtYXRTcGVjaWZpZXIuanNcIjtcbmltcG9ydCBmb3JtYXRUcmltIGZyb20gXCIuL2Zvcm1hdFRyaW0uanNcIjtcbmltcG9ydCBmb3JtYXRUeXBlcyBmcm9tIFwiLi9mb3JtYXRUeXBlcy5qc1wiO1xuaW1wb3J0IHsgcHJlZml4RXhwb25lbnQgfSBmcm9tIFwiLi9mb3JtYXRQcmVmaXhBdXRvLmpzXCI7XG5pbXBvcnQgaWRlbnRpdHkgZnJvbSBcIi4vaWRlbnRpdHkuanNcIjtcbnZhciBtYXAgPSBBcnJheS5wcm90b3R5cGUubWFwLFxuICAgIHByZWZpeGVzID0gW1wieVwiLCBcInpcIiwgXCJhXCIsIFwiZlwiLCBcInBcIiwgXCJuXCIsIFwiwrVcIiwgXCJtXCIsIFwiXCIsIFwia1wiLCBcIk1cIiwgXCJHXCIsIFwiVFwiLCBcIlBcIiwgXCJFXCIsIFwiWlwiLCBcIllcIl07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAobG9jYWxlKSB7XG4gIHZhciBncm91cCA9IGxvY2FsZS5ncm91cGluZyA9PT0gdW5kZWZpbmVkIHx8IGxvY2FsZS50aG91c2FuZHMgPT09IHVuZGVmaW5lZCA/IGlkZW50aXR5IDogZm9ybWF0R3JvdXAobWFwLmNhbGwobG9jYWxlLmdyb3VwaW5nLCBOdW1iZXIpLCBsb2NhbGUudGhvdXNhbmRzICsgXCJcIiksXG4gICAgICBjdXJyZW5jeVByZWZpeCA9IGxvY2FsZS5jdXJyZW5jeSA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IGxvY2FsZS5jdXJyZW5jeVswXSArIFwiXCIsXG4gICAgICBjdXJyZW5jeVN1ZmZpeCA9IGxvY2FsZS5jdXJyZW5jeSA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IGxvY2FsZS5jdXJyZW5jeVsxXSArIFwiXCIsXG4gICAgICBkZWNpbWFsID0gbG9jYWxlLmRlY2ltYWwgPT09IHVuZGVmaW5lZCA/IFwiLlwiIDogbG9jYWxlLmRlY2ltYWwgKyBcIlwiLFxuICAgICAgbnVtZXJhbHMgPSBsb2NhbGUubnVtZXJhbHMgPT09IHVuZGVmaW5lZCA/IGlkZW50aXR5IDogZm9ybWF0TnVtZXJhbHMobWFwLmNhbGwobG9jYWxlLm51bWVyYWxzLCBTdHJpbmcpKSxcbiAgICAgIHBlcmNlbnQgPSBsb2NhbGUucGVyY2VudCA9PT0gdW5kZWZpbmVkID8gXCIlXCIgOiBsb2NhbGUucGVyY2VudCArIFwiXCIsXG4gICAgICBtaW51cyA9IGxvY2FsZS5taW51cyA9PT0gdW5kZWZpbmVkID8gXCLiiJJcIiA6IGxvY2FsZS5taW51cyArIFwiXCIsXG4gICAgICBuYW4gPSBsb2NhbGUubmFuID09PSB1bmRlZmluZWQgPyBcIk5hTlwiIDogbG9jYWxlLm5hbiArIFwiXCI7XG5cbiAgZnVuY3Rpb24gbmV3Rm9ybWF0KHNwZWNpZmllcikge1xuICAgIHNwZWNpZmllciA9IGZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpO1xuICAgIHZhciBmaWxsID0gc3BlY2lmaWVyLmZpbGwsXG4gICAgICAgIGFsaWduID0gc3BlY2lmaWVyLmFsaWduLFxuICAgICAgICBzaWduID0gc3BlY2lmaWVyLnNpZ24sXG4gICAgICAgIHN5bWJvbCA9IHNwZWNpZmllci5zeW1ib2wsXG4gICAgICAgIHplcm8gPSBzcGVjaWZpZXIuemVybyxcbiAgICAgICAgd2lkdGggPSBzcGVjaWZpZXIud2lkdGgsXG4gICAgICAgIGNvbW1hID0gc3BlY2lmaWVyLmNvbW1hLFxuICAgICAgICBwcmVjaXNpb24gPSBzcGVjaWZpZXIucHJlY2lzaW9uLFxuICAgICAgICB0cmltID0gc3BlY2lmaWVyLnRyaW0sXG4gICAgICAgIHR5cGUgPSBzcGVjaWZpZXIudHlwZTsgLy8gVGhlIFwiblwiIHR5cGUgaXMgYW4gYWxpYXMgZm9yIFwiLGdcIi5cblxuICAgIGlmICh0eXBlID09PSBcIm5cIikgY29tbWEgPSB0cnVlLCB0eXBlID0gXCJnXCI7IC8vIFRoZSBcIlwiIHR5cGUsIGFuZCBhbnkgaW52YWxpZCB0eXBlLCBpcyBhbiBhbGlhcyBmb3IgXCIuMTJ+Z1wiLlxuICAgIGVsc2UgaWYgKCFmb3JtYXRUeXBlc1t0eXBlXSkgcHJlY2lzaW9uID09PSB1bmRlZmluZWQgJiYgKHByZWNpc2lvbiA9IDEyKSwgdHJpbSA9IHRydWUsIHR5cGUgPSBcImdcIjsgLy8gSWYgemVybyBmaWxsIGlzIHNwZWNpZmllZCwgcGFkZGluZyBnb2VzIGFmdGVyIHNpZ24gYW5kIGJlZm9yZSBkaWdpdHMuXG5cbiAgICBpZiAoemVybyB8fCBmaWxsID09PSBcIjBcIiAmJiBhbGlnbiA9PT0gXCI9XCIpIHplcm8gPSB0cnVlLCBmaWxsID0gXCIwXCIsIGFsaWduID0gXCI9XCI7IC8vIENvbXB1dGUgdGhlIHByZWZpeCBhbmQgc3VmZml4LlxuICAgIC8vIEZvciBTSS1wcmVmaXgsIHRoZSBzdWZmaXggaXMgbGF6aWx5IGNvbXB1dGVkLlxuXG4gICAgdmFyIHByZWZpeCA9IHN5bWJvbCA9PT0gXCIkXCIgPyBjdXJyZW5jeVByZWZpeCA6IHN5bWJvbCA9PT0gXCIjXCIgJiYgL1tib3hYXS8udGVzdCh0eXBlKSA/IFwiMFwiICsgdHlwZS50b0xvd2VyQ2FzZSgpIDogXCJcIixcbiAgICAgICAgc3VmZml4ID0gc3ltYm9sID09PSBcIiRcIiA/IGN1cnJlbmN5U3VmZml4IDogL1slcF0vLnRlc3QodHlwZSkgPyBwZXJjZW50IDogXCJcIjsgLy8gV2hhdCBmb3JtYXQgZnVuY3Rpb24gc2hvdWxkIHdlIHVzZT9cbiAgICAvLyBJcyB0aGlzIGFuIGludGVnZXIgdHlwZT9cbiAgICAvLyBDYW4gdGhpcyB0eXBlIGdlbmVyYXRlIGV4cG9uZW50aWFsIG5vdGF0aW9uP1xuXG4gICAgdmFyIGZvcm1hdFR5cGUgPSBmb3JtYXRUeXBlc1t0eXBlXSxcbiAgICAgICAgbWF5YmVTdWZmaXggPSAvW2RlZmdwcnMlXS8udGVzdCh0eXBlKTsgLy8gU2V0IHRoZSBkZWZhdWx0IHByZWNpc2lvbiBpZiBub3Qgc3BlY2lmaWVkLFxuICAgIC8vIG9yIGNsYW1wIHRoZSBzcGVjaWZpZWQgcHJlY2lzaW9uIHRvIHRoZSBzdXBwb3J0ZWQgcmFuZ2UuXG4gICAgLy8gRm9yIHNpZ25pZmljYW50IHByZWNpc2lvbiwgaXQgbXVzdCBiZSBpbiBbMSwgMjFdLlxuICAgIC8vIEZvciBmaXhlZCBwcmVjaXNpb24sIGl0IG11c3QgYmUgaW4gWzAsIDIwXS5cblxuICAgIHByZWNpc2lvbiA9IHByZWNpc2lvbiA9PT0gdW5kZWZpbmVkID8gNiA6IC9bZ3Byc10vLnRlc3QodHlwZSkgPyBNYXRoLm1heCgxLCBNYXRoLm1pbigyMSwgcHJlY2lzaW9uKSkgOiBNYXRoLm1heCgwLCBNYXRoLm1pbigyMCwgcHJlY2lzaW9uKSk7XG5cbiAgICBmdW5jdGlvbiBmb3JtYXQodmFsdWUpIHtcbiAgICAgIHZhciB2YWx1ZVByZWZpeCA9IHByZWZpeCxcbiAgICAgICAgICB2YWx1ZVN1ZmZpeCA9IHN1ZmZpeCxcbiAgICAgICAgICBpLFxuICAgICAgICAgIG4sXG4gICAgICAgICAgYztcblxuICAgICAgaWYgKHR5cGUgPT09IFwiY1wiKSB7XG4gICAgICAgIHZhbHVlU3VmZml4ID0gZm9ybWF0VHlwZSh2YWx1ZSkgKyB2YWx1ZVN1ZmZpeDtcbiAgICAgICAgdmFsdWUgPSBcIlwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSArdmFsdWU7IC8vIERldGVybWluZSB0aGUgc2lnbi4gLTAgaXMgbm90IGxlc3MgdGhhbiAwLCBidXQgMSAvIC0wIGlzIVxuXG4gICAgICAgIHZhciB2YWx1ZU5lZ2F0aXZlID0gdmFsdWUgPCAwIHx8IDEgLyB2YWx1ZSA8IDA7IC8vIFBlcmZvcm0gdGhlIGluaXRpYWwgZm9ybWF0dGluZy5cblxuICAgICAgICB2YWx1ZSA9IGlzTmFOKHZhbHVlKSA/IG5hbiA6IGZvcm1hdFR5cGUoTWF0aC5hYnModmFsdWUpLCBwcmVjaXNpb24pOyAvLyBUcmltIGluc2lnbmlmaWNhbnQgemVyb3MuXG5cbiAgICAgICAgaWYgKHRyaW0pIHZhbHVlID0gZm9ybWF0VHJpbSh2YWx1ZSk7IC8vIElmIGEgbmVnYXRpdmUgdmFsdWUgcm91bmRzIHRvIHplcm8gYWZ0ZXIgZm9ybWF0dGluZywgYW5kIG5vIGV4cGxpY2l0IHBvc2l0aXZlIHNpZ24gaXMgcmVxdWVzdGVkLCBoaWRlIHRoZSBzaWduLlxuXG4gICAgICAgIGlmICh2YWx1ZU5lZ2F0aXZlICYmICt2YWx1ZSA9PT0gMCAmJiBzaWduICE9PSBcIitcIikgdmFsdWVOZWdhdGl2ZSA9IGZhbHNlOyAvLyBDb21wdXRlIHRoZSBwcmVmaXggYW5kIHN1ZmZpeC5cblxuICAgICAgICB2YWx1ZVByZWZpeCA9ICh2YWx1ZU5lZ2F0aXZlID8gc2lnbiA9PT0gXCIoXCIgPyBzaWduIDogbWludXMgOiBzaWduID09PSBcIi1cIiB8fCBzaWduID09PSBcIihcIiA/IFwiXCIgOiBzaWduKSArIHZhbHVlUHJlZml4O1xuICAgICAgICB2YWx1ZVN1ZmZpeCA9ICh0eXBlID09PSBcInNcIiA/IHByZWZpeGVzWzggKyBwcmVmaXhFeHBvbmVudCAvIDNdIDogXCJcIikgKyB2YWx1ZVN1ZmZpeCArICh2YWx1ZU5lZ2F0aXZlICYmIHNpZ24gPT09IFwiKFwiID8gXCIpXCIgOiBcIlwiKTsgLy8gQnJlYWsgdGhlIGZvcm1hdHRlZCB2YWx1ZSBpbnRvIHRoZSBpbnRlZ2VyIOKAnHZhbHVl4oCdIHBhcnQgdGhhdCBjYW4gYmVcbiAgICAgICAgLy8gZ3JvdXBlZCwgYW5kIGZyYWN0aW9uYWwgb3IgZXhwb25lbnRpYWwg4oCcc3VmZml44oCdIHBhcnQgdGhhdCBpcyBub3QuXG5cbiAgICAgICAgaWYgKG1heWJlU3VmZml4KSB7XG4gICAgICAgICAgaSA9IC0xLCBuID0gdmFsdWUubGVuZ3RoO1xuXG4gICAgICAgICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgICAgICAgIGlmIChjID0gdmFsdWUuY2hhckNvZGVBdChpKSwgNDggPiBjIHx8IGMgPiA1Nykge1xuICAgICAgICAgICAgICB2YWx1ZVN1ZmZpeCA9IChjID09PSA0NiA/IGRlY2ltYWwgKyB2YWx1ZS5zbGljZShpICsgMSkgOiB2YWx1ZS5zbGljZShpKSkgKyB2YWx1ZVN1ZmZpeDtcbiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zbGljZSgwLCBpKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IC8vIElmIHRoZSBmaWxsIGNoYXJhY3RlciBpcyBub3QgXCIwXCIsIGdyb3VwaW5nIGlzIGFwcGxpZWQgYmVmb3JlIHBhZGRpbmcuXG5cblxuICAgICAgaWYgKGNvbW1hICYmICF6ZXJvKSB2YWx1ZSA9IGdyb3VwKHZhbHVlLCBJbmZpbml0eSk7IC8vIENvbXB1dGUgdGhlIHBhZGRpbmcuXG5cbiAgICAgIHZhciBsZW5ndGggPSB2YWx1ZVByZWZpeC5sZW5ndGggKyB2YWx1ZS5sZW5ndGggKyB2YWx1ZVN1ZmZpeC5sZW5ndGgsXG4gICAgICAgICAgcGFkZGluZyA9IGxlbmd0aCA8IHdpZHRoID8gbmV3IEFycmF5KHdpZHRoIC0gbGVuZ3RoICsgMSkuam9pbihmaWxsKSA6IFwiXCI7IC8vIElmIHRoZSBmaWxsIGNoYXJhY3RlciBpcyBcIjBcIiwgZ3JvdXBpbmcgaXMgYXBwbGllZCBhZnRlciBwYWRkaW5nLlxuXG4gICAgICBpZiAoY29tbWEgJiYgemVybykgdmFsdWUgPSBncm91cChwYWRkaW5nICsgdmFsdWUsIHBhZGRpbmcubGVuZ3RoID8gd2lkdGggLSB2YWx1ZVN1ZmZpeC5sZW5ndGggOiBJbmZpbml0eSksIHBhZGRpbmcgPSBcIlwiOyAvLyBSZWNvbnN0cnVjdCB0aGUgZmluYWwgb3V0cHV0IGJhc2VkIG9uIHRoZSBkZXNpcmVkIGFsaWdubWVudC5cblxuICAgICAgc3dpdGNoIChhbGlnbikge1xuICAgICAgICBjYXNlIFwiPFwiOlxuICAgICAgICAgIHZhbHVlID0gdmFsdWVQcmVmaXggKyB2YWx1ZSArIHZhbHVlU3VmZml4ICsgcGFkZGluZztcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiPVwiOlxuICAgICAgICAgIHZhbHVlID0gdmFsdWVQcmVmaXggKyBwYWRkaW5nICsgdmFsdWUgKyB2YWx1ZVN1ZmZpeDtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwiXlwiOlxuICAgICAgICAgIHZhbHVlID0gcGFkZGluZy5zbGljZSgwLCBsZW5ndGggPSBwYWRkaW5nLmxlbmd0aCA+PiAxKSArIHZhbHVlUHJlZml4ICsgdmFsdWUgKyB2YWx1ZVN1ZmZpeCArIHBhZGRpbmcuc2xpY2UobGVuZ3RoKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHZhbHVlID0gcGFkZGluZyArIHZhbHVlUHJlZml4ICsgdmFsdWUgKyB2YWx1ZVN1ZmZpeDtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bWVyYWxzKHZhbHVlKTtcbiAgICB9XG5cbiAgICBmb3JtYXQudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gc3BlY2lmaWVyICsgXCJcIjtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGZvcm1hdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFByZWZpeChzcGVjaWZpZXIsIHZhbHVlKSB7XG4gICAgdmFyIGYgPSBuZXdGb3JtYXQoKHNwZWNpZmllciA9IGZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpLCBzcGVjaWZpZXIudHlwZSA9IFwiZlwiLCBzcGVjaWZpZXIpKSxcbiAgICAgICAgZSA9IE1hdGgubWF4KC04LCBNYXRoLm1pbig4LCBNYXRoLmZsb29yKGV4cG9uZW50KHZhbHVlKSAvIDMpKSkgKiAzLFxuICAgICAgICBrID0gTWF0aC5wb3coMTAsIC1lKSxcbiAgICAgICAgcHJlZml4ID0gcHJlZml4ZXNbOCArIGUgLyAzXTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZihrICogdmFsdWUpICsgcHJlZml4O1xuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGZvcm1hdDogbmV3Rm9ybWF0LFxuICAgIGZvcm1hdFByZWZpeDogZm9ybWF0UHJlZml4XG4gIH07XG59IiwiaW1wb3J0IGZvcm1hdExvY2FsZSBmcm9tIFwiLi9sb2NhbGUuanNcIjtcbnZhciBsb2NhbGU7XG5leHBvcnQgdmFyIGZvcm1hdDtcbmV4cG9ydCB2YXIgZm9ybWF0UHJlZml4O1xuZGVmYXVsdExvY2FsZSh7XG4gIHRob3VzYW5kczogXCIsXCIsXG4gIGdyb3VwaW5nOiBbM10sXG4gIGN1cnJlbmN5OiBbXCIkXCIsIFwiXCJdXG59KTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGRlZmF1bHRMb2NhbGUoZGVmaW5pdGlvbikge1xuICBsb2NhbGUgPSBmb3JtYXRMb2NhbGUoZGVmaW5pdGlvbik7XG4gIGZvcm1hdCA9IGxvY2FsZS5mb3JtYXQ7XG4gIGZvcm1hdFByZWZpeCA9IGxvY2FsZS5mb3JtYXRQcmVmaXg7XG4gIHJldHVybiBsb2NhbGU7XG59IiwiaW1wb3J0IGV4cG9uZW50IGZyb20gXCIuL2V4cG9uZW50LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RlcCwgbWF4KSB7XG4gIHN0ZXAgPSBNYXRoLmFicyhzdGVwKSwgbWF4ID0gTWF0aC5hYnMobWF4KSAtIHN0ZXA7XG4gIHJldHVybiBNYXRoLm1heCgwLCBleHBvbmVudChtYXgpIC0gZXhwb25lbnQoc3RlcCkpICsgMTtcbn0iLCJpbXBvcnQgZXhwb25lbnQgZnJvbSBcIi4vZXhwb25lbnQuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzdGVwKSB7XG4gIHJldHVybiBNYXRoLm1heCgwLCAtZXhwb25lbnQoTWF0aC5hYnMoc3RlcCkpKTtcbn0iLCJpbXBvcnQgeyB0aWNrU3RlcCB9IGZyb20gXCJkMy1hcnJheVwiO1xuaW1wb3J0IHsgZm9ybWF0LCBmb3JtYXRQcmVmaXgsIGZvcm1hdFNwZWNpZmllciwgcHJlY2lzaW9uRml4ZWQsIHByZWNpc2lvblByZWZpeCwgcHJlY2lzaW9uUm91bmQgfSBmcm9tIFwiZDMtZm9ybWF0XCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0aWNrRm9ybWF0KHN0YXJ0LCBzdG9wLCBjb3VudCwgc3BlY2lmaWVyKSB7XG4gIHZhciBzdGVwID0gdGlja1N0ZXAoc3RhcnQsIHN0b3AsIGNvdW50KSxcbiAgICAgIHByZWNpc2lvbjtcbiAgc3BlY2lmaWVyID0gZm9ybWF0U3BlY2lmaWVyKHNwZWNpZmllciA9PSBudWxsID8gXCIsZlwiIDogc3BlY2lmaWVyKTtcblxuICBzd2l0Y2ggKHNwZWNpZmllci50eXBlKSB7XG4gICAgY2FzZSBcInNcIjpcbiAgICAgIHtcbiAgICAgICAgdmFyIHZhbHVlID0gTWF0aC5tYXgoTWF0aC5hYnMoc3RhcnQpLCBNYXRoLmFicyhzdG9wKSk7XG4gICAgICAgIGlmIChzcGVjaWZpZXIucHJlY2lzaW9uID09IG51bGwgJiYgIWlzTmFOKHByZWNpc2lvbiA9IHByZWNpc2lvblByZWZpeChzdGVwLCB2YWx1ZSkpKSBzcGVjaWZpZXIucHJlY2lzaW9uID0gcHJlY2lzaW9uO1xuICAgICAgICByZXR1cm4gZm9ybWF0UHJlZml4KHNwZWNpZmllciwgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgY2FzZSBcIlwiOlxuICAgIGNhc2UgXCJlXCI6XG4gICAgY2FzZSBcImdcIjpcbiAgICBjYXNlIFwicFwiOlxuICAgIGNhc2UgXCJyXCI6XG4gICAgICB7XG4gICAgICAgIGlmIChzcGVjaWZpZXIucHJlY2lzaW9uID09IG51bGwgJiYgIWlzTmFOKHByZWNpc2lvbiA9IHByZWNpc2lvblJvdW5kKHN0ZXAsIE1hdGgubWF4KE1hdGguYWJzKHN0YXJ0KSwgTWF0aC5hYnMoc3RvcCkpKSkpIHNwZWNpZmllci5wcmVjaXNpb24gPSBwcmVjaXNpb24gLSAoc3BlY2lmaWVyLnR5cGUgPT09IFwiZVwiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIFwiZlwiOlxuICAgIGNhc2UgXCIlXCI6XG4gICAgICB7XG4gICAgICAgIGlmIChzcGVjaWZpZXIucHJlY2lzaW9uID09IG51bGwgJiYgIWlzTmFOKHByZWNpc2lvbiA9IHByZWNpc2lvbkZpeGVkKHN0ZXApKSkgc3BlY2lmaWVyLnByZWNpc2lvbiA9IHByZWNpc2lvbiAtIChzcGVjaWZpZXIudHlwZSA9PT0gXCIlXCIpICogMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gIH1cblxuICByZXR1cm4gZm9ybWF0KHNwZWNpZmllcik7XG59IiwiaW1wb3J0IHsgdGlja3MsIHRpY2tJbmNyZW1lbnQgfSBmcm9tIFwiZDMtYXJyYXlcIjtcbmltcG9ydCBjb250aW51b3VzLCB7IGNvcHkgfSBmcm9tIFwiLi9jb250aW51b3VzLmpzXCI7XG5pbXBvcnQgeyBpbml0UmFuZ2UgfSBmcm9tIFwiLi9pbml0LmpzXCI7XG5pbXBvcnQgdGlja0Zvcm1hdCBmcm9tIFwiLi90aWNrRm9ybWF0LmpzXCI7XG5leHBvcnQgZnVuY3Rpb24gbGluZWFyaXNoKHNjYWxlKSB7XG4gIHZhciBkb21haW4gPSBzY2FsZS5kb21haW47XG5cbiAgc2NhbGUudGlja3MgPSBmdW5jdGlvbiAoY291bnQpIHtcbiAgICB2YXIgZCA9IGRvbWFpbigpO1xuICAgIHJldHVybiB0aWNrcyhkWzBdLCBkW2QubGVuZ3RoIC0gMV0sIGNvdW50ID09IG51bGwgPyAxMCA6IGNvdW50KTtcbiAgfTtcblxuICBzY2FsZS50aWNrRm9ybWF0ID0gZnVuY3Rpb24gKGNvdW50LCBzcGVjaWZpZXIpIHtcbiAgICB2YXIgZCA9IGRvbWFpbigpO1xuICAgIHJldHVybiB0aWNrRm9ybWF0KGRbMF0sIGRbZC5sZW5ndGggLSAxXSwgY291bnQgPT0gbnVsbCA/IDEwIDogY291bnQsIHNwZWNpZmllcik7XG4gIH07XG5cbiAgc2NhbGUubmljZSA9IGZ1bmN0aW9uIChjb3VudCkge1xuICAgIGlmIChjb3VudCA9PSBudWxsKSBjb3VudCA9IDEwO1xuICAgIHZhciBkID0gZG9tYWluKCk7XG4gICAgdmFyIGkwID0gMDtcbiAgICB2YXIgaTEgPSBkLmxlbmd0aCAtIDE7XG4gICAgdmFyIHN0YXJ0ID0gZFtpMF07XG4gICAgdmFyIHN0b3AgPSBkW2kxXTtcbiAgICB2YXIgcHJlc3RlcDtcbiAgICB2YXIgc3RlcDtcbiAgICB2YXIgbWF4SXRlciA9IDEwO1xuXG4gICAgaWYgKHN0b3AgPCBzdGFydCkge1xuICAgICAgc3RlcCA9IHN0YXJ0LCBzdGFydCA9IHN0b3AsIHN0b3AgPSBzdGVwO1xuICAgICAgc3RlcCA9IGkwLCBpMCA9IGkxLCBpMSA9IHN0ZXA7XG4gICAgfVxuXG4gICAgd2hpbGUgKG1heEl0ZXItLSA+IDApIHtcbiAgICAgIHN0ZXAgPSB0aWNrSW5jcmVtZW50KHN0YXJ0LCBzdG9wLCBjb3VudCk7XG5cbiAgICAgIGlmIChzdGVwID09PSBwcmVzdGVwKSB7XG4gICAgICAgIGRbaTBdID0gc3RhcnQ7XG4gICAgICAgIGRbaTFdID0gc3RvcDtcbiAgICAgICAgcmV0dXJuIGRvbWFpbihkKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RlcCA+IDApIHtcbiAgICAgICAgc3RhcnQgPSBNYXRoLmZsb29yKHN0YXJ0IC8gc3RlcCkgKiBzdGVwO1xuICAgICAgICBzdG9wID0gTWF0aC5jZWlsKHN0b3AgLyBzdGVwKSAqIHN0ZXA7XG4gICAgICB9IGVsc2UgaWYgKHN0ZXAgPCAwKSB7XG4gICAgICAgIHN0YXJ0ID0gTWF0aC5jZWlsKHN0YXJ0ICogc3RlcCkgLyBzdGVwO1xuICAgICAgICBzdG9wID0gTWF0aC5mbG9vcihzdG9wICogc3RlcCkgLyBzdGVwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHByZXN0ZXAgPSBzdGVwO1xuICAgIH1cblxuICAgIHJldHVybiBzY2FsZTtcbiAgfTtcblxuICByZXR1cm4gc2NhbGU7XG59XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBsaW5lYXIoKSB7XG4gIHZhciBzY2FsZSA9IGNvbnRpbnVvdXMoKTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBjb3B5KHNjYWxlLCBsaW5lYXIoKSk7XG4gIH07XG5cbiAgaW5pdFJhbmdlLmFwcGx5KHNjYWxlLCBhcmd1bWVudHMpO1xuICByZXR1cm4gbGluZWFyaXNoKHNjYWxlKTtcbn0iLCJpbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIi9ob21lL3J1bm5lci93b3JrL2p1c3RpY2U0MC10b29sL2p1c3RpY2U0MC10b29sL2NsaWVudC9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0IHsgaW50ZXJwb2xhdGUsIGludGVycG9sYXRlUm91bmQgfSBmcm9tIFwiZDMtaW50ZXJwb2xhdGVcIjtcbmltcG9ydCB7IGlkZW50aXR5IH0gZnJvbSBcIi4vY29udGludW91cy5qc1wiO1xuaW1wb3J0IHsgaW5pdEludGVycG9sYXRvciB9IGZyb20gXCIuL2luaXQuanNcIjtcbmltcG9ydCB7IGxpbmVhcmlzaCB9IGZyb20gXCIuL2xpbmVhci5qc1wiO1xuaW1wb3J0IHsgbG9nZ2lzaCB9IGZyb20gXCIuL2xvZy5qc1wiO1xuaW1wb3J0IHsgc3ltbG9naXNoIH0gZnJvbSBcIi4vc3ltbG9nLmpzXCI7XG5pbXBvcnQgeyBwb3dpc2ggfSBmcm9tIFwiLi9wb3cuanNcIjtcblxuZnVuY3Rpb24gdHJhbnNmb3JtZXIoKSB7XG4gIHZhciB4MCA9IDAsXG4gICAgICB4MSA9IDEsXG4gICAgICB0MCxcbiAgICAgIHQxLFxuICAgICAgazEwLFxuICAgICAgdHJhbnNmb3JtLFxuICAgICAgaW50ZXJwb2xhdG9yID0gaWRlbnRpdHksXG4gICAgICBjbGFtcCA9IGZhbHNlLFxuICAgICAgdW5rbm93bjtcblxuICBmdW5jdGlvbiBzY2FsZSh4KSB7XG4gICAgcmV0dXJuIHggPT0gbnVsbCB8fCBpc05hTih4ID0gK3gpID8gdW5rbm93biA6IGludGVycG9sYXRvcihrMTAgPT09IDAgPyAwLjUgOiAoeCA9ICh0cmFuc2Zvcm0oeCkgLSB0MCkgKiBrMTAsIGNsYW1wID8gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgeCkpIDogeCkpO1xuICB9XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24gKF8pIHtcbiAgICB2YXIgX3JlZiwgX3JlZjI7XG5cbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICgoX3JlZiA9IF8sIF9yZWYyID0gX3NsaWNlZFRvQXJyYXkoX3JlZiwgMiksIHgwID0gX3JlZjJbMF0sIHgxID0gX3JlZjJbMV0sIF9yZWYpLCB0MCA9IHRyYW5zZm9ybSh4MCA9ICt4MCksIHQxID0gdHJhbnNmb3JtKHgxID0gK3gxKSwgazEwID0gdDAgPT09IHQxID8gMCA6IDEgLyAodDEgLSB0MCksIHNjYWxlKSA6IFt4MCwgeDFdO1xuICB9O1xuXG4gIHNjYWxlLmNsYW1wID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjbGFtcCA9ICEhXywgc2NhbGUpIDogY2xhbXA7XG4gIH07XG5cbiAgc2NhbGUuaW50ZXJwb2xhdG9yID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChpbnRlcnBvbGF0b3IgPSBfLCBzY2FsZSkgOiBpbnRlcnBvbGF0b3I7XG4gIH07XG5cbiAgZnVuY3Rpb24gcmFuZ2UoaW50ZXJwb2xhdGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKF8pIHtcbiAgICAgIHZhciBfcmVmMywgX3JlZjQ7XG5cbiAgICAgIHZhciByMCwgcjE7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICgoX3JlZjMgPSBfLCBfcmVmNCA9IF9zbGljZWRUb0FycmF5KF9yZWYzLCAyKSwgcjAgPSBfcmVmNFswXSwgcjEgPSBfcmVmNFsxXSwgX3JlZjMpLCBpbnRlcnBvbGF0b3IgPSBpbnRlcnBvbGF0ZShyMCwgcjEpLCBzY2FsZSkgOiBbaW50ZXJwb2xhdG9yKDApLCBpbnRlcnBvbGF0b3IoMSldO1xuICAgIH07XG4gIH1cblxuICBzY2FsZS5yYW5nZSA9IHJhbmdlKGludGVycG9sYXRlKTtcbiAgc2NhbGUucmFuZ2VSb3VuZCA9IHJhbmdlKGludGVycG9sYXRlUm91bmQpO1xuXG4gIHNjYWxlLnVua25vd24gPSBmdW5jdGlvbiAoXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHVua25vd24gPSBfLCBzY2FsZSkgOiB1bmtub3duO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAodCkge1xuICAgIHRyYW5zZm9ybSA9IHQsIHQwID0gdCh4MCksIHQxID0gdCh4MSksIGsxMCA9IHQwID09PSB0MSA/IDAgOiAxIC8gKHQxIC0gdDApO1xuICAgIHJldHVybiBzY2FsZTtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvcHkoc291cmNlLCB0YXJnZXQpIHtcbiAgcmV0dXJuIHRhcmdldC5kb21haW4oc291cmNlLmRvbWFpbigpKS5pbnRlcnBvbGF0b3Ioc291cmNlLmludGVycG9sYXRvcigpKS5jbGFtcChzb3VyY2UuY2xhbXAoKSkudW5rbm93bihzb3VyY2UudW5rbm93bigpKTtcbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHNlcXVlbnRpYWwoKSB7XG4gIHZhciBzY2FsZSA9IGxpbmVhcmlzaCh0cmFuc2Zvcm1lcigpKGlkZW50aXR5KSk7XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gY29weShzY2FsZSwgc2VxdWVudGlhbCgpKTtcbiAgfTtcblxuICByZXR1cm4gaW5pdEludGVycG9sYXRvci5hcHBseShzY2FsZSwgYXJndW1lbnRzKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzZXF1ZW50aWFsTG9nKCkge1xuICB2YXIgc2NhbGUgPSBsb2dnaXNoKHRyYW5zZm9ybWVyKCkpLmRvbWFpbihbMSwgMTBdKTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBjb3B5KHNjYWxlLCBzZXF1ZW50aWFsTG9nKCkpLmJhc2Uoc2NhbGUuYmFzZSgpKTtcbiAgfTtcblxuICByZXR1cm4gaW5pdEludGVycG9sYXRvci5hcHBseShzY2FsZSwgYXJndW1lbnRzKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzZXF1ZW50aWFsU3ltbG9nKCkge1xuICB2YXIgc2NhbGUgPSBzeW1sb2dpc2godHJhbnNmb3JtZXIoKSk7XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gY29weShzY2FsZSwgc2VxdWVudGlhbFN5bWxvZygpKS5jb25zdGFudChzY2FsZS5jb25zdGFudCgpKTtcbiAgfTtcblxuICByZXR1cm4gaW5pdEludGVycG9sYXRvci5hcHBseShzY2FsZSwgYXJndW1lbnRzKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzZXF1ZW50aWFsUG93KCkge1xuICB2YXIgc2NhbGUgPSBwb3dpc2godHJhbnNmb3JtZXIoKSk7XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gY29weShzY2FsZSwgc2VxdWVudGlhbFBvdygpKS5leHBvbmVudChzY2FsZS5leHBvbmVudCgpKTtcbiAgfTtcblxuICByZXR1cm4gaW5pdEludGVycG9sYXRvci5hcHBseShzY2FsZSwgYXJndW1lbnRzKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzZXF1ZW50aWFsU3FydCgpIHtcbiAgcmV0dXJuIHNlcXVlbnRpYWxQb3cuYXBwbHkobnVsbCwgYXJndW1lbnRzKS5leHBvbmVudCgwLjUpO1xufSIsImV4cG9ydCB7IGRlZmF1bHQgYXMgc2NhbGVCYW5kLCBwb2ludCBhcyBzY2FsZVBvaW50IH0gZnJvbSBcIi4vYmFuZC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBzY2FsZUlkZW50aXR5IH0gZnJvbSBcIi4vaWRlbnRpdHkuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc2NhbGVMaW5lYXIgfSBmcm9tIFwiLi9saW5lYXIuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc2NhbGVMb2cgfSBmcm9tIFwiLi9sb2cuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc2NhbGVTeW1sb2cgfSBmcm9tIFwiLi9zeW1sb2cuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc2NhbGVPcmRpbmFsLCBpbXBsaWNpdCBhcyBzY2FsZUltcGxpY2l0IH0gZnJvbSBcIi4vb3JkaW5hbC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBzY2FsZVBvdywgc3FydCBhcyBzY2FsZVNxcnQgfSBmcm9tIFwiLi9wb3cuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc2NhbGVSYWRpYWwgfSBmcm9tIFwiLi9yYWRpYWwuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc2NhbGVRdWFudGlsZSB9IGZyb20gXCIuL3F1YW50aWxlLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjYWxlUXVhbnRpemUgfSBmcm9tIFwiLi9xdWFudGl6ZS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBzY2FsZVRocmVzaG9sZCB9IGZyb20gXCIuL3RocmVzaG9sZC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBzY2FsZVRpbWUgfSBmcm9tIFwiLi90aW1lLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjYWxlVXRjIH0gZnJvbSBcIi4vdXRjVGltZS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBzY2FsZVNlcXVlbnRpYWwsIHNlcXVlbnRpYWxMb2cgYXMgc2NhbGVTZXF1ZW50aWFsTG9nLCBzZXF1ZW50aWFsUG93IGFzIHNjYWxlU2VxdWVudGlhbFBvdywgc2VxdWVudGlhbFNxcnQgYXMgc2NhbGVTZXF1ZW50aWFsU3FydCwgc2VxdWVudGlhbFN5bWxvZyBhcyBzY2FsZVNlcXVlbnRpYWxTeW1sb2cgfSBmcm9tIFwiLi9zZXF1ZW50aWFsLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjYWxlU2VxdWVudGlhbFF1YW50aWxlIH0gZnJvbSBcIi4vc2VxdWVudGlhbFF1YW50aWxlLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjYWxlRGl2ZXJnaW5nLCBkaXZlcmdpbmdMb2cgYXMgc2NhbGVEaXZlcmdpbmdMb2csIGRpdmVyZ2luZ1BvdyBhcyBzY2FsZURpdmVyZ2luZ1BvdywgZGl2ZXJnaW5nU3FydCBhcyBzY2FsZURpdmVyZ2luZ1NxcnQsIGRpdmVyZ2luZ1N5bWxvZyBhcyBzY2FsZURpdmVyZ2luZ1N5bWxvZyB9IGZyb20gXCIuL2RpdmVyZ2luZy5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB0aWNrRm9ybWF0IH0gZnJvbSBcIi4vdGlja0Zvcm1hdC5qc1wiOyIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzcGVjaWZpZXIpIHtcbiAgdmFyIG4gPSBzcGVjaWZpZXIubGVuZ3RoIC8gNiB8IDAsXG4gICAgICBjb2xvcnMgPSBuZXcgQXJyYXkobiksXG4gICAgICBpID0gMDtcblxuICB3aGlsZSAoaSA8IG4pIHtcbiAgICBjb2xvcnNbaV0gPSBcIiNcIiArIHNwZWNpZmllci5zbGljZShpICogNiwgKytpICogNik7XG4gIH1cblxuICByZXR1cm4gY29sb3JzO1xufSIsImltcG9ydCB7IGludGVycG9sYXRlUmdiQmFzaXMgfSBmcm9tIFwiZDMtaW50ZXJwb2xhdGVcIjtcbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAoc2NoZW1lKSB7XG4gIHJldHVybiBpbnRlcnBvbGF0ZVJnYkJhc2lzKHNjaGVtZVtzY2hlbWUubGVuZ3RoIC0gMV0pO1xufSk7IiwiaW1wb3J0IGNvbG9ycyBmcm9tIFwiLi4vY29sb3JzLmpzXCI7XG5pbXBvcnQgcmFtcCBmcm9tIFwiLi4vcmFtcC5qc1wiO1xuZXhwb3J0IHZhciBzY2hlbWUgPSBuZXcgQXJyYXkoMykuY29uY2F0KFwiZGVlYmY3OWVjYWUxMzE4MmJkXCIsIFwiZWZmM2ZmYmRkN2U3NmJhZWQ2MjE3MWI1XCIsIFwiZWZmM2ZmYmRkN2U3NmJhZWQ2MzE4MmJkMDg1MTljXCIsIFwiZWZmM2ZmYzZkYmVmOWVjYWUxNmJhZWQ2MzE4MmJkMDg1MTljXCIsIFwiZWZmM2ZmYzZkYmVmOWVjYWUxNmJhZWQ2NDI5MmM2MjE3MWI1MDg0NTk0XCIsIFwiZjdmYmZmZGVlYmY3YzZkYmVmOWVjYWUxNmJhZWQ2NDI5MmM2MjE3MWI1MDg0NTk0XCIsIFwiZjdmYmZmZGVlYmY3YzZkYmVmOWVjYWUxNmJhZWQ2NDI5MmM2MjE3MWI1MDg1MTljMDgzMDZiXCIpLm1hcChjb2xvcnMpO1xuZXhwb3J0IGRlZmF1bHQgcmFtcChzY2hlbWUpOyIsImV4cG9ydCB7IGRlZmF1bHQgYXMgc2NoZW1lQ2F0ZWdvcnkxMCB9IGZyb20gXCIuL2NhdGVnb3JpY2FsL2NhdGVnb3J5MTAuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc2NoZW1lQWNjZW50IH0gZnJvbSBcIi4vY2F0ZWdvcmljYWwvQWNjZW50LmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjaGVtZURhcmsyIH0gZnJvbSBcIi4vY2F0ZWdvcmljYWwvRGFyazIuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc2NoZW1lUGFpcmVkIH0gZnJvbSBcIi4vY2F0ZWdvcmljYWwvUGFpcmVkLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjaGVtZVBhc3RlbDEgfSBmcm9tIFwiLi9jYXRlZ29yaWNhbC9QYXN0ZWwxLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjaGVtZVBhc3RlbDIgfSBmcm9tIFwiLi9jYXRlZ29yaWNhbC9QYXN0ZWwyLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjaGVtZVNldDEgfSBmcm9tIFwiLi9jYXRlZ29yaWNhbC9TZXQxLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjaGVtZVNldDIgfSBmcm9tIFwiLi9jYXRlZ29yaWNhbC9TZXQyLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjaGVtZVNldDMgfSBmcm9tIFwiLi9jYXRlZ29yaWNhbC9TZXQzLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNjaGVtZVRhYmxlYXUxMCB9IGZyb20gXCIuL2NhdGVnb3JpY2FsL1RhYmxlYXUxMC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZUJyQkcsIHNjaGVtZSBhcyBzY2hlbWVCckJHIH0gZnJvbSBcIi4vZGl2ZXJnaW5nL0JyQkcuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaW50ZXJwb2xhdGVQUkduLCBzY2hlbWUgYXMgc2NoZW1lUFJHbiB9IGZyb20gXCIuL2RpdmVyZ2luZy9QUkduLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGludGVycG9sYXRlUGlZRywgc2NoZW1lIGFzIHNjaGVtZVBpWUcgfSBmcm9tIFwiLi9kaXZlcmdpbmcvUGlZRy5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZVB1T3IsIHNjaGVtZSBhcyBzY2hlbWVQdU9yIH0gZnJvbSBcIi4vZGl2ZXJnaW5nL1B1T3IuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaW50ZXJwb2xhdGVSZEJ1LCBzY2hlbWUgYXMgc2NoZW1lUmRCdSB9IGZyb20gXCIuL2RpdmVyZ2luZy9SZEJ1LmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGludGVycG9sYXRlUmRHeSwgc2NoZW1lIGFzIHNjaGVtZVJkR3kgfSBmcm9tIFwiLi9kaXZlcmdpbmcvUmRHeS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZVJkWWxCdSwgc2NoZW1lIGFzIHNjaGVtZVJkWWxCdSB9IGZyb20gXCIuL2RpdmVyZ2luZy9SZFlsQnUuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaW50ZXJwb2xhdGVSZFlsR24sIHNjaGVtZSBhcyBzY2hlbWVSZFlsR24gfSBmcm9tIFwiLi9kaXZlcmdpbmcvUmRZbEduLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGludGVycG9sYXRlU3BlY3RyYWwsIHNjaGVtZSBhcyBzY2hlbWVTcGVjdHJhbCB9IGZyb20gXCIuL2RpdmVyZ2luZy9TcGVjdHJhbC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZUJ1R24sIHNjaGVtZSBhcyBzY2hlbWVCdUduIH0gZnJvbSBcIi4vc2VxdWVudGlhbC1tdWx0aS9CdUduLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGludGVycG9sYXRlQnVQdSwgc2NoZW1lIGFzIHNjaGVtZUJ1UHUgfSBmcm9tIFwiLi9zZXF1ZW50aWFsLW11bHRpL0J1UHUuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaW50ZXJwb2xhdGVHbkJ1LCBzY2hlbWUgYXMgc2NoZW1lR25CdSB9IGZyb20gXCIuL3NlcXVlbnRpYWwtbXVsdGkvR25CdS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZU9yUmQsIHNjaGVtZSBhcyBzY2hlbWVPclJkIH0gZnJvbSBcIi4vc2VxdWVudGlhbC1tdWx0aS9PclJkLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGludGVycG9sYXRlUHVCdUduLCBzY2hlbWUgYXMgc2NoZW1lUHVCdUduIH0gZnJvbSBcIi4vc2VxdWVudGlhbC1tdWx0aS9QdUJ1R24uanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaW50ZXJwb2xhdGVQdUJ1LCBzY2hlbWUgYXMgc2NoZW1lUHVCdSB9IGZyb20gXCIuL3NlcXVlbnRpYWwtbXVsdGkvUHVCdS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZVB1UmQsIHNjaGVtZSBhcyBzY2hlbWVQdVJkIH0gZnJvbSBcIi4vc2VxdWVudGlhbC1tdWx0aS9QdVJkLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGludGVycG9sYXRlUmRQdSwgc2NoZW1lIGFzIHNjaGVtZVJkUHUgfSBmcm9tIFwiLi9zZXF1ZW50aWFsLW11bHRpL1JkUHUuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaW50ZXJwb2xhdGVZbEduQnUsIHNjaGVtZSBhcyBzY2hlbWVZbEduQnUgfSBmcm9tIFwiLi9zZXF1ZW50aWFsLW11bHRpL1lsR25CdS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZVlsR24sIHNjaGVtZSBhcyBzY2hlbWVZbEduIH0gZnJvbSBcIi4vc2VxdWVudGlhbC1tdWx0aS9ZbEduLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGludGVycG9sYXRlWWxPckJyLCBzY2hlbWUgYXMgc2NoZW1lWWxPckJyIH0gZnJvbSBcIi4vc2VxdWVudGlhbC1tdWx0aS9ZbE9yQnIuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaW50ZXJwb2xhdGVZbE9yUmQsIHNjaGVtZSBhcyBzY2hlbWVZbE9yUmQgfSBmcm9tIFwiLi9zZXF1ZW50aWFsLW11bHRpL1lsT3JSZC5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZUJsdWVzLCBzY2hlbWUgYXMgc2NoZW1lQmx1ZXMgfSBmcm9tIFwiLi9zZXF1ZW50aWFsLXNpbmdsZS9CbHVlcy5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZUdyZWVucywgc2NoZW1lIGFzIHNjaGVtZUdyZWVucyB9IGZyb20gXCIuL3NlcXVlbnRpYWwtc2luZ2xlL0dyZWVucy5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZUdyZXlzLCBzY2hlbWUgYXMgc2NoZW1lR3JleXMgfSBmcm9tIFwiLi9zZXF1ZW50aWFsLXNpbmdsZS9HcmV5cy5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZVB1cnBsZXMsIHNjaGVtZSBhcyBzY2hlbWVQdXJwbGVzIH0gZnJvbSBcIi4vc2VxdWVudGlhbC1zaW5nbGUvUHVycGxlcy5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZVJlZHMsIHNjaGVtZSBhcyBzY2hlbWVSZWRzIH0gZnJvbSBcIi4vc2VxdWVudGlhbC1zaW5nbGUvUmVkcy5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZU9yYW5nZXMsIHNjaGVtZSBhcyBzY2hlbWVPcmFuZ2VzIH0gZnJvbSBcIi4vc2VxdWVudGlhbC1zaW5nbGUvT3Jhbmdlcy5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbnRlcnBvbGF0ZUNpdmlkaXMgfSBmcm9tIFwiLi9zZXF1ZW50aWFsLW11bHRpL2NpdmlkaXMuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaW50ZXJwb2xhdGVDdWJlaGVsaXhEZWZhdWx0IH0gZnJvbSBcIi4vc2VxdWVudGlhbC1tdWx0aS9jdWJlaGVsaXguanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaW50ZXJwb2xhdGVSYWluYm93LCB3YXJtIGFzIGludGVycG9sYXRlV2FybSwgY29vbCBhcyBpbnRlcnBvbGF0ZUNvb2wgfSBmcm9tIFwiLi9zZXF1ZW50aWFsLW11bHRpL3JhaW5ib3cuanNcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaW50ZXJwb2xhdGVTaW5lYm93IH0gZnJvbSBcIi4vc2VxdWVudGlhbC1tdWx0aS9zaW5lYm93LmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGludGVycG9sYXRlVHVyYm8gfSBmcm9tIFwiLi9zZXF1ZW50aWFsLW11bHRpL3R1cmJvLmpzXCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGludGVycG9sYXRlVmlyaWRpcywgbWFnbWEgYXMgaW50ZXJwb2xhdGVNYWdtYSwgaW5mZXJubyBhcyBpbnRlcnBvbGF0ZUluZmVybm8sIHBsYXNtYSBhcyBpbnRlcnBvbGF0ZVBsYXNtYSB9IGZyb20gXCIuL3NlcXVlbnRpYWwtbXVsdGkvdmlyaWRpcy5qc1wiOyIsImV4cG9ydCBmdW5jdGlvbiBUcmFuc2Zvcm0oaywgeCwgeSkge1xuICB0aGlzLmsgPSBrO1xuICB0aGlzLnggPSB4O1xuICB0aGlzLnkgPSB5O1xufVxuVHJhbnNmb3JtLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IFRyYW5zZm9ybSxcbiAgc2NhbGU6IGZ1bmN0aW9uIHNjYWxlKGspIHtcbiAgICByZXR1cm4gayA9PT0gMSA/IHRoaXMgOiBuZXcgVHJhbnNmb3JtKHRoaXMuayAqIGssIHRoaXMueCwgdGhpcy55KTtcbiAgfSxcbiAgdHJhbnNsYXRlOiBmdW5jdGlvbiB0cmFuc2xhdGUoeCwgeSkge1xuICAgIHJldHVybiB4ID09PSAwICYgeSA9PT0gMCA/IHRoaXMgOiBuZXcgVHJhbnNmb3JtKHRoaXMuaywgdGhpcy54ICsgdGhpcy5rICogeCwgdGhpcy55ICsgdGhpcy5rICogeSk7XG4gIH0sXG4gIGFwcGx5OiBmdW5jdGlvbiBhcHBseShwb2ludCkge1xuICAgIHJldHVybiBbcG9pbnRbMF0gKiB0aGlzLmsgKyB0aGlzLngsIHBvaW50WzFdICogdGhpcy5rICsgdGhpcy55XTtcbiAgfSxcbiAgYXBwbHlYOiBmdW5jdGlvbiBhcHBseVgoeCkge1xuICAgIHJldHVybiB4ICogdGhpcy5rICsgdGhpcy54O1xuICB9LFxuICBhcHBseVk6IGZ1bmN0aW9uIGFwcGx5WSh5KSB7XG4gICAgcmV0dXJuIHkgKiB0aGlzLmsgKyB0aGlzLnk7XG4gIH0sXG4gIGludmVydDogZnVuY3Rpb24gaW52ZXJ0KGxvY2F0aW9uKSB7XG4gICAgcmV0dXJuIFsobG9jYXRpb25bMF0gLSB0aGlzLngpIC8gdGhpcy5rLCAobG9jYXRpb25bMV0gLSB0aGlzLnkpIC8gdGhpcy5rXTtcbiAgfSxcbiAgaW52ZXJ0WDogZnVuY3Rpb24gaW52ZXJ0WCh4KSB7XG4gICAgcmV0dXJuICh4IC0gdGhpcy54KSAvIHRoaXMuaztcbiAgfSxcbiAgaW52ZXJ0WTogZnVuY3Rpb24gaW52ZXJ0WSh5KSB7XG4gICAgcmV0dXJuICh5IC0gdGhpcy55KSAvIHRoaXMuaztcbiAgfSxcbiAgcmVzY2FsZVg6IGZ1bmN0aW9uIHJlc2NhbGVYKHgpIHtcbiAgICByZXR1cm4geC5jb3B5KCkuZG9tYWluKHgucmFuZ2UoKS5tYXAodGhpcy5pbnZlcnRYLCB0aGlzKS5tYXAoeC5pbnZlcnQsIHgpKTtcbiAgfSxcbiAgcmVzY2FsZVk6IGZ1bmN0aW9uIHJlc2NhbGVZKHkpIHtcbiAgICByZXR1cm4geS5jb3B5KCkuZG9tYWluKHkucmFuZ2UoKS5tYXAodGhpcy5pbnZlcnRZLCB0aGlzKS5tYXAoeS5pbnZlcnQsIHkpKTtcbiAgfSxcbiAgdG9TdHJpbmc6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiBcInRyYW5zbGF0ZShcIiArIHRoaXMueCArIFwiLFwiICsgdGhpcy55ICsgXCIpIHNjYWxlKFwiICsgdGhpcy5rICsgXCIpXCI7XG4gIH1cbn07XG5leHBvcnQgdmFyIGlkZW50aXR5ID0gbmV3IFRyYW5zZm9ybSgxLCAwLCAwKTtcbnRyYW5zZm9ybS5wcm90b3R5cGUgPSBUcmFuc2Zvcm0ucHJvdG90eXBlO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdHJhbnNmb3JtKG5vZGUpIHtcbiAgd2hpbGUgKCFub2RlLl9fem9vbSkge1xuICAgIGlmICghKG5vZGUgPSBub2RlLnBhcmVudE5vZGUpKSByZXR1cm4gaWRlbnRpdHk7XG4gIH1cblxuICByZXR1cm4gbm9kZS5fX3pvb207XG59IiwiaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLm1hdGguaHlwb3QuanNcIjtcbmltcG9ydCB7IGRpc3BhdGNoIH0gZnJvbSBcImQzLWRpc3BhdGNoXCI7XG5pbXBvcnQgeyBkcmFnRGlzYWJsZSwgZHJhZ0VuYWJsZSB9IGZyb20gXCJkMy1kcmFnXCI7XG5pbXBvcnQgeyBpbnRlcnBvbGF0ZVpvb20gfSBmcm9tIFwiZDMtaW50ZXJwb2xhdGVcIjtcbmltcG9ydCB7IHNlbGVjdCwgcG9pbnRlciB9IGZyb20gXCJkMy1zZWxlY3Rpb25cIjtcbmltcG9ydCB7IGludGVycnVwdCB9IGZyb20gXCJkMy10cmFuc2l0aW9uXCI7XG5pbXBvcnQgY29uc3RhbnQgZnJvbSBcIi4vY29uc3RhbnQuanNcIjtcbmltcG9ydCBab29tRXZlbnQgZnJvbSBcIi4vZXZlbnQuanNcIjtcbmltcG9ydCB7IFRyYW5zZm9ybSwgaWRlbnRpdHkgfSBmcm9tIFwiLi90cmFuc2Zvcm0uanNcIjtcbmltcG9ydCBub2V2ZW50LCB7IG5vcHJvcGFnYXRpb24gfSBmcm9tIFwiLi9ub2V2ZW50LmpzXCI7IC8vIElnbm9yZSByaWdodC1jbGljaywgc2luY2UgdGhhdCBzaG91bGQgb3BlbiB0aGUgY29udGV4dCBtZW51LlxuLy8gZXhjZXB0IGZvciBwaW5jaC10by16b29tLCB3aGljaCBpcyBzZW50IGFzIGEgd2hlZWwrY3RybEtleSBldmVudFxuXG5mdW5jdGlvbiBkZWZhdWx0RmlsdGVyKGV2ZW50KSB7XG4gIHJldHVybiAoIWV2ZW50LmN0cmxLZXkgfHwgZXZlbnQudHlwZSA9PT0gJ3doZWVsJykgJiYgIWV2ZW50LmJ1dHRvbjtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdEV4dGVudCgpIHtcbiAgdmFyIGUgPSB0aGlzO1xuXG4gIGlmIChlIGluc3RhbmNlb2YgU1ZHRWxlbWVudCkge1xuICAgIGUgPSBlLm93bmVyU1ZHRWxlbWVudCB8fCBlO1xuXG4gICAgaWYgKGUuaGFzQXR0cmlidXRlKFwidmlld0JveFwiKSkge1xuICAgICAgZSA9IGUudmlld0JveC5iYXNlVmFsO1xuICAgICAgcmV0dXJuIFtbZS54LCBlLnldLCBbZS54ICsgZS53aWR0aCwgZS55ICsgZS5oZWlnaHRdXTtcbiAgICB9XG5cbiAgICByZXR1cm4gW1swLCAwXSwgW2Uud2lkdGguYmFzZVZhbC52YWx1ZSwgZS5oZWlnaHQuYmFzZVZhbC52YWx1ZV1dO1xuICB9XG5cbiAgcmV0dXJuIFtbMCwgMF0sIFtlLmNsaWVudFdpZHRoLCBlLmNsaWVudEhlaWdodF1dO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0VHJhbnNmb3JtKCkge1xuICByZXR1cm4gdGhpcy5fX3pvb20gfHwgaWRlbnRpdHk7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRXaGVlbERlbHRhKGV2ZW50KSB7XG4gIHJldHVybiAtZXZlbnQuZGVsdGFZICogKGV2ZW50LmRlbHRhTW9kZSA9PT0gMSA/IDAuMDUgOiBldmVudC5kZWx0YU1vZGUgPyAxIDogMC4wMDIpICogKGV2ZW50LmN0cmxLZXkgPyAxMCA6IDEpO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0VG91Y2hhYmxlKCkge1xuICByZXR1cm4gbmF2aWdhdG9yLm1heFRvdWNoUG9pbnRzIHx8IFwib250b3VjaHN0YXJ0XCIgaW4gdGhpcztcbn1cblxuZnVuY3Rpb24gZGVmYXVsdENvbnN0cmFpbih0cmFuc2Zvcm0sIGV4dGVudCwgdHJhbnNsYXRlRXh0ZW50KSB7XG4gIHZhciBkeDAgPSB0cmFuc2Zvcm0uaW52ZXJ0WChleHRlbnRbMF1bMF0pIC0gdHJhbnNsYXRlRXh0ZW50WzBdWzBdLFxuICAgICAgZHgxID0gdHJhbnNmb3JtLmludmVydFgoZXh0ZW50WzFdWzBdKSAtIHRyYW5zbGF0ZUV4dGVudFsxXVswXSxcbiAgICAgIGR5MCA9IHRyYW5zZm9ybS5pbnZlcnRZKGV4dGVudFswXVsxXSkgLSB0cmFuc2xhdGVFeHRlbnRbMF1bMV0sXG4gICAgICBkeTEgPSB0cmFuc2Zvcm0uaW52ZXJ0WShleHRlbnRbMV1bMV0pIC0gdHJhbnNsYXRlRXh0ZW50WzFdWzFdO1xuICByZXR1cm4gdHJhbnNmb3JtLnRyYW5zbGF0ZShkeDEgPiBkeDAgPyAoZHgwICsgZHgxKSAvIDIgOiBNYXRoLm1pbigwLCBkeDApIHx8IE1hdGgubWF4KDAsIGR4MSksIGR5MSA+IGR5MCA/IChkeTAgKyBkeTEpIC8gMiA6IE1hdGgubWluKDAsIGR5MCkgfHwgTWF0aC5tYXgoMCwgZHkxKSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGZpbHRlciA9IGRlZmF1bHRGaWx0ZXIsXG4gICAgICBleHRlbnQgPSBkZWZhdWx0RXh0ZW50LFxuICAgICAgY29uc3RyYWluID0gZGVmYXVsdENvbnN0cmFpbixcbiAgICAgIHdoZWVsRGVsdGEgPSBkZWZhdWx0V2hlZWxEZWx0YSxcbiAgICAgIHRvdWNoYWJsZSA9IGRlZmF1bHRUb3VjaGFibGUsXG4gICAgICBzY2FsZUV4dGVudCA9IFswLCBJbmZpbml0eV0sXG4gICAgICB0cmFuc2xhdGVFeHRlbnQgPSBbWy1JbmZpbml0eSwgLUluZmluaXR5XSwgW0luZmluaXR5LCBJbmZpbml0eV1dLFxuICAgICAgZHVyYXRpb24gPSAyNTAsXG4gICAgICBpbnRlcnBvbGF0ZSA9IGludGVycG9sYXRlWm9vbSxcbiAgICAgIGxpc3RlbmVycyA9IGRpc3BhdGNoKFwic3RhcnRcIiwgXCJ6b29tXCIsIFwiZW5kXCIpLFxuICAgICAgdG91Y2hzdGFydGluZyxcbiAgICAgIHRvdWNoZmlyc3QsXG4gICAgICB0b3VjaGVuZGluZyxcbiAgICAgIHRvdWNoRGVsYXkgPSA1MDAsXG4gICAgICB3aGVlbERlbGF5ID0gMTUwLFxuICAgICAgY2xpY2tEaXN0YW5jZTIgPSAwLFxuICAgICAgdGFwRGlzdGFuY2UgPSAxMDtcblxuICBmdW5jdGlvbiB6b29tKHNlbGVjdGlvbikge1xuICAgIHNlbGVjdGlvbi5wcm9wZXJ0eShcIl9fem9vbVwiLCBkZWZhdWx0VHJhbnNmb3JtKS5vbihcIndoZWVsLnpvb21cIiwgd2hlZWxlZCwge1xuICAgICAgcGFzc2l2ZTogZmFsc2VcbiAgICB9KS5vbihcIm1vdXNlZG93bi56b29tXCIsIG1vdXNlZG93bmVkKS5vbihcImRibGNsaWNrLnpvb21cIiwgZGJsY2xpY2tlZCkuZmlsdGVyKHRvdWNoYWJsZSkub24oXCJ0b3VjaHN0YXJ0Lnpvb21cIiwgdG91Y2hzdGFydGVkKS5vbihcInRvdWNobW92ZS56b29tXCIsIHRvdWNobW92ZWQpLm9uKFwidG91Y2hlbmQuem9vbSB0b3VjaGNhbmNlbC56b29tXCIsIHRvdWNoZW5kZWQpLnN0eWxlKFwiLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yXCIsIFwicmdiYSgwLDAsMCwwKVwiKTtcbiAgfVxuXG4gIHpvb20udHJhbnNmb3JtID0gZnVuY3Rpb24gKGNvbGxlY3Rpb24sIHRyYW5zZm9ybSwgcG9pbnQsIGV2ZW50KSB7XG4gICAgdmFyIHNlbGVjdGlvbiA9IGNvbGxlY3Rpb24uc2VsZWN0aW9uID8gY29sbGVjdGlvbi5zZWxlY3Rpb24oKSA6IGNvbGxlY3Rpb247XG4gICAgc2VsZWN0aW9uLnByb3BlcnR5KFwiX196b29tXCIsIGRlZmF1bHRUcmFuc2Zvcm0pO1xuXG4gICAgaWYgKGNvbGxlY3Rpb24gIT09IHNlbGVjdGlvbikge1xuICAgICAgc2NoZWR1bGUoY29sbGVjdGlvbiwgdHJhbnNmb3JtLCBwb2ludCwgZXZlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZWxlY3Rpb24uaW50ZXJydXB0KCkuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdlc3R1cmUodGhpcywgYXJndW1lbnRzKS5ldmVudChldmVudCkuc3RhcnQoKS56b29tKG51bGwsIHR5cGVvZiB0cmFuc2Zvcm0gPT09IFwiZnVuY3Rpb25cIiA/IHRyYW5zZm9ybS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogdHJhbnNmb3JtKS5lbmQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICB6b29tLnNjYWxlQnkgPSBmdW5jdGlvbiAoc2VsZWN0aW9uLCBrLCBwLCBldmVudCkge1xuICAgIHpvb20uc2NhbGVUbyhzZWxlY3Rpb24sIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBrMCA9IHRoaXMuX196b29tLmssXG4gICAgICAgICAgazEgPSB0eXBlb2YgayA9PT0gXCJmdW5jdGlvblwiID8gay5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogaztcbiAgICAgIHJldHVybiBrMCAqIGsxO1xuICAgIH0sIHAsIGV2ZW50KTtcbiAgfTtcblxuICB6b29tLnNjYWxlVG8gPSBmdW5jdGlvbiAoc2VsZWN0aW9uLCBrLCBwLCBldmVudCkge1xuICAgIHpvb20udHJhbnNmb3JtKHNlbGVjdGlvbiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGUgPSBleHRlbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKSxcbiAgICAgICAgICB0MCA9IHRoaXMuX196b29tLFxuICAgICAgICAgIHAwID0gcCA9PSBudWxsID8gY2VudHJvaWQoZSkgOiB0eXBlb2YgcCA9PT0gXCJmdW5jdGlvblwiID8gcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogcCxcbiAgICAgICAgICBwMSA9IHQwLmludmVydChwMCksXG4gICAgICAgICAgazEgPSB0eXBlb2YgayA9PT0gXCJmdW5jdGlvblwiID8gay5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogaztcbiAgICAgIHJldHVybiBjb25zdHJhaW4odHJhbnNsYXRlKHNjYWxlKHQwLCBrMSksIHAwLCBwMSksIGUsIHRyYW5zbGF0ZUV4dGVudCk7XG4gICAgfSwgcCwgZXZlbnQpO1xuICB9O1xuXG4gIHpvb20udHJhbnNsYXRlQnkgPSBmdW5jdGlvbiAoc2VsZWN0aW9uLCB4LCB5LCBldmVudCkge1xuICAgIHpvb20udHJhbnNmb3JtKHNlbGVjdGlvbiwgZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGNvbnN0cmFpbih0aGlzLl9fem9vbS50cmFuc2xhdGUodHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHguYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IHgsIHR5cGVvZiB5ID09PSBcImZ1bmN0aW9uXCIgPyB5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiB5KSwgZXh0ZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyksIHRyYW5zbGF0ZUV4dGVudCk7XG4gICAgfSwgbnVsbCwgZXZlbnQpO1xuICB9O1xuXG4gIHpvb20udHJhbnNsYXRlVG8gPSBmdW5jdGlvbiAoc2VsZWN0aW9uLCB4LCB5LCBwLCBldmVudCkge1xuICAgIHpvb20udHJhbnNmb3JtKHNlbGVjdGlvbiwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGUgPSBleHRlbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKSxcbiAgICAgICAgICB0ID0gdGhpcy5fX3pvb20sXG4gICAgICAgICAgcDAgPSBwID09IG51bGwgPyBjZW50cm9pZChlKSA6IHR5cGVvZiBwID09PSBcImZ1bmN0aW9uXCIgPyBwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiBwO1xuICAgICAgcmV0dXJuIGNvbnN0cmFpbihpZGVudGl0eS50cmFuc2xhdGUocDBbMF0sIHAwWzFdKS5zY2FsZSh0LmspLnRyYW5zbGF0ZSh0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiID8gLXguYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IC14LCB0eXBlb2YgeSA9PT0gXCJmdW5jdGlvblwiID8gLXkuYXBwbHkodGhpcywgYXJndW1lbnRzKSA6IC15KSwgZSwgdHJhbnNsYXRlRXh0ZW50KTtcbiAgICB9LCBwLCBldmVudCk7XG4gIH07XG5cbiAgZnVuY3Rpb24gc2NhbGUodHJhbnNmb3JtLCBrKSB7XG4gICAgayA9IE1hdGgubWF4KHNjYWxlRXh0ZW50WzBdLCBNYXRoLm1pbihzY2FsZUV4dGVudFsxXSwgaykpO1xuICAgIHJldHVybiBrID09PSB0cmFuc2Zvcm0uayA/IHRyYW5zZm9ybSA6IG5ldyBUcmFuc2Zvcm0oaywgdHJhbnNmb3JtLngsIHRyYW5zZm9ybS55KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYW5zbGF0ZSh0cmFuc2Zvcm0sIHAwLCBwMSkge1xuICAgIHZhciB4ID0gcDBbMF0gLSBwMVswXSAqIHRyYW5zZm9ybS5rLFxuICAgICAgICB5ID0gcDBbMV0gLSBwMVsxXSAqIHRyYW5zZm9ybS5rO1xuICAgIHJldHVybiB4ID09PSB0cmFuc2Zvcm0ueCAmJiB5ID09PSB0cmFuc2Zvcm0ueSA/IHRyYW5zZm9ybSA6IG5ldyBUcmFuc2Zvcm0odHJhbnNmb3JtLmssIHgsIHkpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2VudHJvaWQoZXh0ZW50KSB7XG4gICAgcmV0dXJuIFsoK2V4dGVudFswXVswXSArICtleHRlbnRbMV1bMF0pIC8gMiwgKCtleHRlbnRbMF1bMV0gKyArZXh0ZW50WzFdWzFdKSAvIDJdO1xuICB9XG5cbiAgZnVuY3Rpb24gc2NoZWR1bGUodHJhbnNpdGlvbiwgdHJhbnNmb3JtLCBwb2ludCwgZXZlbnQpIHtcbiAgICB0cmFuc2l0aW9uLm9uKFwic3RhcnQuem9vbVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICBnZXN0dXJlKHRoaXMsIGFyZ3VtZW50cykuZXZlbnQoZXZlbnQpLnN0YXJ0KCk7XG4gICAgfSkub24oXCJpbnRlcnJ1cHQuem9vbSBlbmQuem9vbVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICBnZXN0dXJlKHRoaXMsIGFyZ3VtZW50cykuZXZlbnQoZXZlbnQpLmVuZCgpO1xuICAgIH0pLnR3ZWVuKFwiem9vbVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdGhhdCA9IHRoaXMsXG4gICAgICAgICAgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICBnID0gZ2VzdHVyZSh0aGF0LCBhcmdzKS5ldmVudChldmVudCksXG4gICAgICAgICAgZSA9IGV4dGVudC5hcHBseSh0aGF0LCBhcmdzKSxcbiAgICAgICAgICBwID0gcG9pbnQgPT0gbnVsbCA/IGNlbnRyb2lkKGUpIDogdHlwZW9mIHBvaW50ID09PSBcImZ1bmN0aW9uXCIgPyBwb2ludC5hcHBseSh0aGF0LCBhcmdzKSA6IHBvaW50LFxuICAgICAgICAgIHcgPSBNYXRoLm1heChlWzFdWzBdIC0gZVswXVswXSwgZVsxXVsxXSAtIGVbMF1bMV0pLFxuICAgICAgICAgIGEgPSB0aGF0Ll9fem9vbSxcbiAgICAgICAgICBiID0gdHlwZW9mIHRyYW5zZm9ybSA9PT0gXCJmdW5jdGlvblwiID8gdHJhbnNmb3JtLmFwcGx5KHRoYXQsIGFyZ3MpIDogdHJhbnNmb3JtLFxuICAgICAgICAgIGkgPSBpbnRlcnBvbGF0ZShhLmludmVydChwKS5jb25jYXQodyAvIGEuayksIGIuaW52ZXJ0KHApLmNvbmNhdCh3IC8gYi5rKSk7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgaWYgKHQgPT09IDEpIHQgPSBiOyAvLyBBdm9pZCByb3VuZGluZyBlcnJvciBvbiBlbmQuXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGwgPSBpKHQpLFxuICAgICAgICAgICAgICAgIGsgPSB3IC8gbFsyXTtcbiAgICAgICAgICAgIHQgPSBuZXcgVHJhbnNmb3JtKGssIHBbMF0gLSBsWzBdICogaywgcFsxXSAtIGxbMV0gKiBrKTtcbiAgICAgICAgICB9XG4gICAgICAgIGcuem9vbShudWxsLCB0KTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXN0dXJlKHRoYXQsIGFyZ3MsIGNsZWFuKSB7XG4gICAgcmV0dXJuICFjbGVhbiAmJiB0aGF0Ll9fem9vbWluZyB8fCBuZXcgR2VzdHVyZSh0aGF0LCBhcmdzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIEdlc3R1cmUodGhhdCwgYXJncykge1xuICAgIHRoaXMudGhhdCA9IHRoYXQ7XG4gICAgdGhpcy5hcmdzID0gYXJncztcbiAgICB0aGlzLmFjdGl2ZSA9IDA7XG4gICAgdGhpcy5zb3VyY2VFdmVudCA9IG51bGw7XG4gICAgdGhpcy5leHRlbnQgPSBleHRlbnQuYXBwbHkodGhhdCwgYXJncyk7XG4gICAgdGhpcy50YXBzID0gMDtcbiAgfVxuXG4gIEdlc3R1cmUucHJvdG90eXBlID0ge1xuICAgIGV2ZW50OiBmdW5jdGlvbiBldmVudChfZXZlbnQpIHtcbiAgICAgIGlmIChfZXZlbnQpIHRoaXMuc291cmNlRXZlbnQgPSBfZXZlbnQ7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIHN0YXJ0OiBmdW5jdGlvbiBzdGFydCgpIHtcbiAgICAgIGlmICgrK3RoaXMuYWN0aXZlID09PSAxKSB7XG4gICAgICAgIHRoaXMudGhhdC5fX3pvb21pbmcgPSB0aGlzO1xuICAgICAgICB0aGlzLmVtaXQoXCJzdGFydFwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICB6b29tOiBmdW5jdGlvbiB6b29tKGtleSwgdHJhbnNmb3JtKSB7XG4gICAgICBpZiAodGhpcy5tb3VzZSAmJiBrZXkgIT09IFwibW91c2VcIikgdGhpcy5tb3VzZVsxXSA9IHRyYW5zZm9ybS5pbnZlcnQodGhpcy5tb3VzZVswXSk7XG4gICAgICBpZiAodGhpcy50b3VjaDAgJiYga2V5ICE9PSBcInRvdWNoXCIpIHRoaXMudG91Y2gwWzFdID0gdHJhbnNmb3JtLmludmVydCh0aGlzLnRvdWNoMFswXSk7XG4gICAgICBpZiAodGhpcy50b3VjaDEgJiYga2V5ICE9PSBcInRvdWNoXCIpIHRoaXMudG91Y2gxWzFdID0gdHJhbnNmb3JtLmludmVydCh0aGlzLnRvdWNoMVswXSk7XG4gICAgICB0aGlzLnRoYXQuX196b29tID0gdHJhbnNmb3JtO1xuICAgICAgdGhpcy5lbWl0KFwiem9vbVwiKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgZW5kOiBmdW5jdGlvbiBlbmQoKSB7XG4gICAgICBpZiAoLS10aGlzLmFjdGl2ZSA9PT0gMCkge1xuICAgICAgICBkZWxldGUgdGhpcy50aGF0Ll9fem9vbWluZztcbiAgICAgICAgdGhpcy5lbWl0KFwiZW5kXCIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGVtaXQ6IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICAgICAgdmFyIGQgPSBzZWxlY3QodGhpcy50aGF0KS5kYXR1bSgpO1xuICAgICAgbGlzdGVuZXJzLmNhbGwodHlwZSwgdGhpcy50aGF0LCBuZXcgWm9vbUV2ZW50KHR5cGUsIHtcbiAgICAgICAgc291cmNlRXZlbnQ6IHRoaXMuc291cmNlRXZlbnQsXG4gICAgICAgIHRhcmdldDogem9vbSxcbiAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgdHJhbnNmb3JtOiB0aGlzLnRoYXQuX196b29tLFxuICAgICAgICBkaXNwYXRjaDogbGlzdGVuZXJzXG4gICAgICB9KSwgZCk7XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIHdoZWVsZWQoZXZlbnQpIHtcbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXkgLSAxXSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG5cbiAgICBpZiAoIWZpbHRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSByZXR1cm47XG4gICAgdmFyIGcgPSBnZXN0dXJlKHRoaXMsIGFyZ3MpLmV2ZW50KGV2ZW50KSxcbiAgICAgICAgdCA9IHRoaXMuX196b29tLFxuICAgICAgICBrID0gTWF0aC5tYXgoc2NhbGVFeHRlbnRbMF0sIE1hdGgubWluKHNjYWxlRXh0ZW50WzFdLCB0LmsgKiBNYXRoLnBvdygyLCB3aGVlbERlbHRhLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpKSksXG4gICAgICAgIHAgPSBwb2ludGVyKGV2ZW50KTsgLy8gSWYgdGhlIG1vdXNlIGlzIGluIHRoZSBzYW1lIGxvY2F0aW9uIGFzIGJlZm9yZSwgcmV1c2UgaXQuXG4gICAgLy8gSWYgdGhlcmUgd2VyZSByZWNlbnQgd2hlZWwgZXZlbnRzLCByZXNldCB0aGUgd2hlZWwgaWRsZSB0aW1lb3V0LlxuXG4gICAgaWYgKGcud2hlZWwpIHtcbiAgICAgIGlmIChnLm1vdXNlWzBdWzBdICE9PSBwWzBdIHx8IGcubW91c2VbMF1bMV0gIT09IHBbMV0pIHtcbiAgICAgICAgZy5tb3VzZVsxXSA9IHQuaW52ZXJ0KGcubW91c2VbMF0gPSBwKTtcbiAgICAgIH1cblxuICAgICAgY2xlYXJUaW1lb3V0KGcud2hlZWwpO1xuICAgIH0gLy8gSWYgdGhpcyB3aGVlbCBldmVudCB3b27igJl0IHRyaWdnZXIgYSB0cmFuc2Zvcm0gY2hhbmdlLCBpZ25vcmUgaXQuXG4gICAgZWxzZSBpZiAodC5rID09PSBrKSByZXR1cm47IC8vIE90aGVyd2lzZSwgY2FwdHVyZSB0aGUgbW91c2UgcG9pbnQgYW5kIGxvY2F0aW9uIGF0IHRoZSBzdGFydC5cbiAgICAgIGVsc2Uge1xuICAgICAgICAgIGcubW91c2UgPSBbcCwgdC5pbnZlcnQocCldO1xuICAgICAgICAgIGludGVycnVwdCh0aGlzKTtcbiAgICAgICAgICBnLnN0YXJ0KCk7XG4gICAgICAgIH1cblxuICAgIG5vZXZlbnQoZXZlbnQpO1xuICAgIGcud2hlZWwgPSBzZXRUaW1lb3V0KHdoZWVsaWRsZWQsIHdoZWVsRGVsYXkpO1xuICAgIGcuem9vbShcIm1vdXNlXCIsIGNvbnN0cmFpbih0cmFuc2xhdGUoc2NhbGUodCwgayksIGcubW91c2VbMF0sIGcubW91c2VbMV0pLCBnLmV4dGVudCwgdHJhbnNsYXRlRXh0ZW50KSk7XG5cbiAgICBmdW5jdGlvbiB3aGVlbGlkbGVkKCkge1xuICAgICAgZy53aGVlbCA9IG51bGw7XG4gICAgICBnLmVuZCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG1vdXNlZG93bmVkKGV2ZW50KSB7XG4gICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4yID4gMSA/IF9sZW4yIC0gMSA6IDApLCBfa2V5MiA9IDE7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHtcbiAgICAgIGFyZ3NbX2tleTIgLSAxXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgfVxuXG4gICAgaWYgKHRvdWNoZW5kaW5nIHx8ICFmaWx0ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgcmV0dXJuO1xuICAgIHZhciBjdXJyZW50VGFyZ2V0ID0gZXZlbnQuY3VycmVudFRhcmdldCxcbiAgICAgICAgZyA9IGdlc3R1cmUodGhpcywgYXJncywgdHJ1ZSkuZXZlbnQoZXZlbnQpLFxuICAgICAgICB2ID0gc2VsZWN0KGV2ZW50LnZpZXcpLm9uKFwibW91c2Vtb3ZlLnpvb21cIiwgbW91c2Vtb3ZlZCwgdHJ1ZSkub24oXCJtb3VzZXVwLnpvb21cIiwgbW91c2V1cHBlZCwgdHJ1ZSksXG4gICAgICAgIHAgPSBwb2ludGVyKGV2ZW50LCBjdXJyZW50VGFyZ2V0KSxcbiAgICAgICAgeDAgPSBldmVudC5jbGllbnRYLFxuICAgICAgICB5MCA9IGV2ZW50LmNsaWVudFk7XG4gICAgZHJhZ0Rpc2FibGUoZXZlbnQudmlldyk7XG4gICAgbm9wcm9wYWdhdGlvbihldmVudCk7XG4gICAgZy5tb3VzZSA9IFtwLCB0aGlzLl9fem9vbS5pbnZlcnQocCldO1xuICAgIGludGVycnVwdCh0aGlzKTtcbiAgICBnLnN0YXJ0KCk7XG5cbiAgICBmdW5jdGlvbiBtb3VzZW1vdmVkKGV2ZW50KSB7XG4gICAgICBub2V2ZW50KGV2ZW50KTtcblxuICAgICAgaWYgKCFnLm1vdmVkKSB7XG4gICAgICAgIHZhciBkeCA9IGV2ZW50LmNsaWVudFggLSB4MCxcbiAgICAgICAgICAgIGR5ID0gZXZlbnQuY2xpZW50WSAtIHkwO1xuICAgICAgICBnLm1vdmVkID0gZHggKiBkeCArIGR5ICogZHkgPiBjbGlja0Rpc3RhbmNlMjtcbiAgICAgIH1cblxuICAgICAgZy5ldmVudChldmVudCkuem9vbShcIm1vdXNlXCIsIGNvbnN0cmFpbih0cmFuc2xhdGUoZy50aGF0Ll9fem9vbSwgZy5tb3VzZVswXSA9IHBvaW50ZXIoZXZlbnQsIGN1cnJlbnRUYXJnZXQpLCBnLm1vdXNlWzFdKSwgZy5leHRlbnQsIHRyYW5zbGF0ZUV4dGVudCkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1vdXNldXBwZWQoZXZlbnQpIHtcbiAgICAgIHYub24oXCJtb3VzZW1vdmUuem9vbSBtb3VzZXVwLnpvb21cIiwgbnVsbCk7XG4gICAgICBkcmFnRW5hYmxlKGV2ZW50LnZpZXcsIGcubW92ZWQpO1xuICAgICAgbm9ldmVudChldmVudCk7XG4gICAgICBnLmV2ZW50KGV2ZW50KS5lbmQoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBkYmxjbGlja2VkKGV2ZW50KSB7XG4gICAgZm9yICh2YXIgX2xlbjMgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4zID4gMSA/IF9sZW4zIC0gMSA6IDApLCBfa2V5MyA9IDE7IF9rZXkzIDwgX2xlbjM7IF9rZXkzKyspIHtcbiAgICAgIGFyZ3NbX2tleTMgLSAxXSA9IGFyZ3VtZW50c1tfa2V5M107XG4gICAgfVxuXG4gICAgaWYgKCFmaWx0ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSkgcmV0dXJuO1xuICAgIHZhciB0MCA9IHRoaXMuX196b29tLFxuICAgICAgICBwMCA9IHBvaW50ZXIoZXZlbnQuY2hhbmdlZFRvdWNoZXMgPyBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSA6IGV2ZW50LCB0aGlzKSxcbiAgICAgICAgcDEgPSB0MC5pbnZlcnQocDApLFxuICAgICAgICBrMSA9IHQwLmsgKiAoZXZlbnQuc2hpZnRLZXkgPyAwLjUgOiAyKSxcbiAgICAgICAgdDEgPSBjb25zdHJhaW4odHJhbnNsYXRlKHNjYWxlKHQwLCBrMSksIHAwLCBwMSksIGV4dGVudC5hcHBseSh0aGlzLCBhcmdzKSwgdHJhbnNsYXRlRXh0ZW50KTtcbiAgICBub2V2ZW50KGV2ZW50KTtcbiAgICBpZiAoZHVyYXRpb24gPiAwKSBzZWxlY3QodGhpcykudHJhbnNpdGlvbigpLmR1cmF0aW9uKGR1cmF0aW9uKS5jYWxsKHNjaGVkdWxlLCB0MSwgcDAsIGV2ZW50KTtlbHNlIHNlbGVjdCh0aGlzKS5jYWxsKHpvb20udHJhbnNmb3JtLCB0MSwgcDAsIGV2ZW50KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvdWNoc3RhcnRlZChldmVudCkge1xuICAgIGZvciAodmFyIF9sZW40ID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuNCA+IDEgPyBfbGVuNCAtIDEgOiAwKSwgX2tleTQgPSAxOyBfa2V5NCA8IF9sZW40OyBfa2V5NCsrKSB7XG4gICAgICBhcmdzW19rZXk0IC0gMV0gPSBhcmd1bWVudHNbX2tleTRdO1xuICAgIH1cblxuICAgIGlmICghZmlsdGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpIHJldHVybjtcbiAgICB2YXIgdG91Y2hlcyA9IGV2ZW50LnRvdWNoZXMsXG4gICAgICAgIG4gPSB0b3VjaGVzLmxlbmd0aCxcbiAgICAgICAgZyA9IGdlc3R1cmUodGhpcywgYXJncywgZXZlbnQuY2hhbmdlZFRvdWNoZXMubGVuZ3RoID09PSBuKS5ldmVudChldmVudCksXG4gICAgICAgIHN0YXJ0ZWQsXG4gICAgICAgIGksXG4gICAgICAgIHQsXG4gICAgICAgIHA7XG4gICAgbm9wcm9wYWdhdGlvbihldmVudCk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICB0ID0gdG91Y2hlc1tpXSwgcCA9IHBvaW50ZXIodCwgdGhpcyk7XG4gICAgICBwID0gW3AsIHRoaXMuX196b29tLmludmVydChwKSwgdC5pZGVudGlmaWVyXTtcbiAgICAgIGlmICghZy50b3VjaDApIGcudG91Y2gwID0gcCwgc3RhcnRlZCA9IHRydWUsIGcudGFwcyA9IDEgKyAhIXRvdWNoc3RhcnRpbmc7ZWxzZSBpZiAoIWcudG91Y2gxICYmIGcudG91Y2gwWzJdICE9PSBwWzJdKSBnLnRvdWNoMSA9IHAsIGcudGFwcyA9IDA7XG4gICAgfVxuXG4gICAgaWYgKHRvdWNoc3RhcnRpbmcpIHRvdWNoc3RhcnRpbmcgPSBjbGVhclRpbWVvdXQodG91Y2hzdGFydGluZyk7XG5cbiAgICBpZiAoc3RhcnRlZCkge1xuICAgICAgaWYgKGcudGFwcyA8IDIpIHRvdWNoZmlyc3QgPSBwWzBdLCB0b3VjaHN0YXJ0aW5nID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRvdWNoc3RhcnRpbmcgPSBudWxsO1xuICAgICAgfSwgdG91Y2hEZWxheSk7XG4gICAgICBpbnRlcnJ1cHQodGhpcyk7XG4gICAgICBnLnN0YXJ0KCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdG91Y2htb3ZlZChldmVudCkge1xuICAgIGlmICghdGhpcy5fX3pvb21pbmcpIHJldHVybjtcblxuICAgIGZvciAodmFyIF9sZW41ID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuNSA+IDEgPyBfbGVuNSAtIDEgOiAwKSwgX2tleTUgPSAxOyBfa2V5NSA8IF9sZW41OyBfa2V5NSsrKSB7XG4gICAgICBhcmdzW19rZXk1IC0gMV0gPSBhcmd1bWVudHNbX2tleTVdO1xuICAgIH1cblxuICAgIHZhciBnID0gZ2VzdHVyZSh0aGlzLCBhcmdzKS5ldmVudChldmVudCksXG4gICAgICAgIHRvdWNoZXMgPSBldmVudC5jaGFuZ2VkVG91Y2hlcyxcbiAgICAgICAgbiA9IHRvdWNoZXMubGVuZ3RoLFxuICAgICAgICBpLFxuICAgICAgICB0LFxuICAgICAgICBwLFxuICAgICAgICBsO1xuICAgIG5vZXZlbnQoZXZlbnQpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgdCA9IHRvdWNoZXNbaV0sIHAgPSBwb2ludGVyKHQsIHRoaXMpO1xuICAgICAgaWYgKGcudG91Y2gwICYmIGcudG91Y2gwWzJdID09PSB0LmlkZW50aWZpZXIpIGcudG91Y2gwWzBdID0gcDtlbHNlIGlmIChnLnRvdWNoMSAmJiBnLnRvdWNoMVsyXSA9PT0gdC5pZGVudGlmaWVyKSBnLnRvdWNoMVswXSA9IHA7XG4gICAgfVxuXG4gICAgdCA9IGcudGhhdC5fX3pvb207XG5cbiAgICBpZiAoZy50b3VjaDEpIHtcbiAgICAgIHZhciBwMCA9IGcudG91Y2gwWzBdLFxuICAgICAgICAgIGwwID0gZy50b3VjaDBbMV0sXG4gICAgICAgICAgcDEgPSBnLnRvdWNoMVswXSxcbiAgICAgICAgICBsMSA9IGcudG91Y2gxWzFdLFxuICAgICAgICAgIGRwID0gKGRwID0gcDFbMF0gLSBwMFswXSkgKiBkcCArIChkcCA9IHAxWzFdIC0gcDBbMV0pICogZHAsXG4gICAgICAgICAgZGwgPSAoZGwgPSBsMVswXSAtIGwwWzBdKSAqIGRsICsgKGRsID0gbDFbMV0gLSBsMFsxXSkgKiBkbDtcbiAgICAgIHQgPSBzY2FsZSh0LCBNYXRoLnNxcnQoZHAgLyBkbCkpO1xuICAgICAgcCA9IFsocDBbMF0gKyBwMVswXSkgLyAyLCAocDBbMV0gKyBwMVsxXSkgLyAyXTtcbiAgICAgIGwgPSBbKGwwWzBdICsgbDFbMF0pIC8gMiwgKGwwWzFdICsgbDFbMV0pIC8gMl07XG4gICAgfSBlbHNlIGlmIChnLnRvdWNoMCkgcCA9IGcudG91Y2gwWzBdLCBsID0gZy50b3VjaDBbMV07ZWxzZSByZXR1cm47XG5cbiAgICBnLnpvb20oXCJ0b3VjaFwiLCBjb25zdHJhaW4odHJhbnNsYXRlKHQsIHAsIGwpLCBnLmV4dGVudCwgdHJhbnNsYXRlRXh0ZW50KSk7XG4gIH1cblxuICBmdW5jdGlvbiB0b3VjaGVuZGVkKGV2ZW50KSB7XG4gICAgZm9yICh2YXIgX2xlbjYgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW42ID4gMSA/IF9sZW42IC0gMSA6IDApLCBfa2V5NiA9IDE7IF9rZXk2IDwgX2xlbjY7IF9rZXk2KyspIHtcbiAgICAgIGFyZ3NbX2tleTYgLSAxXSA9IGFyZ3VtZW50c1tfa2V5Nl07XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLl9fem9vbWluZykgcmV0dXJuO1xuICAgIHZhciBnID0gZ2VzdHVyZSh0aGlzLCBhcmdzKS5ldmVudChldmVudCksXG4gICAgICAgIHRvdWNoZXMgPSBldmVudC5jaGFuZ2VkVG91Y2hlcyxcbiAgICAgICAgbiA9IHRvdWNoZXMubGVuZ3RoLFxuICAgICAgICBpLFxuICAgICAgICB0O1xuICAgIG5vcHJvcGFnYXRpb24oZXZlbnQpO1xuICAgIGlmICh0b3VjaGVuZGluZykgY2xlYXJUaW1lb3V0KHRvdWNoZW5kaW5nKTtcbiAgICB0b3VjaGVuZGluZyA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgdG91Y2hlbmRpbmcgPSBudWxsO1xuICAgIH0sIHRvdWNoRGVsYXkpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgdCA9IHRvdWNoZXNbaV07XG4gICAgICBpZiAoZy50b3VjaDAgJiYgZy50b3VjaDBbMl0gPT09IHQuaWRlbnRpZmllcikgZGVsZXRlIGcudG91Y2gwO2Vsc2UgaWYgKGcudG91Y2gxICYmIGcudG91Y2gxWzJdID09PSB0LmlkZW50aWZpZXIpIGRlbGV0ZSBnLnRvdWNoMTtcbiAgICB9XG5cbiAgICBpZiAoZy50b3VjaDEgJiYgIWcudG91Y2gwKSBnLnRvdWNoMCA9IGcudG91Y2gxLCBkZWxldGUgZy50b3VjaDE7XG4gICAgaWYgKGcudG91Y2gwKSBnLnRvdWNoMFsxXSA9IHRoaXMuX196b29tLmludmVydChnLnRvdWNoMFswXSk7ZWxzZSB7XG4gICAgICBnLmVuZCgpOyAvLyBJZiB0aGlzIHdhcyBhIGRibHRhcCwgcmVyb3V0ZSB0byB0aGUgKG9wdGlvbmFsKSBkYmxjbGljay56b29tIGhhbmRsZXIuXG5cbiAgICAgIGlmIChnLnRhcHMgPT09IDIpIHtcbiAgICAgICAgdCA9IHBvaW50ZXIodCwgdGhpcyk7XG5cbiAgICAgICAgaWYgKE1hdGguaHlwb3QodG91Y2hmaXJzdFswXSAtIHRbMF0sIHRvdWNoZmlyc3RbMV0gLSB0WzFdKSA8IHRhcERpc3RhbmNlKSB7XG4gICAgICAgICAgdmFyIHAgPSBzZWxlY3QodGhpcykub24oXCJkYmxjbGljay56b29tXCIpO1xuICAgICAgICAgIGlmIChwKSBwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB6b29tLndoZWVsRGVsdGEgPSBmdW5jdGlvbiAoXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHdoZWVsRGVsdGEgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50KCtfKSwgem9vbSkgOiB3aGVlbERlbHRhO1xuICB9O1xuXG4gIHpvb20uZmlsdGVyID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChmaWx0ZXIgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50KCEhXyksIHpvb20pIDogZmlsdGVyO1xuICB9O1xuXG4gIHpvb20udG91Y2hhYmxlID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0b3VjaGFibGUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50KCEhXyksIHpvb20pIDogdG91Y2hhYmxlO1xuICB9O1xuXG4gIHpvb20uZXh0ZW50ID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChleHRlbnQgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50KFtbK19bMF1bMF0sICtfWzBdWzFdXSwgWytfWzFdWzBdLCArX1sxXVsxXV1dKSwgem9vbSkgOiBleHRlbnQ7XG4gIH07XG5cbiAgem9vbS5zY2FsZUV4dGVudCA9IGZ1bmN0aW9uIChfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc2NhbGVFeHRlbnRbMF0gPSArX1swXSwgc2NhbGVFeHRlbnRbMV0gPSArX1sxXSwgem9vbSkgOiBbc2NhbGVFeHRlbnRbMF0sIHNjYWxlRXh0ZW50WzFdXTtcbiAgfTtcblxuICB6b29tLnRyYW5zbGF0ZUV4dGVudCA9IGZ1bmN0aW9uIChfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodHJhbnNsYXRlRXh0ZW50WzBdWzBdID0gK19bMF1bMF0sIHRyYW5zbGF0ZUV4dGVudFsxXVswXSA9ICtfWzFdWzBdLCB0cmFuc2xhdGVFeHRlbnRbMF1bMV0gPSArX1swXVsxXSwgdHJhbnNsYXRlRXh0ZW50WzFdWzFdID0gK19bMV1bMV0sIHpvb20pIDogW1t0cmFuc2xhdGVFeHRlbnRbMF1bMF0sIHRyYW5zbGF0ZUV4dGVudFswXVsxXV0sIFt0cmFuc2xhdGVFeHRlbnRbMV1bMF0sIHRyYW5zbGF0ZUV4dGVudFsxXVsxXV1dO1xuICB9O1xuXG4gIHpvb20uY29uc3RyYWluID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjb25zdHJhaW4gPSBfLCB6b29tKSA6IGNvbnN0cmFpbjtcbiAgfTtcblxuICB6b29tLmR1cmF0aW9uID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkdXJhdGlvbiA9ICtfLCB6b29tKSA6IGR1cmF0aW9uO1xuICB9O1xuXG4gIHpvb20uaW50ZXJwb2xhdGUgPSBmdW5jdGlvbiAoXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGludGVycG9sYXRlID0gXywgem9vbSkgOiBpbnRlcnBvbGF0ZTtcbiAgfTtcblxuICB6b29tLm9uID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IGxpc3RlbmVycy5vbi5hcHBseShsaXN0ZW5lcnMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHZhbHVlID09PSBsaXN0ZW5lcnMgPyB6b29tIDogdmFsdWU7XG4gIH07XG5cbiAgem9vbS5jbGlja0Rpc3RhbmNlID0gZnVuY3Rpb24gKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjbGlja0Rpc3RhbmNlMiA9IChfID0gK18pICogXywgem9vbSkgOiBNYXRoLnNxcnQoY2xpY2tEaXN0YW5jZTIpO1xuICB9O1xuXG4gIHpvb20udGFwRGlzdGFuY2UgPSBmdW5jdGlvbiAoXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRhcERpc3RhbmNlID0gK18sIHpvb20pIDogdGFwRGlzdGFuY2U7XG4gIH07XG5cbiAgcmV0dXJuIHpvb207XG59IiwiZXhwb3J0IHsgZGVmYXVsdCBhcyB6b29tIH0gZnJvbSBcIi4vem9vbS5qc1wiO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB6b29tVHJhbnNmb3JtLCBpZGVudGl0eSBhcyB6b29tSWRlbnRpdHksIFRyYW5zZm9ybSBhcyBab29tVHJhbnNmb3JtIH0gZnJvbSBcIi4vdHJhbnNmb3JtLmpzXCI7IiwiZXhwb3J0ICogZnJvbSBcImQzLWFycmF5XCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtYXhpc1wiO1xuZXhwb3J0ICogZnJvbSBcImQzLWJydXNoXCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtY2hvcmRcIjtcbmV4cG9ydCAqIGZyb20gXCJkMy1jb2xvclwiO1xuZXhwb3J0ICogZnJvbSBcImQzLWNvbnRvdXJcIjtcbmV4cG9ydCAqIGZyb20gXCJkMy1kZWxhdW5heVwiO1xuZXhwb3J0ICogZnJvbSBcImQzLWRpc3BhdGNoXCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtZHJhZ1wiO1xuZXhwb3J0ICogZnJvbSBcImQzLWRzdlwiO1xuZXhwb3J0ICogZnJvbSBcImQzLWVhc2VcIjtcbmV4cG9ydCAqIGZyb20gXCJkMy1mZXRjaFwiO1xuZXhwb3J0ICogZnJvbSBcImQzLWZvcmNlXCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtZm9ybWF0XCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtZ2VvXCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtaGllcmFyY2h5XCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtaW50ZXJwb2xhdGVcIjtcbmV4cG9ydCAqIGZyb20gXCJkMy1wYXRoXCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtcG9seWdvblwiO1xuZXhwb3J0ICogZnJvbSBcImQzLXF1YWR0cmVlXCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtcmFuZG9tXCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtc2NhbGVcIjtcbmV4cG9ydCAqIGZyb20gXCJkMy1zY2FsZS1jaHJvbWF0aWNcIjtcbmV4cG9ydCAqIGZyb20gXCJkMy1zZWxlY3Rpb25cIjtcbmV4cG9ydCAqIGZyb20gXCJkMy1zaGFwZVwiO1xuZXhwb3J0ICogZnJvbSBcImQzLXRpbWVcIjtcbmV4cG9ydCAqIGZyb20gXCJkMy10aW1lLWZvcm1hdFwiO1xuZXhwb3J0ICogZnJvbSBcImQzLXRpbWVyXCI7XG5leHBvcnQgKiBmcm9tIFwiZDMtdHJhbnNpdGlvblwiO1xuZXhwb3J0ICogZnJvbSBcImQzLXpvb21cIjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvT3ZlcmxheVBvc2l0aW9uaW5nXG4gKi9cblxuLyoqXG4gKiBPdmVybGF5IHBvc2l0aW9uOiBgJ2JvdHRvbS1sZWZ0J2AsIGAnYm90dG9tLWNlbnRlcidgLCAgYCdib3R0b20tcmlnaHQnYCxcbiAqIGAnY2VudGVyLWxlZnQnYCwgYCdjZW50ZXItY2VudGVyJ2AsIGAnY2VudGVyLXJpZ2h0J2AsIGAndG9wLWxlZnQnYCxcbiAqIGAndG9wLWNlbnRlcidgLCBgJ3RvcC1yaWdodCdgXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIEJPVFRPTV9MRUZUOiAnYm90dG9tLWxlZnQnLFxuICBCT1RUT01fQ0VOVEVSOiAnYm90dG9tLWNlbnRlcicsXG4gIEJPVFRPTV9SSUdIVDogJ2JvdHRvbS1yaWdodCcsXG4gIENFTlRFUl9MRUZUOiAnY2VudGVyLWxlZnQnLFxuICBDRU5URVJfQ0VOVEVSOiAnY2VudGVyLWNlbnRlcicsXG4gIENFTlRFUl9SSUdIVDogJ2NlbnRlci1yaWdodCcsXG4gIFRPUF9MRUZUOiAndG9wLWxlZnQnLFxuICBUT1BfQ0VOVEVSOiAndG9wLWNlbnRlcicsXG4gIFRPUF9SSUdIVDogJ3RvcC1yaWdodCdcbn07IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9PdmVybGF5XG4gKi9cblxuXG5pbXBvcnQgQmFzZU9iamVjdCwgeyBnZXRDaGFuZ2VFdmVudFR5cGUgfSBmcm9tICcuL09iamVjdC5qcyc7XG5pbXBvcnQgTWFwRXZlbnRUeXBlIGZyb20gJy4vTWFwRXZlbnRUeXBlLmpzJztcbmltcG9ydCBPdmVybGF5UG9zaXRpb25pbmcgZnJvbSAnLi9PdmVybGF5UG9zaXRpb25pbmcuanMnO1xuaW1wb3J0IHsgQ0xBU1NfU0VMRUNUQUJMRSB9IGZyb20gJy4vY3NzLmpzJztcbmltcG9ydCB7IGNvbnRhaW5zRXh0ZW50IH0gZnJvbSAnLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgbGlzdGVuLCB1bmxpc3RlbkJ5S2V5IH0gZnJvbSAnLi9ldmVudHMuanMnO1xuaW1wb3J0IHsgb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGgsIHJlbW92ZUNoaWxkcmVuLCByZW1vdmVOb2RlIH0gZnJvbSAnLi9kb20uanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcnxzdHJpbmd9IFtpZF0gU2V0IHRoZSBvdmVybGF5IGlkLiBUaGUgb3ZlcmxheSBpZCBjYW4gYmUgdXNlZFxuICogd2l0aCB0aGUge0BsaW5rIG1vZHVsZTpvbC9NYXB+TWFwI2dldE92ZXJsYXlCeUlkfSBtZXRob2QuXG4gKiBAcHJvcGVydHkge0hUTUxFbGVtZW50fSBbZWxlbWVudF0gVGhlIG92ZXJsYXkgZWxlbWVudC5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gW29mZnNldD1bMCwgMF1dIE9mZnNldHMgaW4gcGl4ZWxzIHVzZWQgd2hlbiBwb3NpdGlvbmluZ1xuICogdGhlIG92ZXJsYXkuIFRoZSBmaXJzdCBlbGVtZW50IGluIHRoZVxuICogYXJyYXkgaXMgdGhlIGhvcml6b250YWwgb2Zmc2V0LiBBIHBvc2l0aXZlIHZhbHVlIHNoaWZ0cyB0aGUgb3ZlcmxheSByaWdodC5cbiAqIFRoZSBzZWNvbmQgZWxlbWVudCBpbiB0aGUgYXJyYXkgaXMgdGhlIHZlcnRpY2FsIG9mZnNldC4gQSBwb3NpdGl2ZSB2YWx1ZVxuICogc2hpZnRzIHRoZSBvdmVybGF5IGRvd24uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBbcG9zaXRpb25dIFRoZSBvdmVybGF5IHBvc2l0aW9uXG4gKiBpbiBtYXAgcHJvamVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9PdmVybGF5UG9zaXRpb25pbmcuanNcIikuZGVmYXVsdH0gW3Bvc2l0aW9uaW5nPSd0b3AtbGVmdCddIERlZmluZXMgaG93XG4gKiB0aGUgb3ZlcmxheSBpcyBhY3R1YWxseSBwb3NpdGlvbmVkIHdpdGggcmVzcGVjdCB0byBpdHMgYHBvc2l0aW9uYCBwcm9wZXJ0eS5cbiAqIFBvc3NpYmxlIHZhbHVlcyBhcmUgYCdib3R0b20tbGVmdCdgLCBgJ2JvdHRvbS1jZW50ZXInYCwgYCdib3R0b20tcmlnaHQnYCxcbiAqIGAnY2VudGVyLWxlZnQnYCwgYCdjZW50ZXItY2VudGVyJ2AsIGAnY2VudGVyLXJpZ2h0J2AsIGAndG9wLWxlZnQnYCxcbiAqIGAndG9wLWNlbnRlcidgLCBhbmQgYCd0b3AtcmlnaHQnYC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3N0b3BFdmVudD10cnVlXSBXaGV0aGVyIGV2ZW50IHByb3BhZ2F0aW9uIHRvIHRoZSBtYXBcbiAqIHZpZXdwb3J0IHNob3VsZCBiZSBzdG9wcGVkLiBJZiBgdHJ1ZWAgdGhlIG92ZXJsYXkgaXMgcGxhY2VkIGluIHRoZSBzYW1lXG4gKiBjb250YWluZXIgYXMgdGhhdCBvZiB0aGUgY29udHJvbHMgKENTUyBjbGFzcyBuYW1lXG4gKiBgb2wtb3ZlcmxheWNvbnRhaW5lci1zdG9wZXZlbnRgKTsgaWYgYGZhbHNlYCBpdCBpcyBwbGFjZWQgaW4gdGhlIGNvbnRhaW5lclxuICogd2l0aCBDU1MgY2xhc3MgbmFtZSBzcGVjaWZpZWQgYnkgdGhlIGBjbGFzc05hbWVgIHByb3BlcnR5LlxuICogQHByb3BlcnR5IHtib29sZWFufSBbaW5zZXJ0Rmlyc3Q9dHJ1ZV0gV2hldGhlciB0aGUgb3ZlcmxheSBpcyBpbnNlcnRlZCBmaXJzdFxuICogaW4gdGhlIG92ZXJsYXkgY29udGFpbmVyLCBvciBhcHBlbmRlZC4gSWYgdGhlIG92ZXJsYXkgaXMgcGxhY2VkIGluIHRoZSBzYW1lXG4gKiBjb250YWluZXIgYXMgdGhhdCBvZiB0aGUgY29udHJvbHMgKHNlZSB0aGUgYHN0b3BFdmVudGAgb3B0aW9uKSB5b3Ugd2lsbFxuICogcHJvYmFibHkgc2V0IGBpbnNlcnRGaXJzdGAgdG8gYHRydWVgIHNvIHRoZSBvdmVybGF5IGlzIGRpc3BsYXllZCBiZWxvdyB0aGVcbiAqIGNvbnRyb2xzLlxuICogQHByb3BlcnR5IHtQYW5JbnRvVmlld09wdGlvbnN8Ym9vbGVhbn0gW2F1dG9QYW49ZmFsc2VdIFBhbiB0aGUgbWFwIHdoZW4gY2FsbGluZ1xuICogYHNldFBvc2l0aW9uYCwgc28gdGhhdCB0aGUgb3ZlcmxheSBpcyBlbnRpcmVseSB2aXNpYmxlIGluIHRoZSBjdXJyZW50IHZpZXdwb3J0P1xuICogSWYgYHRydWVgIChkZXByZWNhdGVkKSwgdGhlbiBgYXV0b1BhbkFuaW1hdGlvbmAgYW5kIGBhdXRvUGFuTWFyZ2luYCB3aWxsIGJlXG4gKiB1c2VkIHRvIGRldGVybWluZSB0aGUgcGFubmluZyBwYXJhbWV0ZXJzOyBpZiBhbiBvYmplY3QgaXMgc3VwcGxpZWQgdGhlbiBvdGhlclxuICogcGFyYW1ldGVycyBhcmUgaWdub3JlZC5cbiAqIEBwcm9wZXJ0eSB7UGFuT3B0aW9uc30gW2F1dG9QYW5BbmltYXRpb25dIFRoZSBhbmltYXRpb24gb3B0aW9ucyB1c2VkIHRvIHBhblxuICogdGhlIG92ZXJsYXkgaW50byB2aWV3LiBUaGlzIGFuaW1hdGlvbiBpcyBvbmx5IHVzZWQgd2hlbiBgYXV0b1BhbmAgaXMgZW5hYmxlZC5cbiAqIEEgYGR1cmF0aW9uYCBhbmQgYGVhc2luZ2AgbWF5IGJlIHByb3ZpZGVkIHRvIGN1c3RvbWl6ZSB0aGUgYW5pbWF0aW9uLlxuICogRGVwcmVjYXRlZCBhbmQgaWdub3JlZCBpZiBgYXV0b1BhbmAgaXMgc3VwcGxpZWQgYXMgYW4gb2JqZWN0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFthdXRvUGFuTWFyZ2luPTIwXSBUaGUgbWFyZ2luIChpbiBwaXhlbHMpIGJldHdlZW4gdGhlXG4gKiBvdmVybGF5IGFuZCB0aGUgYm9yZGVycyBvZiB0aGUgbWFwIHdoZW4gYXV0b3Bhbm5pbmcuIERlcHJlY2F0ZWQgYW5kIGlnbm9yZWRcbiAqIGlmIGBhdXRvUGFuYCBpcyBzdXBwbGllZCBhcyBhbiBvYmplY3QuXG4gKiBAcHJvcGVydHkge1BhbkludG9WaWV3T3B0aW9uc30gW2F1dG9QYW5PcHRpb25zXSBUaGUgb3B0aW9ucyB0byB1c2UgZm9yIHRoZVxuICogYXV0b1Bhbi4gVGhpcyBpcyBvbmx5IHVzZWQgd2hlbiBgYXV0b1BhbmAgaXMgZW5hYmxlZCBhbmQgaGFzIHByZWZlcmVuY2Ugb3ZlclxuICogdGhlIGluZGl2aWR1YWwgYGF1dG9QYW5NYXJnaW5gIGFuZCBgYXV0b1Bhbk9wdGlvbnNgLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjbGFzc05hbWU9J29sLW92ZXJsYXktY29udGFpbmVyIG9sLXNlbGVjdGFibGUnXSBDU1MgY2xhc3NcbiAqIG5hbWUuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBQYW5PcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2R1cmF0aW9uPTEwMDBdIFRoZSBkdXJhdGlvbiBvZiB0aGUgYW5pbWF0aW9uIGluXG4gKiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6bnVtYmVyfSBbZWFzaW5nXSBUaGUgZWFzaW5nIGZ1bmN0aW9uIHRvIHVzZS4gQ2FuXG4gKiBiZSBvbmUgZnJvbSB7QGxpbmsgbW9kdWxlOm9sL2Vhc2luZ30gb3IgYSBjdXN0b20gZnVuY3Rpb24uXG4gKiBEZWZhdWx0IGlzIHtAbGluayBtb2R1bGU6b2wvZWFzaW5nfmluQW5kT3V0fS5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFBhbkludG9WaWV3T3B0aW9uc1xuICogQHByb3BlcnR5IHtQYW5PcHRpb25zfSBbYW5pbWF0aW9uPXt9XSBUaGUgYW5pbWF0aW9uIHBhcmFtZXRlcnMgZm9yIHRoZSBwYW5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWFyZ2luPTIwXSBUaGUgbWFyZ2luIChpbiBwaXhlbHMpIGJldHdlZW4gdGhlXG4gKiBvdmVybGF5IGFuZCB0aGUgYm9yZGVycyBvZiB0aGUgbWFwIHdoZW4gcGFubmluZyBpbnRvIHZpZXcuXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQHByb3RlY3RlZFxuICovXG5cbnZhciBQcm9wZXJ0eSA9IHtcbiAgRUxFTUVOVDogJ2VsZW1lbnQnLFxuICBNQVA6ICdtYXAnLFxuICBPRkZTRVQ6ICdvZmZzZXQnLFxuICBQT1NJVElPTjogJ3Bvc2l0aW9uJyxcbiAgUE9TSVRJT05JTkc6ICdwb3NpdGlvbmluZydcbn07XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFuIGVsZW1lbnQgdG8gYmUgZGlzcGxheWVkIG92ZXIgdGhlIG1hcCBhbmQgYXR0YWNoZWQgdG8gYSBzaW5nbGUgbWFwXG4gKiBsb2NhdGlvbi4gIExpa2Uge0BsaW5rIG1vZHVsZTpvbC9jb250cm9sL0NvbnRyb2x+Q29udHJvbH0sIE92ZXJsYXlzIGFyZVxuICogdmlzaWJsZSB3aWRnZXRzLiBVbmxpa2UgQ29udHJvbHMsIHRoZXkgYXJlIG5vdCBpbiBhIGZpeGVkIHBvc2l0aW9uIG9uIHRoZVxuICogc2NyZWVuLCBidXQgYXJlIHRpZWQgdG8gYSBnZW9ncmFwaGljYWwgY29vcmRpbmF0ZSwgc28gcGFubmluZyB0aGUgbWFwIHdpbGxcbiAqIG1vdmUgYW4gT3ZlcmxheSBidXQgbm90IGEgQ29udHJvbC5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICBpbXBvcnQgT3ZlcmxheSBmcm9tICdvbC9PdmVybGF5JztcbiAqXG4gKiAgICAgdmFyIHBvcHVwID0gbmV3IE92ZXJsYXkoe1xuICogICAgICAgZWxlbWVudDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BvcHVwJylcbiAqICAgICB9KTtcbiAqICAgICBwb3B1cC5zZXRQb3NpdGlvbihjb29yZGluYXRlKTtcbiAqICAgICBtYXAuYWRkT3ZlcmxheShwb3B1cCk7XG4gKlxuICogQGFwaVxuICovXG5cbnZhciBPdmVybGF5ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKE92ZXJsYXksIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3ZlcmxheSBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIE92ZXJsYXkob3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtPcHRpb25zfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcnxzdHJpbmd8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMuaWQgPSBvcHRpb25zLmlkO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmluc2VydEZpcnN0ID0gb3B0aW9ucy5pbnNlcnRGaXJzdCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5pbnNlcnRGaXJzdCA6IHRydWU7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3RvcEV2ZW50ID0gb3B0aW9ucy5zdG9wRXZlbnQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc3RvcEV2ZW50IDogdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIF90aGlzLmVsZW1lbnQuY2xhc3NOYW1lID0gb3B0aW9ucy5jbGFzc05hbWUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xhc3NOYW1lIDogJ29sLW92ZXJsYXktY29udGFpbmVyICcgKyBDTEFTU19TRUxFQ1RBQkxFO1xuICAgIF90aGlzLmVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIF90aGlzLmVsZW1lbnQuc3R5bGUucG9pbnRlckV2ZW50cyA9ICdhdXRvJztcbiAgICB2YXIgYXV0b1BhbiA9IG9wdGlvbnMuYXV0b1BhbjtcblxuICAgIGlmIChhdXRvUGFuICYmICdvYmplY3QnICE9PSB0eXBlb2YgYXV0b1Bhbikge1xuICAgICAgYXV0b1BhbiA9IHtcbiAgICAgICAgYW5pbWF0aW9uOiBvcHRpb25zLmF1dG9QYW5BbmltYXRpb24sXG4gICAgICAgIG1hcmdpbjogb3B0aW9ucy5hdXRvUGFuTWFyZ2luXG4gICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge1BhbkludG9WaWV3T3B0aW9uc3xmYWxzZX1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuYXV0b1BhbiA9XG4gICAgLyoqIEB0eXBlIHtQYW5JbnRvVmlld09wdGlvbnN9ICovXG4gICAgYXV0b1BhbiB8fCBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge3t0cmFuc2Zvcm1fOiBzdHJpbmcsXG4gICAgICogICAgICAgICB2aXNpYmxlOiBib29sZWFufX1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkID0ge1xuICAgICAgdHJhbnNmb3JtXzogJycsXG4gICAgICB2aXNpYmxlOiB0cnVlXG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuL2V2ZW50cy5qc1wiKS5FdmVudHNLZXl9XG4gICAgICovXG5cbiAgICBfdGhpcy5tYXBQb3N0cmVuZGVyTGlzdGVuZXJLZXkgPSBudWxsO1xuXG4gICAgX3RoaXMuYWRkRXZlbnRMaXN0ZW5lcihnZXRDaGFuZ2VFdmVudFR5cGUoUHJvcGVydHkuRUxFTUVOVCksIF90aGlzLmhhbmRsZUVsZW1lbnRDaGFuZ2VkKTtcblxuICAgIF90aGlzLmFkZEV2ZW50TGlzdGVuZXIoZ2V0Q2hhbmdlRXZlbnRUeXBlKFByb3BlcnR5Lk1BUCksIF90aGlzLmhhbmRsZU1hcENoYW5nZWQpO1xuXG4gICAgX3RoaXMuYWRkRXZlbnRMaXN0ZW5lcihnZXRDaGFuZ2VFdmVudFR5cGUoUHJvcGVydHkuT0ZGU0VUKSwgX3RoaXMuaGFuZGxlT2Zmc2V0Q2hhbmdlZCk7XG5cbiAgICBfdGhpcy5hZGRFdmVudExpc3RlbmVyKGdldENoYW5nZUV2ZW50VHlwZShQcm9wZXJ0eS5QT1NJVElPTiksIF90aGlzLmhhbmRsZVBvc2l0aW9uQ2hhbmdlZCk7XG5cbiAgICBfdGhpcy5hZGRFdmVudExpc3RlbmVyKGdldENoYW5nZUV2ZW50VHlwZShQcm9wZXJ0eS5QT1NJVElPTklORyksIF90aGlzLmhhbmRsZVBvc2l0aW9uaW5nQ2hhbmdlZCk7XG5cbiAgICBpZiAob3B0aW9ucy5lbGVtZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIF90aGlzLnNldEVsZW1lbnQob3B0aW9ucy5lbGVtZW50KTtcbiAgICB9XG5cbiAgICBfdGhpcy5zZXRPZmZzZXQob3B0aW9ucy5vZmZzZXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMub2Zmc2V0IDogWzAsIDBdKTtcblxuICAgIF90aGlzLnNldFBvc2l0aW9uaW5nKG9wdGlvbnMucG9zaXRpb25pbmcgIT09IHVuZGVmaW5lZCA/XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL092ZXJsYXlQb3NpdGlvbmluZy5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIG9wdGlvbnMucG9zaXRpb25pbmcgOiBPdmVybGF5UG9zaXRpb25pbmcuVE9QX0xFRlQpO1xuXG4gICAgaWYgKG9wdGlvbnMucG9zaXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgX3RoaXMuc2V0UG9zaXRpb24ob3B0aW9ucy5wb3NpdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIERPTSBlbGVtZW50IG9mIHRoaXMgb3ZlcmxheS5cbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR8dW5kZWZpbmVkfSBUaGUgRWxlbWVudCBjb250YWluaW5nIHRoZSBvdmVybGF5LlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuZ2V0RWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtIVE1MRWxlbWVudHx1bmRlZmluZWR9ICovXG4gICAgICB0aGlzLmdldChQcm9wZXJ0eS5FTEVNRU5UKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG92ZXJsYXkgaWRlbnRpZmllciB3aGljaCBpcyBzZXQgb24gY29uc3RydWN0b3IuXG4gICAqIEByZXR1cm4ge251bWJlcnxzdHJpbmd8dW5kZWZpbmVkfSBJZC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLmdldElkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmlkO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtYXAgYXNzb2NpYXRlZCB3aXRoIHRoaXMgb3ZlcmxheS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdHx1bmRlZmluZWR9IFRoZSBtYXAgdGhhdCB0aGVcbiAgICogb3ZlcmxheSBpcyBwYXJ0IG9mLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuZ2V0TWFwID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR8dW5kZWZpbmVkfSAqL1xuICAgICAgdGhpcy5nZXQoUHJvcGVydHkuTUFQKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG9mZnNldCBvZiB0aGlzIG92ZXJsYXkuXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFRoZSBvZmZzZXQuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5nZXRPZmZzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIHRoaXMuZ2V0KFByb3BlcnR5Lk9GRlNFVClcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoaXMgb3ZlcmxheS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkfSBUaGUgc3BhdGlhbCBwb2ludCB0aGF0IHRoZSBvdmVybGF5IGlzXG4gICAqICAgICBhbmNob3JlZCBhdC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH0gKi9cbiAgICAgIHRoaXMuZ2V0KFByb3BlcnR5LlBPU0lUSU9OKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1cnJlbnQgcG9zaXRpb25pbmcgb2YgdGhpcyBvdmVybGF5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL092ZXJsYXlQb3NpdGlvbmluZy5qc1wiKS5kZWZhdWx0fSBIb3cgdGhlIG92ZXJsYXkgaXMgcG9zaXRpb25lZFxuICAgKiAgICAgcmVsYXRpdmUgdG8gaXRzIHBvaW50IG9uIHRoZSBtYXAuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5nZXRQb3NpdGlvbmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL092ZXJsYXlQb3NpdGlvbmluZy5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgdGhpcy5nZXQoUHJvcGVydHkuUE9TSVRJT05JTkcpXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5oYW5kbGVFbGVtZW50Q2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZW1vdmVDaGlsZHJlbih0aGlzLmVsZW1lbnQpO1xuICAgIHZhciBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50KCk7XG5cbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5oYW5kbGVNYXBDaGFuZ2VkID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLm1hcFBvc3RyZW5kZXJMaXN0ZW5lcktleSkge1xuICAgICAgcmVtb3ZlTm9kZSh0aGlzLmVsZW1lbnQpO1xuICAgICAgdW5saXN0ZW5CeUtleSh0aGlzLm1hcFBvc3RyZW5kZXJMaXN0ZW5lcktleSk7XG4gICAgICB0aGlzLm1hcFBvc3RyZW5kZXJMaXN0ZW5lcktleSA9IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIG1hcCA9IHRoaXMuZ2V0TWFwKCk7XG5cbiAgICBpZiAobWFwKSB7XG4gICAgICB0aGlzLm1hcFBvc3RyZW5kZXJMaXN0ZW5lcktleSA9IGxpc3RlbihtYXAsIE1hcEV2ZW50VHlwZS5QT1NUUkVOREVSLCB0aGlzLnJlbmRlciwgdGhpcyk7XG4gICAgICB0aGlzLnVwZGF0ZVBpeGVsUG9zaXRpb24oKTtcbiAgICAgIHZhciBjb250YWluZXIgPSB0aGlzLnN0b3BFdmVudCA/IG1hcC5nZXRPdmVybGF5Q29udGFpbmVyU3RvcEV2ZW50KCkgOiBtYXAuZ2V0T3ZlcmxheUNvbnRhaW5lcigpO1xuXG4gICAgICBpZiAodGhpcy5pbnNlcnRGaXJzdCkge1xuICAgICAgICBjb250YWluZXIuaW5zZXJ0QmVmb3JlKHRoaXMuZWxlbWVudCwgY29udGFpbmVyLmNoaWxkTm9kZXNbMF0gfHwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5wZXJmb3JtQXV0b1BhbigpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy51cGRhdGVQaXhlbFBvc2l0aW9uKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuaGFuZGxlT2Zmc2V0Q2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVwZGF0ZVBpeGVsUG9zaXRpb24oKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5oYW5kbGVQb3NpdGlvbkNoYW5nZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy51cGRhdGVQaXhlbFBvc2l0aW9uKCk7XG4gICAgdGhpcy5wZXJmb3JtQXV0b1BhbigpO1xuICB9O1xuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLmhhbmRsZVBvc2l0aW9uaW5nQ2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVwZGF0ZVBpeGVsUG9zaXRpb24oKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgRE9NIGVsZW1lbnQgdG8gYmUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgb3ZlcmxheS5cbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudHx1bmRlZmluZWR9IGVsZW1lbnQgVGhlIEVsZW1lbnQgY29udGFpbmluZyB0aGUgb3ZlcmxheS5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLnNldEVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIHRoaXMuc2V0KFByb3BlcnR5LkVMRU1FTlQsIGVsZW1lbnQpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBtYXAgdG8gYmUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgb3ZlcmxheS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fHVuZGVmaW5lZH0gbWFwIFRoZSBtYXAgdGhhdCB0aGVcbiAgICogb3ZlcmxheSBpcyBwYXJ0IG9mLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuc2V0TWFwID0gZnVuY3Rpb24gKG1hcCkge1xuICAgIHRoaXMuc2V0KFByb3BlcnR5Lk1BUCwgbWFwKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgb2Zmc2V0IGZvciB0aGlzIG92ZXJsYXkuXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gb2Zmc2V0IE9mZnNldC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLnNldE9mZnNldCA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgICB0aGlzLnNldChQcm9wZXJ0eS5PRkZTRVQsIG9mZnNldCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHBvc2l0aW9uIGZvciB0aGlzIG92ZXJsYXkuIElmIHRoZSBwb3NpdGlvbiBpcyBgdW5kZWZpbmVkYCB0aGVcbiAgICogb3ZlcmxheSBpcyBoaWRkZW4uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkfSBwb3NpdGlvbiBUaGUgc3BhdGlhbCBwb2ludCB0aGF0IHRoZSBvdmVybGF5XG4gICAqICAgICBpcyBhbmNob3JlZCBhdC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLnNldFBvc2l0aW9uID0gZnVuY3Rpb24gKHBvc2l0aW9uKSB7XG4gICAgdGhpcy5zZXQoUHJvcGVydHkuUE9TSVRJT04sIHBvc2l0aW9uKTtcbiAgfTtcbiAgLyoqXG4gICAqIFBhbiB0aGUgbWFwIHNvIHRoYXQgdGhlIG92ZXJsYXkgaXMgZW50aXJlbHkgdmlzaXNibGUgaW4gdGhlIGN1cnJlbnQgdmlld3BvcnRcbiAgICogKGlmIG5lY2Vzc2FyeSkgdXNpbmcgdGhlIGNvbmZpZ3VyZWQgYXV0b1BhbiBwYXJhbWV0ZXJzXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5wZXJmb3JtQXV0b1BhbiA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5hdXRvUGFuKSB7XG4gICAgICB0aGlzLnBhbkludG9WaWV3KHRoaXMuYXV0b1Bhbik7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUGFuIHRoZSBtYXAgc28gdGhhdCB0aGUgb3ZlcmxheSBpcyBlbnRpcmVseSB2aXNpYmxlIGluIHRoZSBjdXJyZW50IHZpZXdwb3J0XG4gICAqIChpZiBuZWNlc3NhcnkpLlxuICAgKiBAcGFyYW0ge1BhbkludG9WaWV3T3B0aW9ucz19IG9wdF9wYW5JbnRvVmlld09wdGlvbnMgT3B0aW9ucyBmb3IgdGhlIHBhbiBhY3Rpb25cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLnBhbkludG9WaWV3ID0gZnVuY3Rpb24gKG9wdF9wYW5JbnRvVmlld09wdGlvbnMpIHtcbiAgICB2YXIgbWFwID0gdGhpcy5nZXRNYXAoKTtcblxuICAgIGlmICghbWFwIHx8ICFtYXAuZ2V0VGFyZ2V0RWxlbWVudCgpIHx8ICF0aGlzLmdldChQcm9wZXJ0eS5QT1NJVElPTikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbWFwUmVjdCA9IHRoaXMuZ2V0UmVjdChtYXAuZ2V0VGFyZ2V0RWxlbWVudCgpLCBtYXAuZ2V0U2l6ZSgpKTtcbiAgICB2YXIgZWxlbWVudCA9IHRoaXMuZ2V0RWxlbWVudCgpO1xuICAgIHZhciBvdmVybGF5UmVjdCA9IHRoaXMuZ2V0UmVjdChlbGVtZW50LCBbb3V0ZXJXaWR0aChlbGVtZW50KSwgb3V0ZXJIZWlnaHQoZWxlbWVudCldKTtcbiAgICB2YXIgcGFuSW50b1ZpZXdPcHRpb25zID0gb3B0X3BhbkludG9WaWV3T3B0aW9ucyB8fCB7fTtcbiAgICB2YXIgbXlNYXJnaW4gPSBwYW5JbnRvVmlld09wdGlvbnMubWFyZ2luID09PSB1bmRlZmluZWQgPyAyMCA6IHBhbkludG9WaWV3T3B0aW9ucy5tYXJnaW47XG5cbiAgICBpZiAoIWNvbnRhaW5zRXh0ZW50KG1hcFJlY3QsIG92ZXJsYXlSZWN0KSkge1xuICAgICAgLy8gdGhlIG92ZXJsYXkgaXMgbm90IGNvbXBsZXRlbHkgaW5zaWRlIHRoZSB2aWV3cG9ydCwgc28gcGFuIHRoZSBtYXBcbiAgICAgIHZhciBvZmZzZXRMZWZ0ID0gb3ZlcmxheVJlY3RbMF0gLSBtYXBSZWN0WzBdO1xuICAgICAgdmFyIG9mZnNldFJpZ2h0ID0gbWFwUmVjdFsyXSAtIG92ZXJsYXlSZWN0WzJdO1xuICAgICAgdmFyIG9mZnNldFRvcCA9IG92ZXJsYXlSZWN0WzFdIC0gbWFwUmVjdFsxXTtcbiAgICAgIHZhciBvZmZzZXRCb3R0b20gPSBtYXBSZWN0WzNdIC0gb3ZlcmxheVJlY3RbM107XG4gICAgICB2YXIgZGVsdGEgPSBbMCwgMF07XG5cbiAgICAgIGlmIChvZmZzZXRMZWZ0IDwgMCkge1xuICAgICAgICAvLyBtb3ZlIG1hcCB0byB0aGUgbGVmdFxuICAgICAgICBkZWx0YVswXSA9IG9mZnNldExlZnQgLSBteU1hcmdpbjtcbiAgICAgIH0gZWxzZSBpZiAob2Zmc2V0UmlnaHQgPCAwKSB7XG4gICAgICAgIC8vIG1vdmUgbWFwIHRvIHRoZSByaWdodFxuICAgICAgICBkZWx0YVswXSA9IE1hdGguYWJzKG9mZnNldFJpZ2h0KSArIG15TWFyZ2luO1xuICAgICAgfVxuXG4gICAgICBpZiAob2Zmc2V0VG9wIDwgMCkge1xuICAgICAgICAvLyBtb3ZlIG1hcCB1cFxuICAgICAgICBkZWx0YVsxXSA9IG9mZnNldFRvcCAtIG15TWFyZ2luO1xuICAgICAgfSBlbHNlIGlmIChvZmZzZXRCb3R0b20gPCAwKSB7XG4gICAgICAgIC8vIG1vdmUgbWFwIGRvd25cbiAgICAgICAgZGVsdGFbMV0gPSBNYXRoLmFicyhvZmZzZXRCb3R0b20pICsgbXlNYXJnaW47XG4gICAgICB9XG5cbiAgICAgIGlmIChkZWx0YVswXSAhPT0gMCB8fCBkZWx0YVsxXSAhPT0gMCkge1xuICAgICAgICB2YXIgY2VudGVyID1cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gKi9cbiAgICAgICAgbWFwLmdldFZpZXcoKS5nZXRDZW50ZXJJbnRlcm5hbCgpO1xuICAgICAgICB2YXIgY2VudGVyUHggPSBtYXAuZ2V0UGl4ZWxGcm9tQ29vcmRpbmF0ZUludGVybmFsKGNlbnRlcik7XG5cbiAgICAgICAgaWYgKCFjZW50ZXJQeCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBuZXdDZW50ZXJQeCA9IFtjZW50ZXJQeFswXSArIGRlbHRhWzBdLCBjZW50ZXJQeFsxXSArIGRlbHRhWzFdXTtcbiAgICAgICAgdmFyIHBhbk9wdGlvbnMgPSBwYW5JbnRvVmlld09wdGlvbnMuYW5pbWF0aW9uIHx8IHt9O1xuICAgICAgICBtYXAuZ2V0VmlldygpLmFuaW1hdGVJbnRlcm5hbCh7XG4gICAgICAgICAgY2VudGVyOiBtYXAuZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbEludGVybmFsKG5ld0NlbnRlclB4KSxcbiAgICAgICAgICBkdXJhdGlvbjogcGFuT3B0aW9ucy5kdXJhdGlvbixcbiAgICAgICAgICBlYXNpbmc6IHBhbk9wdGlvbnMuZWFzaW5nXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZXh0ZW50IG9mIGFuIGVsZW1lbnQgcmVsYXRpdmUgdG8gdGhlIGRvY3VtZW50XG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnQgVGhlIGVsZW1lbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemV9IHNpemUgVGhlIHNpemUgb2YgdGhlIGVsZW1lbnQuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gVGhlIGV4dGVudC5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLmdldFJlY3QgPSBmdW5jdGlvbiAoZWxlbWVudCwgc2l6ZSkge1xuICAgIHZhciBib3ggPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHZhciBvZmZzZXRYID0gYm94LmxlZnQgKyB3aW5kb3cucGFnZVhPZmZzZXQ7XG4gICAgdmFyIG9mZnNldFkgPSBib3gudG9wICsgd2luZG93LnBhZ2VZT2Zmc2V0O1xuICAgIHJldHVybiBbb2Zmc2V0WCwgb2Zmc2V0WSwgb2Zmc2V0WCArIHNpemVbMF0sIG9mZnNldFkgKyBzaXplWzFdXTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgcG9zaXRpb25pbmcgZm9yIHRoaXMgb3ZlcmxheS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL092ZXJsYXlQb3NpdGlvbmluZy5qc1wiKS5kZWZhdWx0fSBwb3NpdGlvbmluZyBob3cgdGhlIG92ZXJsYXkgaXNcbiAgICogICAgIHBvc2l0aW9uZWQgcmVsYXRpdmUgdG8gaXRzIHBvaW50IG9uIHRoZSBtYXAuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5zZXRQb3NpdGlvbmluZyA9IGZ1bmN0aW9uIChwb3NpdGlvbmluZykge1xuICAgIHRoaXMuc2V0KFByb3BlcnR5LlBPU0lUSU9OSU5HLCBwb3NpdGlvbmluZyk7XG4gIH07XG4gIC8qKlxuICAgKiBNb2RpZnkgdGhlIHZpc2liaWxpdHkgb2YgdGhlIGVsZW1lbnQuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gdmlzaWJsZSBFbGVtZW50IHZpc2liaWxpdHkuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5zZXRWaXNpYmxlID0gZnVuY3Rpb24gKHZpc2libGUpIHtcbiAgICBpZiAodGhpcy5yZW5kZXJlZC52aXNpYmxlICE9PSB2aXNpYmxlKSB7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IHZpc2libGUgPyAnJyA6ICdub25lJztcbiAgICAgIHRoaXMucmVuZGVyZWQudmlzaWJsZSA9IHZpc2libGU7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogVXBkYXRlIHBpeGVsIHBvc2l0aW9uLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUudXBkYXRlUGl4ZWxQb3NpdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbWFwID0gdGhpcy5nZXRNYXAoKTtcbiAgICB2YXIgcG9zaXRpb24gPSB0aGlzLmdldFBvc2l0aW9uKCk7XG5cbiAgICBpZiAoIW1hcCB8fCAhbWFwLmlzUmVuZGVyZWQoKSB8fCAhcG9zaXRpb24pIHtcbiAgICAgIHRoaXMuc2V0VmlzaWJsZShmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHBpeGVsID0gbWFwLmdldFBpeGVsRnJvbUNvb3JkaW5hdGUocG9zaXRpb24pO1xuICAgIHZhciBtYXBTaXplID0gbWFwLmdldFNpemUoKTtcbiAgICB0aGlzLnVwZGF0ZVJlbmRlcmVkUG9zaXRpb24ocGl4ZWwsIG1hcFNpemUpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3BpeGVsLmpzXCIpLlBpeGVsfSBwaXhlbCBUaGUgcGl4ZWwgbG9jYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemV8dW5kZWZpbmVkfSBtYXBTaXplIFRoZSBtYXAgc2l6ZS5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLnVwZGF0ZVJlbmRlcmVkUG9zaXRpb24gPSBmdW5jdGlvbiAocGl4ZWwsIG1hcFNpemUpIHtcbiAgICB2YXIgc3R5bGUgPSB0aGlzLmVsZW1lbnQuc3R5bGU7XG4gICAgdmFyIG9mZnNldCA9IHRoaXMuZ2V0T2Zmc2V0KCk7XG4gICAgdmFyIHBvc2l0aW9uaW5nID0gdGhpcy5nZXRQb3NpdGlvbmluZygpO1xuICAgIHRoaXMuc2V0VmlzaWJsZSh0cnVlKTtcbiAgICB2YXIgeCA9IE1hdGgucm91bmQocGl4ZWxbMF0gKyBvZmZzZXRbMF0pICsgJ3B4JztcbiAgICB2YXIgeSA9IE1hdGgucm91bmQocGl4ZWxbMV0gKyBvZmZzZXRbMV0pICsgJ3B4JztcbiAgICB2YXIgcG9zWCA9ICcwJSc7XG4gICAgdmFyIHBvc1kgPSAnMCUnO1xuXG4gICAgaWYgKHBvc2l0aW9uaW5nID09IE92ZXJsYXlQb3NpdGlvbmluZy5CT1RUT01fUklHSFQgfHwgcG9zaXRpb25pbmcgPT0gT3ZlcmxheVBvc2l0aW9uaW5nLkNFTlRFUl9SSUdIVCB8fCBwb3NpdGlvbmluZyA9PSBPdmVybGF5UG9zaXRpb25pbmcuVE9QX1JJR0hUKSB7XG4gICAgICBwb3NYID0gJy0xMDAlJztcbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uaW5nID09IE92ZXJsYXlQb3NpdGlvbmluZy5CT1RUT01fQ0VOVEVSIHx8IHBvc2l0aW9uaW5nID09IE92ZXJsYXlQb3NpdGlvbmluZy5DRU5URVJfQ0VOVEVSIHx8IHBvc2l0aW9uaW5nID09IE92ZXJsYXlQb3NpdGlvbmluZy5UT1BfQ0VOVEVSKSB7XG4gICAgICBwb3NYID0gJy01MCUnO1xuICAgIH1cblxuICAgIGlmIChwb3NpdGlvbmluZyA9PSBPdmVybGF5UG9zaXRpb25pbmcuQk9UVE9NX0xFRlQgfHwgcG9zaXRpb25pbmcgPT0gT3ZlcmxheVBvc2l0aW9uaW5nLkJPVFRPTV9DRU5URVIgfHwgcG9zaXRpb25pbmcgPT0gT3ZlcmxheVBvc2l0aW9uaW5nLkJPVFRPTV9SSUdIVCkge1xuICAgICAgcG9zWSA9ICctMTAwJSc7XG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbmluZyA9PSBPdmVybGF5UG9zaXRpb25pbmcuQ0VOVEVSX0xFRlQgfHwgcG9zaXRpb25pbmcgPT0gT3ZlcmxheVBvc2l0aW9uaW5nLkNFTlRFUl9DRU5URVIgfHwgcG9zaXRpb25pbmcgPT0gT3ZlcmxheVBvc2l0aW9uaW5nLkNFTlRFUl9SSUdIVCkge1xuICAgICAgcG9zWSA9ICctNTAlJztcbiAgICB9XG5cbiAgICB2YXIgdHJhbnNmb3JtID0gXCJ0cmFuc2xhdGUoXCIgKyBwb3NYICsgXCIsIFwiICsgcG9zWSArIFwiKSB0cmFuc2xhdGUoXCIgKyB4ICsgXCIsIFwiICsgeSArIFwiKVwiO1xuXG4gICAgaWYgKHRoaXMucmVuZGVyZWQudHJhbnNmb3JtXyAhPSB0cmFuc2Zvcm0pIHtcbiAgICAgIHRoaXMucmVuZGVyZWQudHJhbnNmb3JtXyA9IHRyYW5zZm9ybTtcbiAgICAgIHN0eWxlLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTsgLy8gQHRzLWlnbm9yZSBJRTlcblxuICAgICAgc3R5bGUubXNUcmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogcmV0dXJucyB0aGUgb3B0aW9ucyB0aGlzIE92ZXJsYXkgaGFzIGJlZW4gY3JlYXRlZCB3aXRoXG4gICAqIEByZXR1cm4ge09wdGlvbnN9IG92ZXJsYXkgb3B0aW9uc1xuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLmdldE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucztcbiAgfTtcblxuICByZXR1cm4gT3ZlcmxheTtcbn0oQmFzZU9iamVjdCk7XG5cbmV4cG9ydCBkZWZhdWx0IE92ZXJsYXk7IiwiaW1wb3J0IFJlYWN0LCB7dXNlU3RhdGUsIHVzZUVmZmVjdCwgdXNlUmVmfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgTWFwIGZyb20gJ29sL01hcCc7XG5pbXBvcnQgVmlldyBmcm9tICdvbC9WaWV3JztcbmltcG9ydCBGZWF0dXJlIGZyb20gJ29sL0ZlYXR1cmUnO1xuaW1wb3J0IEdlb21ldHJ5IGZyb20gJ29sL2dlb20vR2VvbWV0cnknO1xuaW1wb3J0IFZlY3RvckxheWVyIGZyb20gJ29sL2xheWVyL1ZlY3Rvcic7XG5pbXBvcnQgVmVjdG9yU291cmNlIGZyb20gJ29sL3NvdXJjZS9WZWN0b3InO1xuaW1wb3J0IHtmcm9tTG9uTGF0fSBmcm9tICdvbC9wcm9qJztcbmltcG9ydCAqIGFzIHN0eWxlcyBmcm9tICcuL21hcC5tb2R1bGUuc2Nzcyc7XG4vLyBpbXBvcnQgb2xtcyBmcm9tICdvbC1tYXBib3gtc3R5bGUnO1xuaW1wb3J0IFRpbGVMYXllciBmcm9tICdvbC9sYXllci9UaWxlJztcbmltcG9ydCBWZWN0b3JUaWxlTGF5ZXIgZnJvbSAnb2wvbGF5ZXIvVmVjdG9yVGlsZS5qcyc7XG5pbXBvcnQgVmVjdG9yVGlsZVNvdXJjZSBmcm9tICdvbC9zb3VyY2UvVmVjdG9yVGlsZS5qcyc7XG5pbXBvcnQgTVZUIGZyb20gJ29sL2Zvcm1hdC9NVlQuanMnO1xuaW1wb3J0IHtGaWxsLCBTdHlsZX0gZnJvbSAnb2wvc3R5bGUuanMnO1xuaW1wb3J0IFhZWiBmcm9tICdvbC9zb3VyY2UvWFlaJztcbmltcG9ydCAqIGFzIGQzIGZyb20gJ2QzJztcbmltcG9ydCB7dHJhbnNmb3JtfSBmcm9tICdvbC9wcm9qJztcbmltcG9ydCB7dG9TdHJpbmdYWX0gZnJvbSAnb2wvY29vcmRpbmF0ZSc7XG5pbXBvcnQgT3ZlcmxheSBmcm9tICdvbC9PdmVybGF5JztcblxuXG5pbnRlcmZhY2UgSU1hcFdyYXBwZXJQcm9wcyB7XG4gIGZlYXR1cmVzOiBGZWF0dXJlPEdlb21ldHJ5PltdLFxufTtcblxuLy8gVGhlIGJlbG93IGFkYXB0ZWQgZnJvbVxuLy8gaHR0cHM6Ly90YXlsb3IuY2FsbHNlbi5tZS91c2luZy1vcGVubGF5ZXJzLXdpdGgtcmVhY3QtZnVuY3Rpb25hbC1jb21wb25lbnRzL1xuY29uc3QgTWFwV3JhcHBlciA9ICh7ZmVhdHVyZXN9OiBJTWFwV3JhcHBlclByb3BzKSA9PiB7XG4gIGNvbnN0IFttYXAsIHNldE1hcF0gPSB1c2VTdGF0ZTxNYXA+KCk7XG4gIGNvbnN0IFtjdXJyZW50T3ZlcmxheSwgc2V0Q3VycmVudE92ZXJsYXldID0gdXNlU3RhdGU8T3ZlcmxheT4oKTtcbiAgY29uc3QgW2ZlYXR1cmVzTGF5ZXIsIHNldEZlYXR1cmVzTGF5ZXJdID0gdXNlU3RhdGU8VmVjdG9yTGF5ZXI+KCk7XG4gIGNvbnN0IFtzZWxlY3RlZEZlYXR1cmUsIHNldFNlbGVjdGVkRmVhdHVyZV0gPSB1c2VTdGF0ZTxGZWF0dXJlPigpO1xuICBjb25zdCBbaG92ZXJlZEZlYXR1cmUsIHNldEhvdmVyZWRGZWF0dXJlXSA9IHVzZVN0YXRlPEZlYXR1cmU+KCk7XG4gIGNvbnN0IFtzZWxlY3RlZENvb3JkLCBzZXRTZWxlY3RlZENvb3JkXSA9IHVzZVN0YXRlKCk7XG5cbiAgY29uc3QgbWFwRWxlbWVudCA9IHVzZVJlZigpIGFzXG4gICAgICAgIFJlYWN0Lk11dGFibGVSZWZPYmplY3Q8SFRNTElucHV0RWxlbWVudD47XG4gIGNvbnN0IG1hcFJlZiA9IHVzZVJlZigpIGFzIFJlYWN0Lk11dGFibGVSZWZPYmplY3Q8TWFwPjtcblxuXG4gIGNvbnN0IHBvcHVwQ29udGFpbmVyID0gUmVhY3QudXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcbiAgY29uc3QgcG9wdXBDbG9zZXIgPSBSZWFjdC51c2VSZWY8SFRNTERpdkVsZW1lbnQ+KG51bGwpO1xuICBjb25zdCBwb3B1cENvbnRlbnQgPSBSZWFjdC51c2VSZWY8SFRNTERpdkVsZW1lbnQ+KG51bGwpO1xuXG4gIGNvbnN0IG92ZXJsYXlSZWYgPSB1c2VSZWYoKSBhcyBSZWFjdC5NdXRhYmxlUmVmT2JqZWN0PE1hcD47XG4gIG1hcFJlZi5jdXJyZW50ID0gbWFwO1xuICBvdmVybGF5UmVmLmN1cnJlbnQgPSBjdXJyZW50T3ZlcmxheTtcblxuICB1c2VFZmZlY3QoICgpID0+IHtcbiAgICAvLyBjcmVhdGUgYW5kIGFkZCBpbml0aWFsIHZlY3RvciBzb3VyY2UgbGF5ZXIsIHRvIGJlIHJlcGxhY2VkIGxheWVyXG4gICAgY29uc3QgaW5pdGlhbEZlYXR1cmVzTGF5ZXIgPSBuZXcgVmVjdG9yTGF5ZXIoe1xuICAgICAgc291cmNlOiBuZXcgVmVjdG9yU291cmNlKCksXG4gICAgfSk7XG5cbiAgICBjb25zdCBqNDBzb3VyY2UgPSBuZXcgVmVjdG9yVGlsZVNvdXJjZSh7XG4gICAgICAnZm9ybWF0JzogbmV3IE1WVCgpLFxuICAgICAgJ3VybCc6ICdodHRwOi8vbG9jYWxob3N0OjgwODAvZGF0YS9ibG9jazIwMTAve3p9L3t4fS97eX0ucGJmJyxcbiAgICAgIC8vICd1cmwnOiAnaHR0cDovL3VzZHMtZ2VvcGxhdGZvcm0tanVzdGljZTQwLXdlYnNpdGUuczMtd2Vic2l0ZS11cy1lYXN0LTEuYW1hem9uYXdzLmNvbS9ubS97en0ve3h9L3t5fS5wYmYnLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY29sb3JzID0gZDMuc2NhbGVTZXF1ZW50aWFsKGQzLmludGVycG9sYXRlQmx1ZXMpXG4gICAgICAgIC5kb21haW4oWzAsIDFdKTsgLy8gZDMuc2NhbGVPcmRpbmFsKGQzLmludGVycG9sYXRlQmx1ZXMpO1xuXG4gICAgY29uc3QgajQwTGF5ZXIgPSBuZXcgVmVjdG9yVGlsZUxheWVyKHtcbiAgICAgIGRlY2x1dHRlcjogZmFsc2UsXG4gICAgICBzb3VyY2U6IGo0MHNvdXJjZSxcbiAgICAgIHN0eWxlOiBmdW5jdGlvbihmZWF0dXJlKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBmZWF0dXJlLmdldCgnc2NvcmVfYV9wZXJjZW50aWxlJyk7XG4gICAgICAgIGxldCBjb2xvclN0cmluZztcbiAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICBjb25zdCByZ2IgPSBjb2xvcnMoZGF0YSk7XG4gICAgICAgICAgY29uc3QgcmJnQXJyID0gcmdiLnNsaWNlKFxuICAgICAgICAgICAgICByZ2IuaW5kZXhPZignKCcpICsgMSxcbiAgICAgICAgICAgICAgcmdiLmluZGV4T2YoJyknKSxcbiAgICAgICAgICApLnNwbGl0KCcsICcpO1xuICAgICAgICAgIGNvbG9yU3RyaW5nID0gYHJnYmEoJHtyYmdBcnJbMF19LCAke3JiZ0FyclsxXX0sICR7cmJnQXJyWzJdfSwgMC41KWA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29sb3JTdHJpbmcgPSAnd2hpdGUnO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbnN0IGluT3JPdXQgPSBmZWF0dXJlLmdldCgnc2NvcmVfYV90b3BfcGVyY2VudGlsZV8yNScpO1xuICAgICAgICByZXR1cm4gbmV3IFN0eWxlKHtcbiAgICAgICAgICBmaWxsOiBuZXcgRmlsbCh7XG4gICAgICAgICAgICBjb2xvcjogY29sb3JTdHJpbmcsIC8vIGluT3JPdXQgPT0gJ1RydWUnID8gJ2JsdWUnIDogJ3doaXRlJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH0pO1xuXG5cbiAgICBwb3B1cENsb3Nlci5jdXJyZW50Lm9uY2xpY2sgPSBmdW5jdGlvbigpIHtcbiAgICAgIG92ZXJsYXkuc2V0UG9zaXRpb24odW5kZWZpbmVkKTtcbiAgICAgIHBvcHVwQ2xvc2VyLmN1cnJlbnQuYmx1cigpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBjb25zdCBvdmVybGF5ID0gbmV3IE92ZXJsYXkoe1xuICAgICAgZWxlbWVudDogcG9wdXBDb250YWluZXIuY3VycmVudCxcbiAgICAgIGF1dG9QYW46IHRydWUsXG4gICAgICBhdXRvUGFuQW5pbWF0aW9uOiB7XG4gICAgICAgIGR1cmF0aW9uOiAyNTAsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgaW5pdGlhbE1hcCA9IG5ldyBNYXAoe1xuICAgICAgdGFyZ2V0OiBtYXBFbGVtZW50LmN1cnJlbnQsXG4gICAgICB2aWV3OiBuZXcgVmlldyh7XG4gICAgICAgIGNlbnRlcjogZnJvbUxvbkxhdChbLTg2LjUwMjEzNiwgMzIuNDY4NzEyNl0pLFxuICAgICAgICB6b29tOiA0LFxuICAgICAgfSksXG4gICAgICBsYXllcnM6IFtcbiAgICAgICAgbmV3IFRpbGVMYXllcih7XG4gICAgICAgICAgc291cmNlOiBuZXcgWFlaKHtcbiAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vezEtNH0uYmFzZW1hcHMuY2FydG9jZG4uY29tL2xpZ2h0X2FsbC97en0ve3h9L3t5fUAyeC5wbmcnLFxuICAgICAgICAgIH0pLFxuICAgICAgICB9KSxcbiAgICAgICAgajQwTGF5ZXIsXG4gICAgICBdLFxuICAgICAgY29udHJvbHM6IFtdLFxuICAgICAgb3ZlcmxheXM6IFtvdmVybGF5XSxcbiAgICB9KTtcblxuXG4gICAgaW5pdGlhbE1hcC5vbignY2xpY2snLCBoYW5kbGVNYXBDbGljayk7XG4gICAgaW5pdGlhbE1hcC5vbigncG9pbnRlcm1vdmUnLCBoYW5kbGVQb2ludGVyTW92ZSk7XG4gICAgc2V0TWFwKGluaXRpYWxNYXApO1xuICAgIHNldEN1cnJlbnRPdmVybGF5KG92ZXJsYXkpO1xuICAgIHNldEZlYXR1cmVzTGF5ZXIoaW5pdGlhbEZlYXR1cmVzTGF5ZXIpO1xuICAgIC8vIG9sbXMoaW5pdGlhbE1hcCwgbWFwQ29uZmlnKTtcbiAgfSwgW10pO1xuXG5cbiAgLy8gdXBkYXRlIG1hcCBpZiBmZWF0dXJlcyBwcm9wIGNoYW5nZXNcbiAgdXNlRWZmZWN0KCAoKSA9PiB7XG4gICAgaWYgKGZlYXR1cmVzLmxlbmd0aCkgeyAvLyBtYXkgYmUgZW1wdHkgb24gZmlyc3QgcmVuZGVyXG4gICAgICAvLyBzZXQgZmVhdHVyZXMgdG8gbWFwXG4gICAgICBmZWF0dXJlc0xheWVyPy5zZXRTb3VyY2UoXG4gICAgICAgICAgbmV3IFZlY3RvclNvdXJjZSh7XG4gICAgICAgICAgICBmZWF0dXJlczogZmVhdHVyZXMsXG4gICAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBjb25zdCBleHRlbnQgPSBmZWF0dXJlc0xheWVyPy5nZXRTb3VyY2UoKS5nZXRFeHRlbnQoKTtcbiAgICAgIGlmIChleHRlbnQgIT0gbnVsbCkge1xuICAgICAgICAvLyBmaXQgbWFwIHRvIGZlYXR1cmUgZXh0ZW50ICh3aXRoIDEwMHB4IG9mIHBhZGRpbmcpXG4gICAgICAgIG1hcD8uZ2V0VmlldygpLmZpdChleHRlbnQsIHtcbiAgICAgICAgICBwYWRkaW5nOiBbMTAwLCAxMDAsIDEwMCwgMTAwXSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LCBbZmVhdHVyZXNdKTtcblxuICBjb25zdCBoYW5kbGVNYXBDbGljayA9IChldmVudDogeyBwaXhlbDogYW55OyB9KSA9PiB7XG4gICAgLy8gZ2V0IGNsaWNrZWQgY29vcmRpbmF0ZSB1c2luZyBtYXBSZWYgdG8gYWNjZXNzIGN1cnJlbnQgUmVhY3Qgc3RhdGUgaW5zaWRlIE9wZW5MYXllcnMgY2FsbGJhY2tcbiAgICAvLyAgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzYwNjQzNjcwXG4gICAgY29uc3QgY2xpY2tlZENvb3JkID0gbWFwUmVmLmN1cnJlbnQuZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbChldmVudC5waXhlbCk7XG5cbiAgICAvLyB0cmFuc2Zvcm0gY29vcmQgdG8gRVBTRyA0MzI2IHN0YW5kYXJkIExhdCBMb25nXG4gICAgY29uc3QgdHJhbnNmb3JtZWRDb29yZCA9IHRyYW5zZm9ybShjbGlja2VkQ29vcmQsICdFUFNHOjM4NTcnLCAnRVBTRzo0MzI2Jyk7XG5cbiAgICAvLyBzZXQgUmVhY3Qgc3RhdGVcbiAgICBzZXRTZWxlY3RlZENvb3JkKCB0cmFuc2Zvcm1lZENvb3JkICk7XG4gICAgbWFwUmVmLmN1cnJlbnQuZm9yRWFjaEZlYXR1cmVBdFBpeGVsKGV2ZW50LnBpeGVsLCAoZmVhdHVyZSkgPT4ge1xuICAgICAgc2V0U2VsZWN0ZWRGZWF0dXJlKGZlYXR1cmUpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSk7XG5cbiAgICBvdmVybGF5UmVmLmN1cnJlbnQuc2V0UG9zaXRpb24oY2xpY2tlZENvb3JkKTtcbiAgfTtcblxuICBjb25zdCBoYW5kbGVQb2ludGVyTW92ZSA9IChldmVudDogeyBwaXhlbDogYW55OyB9KSA9PiB7XG4gICAgaWYgKGhvdmVyZWRGZWF0dXJlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGhvdmVyZWRGZWF0dXJlPy5zZXRTdHlsZSh1bmRlZmluZWQpO1xuICAgICAgc2V0SG92ZXJlZEZlYXR1cmUodW5kZWZpbmVkKTtcbiAgICB9XG5cbiAgICBtYXBSZWYuY3VycmVudC5mb3JFYWNoRmVhdHVyZUF0UGl4ZWwoZXZlbnQucGl4ZWwsIChmZWF0dXJlKSA9PiB7XG4gICAgICBzZXRIb3ZlcmVkRmVhdHVyZShmZWF0dXJlKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICB9O1xuICBjb25zdCByZWFkYWJsZVBlcmNlbnQgPSAocGVyY2VudDpudW1iZXIpID0+IHtcbiAgICByZXR1cm4gYCR7cGFyc2VGbG9hdChwZXJjZW50ICogMTAwKS50b0ZpeGVkKDIpfSVgO1xuICB9O1xuXG4gIHJldHVybiAoXG4gICAgPD5cbiAgICAgIDxkaXYgcmVmPXttYXBFbGVtZW50fSBjbGFzc05hbWU9e3N0eWxlcy5tYXBDb250YWluZXJ9PjwvZGl2PlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJjbGlja2VkLWNvb3JkLWxhYmVsXCI+XG4gICAgICAgIDxwPnsgKGhvdmVyZWRGZWF0dXJlKSA/IHJlYWRhYmxlUGVyY2VudChob3ZlcmVkRmVhdHVyZS5wcm9wZXJ0aWVzX1snc2NvcmVfYV9wZXJjZW50aWxlJ10pIDogJycgfTwvcD5cbiAgICAgICAgPHA+eyAoc2VsZWN0ZWRDb29yZCkgPyB0b1N0cmluZ1hZKHNlbGVjdGVkQ29vcmQsIDUpIDogJycgfTwvcD5cbiAgICAgICAgPGRpdiByZWY9e3BvcHVwQ29udGFpbmVyfSBjbGFzc05hbWU9e3N0eWxlcy5wb3B1cENvbnRhaW5lcn0+XG4gICAgICAgICAgPGEgaHJlZj1cIiNcIiByZWY9e3BvcHVwQ2xvc2VyfSBjbGFzc05hbWU9e3N0eWxlcy5wb3B1cENsb3Nlcn0+PC9hPlxuICAgICAgICAgIDxkaXYgcmVmPXtwb3B1cENvbnRlbnR9IGNsYXNzTmFtZT17c3R5bGVzLnBvcHVwQ29udGVudH0+XG4gICAgICAgICAgICB7IChzZWxlY3RlZEZlYXR1cmUpID9cbiAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgPGgyPkp1c3RQcm9ncmVzcyBTY29yZTo8L2gyPlxuICAgICAgICAgICAgICAgICAgPGgzPntyZWFkYWJsZVBlcmNlbnQoc2VsZWN0ZWRGZWF0dXJlLnByb3BlcnRpZXNfWydzY29yZV9hX3BlcmNlbnRpbGUnXSl9PC9oMz5cbiAgICAgICAgICAgICAgICA8L2Rpdj4gOlxuICAgICAgICAgICAgICAgICAgJycgfVxuXG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC8+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBNYXBXcmFwcGVyO1xuIiwiLy8gZXh0cmFjdGVkIGJ5IG1pbmktY3NzLWV4dHJhY3QtcGx1Z2luXG5leHBvcnQgdmFyIGhvd1lvdUNhbkhlbHBDb250YWluZXIgPSBcIkhvd1lvdUNhbkhlbHAtbW9kdWxlLS1ob3dZb3VDYW5IZWxwQ29udGFpbmVyLS0ya3FCYVwiOyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgKiBhcyBzdHlsZXMgZnJvbSAnLi9Ib3dZb3VDYW5IZWxwLm1vZHVsZS5zY3NzJztcblxuY29uc3QgSG93WW91Q2FuSGVscCA9ICgpID0+IHtcbiAgcmV0dXJuIChcbiAgICA8ZGl2IGNsYXNzTmFtZT17c3R5bGVzLmhvd1lvdUNhbkhlbHBDb250YWluZXJ9PlxuICAgICAgPGgyPkhvdyBZb3UgQ2FuIEhlbHAgSW1wcm92ZSB0aGUgVG9vbDwvaDI+XG4gICAgICA8dWw+XG4gICAgICAgIDxsaT5JZiB5b3UgaGF2ZSBpbmZvcm1hdGlvbiB0aGF0IGNvdWxkIGhlbHAsIHdl4oCZZCBsb3ZlIHRvIGhlYXIgZnJvbSB5b3UuPC9saT5cbiAgICAgICAgPGxpPlZpZXcgb3VyIGZ1bGwgc2V0IG9mIGRhdGEgc291cmNlcyBhbmQgbWV0aG9kb2xvZ3lcbiAgICAgICAgICAgIHdoZXJlIHlvdSBjYW4gYWRkIG9yIGRvd25sb2FkIHNvdXJjZXMgYW5kIGNoZWNrIHN0YXR1c2VzIG9uIG91ciBkYXRhIHJvYWRtYXAuPC9saT5cbiAgICAgICAgPGxpPkNoZWNrIG91dCBvdXIgdGltZWxpbmUgYW5kIHNlbmQgZmVlZGJhY2sgb3IgYXR0ZW5kIHJlbGV2YW50IGV2ZW50cy48L2xpPlxuICAgICAgICA8bGk+Q29udGFjdCB1cyBhbmQgc2hhcmUgdGhlIHN0b3JpZXMgb2YgeW91ciBjb21tdW5pdHkuPC9saT5cbiAgICAgIDwvdWw+XG4gICAgPC9kaXY+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBIb3dZb3VDYW5IZWxwO1xuIiwiLy8gZXh0cmFjdGVkIGJ5IG1pbmktY3NzLWV4dHJhY3QtcGx1Z2luXG5leHBvcnQgdmFyIGRpc2NsYWltZXIgPSBcImNlanN0LW1vZHVsZS0tZGlzY2xhaW1lci0tM0xDMXlcIjsiLCJpbXBvcnQgUmVhY3QsIHt1c2VTdGF0ZX0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IExheW91dCBmcm9tICcuLi9jb21wb25lbnRzL2xheW91dCc7XG5pbXBvcnQgTWFwV3JhcHBlciBmcm9tICcuLi9jb21wb25lbnRzL21hcCc7XG4vLyBpbXBvcnQgTWFwQ29udHJvbHMgZnJvbSAnLi4vY29tcG9uZW50cy9tYXBDb250cm9scyc7XG5pbXBvcnQgSG93WW91Q2FuSGVscCBmcm9tICcuLi9jb21wb25lbnRzL0hvd1lvdUNhbkhlbHAnO1xuaW1wb3J0IEZlYXR1cmUgZnJvbSAnb2wvRmVhdHVyZSc7XG5pbXBvcnQgR2VvbWV0cnkgZnJvbSAnb2wvZ2VvbS9HZW9tZXRyeSc7XG5pbXBvcnQge0FsZXJ0fSBmcm9tICdAdHJ1c3N3b3Jrcy9yZWFjdC11c3dkcyc7XG5pbXBvcnQgKiBhcyBzdHlsZXMgZnJvbSAnLi9jZWpzdC5tb2R1bGUuc2Nzcyc7XG5cbmludGVyZmFjZSBJTWFwUGFnZVByb3BzIHtcbiAgbG9jYXRpb246IExvY2F0aW9uO1xufVxuXG5jb25zdCBDRUpTVFBhZ2UgPSAoe2xvY2F0aW9ufTogSU1hcFBhZ2VQcm9wcykgPT4ge1xuICBjb25zdCBbZmVhdHVyZXNdID0gdXNlU3RhdGU8RmVhdHVyZTxHZW9tZXRyeT5bXT4oW10pO1xuXG4gIHJldHVybiAoXG4gICAgPExheW91dCBsb2NhdGlvbj17bG9jYXRpb259PlxuICAgICAgPG1haW4gaWQ9XCJtYWluLWNvbnRlbnRcIiByb2xlPVwibWFpblwiPlxuICAgICAgICA8cCBjbGFzc05hbWU9e3N0eWxlcy5kaXNjbGFpbWVyfT5cbiAgICAgICAgICBUaGUgQ2xpbWF0ZSBhbmQgRWNvbm9taWMgSnVzdGljZSBTY3JlZW5pbmcgVG9vbCBoZWxwc1xuICAgICAgICAgIGlkZW50aWZ5IGFuZCBwcmlvcml0aXplIGNvbW11bml0aWVzIGFjcm9zcyB0aGUgVW5pdGVkXG4gICAgICAgICAgU3RhdGVzIGFuZCBVUyB0ZXJyaXRvcmllcyB0aGF0IGhhdmUgYmVlbiBoaXN0b3JpY2FsbHlcbiAgICAgICAgICBvdmVyYnVyZGVuZWQgYW5kIHVuZGVyc2VydmVkIHNvIHRoYXQgdGhleSBtYXkgcmVjZWl2ZVxuICAgICAgICAgIDQwJSBvZiB0aGUgYmVuZWZpdHMgZnJvbSBpbnZlc3RtZW50cyBpbiBzaXgga2V5IGFyZWFzIGFzXG4gICAgICAgICAgb3V0bGluZWQgaW4gdGhlIDxhXG4gICAgICAgICAgICBocmVmPXsnaHR0cHM6Ly93d3cud2hpdGVob3VzZS5nb3YvYnJpZWZpbmctcm9vbS8nICtcbiAgICAgICAgICAgICAgICAgICAgJ3ByZXNpZGVudGlhbC1hY3Rpb25zLzIwMjEvMDEvMjcvJyArXG4gICAgICAgICAgICAgICAgICAgICdleGVjdXRpdmUtb3JkZXItb24tdGFja2xpbmctdGhlLWNsaW1hdGUtJyArXG4gICAgICAgICAgICAgICAgICAgICdjcmlzaXMtYXQtaG9tZS1hbmQtYWJyb2FkLyd9XG4gICAgICAgICAgICB0YXJnZXQ9eydfYmxhbmsnfVxuICAgICAgICAgICAgcmVsPXsnbm9yZWZlcnJlcid9PlxuICAgICAgICAgICAgICAgICAgICBFeGVjdXRpdmUgT3JkZXIgb24gVGFja2xpbmcgdGhlIENsaW1hdGUgQ3Jpc2lzIGF0IEhvbWUgYW5kXG4gICAgICAgICAgICAgICAgICAgIEFicm9hZDwvYT4uXG4gICAgICAgICAgRXhwbG9yZSB0aGUgbWFwIGJlbG93IG9yIGxlYXJuXG4gICAgICAgICAgbW9yZSBhYm91dCB0aGUgbWV0aG9kb2xvZ3kgYW5kIGRhdGEgaW5kaWNhdG9ycyB1c2VkIHRvXG4gICAgICAgICAgcHJpb3JpdGl6ZSBKdXN0aWNlNDAgY29tbXVuaXRpZXMuXG4gICAgICAgIDwvcD5cbiAgICAgICAgPEFsZXJ0XG4gICAgICAgICAgdHlwZT1cIndhcm5pbmdcIlxuICAgICAgICAgIGhlYWRpbmc9XCJMaW1pdGVkIERhdGEgU291cmNlc1wiPlxuICAgICAgICAgIDxwPlxuICAgICAgICAgICAgSW4gdGhpcyB0b29sLCB3ZSBhcmUgdXNpbmcgZGF0YSBzb3VyY2VzIHRoYXQgb3VyXG4gICAgICAgICAgICBjb21iaW5lZCBieSBvdXIgY3VtdWxhdGl2ZSBpbXBhY3QgbWV0aG9kb2xvZ3kuXG4gICAgICAgICAgICBPdXIgc291cmNlcyB3ZXJlIHNlbGVjdGVkIGJlY2F1c2Ugc2l0IGFtZXQsXG4gICAgICAgICAgICBjb25zZWN0ZXR1ciBhZGlwaXNjaW5nLiBTZWUgYWxsIHRoZSBzb3VyY2VzIHdlXG4gICAgICAgICAgICBhcmUgaW52ZXN0aWdhdGluZyBvbiBvdXIgZGF0YSByb2FkbWFwLlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9BbGVydD5cbiAgICAgICAgey8qIDxNYXBDb250cm9scyBzZXRGZWF0dXJlcz17c2V0RmVhdHVyZXN9Lz4gKi99XG4gICAgICAgIDxNYXBXcmFwcGVyIGZlYXR1cmVzPXtmZWF0dXJlc30gLz5cbiAgICAgICAgPEhvd1lvdUNhbkhlbHAgLz5cbiAgICAgIDwvbWFpbj5cbiAgICA8L0xheW91dD5cbiAgKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IENFSlNUUGFnZTtcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///629\n')},5666:function(module){eval('/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nvar runtime = (function (exports) {\n "use strict";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === "function" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || "@@iterator";\n var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";\n var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";\n\n function define(obj, key, value) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n return obj[key];\n }\n try {\n // IE 8 has a broken Object.defineProperty that only works on DOM objects.\n define({}, "");\n } catch (err) {\n define = function(obj, key, value) {\n return obj[key] = value;\n };\n }\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n exports.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there\'s no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don\'t have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: "normal", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: "throw", arg: err };\n }\n }\n\n var GenStateSuspendedStart = "suspendedStart";\n var GenStateSuspendedYield = "suspendedYield";\n var GenStateExecuting = "executing";\n var GenStateCompleted = "completed";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don\'t natively support it.\n var IteratorPrototype = {};\n IteratorPrototype[iteratorSymbol] = function () {\n return this;\n };\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n GeneratorFunctionPrototype.constructor = GeneratorFunction;\n GeneratorFunction.displayName = define(\n GeneratorFunctionPrototype,\n toStringTagSymbol,\n "GeneratorFunction"\n );\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n ["next", "throw", "return"].forEach(function(method) {\n define(prototype, method, function(arg) {\n return this._invoke(method, arg);\n });\n });\n }\n\n exports.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === "function" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === "GeneratorFunction"\n : false;\n };\n\n exports.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n define(genFun, toStringTagSymbol, "GeneratorFunction");\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `hasOwn.call(value, "__await")` to determine if the yielded value is\n // meant to be awaited.\n exports.awrap = function(arg) {\n return { __await: arg };\n };\n\n function AsyncIterator(generator, PromiseImpl) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === "throw") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value &&\n typeof value === "object" &&\n hasOwn.call(value, "__await")) {\n return PromiseImpl.resolve(value.__await).then(function(value) {\n invoke("next", value, resolve, reject);\n }, function(err) {\n invoke("throw", err, resolve, reject);\n });\n }\n\n return PromiseImpl.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke("throw", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new PromiseImpl(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n AsyncIterator.prototype[asyncIteratorSymbol] = function () {\n return this;\n };\n exports.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {\n if (PromiseImpl === void 0) PromiseImpl = Promise;\n\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList),\n PromiseImpl\n );\n\n return exports.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error("Generator is already running");\n }\n\n if (state === GenStateCompleted) {\n if (method === "throw") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === "next") {\n // Setting context._sent for legacy support of Babel\'s\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === "throw") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === "return") {\n context.abrupt("return", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === "normal") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === "throw") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = "throw";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === "throw") {\n // Note: ["return"] must be used for ES3 parsing compatibility.\n if (delegate.iterator["return"]) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = "return";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === "throw") {\n // If maybeInvokeDelegate(context) changed context.method from\n // "return" to "throw", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = "throw";\n context.arg = new TypeError(\n "The iterator does not provide a \'throw\' method");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === "throw") {\n context.method = "throw";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = "throw";\n context.arg = new TypeError("iterator result is not an object");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was "throw" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was "next", forget context.arg since it has been\n // "consumed" by the delegate iterator. If context.method was\n // "return", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== "return") {\n context.method = "next";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n define(Gp, toStringTagSymbol, "Generator");\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers\' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn\'t happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n Gp[iteratorSymbol] = function() {\n return this;\n };\n\n Gp.toString = function() {\n return "[object Generator]";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = "normal";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: "root" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n exports.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === "function") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n exports.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel\'s\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = "next";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === "t" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === "throw") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = "throw";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = "next";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === "root") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle("end");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, "catchLoc");\n var hasFinally = hasOwn.call(entry, "finallyLoc");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error("try statement without catch or finally");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, "finallyLoc") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === "break" ||\n type === "continue") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = "next";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === "throw") {\n throw record.arg;\n }\n\n if (record.type === "break" ||\n record.type === "continue") {\n this.next = record.arg;\n } else if (record.type === "return") {\n this.rval = this.arg = record.arg;\n this.method = "return";\n this.next = "end";\n } else if (record.type === "normal" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n "catch": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === "throw") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error("illegal catch attempt");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === "next") {\n // Deliberately forget the last sent value so that we don\'t\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n\n // Regardless of whether this script is executing as a CommonJS module\n // or not, return the runtime object so that we can declare the variable\n // regeneratorRuntime in the outer scope, which allows this module to be\n // injected easily by `bin/regenerator --include-runtime script.js`.\n return exports;\n\n}(\n // If this script is executing as a CommonJS module, use module.exports\n // as the regeneratorRuntime namespace. Otherwise create a new empty\n // object. Either way, the resulting object will be used to initialize\n // the regeneratorRuntime variable at the top of this file.\n true ? module.exports : 0\n));\n\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n // This module should not be running in strict mode, so the above\n // assignment should always work unless something is misconfigured. Just\n // in case runtime.js accidentally runs in strict mode, we can escape\n // strict mode using a global Function call. This could conceivably fail\n // if a Content Security Policy forbids using Function, but in that case\n // the proper solution is to fix the accidental strict mode problem. If\n // you\'ve misconfigured your bundler to force strict mode and applied a\n // CSP to forbid Function, and you\'re not willing to fix either of those\n // problems, please detail your unique predicament in a GitHub issue.\n Function("r", "regeneratorRuntime = r")(runtime);\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9yZWdlbmVyYXRvci1ydW50aW1lL3J1bnRpbWUuanM/OTZjZiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZCxLQUFLO0FBQ0wsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQSxXQUFXO0FBQ1g7O0FBRUE7QUFDQTtBQUNBLHdDQUF3QyxXQUFXO0FBQ25EO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7QUFDVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0NBQW9DLGNBQWM7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUNBQWlDLGtCQUFrQjtBQUNuRDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7O0FBRUE7QUFDQSxZQUFZO0FBQ1o7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSw4Q0FBOEMsUUFBUTtBQUN0RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUEsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQSw4Q0FBOEMsUUFBUTtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLDhDQUE4QyxRQUFRO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLDhDQUE4QyxRQUFRO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRSxLQUEwQixvQkFBb0IsQ0FBRTtBQUNsRDs7QUFFQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiNTY2Ni5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE0LXByZXNlbnQsIEZhY2Vib29rLCBJbmMuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG4gKi9cblxudmFyIHJ1bnRpbWUgPSAoZnVuY3Rpb24gKGV4cG9ydHMpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgdmFyIE9wID0gT2JqZWN0LnByb3RvdHlwZTtcbiAgdmFyIGhhc093biA9IE9wLmhhc093blByb3BlcnR5O1xuICB2YXIgdW5kZWZpbmVkOyAvLyBNb3JlIGNvbXByZXNzaWJsZSB0aGFuIHZvaWQgMC5cbiAgdmFyICRTeW1ib2wgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgPyBTeW1ib2wgOiB7fTtcbiAgdmFyIGl0ZXJhdG9yU3ltYm9sID0gJFN5bWJvbC5pdGVyYXRvciB8fCBcIkBAaXRlcmF0b3JcIjtcbiAgdmFyIGFzeW5jSXRlcmF0b3JTeW1ib2wgPSAkU3ltYm9sLmFzeW5jSXRlcmF0b3IgfHwgXCJAQGFzeW5jSXRlcmF0b3JcIjtcbiAgdmFyIHRvU3RyaW5nVGFnU3ltYm9sID0gJFN5bWJvbC50b1N0cmluZ1RhZyB8fCBcIkBAdG9TdHJpbmdUYWdcIjtcblxuICBmdW5jdGlvbiBkZWZpbmUob2JqLCBrZXksIHZhbHVlKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7XG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgd3JpdGFibGU6IHRydWVcbiAgICB9KTtcbiAgICByZXR1cm4gb2JqW2tleV07XG4gIH1cbiAgdHJ5IHtcbiAgICAvLyBJRSA4IGhhcyBhIGJyb2tlbiBPYmplY3QuZGVmaW5lUHJvcGVydHkgdGhhdCBvbmx5IHdvcmtzIG9uIERPTSBvYmplY3RzLlxuICAgIGRlZmluZSh7fSwgXCJcIik7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGRlZmluZSA9IGZ1bmN0aW9uKG9iaiwga2V5LCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIG9ialtrZXldID0gdmFsdWU7XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdyYXAoaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpIHtcbiAgICAvLyBJZiBvdXRlckZuIHByb3ZpZGVkIGFuZCBvdXRlckZuLnByb3RvdHlwZSBpcyBhIEdlbmVyYXRvciwgdGhlbiBvdXRlckZuLnByb3RvdHlwZSBpbnN0YW5jZW9mIEdlbmVyYXRvci5cbiAgICB2YXIgcHJvdG9HZW5lcmF0b3IgPSBvdXRlckZuICYmIG91dGVyRm4ucHJvdG90eXBlIGluc3RhbmNlb2YgR2VuZXJhdG9yID8gb3V0ZXJGbiA6IEdlbmVyYXRvcjtcbiAgICB2YXIgZ2VuZXJhdG9yID0gT2JqZWN0LmNyZWF0ZShwcm90b0dlbmVyYXRvci5wcm90b3R5cGUpO1xuICAgIHZhciBjb250ZXh0ID0gbmV3IENvbnRleHQodHJ5TG9jc0xpc3QgfHwgW10pO1xuXG4gICAgLy8gVGhlIC5faW52b2tlIG1ldGhvZCB1bmlmaWVzIHRoZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIC5uZXh0LFxuICAgIC8vIC50aHJvdywgYW5kIC5yZXR1cm4gbWV0aG9kcy5cbiAgICBnZW5lcmF0b3IuX2ludm9rZSA9IG1ha2VJbnZva2VNZXRob2QoaW5uZXJGbiwgc2VsZiwgY29udGV4dCk7XG5cbiAgICByZXR1cm4gZ2VuZXJhdG9yO1xuICB9XG4gIGV4cG9ydHMud3JhcCA9IHdyYXA7XG5cbiAgLy8gVHJ5L2NhdGNoIGhlbHBlciB0byBtaW5pbWl6ZSBkZW9wdGltaXphdGlvbnMuIFJldHVybnMgYSBjb21wbGV0aW9uXG4gIC8vIHJlY29yZCBsaWtlIGNvbnRleHQudHJ5RW50cmllc1tpXS5jb21wbGV0aW9uLiBUaGlzIGludGVyZmFjZSBjb3VsZFxuICAvLyBoYXZlIGJlZW4gKGFuZCB3YXMgcHJldmlvdXNseSkgZGVzaWduZWQgdG8gdGFrZSBhIGNsb3N1cmUgdG8gYmVcbiAgLy8gaW52b2tlZCB3aXRob3V0IGFyZ3VtZW50cywgYnV0IGluIGFsbCB0aGUgY2FzZXMgd2UgY2FyZSBhYm91dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYW4gZXhpc3RpbmcgbWV0aG9kIHdlIHdhbnQgdG8gY2FsbCwgc28gdGhlcmUncyBubyBuZWVkXG4gIC8vIHRvIGNyZWF0ZSBhIG5ldyBmdW5jdGlvbiBvYmplY3QuIFdlIGNhbiBldmVuIGdldCBhd2F5IHdpdGggYXNzdW1pbmdcbiAgLy8gdGhlIG1ldGhvZCB0YWtlcyBleGFjdGx5IG9uZSBhcmd1bWVudCwgc2luY2UgdGhhdCBoYXBwZW5zIHRvIGJlIHRydWVcbiAgLy8gaW4gZXZlcnkgY2FzZSwgc28gd2UgZG9uJ3QgaGF2ZSB0byB0b3VjaCB0aGUgYXJndW1lbnRzIG9iamVjdC4gVGhlXG4gIC8vIG9ubHkgYWRkaXRpb25hbCBhbGxvY2F0aW9uIHJlcXVpcmVkIGlzIHRoZSBjb21wbGV0aW9uIHJlY29yZCwgd2hpY2hcbiAgLy8gaGFzIGEgc3RhYmxlIHNoYXBlIGFuZCBzbyBob3BlZnVsbHkgc2hvdWxkIGJlIGNoZWFwIHRvIGFsbG9jYXRlLlxuICBmdW5jdGlvbiB0cnlDYXRjaChmbiwgb2JqLCBhcmcpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJub3JtYWxcIiwgYXJnOiBmbi5jYWxsKG9iaiwgYXJnKSB9O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJ0aHJvd1wiLCBhcmc6IGVyciB9O1xuICAgIH1cbiAgfVxuXG4gIHZhciBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0ID0gXCJzdXNwZW5kZWRTdGFydFwiO1xuICB2YXIgR2VuU3RhdGVTdXNwZW5kZWRZaWVsZCA9IFwic3VzcGVuZGVkWWllbGRcIjtcbiAgdmFyIEdlblN0YXRlRXhlY3V0aW5nID0gXCJleGVjdXRpbmdcIjtcbiAgdmFyIEdlblN0YXRlQ29tcGxldGVkID0gXCJjb21wbGV0ZWRcIjtcblxuICAvLyBSZXR1cm5pbmcgdGhpcyBvYmplY3QgZnJvbSB0aGUgaW5uZXJGbiBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzXG4gIC8vIGJyZWFraW5nIG91dCBvZiB0aGUgZGlzcGF0Y2ggc3dpdGNoIHN0YXRlbWVudC5cbiAgdmFyIENvbnRpbnVlU2VudGluZWwgPSB7fTtcblxuICAvLyBEdW1teSBjb25zdHJ1Y3RvciBmdW5jdGlvbnMgdGhhdCB3ZSB1c2UgYXMgdGhlIC5jb25zdHJ1Y3RvciBhbmRcbiAgLy8gLmNvbnN0cnVjdG9yLnByb3RvdHlwZSBwcm9wZXJ0aWVzIGZvciBmdW5jdGlvbnMgdGhhdCByZXR1cm4gR2VuZXJhdG9yXG4gIC8vIG9iamVjdHMuIEZvciBmdWxsIHNwZWMgY29tcGxpYW5jZSwgeW91IG1heSB3aXNoIHRvIGNvbmZpZ3VyZSB5b3VyXG4gIC8vIG1pbmlmaWVyIG5vdCB0byBtYW5nbGUgdGhlIG5hbWVzIG9mIHRoZXNlIHR3byBmdW5jdGlvbnMuXG4gIGZ1bmN0aW9uIEdlbmVyYXRvcigpIHt9XG4gIGZ1bmN0aW9uIEdlbmVyYXRvckZ1bmN0aW9uKCkge31cbiAgZnVuY3Rpb24gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUoKSB7fVxuXG4gIC8vIFRoaXMgaXMgYSBwb2x5ZmlsbCBmb3IgJUl0ZXJhdG9yUHJvdG90eXBlJSBmb3IgZW52aXJvbm1lbnRzIHRoYXRcbiAgLy8gZG9uJ3QgbmF0aXZlbHkgc3VwcG9ydCBpdC5cbiAgdmFyIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG4gIEl0ZXJhdG9yUHJvdG90eXBlW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICB2YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG4gIHZhciBOYXRpdmVJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvICYmIGdldFByb3RvKGdldFByb3RvKHZhbHVlcyhbXSkpKTtcbiAgaWYgKE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlICYmXG4gICAgICBOYXRpdmVJdGVyYXRvclByb3RvdHlwZSAhPT0gT3AgJiZcbiAgICAgIGhhc093bi5jYWxsKE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlLCBpdGVyYXRvclN5bWJvbCkpIHtcbiAgICAvLyBUaGlzIGVudmlyb25tZW50IGhhcyBhIG5hdGl2ZSAlSXRlcmF0b3JQcm90b3R5cGUlOyB1c2UgaXQgaW5zdGVhZFxuICAgIC8vIG9mIHRoZSBwb2x5ZmlsbC5cbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlO1xuICB9XG5cbiAgdmFyIEdwID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUucHJvdG90eXBlID1cbiAgICBHZW5lcmF0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG4gIEdlbmVyYXRvckZ1bmN0aW9uLnByb3RvdHlwZSA9IEdwLmNvbnN0cnVjdG9yID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGU7XG4gIEdlbmVyYXRvckZ1bmN0aW9uUHJvdG90eXBlLmNvbnN0cnVjdG9yID0gR2VuZXJhdG9yRnVuY3Rpb247XG4gIEdlbmVyYXRvckZ1bmN0aW9uLmRpc3BsYXlOYW1lID0gZGVmaW5lKFxuICAgIEdlbmVyYXRvckZ1bmN0aW9uUHJvdG90eXBlLFxuICAgIHRvU3RyaW5nVGFnU3ltYm9sLFxuICAgIFwiR2VuZXJhdG9yRnVuY3Rpb25cIlxuICApO1xuXG4gIC8vIEhlbHBlciBmb3IgZGVmaW5pbmcgdGhlIC5uZXh0LCAudGhyb3csIGFuZCAucmV0dXJuIG1ldGhvZHMgb2YgdGhlXG4gIC8vIEl0ZXJhdG9yIGludGVyZmFjZSBpbiB0ZXJtcyBvZiBhIHNpbmdsZSAuX2ludm9rZSBtZXRob2QuXG4gIGZ1bmN0aW9uIGRlZmluZUl0ZXJhdG9yTWV0aG9kcyhwcm90b3R5cGUpIHtcbiAgICBbXCJuZXh0XCIsIFwidGhyb3dcIiwgXCJyZXR1cm5cIl0uZm9yRWFjaChmdW5jdGlvbihtZXRob2QpIHtcbiAgICAgIGRlZmluZShwcm90b3R5cGUsIG1ldGhvZCwgZnVuY3Rpb24oYXJnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pbnZva2UobWV0aG9kLCBhcmcpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBleHBvcnRzLmlzR2VuZXJhdG9yRnVuY3Rpb24gPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICB2YXIgY3RvciA9IHR5cGVvZiBnZW5GdW4gPT09IFwiZnVuY3Rpb25cIiAmJiBnZW5GdW4uY29uc3RydWN0b3I7XG4gICAgcmV0dXJuIGN0b3JcbiAgICAgID8gY3RvciA9PT0gR2VuZXJhdG9yRnVuY3Rpb24gfHxcbiAgICAgICAgLy8gRm9yIHRoZSBuYXRpdmUgR2VuZXJhdG9yRnVuY3Rpb24gY29uc3RydWN0b3IsIHRoZSBiZXN0IHdlIGNhblxuICAgICAgICAvLyBkbyBpcyB0byBjaGVjayBpdHMgLm5hbWUgcHJvcGVydHkuXG4gICAgICAgIChjdG9yLmRpc3BsYXlOYW1lIHx8IGN0b3IubmFtZSkgPT09IFwiR2VuZXJhdG9yRnVuY3Rpb25cIlxuICAgICAgOiBmYWxzZTtcbiAgfTtcblxuICBleHBvcnRzLm1hcmsgPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICBpZiAoT2JqZWN0LnNldFByb3RvdHlwZU9mKSB7XG4gICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoZ2VuRnVuLCBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlbkZ1bi5fX3Byb3RvX18gPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgICAgIGRlZmluZShnZW5GdW4sIHRvU3RyaW5nVGFnU3ltYm9sLCBcIkdlbmVyYXRvckZ1bmN0aW9uXCIpO1xuICAgIH1cbiAgICBnZW5GdW4ucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShHcCk7XG4gICAgcmV0dXJuIGdlbkZ1bjtcbiAgfTtcblxuICAvLyBXaXRoaW4gdGhlIGJvZHkgb2YgYW55IGFzeW5jIGZ1bmN0aW9uLCBgYXdhaXQgeGAgaXMgdHJhbnNmb3JtZWQgdG9cbiAgLy8gYHlpZWxkIHJlZ2VuZXJhdG9yUnVudGltZS5hd3JhcCh4KWAsIHNvIHRoYXQgdGhlIHJ1bnRpbWUgY2FuIHRlc3RcbiAgLy8gYGhhc093bi5jYWxsKHZhbHVlLCBcIl9fYXdhaXRcIilgIHRvIGRldGVybWluZSBpZiB0aGUgeWllbGRlZCB2YWx1ZSBpc1xuICAvLyBtZWFudCB0byBiZSBhd2FpdGVkLlxuICBleHBvcnRzLmF3cmFwID0gZnVuY3Rpb24oYXJnKSB7XG4gICAgcmV0dXJuIHsgX19hd2FpdDogYXJnIH07XG4gIH07XG5cbiAgZnVuY3Rpb24gQXN5bmNJdGVyYXRvcihnZW5lcmF0b3IsIFByb21pc2VJbXBsKSB7XG4gICAgZnVuY3Rpb24gaW52b2tlKG1ldGhvZCwgYXJnLCByZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChnZW5lcmF0b3JbbWV0aG9kXSwgZ2VuZXJhdG9yLCBhcmcpO1xuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgcmVqZWN0KHJlY29yZC5hcmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlY29yZC5hcmc7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgICAgIGhhc093bi5jYWxsKHZhbHVlLCBcIl9fYXdhaXRcIikpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZUltcGwucmVzb2x2ZSh2YWx1ZS5fX2F3YWl0KS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBpbnZva2UoXCJuZXh0XCIsIHZhbHVlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0sIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgICAgaW52b2tlKFwidGhyb3dcIiwgZXJyLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2VJbXBsLnJlc29sdmUodmFsdWUpLnRoZW4oZnVuY3Rpb24odW53cmFwcGVkKSB7XG4gICAgICAgICAgLy8gV2hlbiBhIHlpZWxkZWQgUHJvbWlzZSBpcyByZXNvbHZlZCwgaXRzIGZpbmFsIHZhbHVlIGJlY29tZXNcbiAgICAgICAgICAvLyB0aGUgLnZhbHVlIG9mIHRoZSBQcm9taXNlPHt2YWx1ZSxkb25lfT4gcmVzdWx0IGZvciB0aGVcbiAgICAgICAgICAvLyBjdXJyZW50IGl0ZXJhdGlvbi5cbiAgICAgICAgICByZXN1bHQudmFsdWUgPSB1bndyYXBwZWQ7XG4gICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9LCBmdW5jdGlvbihlcnJvcikge1xuICAgICAgICAgIC8vIElmIGEgcmVqZWN0ZWQgUHJvbWlzZSB3YXMgeWllbGRlZCwgdGhyb3cgdGhlIHJlamVjdGlvbiBiYWNrXG4gICAgICAgICAgLy8gaW50byB0aGUgYXN5bmMgZ2VuZXJhdG9yIGZ1bmN0aW9uIHNvIGl0IGNhbiBiZSBoYW5kbGVkIHRoZXJlLlxuICAgICAgICAgIHJldHVybiBpbnZva2UoXCJ0aHJvd1wiLCBlcnJvciwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHByZXZpb3VzUHJvbWlzZTtcblxuICAgIGZ1bmN0aW9uIGVucXVldWUobWV0aG9kLCBhcmcpIHtcbiAgICAgIGZ1bmN0aW9uIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2VJbXBsKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgIGludm9rZShtZXRob2QsIGFyZywgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwcmV2aW91c1Byb21pc2UgPVxuICAgICAgICAvLyBJZiBlbnF1ZXVlIGhhcyBiZWVuIGNhbGxlZCBiZWZvcmUsIHRoZW4gd2Ugd2FudCB0byB3YWl0IHVudGlsXG4gICAgICAgIC8vIGFsbCBwcmV2aW91cyBQcm9taXNlcyBoYXZlIGJlZW4gcmVzb2x2ZWQgYmVmb3JlIGNhbGxpbmcgaW52b2tlLFxuICAgICAgICAvLyBzbyB0aGF0IHJlc3VsdHMgYXJlIGFsd2F5cyBkZWxpdmVyZWQgaW4gdGhlIGNvcnJlY3Qgb3JkZXIuIElmXG4gICAgICAgIC8vIGVucXVldWUgaGFzIG5vdCBiZWVuIGNhbGxlZCBiZWZvcmUsIHRoZW4gaXQgaXMgaW1wb3J0YW50IHRvXG4gICAgICAgIC8vIGNhbGwgaW52b2tlIGltbWVkaWF0ZWx5LCB3aXRob3V0IHdhaXRpbmcgb24gYSBjYWxsYmFjayB0byBmaXJlLFxuICAgICAgICAvLyBzbyB0aGF0IHRoZSBhc3luYyBnZW5lcmF0b3IgZnVuY3Rpb24gaGFzIHRoZSBvcHBvcnR1bml0eSB0byBkb1xuICAgICAgICAvLyBhbnkgbmVjZXNzYXJ5IHNldHVwIGluIGEgcHJlZGljdGFibGUgd2F5LiBUaGlzIHByZWRpY3RhYmlsaXR5XG4gICAgICAgIC8vIGlzIHdoeSB0aGUgUHJvbWlzZSBjb25zdHJ1Y3RvciBzeW5jaHJvbm91c2x5IGludm9rZXMgaXRzXG4gICAgICAgIC8vIGV4ZWN1dG9yIGNhbGxiYWNrLCBhbmQgd2h5IGFzeW5jIGZ1bmN0aW9ucyBzeW5jaHJvbm91c2x5XG4gICAgICAgIC8vIGV4ZWN1dGUgY29kZSBiZWZvcmUgdGhlIGZpcnN0IGF3YWl0LiBTaW5jZSB3ZSBpbXBsZW1lbnQgc2ltcGxlXG4gICAgICAgIC8vIGFzeW5jIGZ1bmN0aW9ucyBpbiB0ZXJtcyBvZiBhc3luYyBnZW5lcmF0b3JzLCBpdCBpcyBlc3BlY2lhbGx5XG4gICAgICAgIC8vIGltcG9ydGFudCB0byBnZXQgdGhpcyByaWdodCwgZXZlbiB0aG91Z2ggaXQgcmVxdWlyZXMgY2FyZS5cbiAgICAgICAgcHJldmlvdXNQcm9taXNlID8gcHJldmlvdXNQcm9taXNlLnRoZW4oXG4gICAgICAgICAgY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmcsXG4gICAgICAgICAgLy8gQXZvaWQgcHJvcGFnYXRpbmcgZmFpbHVyZXMgdG8gUHJvbWlzZXMgcmV0dXJuZWQgYnkgbGF0ZXJcbiAgICAgICAgICAvLyBpbnZvY2F0aW9ucyBvZiB0aGUgaXRlcmF0b3IuXG4gICAgICAgICAgY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmdcbiAgICAgICAgKSA6IGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnKCk7XG4gICAgfVxuXG4gICAgLy8gRGVmaW5lIHRoZSB1bmlmaWVkIGhlbHBlciBtZXRob2QgdGhhdCBpcyB1c2VkIHRvIGltcGxlbWVudCAubmV4dCxcbiAgICAvLyAudGhyb3csIGFuZCAucmV0dXJuIChzZWUgZGVmaW5lSXRlcmF0b3JNZXRob2RzKS5cbiAgICB0aGlzLl9pbnZva2UgPSBlbnF1ZXVlO1xuICB9XG5cbiAgZGVmaW5lSXRlcmF0b3JNZXRob2RzKEFzeW5jSXRlcmF0b3IucHJvdG90eXBlKTtcbiAgQXN5bmNJdGVyYXRvci5wcm90b3R5cGVbYXN5bmNJdGVyYXRvclN5bWJvbF0gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG4gIGV4cG9ydHMuQXN5bmNJdGVyYXRvciA9IEFzeW5jSXRlcmF0b3I7XG5cbiAgLy8gTm90ZSB0aGF0IHNpbXBsZSBhc3luYyBmdW5jdGlvbnMgYXJlIGltcGxlbWVudGVkIG9uIHRvcCBvZlxuICAvLyBBc3luY0l0ZXJhdG9yIG9iamVjdHM7IHRoZXkganVzdCByZXR1cm4gYSBQcm9taXNlIGZvciB0aGUgdmFsdWUgb2ZcbiAgLy8gdGhlIGZpbmFsIHJlc3VsdCBwcm9kdWNlZCBieSB0aGUgaXRlcmF0b3IuXG4gIGV4cG9ydHMuYXN5bmMgPSBmdW5jdGlvbihpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdCwgUHJvbWlzZUltcGwpIHtcbiAgICBpZiAoUHJvbWlzZUltcGwgPT09IHZvaWQgMCkgUHJvbWlzZUltcGwgPSBQcm9taXNlO1xuXG4gICAgdmFyIGl0ZXIgPSBuZXcgQXN5bmNJdGVyYXRvcihcbiAgICAgIHdyYXAoaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpLFxuICAgICAgUHJvbWlzZUltcGxcbiAgICApO1xuXG4gICAgcmV0dXJuIGV4cG9ydHMuaXNHZW5lcmF0b3JGdW5jdGlvbihvdXRlckZuKVxuICAgICAgPyBpdGVyIC8vIElmIG91dGVyRm4gaXMgYSBnZW5lcmF0b3IsIHJldHVybiB0aGUgZnVsbCBpdGVyYXRvci5cbiAgICAgIDogaXRlci5uZXh0KCkudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0LmRvbmUgPyByZXN1bHQudmFsdWUgOiBpdGVyLm5leHQoKTtcbiAgICAgICAgfSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gbWFrZUludm9rZU1ldGhvZChpbm5lckZuLCBzZWxmLCBjb250ZXh0KSB7XG4gICAgdmFyIHN0YXRlID0gR2VuU3RhdGVTdXNwZW5kZWRTdGFydDtcblxuICAgIHJldHVybiBmdW5jdGlvbiBpbnZva2UobWV0aG9kLCBhcmcpIHtcbiAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVFeGVjdXRpbmcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgcnVubmluZ1wiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZUNvbXBsZXRlZCkge1xuICAgICAgICBpZiAobWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICB0aHJvdyBhcmc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBCZSBmb3JnaXZpbmcsIHBlciAyNS4zLjMuMy4zIG9mIHRoZSBzcGVjOlxuICAgICAgICAvLyBodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtZ2VuZXJhdG9ycmVzdW1lXG4gICAgICAgIHJldHVybiBkb25lUmVzdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRleHQubWV0aG9kID0gbWV0aG9kO1xuICAgICAgY29udGV4dC5hcmcgPSBhcmc7XG5cbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHZhciBkZWxlZ2F0ZSA9IGNvbnRleHQuZGVsZWdhdGU7XG4gICAgICAgIGlmIChkZWxlZ2F0ZSkge1xuICAgICAgICAgIHZhciBkZWxlZ2F0ZVJlc3VsdCA9IG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpO1xuICAgICAgICAgIGlmIChkZWxlZ2F0ZVJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGRlbGVnYXRlUmVzdWx0ID09PSBDb250aW51ZVNlbnRpbmVsKSBjb250aW51ZTtcbiAgICAgICAgICAgIHJldHVybiBkZWxlZ2F0ZVJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwibmV4dFwiKSB7XG4gICAgICAgICAgLy8gU2V0dGluZyBjb250ZXh0Ll9zZW50IGZvciBsZWdhY3kgc3VwcG9ydCBvZiBCYWJlbCdzXG4gICAgICAgICAgLy8gZnVuY3Rpb24uc2VudCBpbXBsZW1lbnRhdGlvbi5cbiAgICAgICAgICBjb250ZXh0LnNlbnQgPSBjb250ZXh0Ll9zZW50ID0gY29udGV4dC5hcmc7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0KSB7XG4gICAgICAgICAgICBzdGF0ZSA9IEdlblN0YXRlQ29tcGxldGVkO1xuICAgICAgICAgICAgdGhyb3cgY29udGV4dC5hcmc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29udGV4dC5kaXNwYXRjaEV4Y2VwdGlvbihjb250ZXh0LmFyZyk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJyZXR1cm5cIikge1xuICAgICAgICAgIGNvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIGNvbnRleHQuYXJnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRlID0gR2VuU3RhdGVFeGVjdXRpbmc7XG5cbiAgICAgICAgdmFyIHJlY29yZCA9IHRyeUNhdGNoKGlubmVyRm4sIHNlbGYsIGNvbnRleHQpO1xuICAgICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwibm9ybWFsXCIpIHtcbiAgICAgICAgICAvLyBJZiBhbiBleGNlcHRpb24gaXMgdGhyb3duIGZyb20gaW5uZXJGbiwgd2UgbGVhdmUgc3RhdGUgPT09XG4gICAgICAgICAgLy8gR2VuU3RhdGVFeGVjdXRpbmcgYW5kIGxvb3AgYmFjayBmb3IgYW5vdGhlciBpbnZvY2F0aW9uLlxuICAgICAgICAgIHN0YXRlID0gY29udGV4dC5kb25lXG4gICAgICAgICAgICA/IEdlblN0YXRlQ29tcGxldGVkXG4gICAgICAgICAgICA6IEdlblN0YXRlU3VzcGVuZGVkWWllbGQ7XG5cbiAgICAgICAgICBpZiAocmVjb3JkLmFyZyA9PT0gQ29udGludWVTZW50aW5lbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbHVlOiByZWNvcmQuYXJnLFxuICAgICAgICAgICAgZG9uZTogY29udGV4dC5kb25lXG4gICAgICAgICAgfTtcblxuICAgICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICBzdGF0ZSA9IEdlblN0YXRlQ29tcGxldGVkO1xuICAgICAgICAgIC8vIERpc3BhdGNoIHRoZSBleGNlcHRpb24gYnkgbG9vcGluZyBiYWNrIGFyb3VuZCB0byB0aGVcbiAgICAgICAgICAvLyBjb250ZXh0LmRpc3BhdGNoRXhjZXB0aW9uKGNvbnRleHQuYXJnKSBjYWxsIGFib3ZlLlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvLyBDYWxsIGRlbGVnYXRlLml0ZXJhdG9yW2NvbnRleHQubWV0aG9kXShjb250ZXh0LmFyZykgYW5kIGhhbmRsZSB0aGVcbiAgLy8gcmVzdWx0LCBlaXRoZXIgYnkgcmV0dXJuaW5nIGEgeyB2YWx1ZSwgZG9uZSB9IHJlc3VsdCBmcm9tIHRoZVxuICAvLyBkZWxlZ2F0ZSBpdGVyYXRvciwgb3IgYnkgbW9kaWZ5aW5nIGNvbnRleHQubWV0aG9kIGFuZCBjb250ZXh0LmFyZyxcbiAgLy8gc2V0dGluZyBjb250ZXh0LmRlbGVnYXRlIHRvIG51bGwsIGFuZCByZXR1cm5pbmcgdGhlIENvbnRpbnVlU2VudGluZWwuXG4gIGZ1bmN0aW9uIG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpIHtcbiAgICB2YXIgbWV0aG9kID0gZGVsZWdhdGUuaXRlcmF0b3JbY29udGV4dC5tZXRob2RdO1xuICAgIGlmIChtZXRob2QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gQSAudGhyb3cgb3IgLnJldHVybiB3aGVuIHRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBoYXMgbm8gLnRocm93XG4gICAgICAvLyBtZXRob2QgYWx3YXlzIHRlcm1pbmF0ZXMgdGhlIHlpZWxkKiBsb29wLlxuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG5cbiAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIC8vIE5vdGU6IFtcInJldHVyblwiXSBtdXN0IGJlIHVzZWQgZm9yIEVTMyBwYXJzaW5nIGNvbXBhdGliaWxpdHkuXG4gICAgICAgIGlmIChkZWxlZ2F0ZS5pdGVyYXRvcltcInJldHVyblwiXSkge1xuICAgICAgICAgIC8vIElmIHRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBoYXMgYSByZXR1cm4gbWV0aG9kLCBnaXZlIGl0IGFcbiAgICAgICAgICAvLyBjaGFuY2UgdG8gY2xlYW4gdXAuXG4gICAgICAgICAgY29udGV4dC5tZXRob2QgPSBcInJldHVyblwiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgICAgIG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpO1xuXG4gICAgICAgICAgaWYgKGNvbnRleHQubWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgIC8vIElmIG1heWJlSW52b2tlRGVsZWdhdGUoY29udGV4dCkgY2hhbmdlZCBjb250ZXh0Lm1ldGhvZCBmcm9tXG4gICAgICAgICAgICAvLyBcInJldHVyblwiIHRvIFwidGhyb3dcIiwgbGV0IHRoYXQgb3ZlcnJpZGUgdGhlIFR5cGVFcnJvciBiZWxvdy5cbiAgICAgICAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgICBjb250ZXh0LmFyZyA9IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgXCJUaGUgaXRlcmF0b3IgZG9lcyBub3QgcHJvdmlkZSBhICd0aHJvdycgbWV0aG9kXCIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG5cbiAgICB2YXIgcmVjb3JkID0gdHJ5Q2F0Y2gobWV0aG9kLCBkZWxlZ2F0ZS5pdGVyYXRvciwgY29udGV4dC5hcmcpO1xuXG4gICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgY29udGV4dC5hcmcgPSByZWNvcmQuYXJnO1xuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG5cbiAgICB2YXIgaW5mbyA9IHJlY29yZC5hcmc7XG5cbiAgICBpZiAoISBpbmZvKSB7XG4gICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgIGNvbnRleHQuYXJnID0gbmV3IFR5cGVFcnJvcihcIml0ZXJhdG9yIHJlc3VsdCBpcyBub3QgYW4gb2JqZWN0XCIpO1xuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG5cbiAgICBpZiAoaW5mby5kb25lKSB7XG4gICAgICAvLyBBc3NpZ24gdGhlIHJlc3VsdCBvZiB0aGUgZmluaXNoZWQgZGVsZWdhdGUgdG8gdGhlIHRlbXBvcmFyeVxuICAgICAgLy8gdmFyaWFibGUgc3BlY2lmaWVkIGJ5IGRlbGVnYXRlLnJlc3VsdE5hbWUgKHNlZSBkZWxlZ2F0ZVlpZWxkKS5cbiAgICAgIGNvbnRleHRbZGVsZWdhdGUucmVzdWx0TmFtZV0gPSBpbmZvLnZhbHVlO1xuXG4gICAgICAvLyBSZXN1bWUgZXhlY3V0aW9uIGF0IHRoZSBkZXNpcmVkIGxvY2F0aW9uIChzZWUgZGVsZWdhdGVZaWVsZCkuXG4gICAgICBjb250ZXh0Lm5leHQgPSBkZWxlZ2F0ZS5uZXh0TG9jO1xuXG4gICAgICAvLyBJZiBjb250ZXh0Lm1ldGhvZCB3YXMgXCJ0aHJvd1wiIGJ1dCB0aGUgZGVsZWdhdGUgaGFuZGxlZCB0aGVcbiAgICAgIC8vIGV4Y2VwdGlvbiwgbGV0IHRoZSBvdXRlciBnZW5lcmF0b3IgcHJvY2VlZCBub3JtYWxseS4gSWZcbiAgICAgIC8vIGNvbnRleHQubWV0aG9kIHdhcyBcIm5leHRcIiwgZm9yZ2V0IGNvbnRleHQuYXJnIHNpbmNlIGl0IGhhcyBiZWVuXG4gICAgICAvLyBcImNvbnN1bWVkXCIgYnkgdGhlIGRlbGVnYXRlIGl0ZXJhdG9yLiBJZiBjb250ZXh0Lm1ldGhvZCB3YXNcbiAgICAgIC8vIFwicmV0dXJuXCIsIGFsbG93IHRoZSBvcmlnaW5hbCAucmV0dXJuIGNhbGwgdG8gY29udGludWUgaW4gdGhlXG4gICAgICAvLyBvdXRlciBnZW5lcmF0b3IuXG4gICAgICBpZiAoY29udGV4dC5tZXRob2QgIT09IFwicmV0dXJuXCIpIHtcbiAgICAgICAgY29udGV4dC5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgY29udGV4dC5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmUteWllbGQgdGhlIHJlc3VsdCByZXR1cm5lZCBieSB0aGUgZGVsZWdhdGUgbWV0aG9kLlxuICAgICAgcmV0dXJuIGluZm87XG4gICAgfVxuXG4gICAgLy8gVGhlIGRlbGVnYXRlIGl0ZXJhdG9yIGlzIGZpbmlzaGVkLCBzbyBmb3JnZXQgaXQgYW5kIGNvbnRpbnVlIHdpdGhcbiAgICAvLyB0aGUgb3V0ZXIgZ2VuZXJhdG9yLlxuICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICB9XG5cbiAgLy8gRGVmaW5lIEdlbmVyYXRvci5wcm90b3R5cGUue25leHQsdGhyb3cscmV0dXJufSBpbiB0ZXJtcyBvZiB0aGVcbiAgLy8gdW5pZmllZCAuX2ludm9rZSBoZWxwZXIgbWV0aG9kLlxuICBkZWZpbmVJdGVyYXRvck1ldGhvZHMoR3ApO1xuXG4gIGRlZmluZShHcCwgdG9TdHJpbmdUYWdTeW1ib2wsIFwiR2VuZXJhdG9yXCIpO1xuXG4gIC8vIEEgR2VuZXJhdG9yIHNob3VsZCBhbHdheXMgcmV0dXJuIGl0c2VsZiBhcyB0aGUgaXRlcmF0b3Igb2JqZWN0IHdoZW4gdGhlXG4gIC8vIEBAaXRlcmF0b3IgZnVuY3Rpb24gaXMgY2FsbGVkIG9uIGl0LiBTb21lIGJyb3dzZXJzJyBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlXG4gIC8vIGl0ZXJhdG9yIHByb3RvdHlwZSBjaGFpbiBpbmNvcnJlY3RseSBpbXBsZW1lbnQgdGhpcywgY2F1c2luZyB0aGUgR2VuZXJhdG9yXG4gIC8vIG9iamVjdCB0byBub3QgYmUgcmV0dXJuZWQgZnJvbSB0aGlzIGNhbGwuIFRoaXMgZW5zdXJlcyB0aGF0IGRvZXNuJ3QgaGFwcGVuLlxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlZ2VuZXJhdG9yL2lzc3Vlcy8yNzQgZm9yIG1vcmUgZGV0YWlscy5cbiAgR3BbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgR3AudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IEdlbmVyYXRvcl1cIjtcbiAgfTtcblxuICBmdW5jdGlvbiBwdXNoVHJ5RW50cnkobG9jcykge1xuICAgIHZhciBlbnRyeSA9IHsgdHJ5TG9jOiBsb2NzWzBdIH07XG5cbiAgICBpZiAoMSBpbiBsb2NzKSB7XG4gICAgICBlbnRyeS5jYXRjaExvYyA9IGxvY3NbMV07XG4gICAgfVxuXG4gICAgaWYgKDIgaW4gbG9jcykge1xuICAgICAgZW50cnkuZmluYWxseUxvYyA9IGxvY3NbMl07XG4gICAgICBlbnRyeS5hZnRlckxvYyA9IGxvY3NbM107XG4gICAgfVxuXG4gICAgdGhpcy50cnlFbnRyaWVzLnB1c2goZW50cnkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzZXRUcnlFbnRyeShlbnRyeSkge1xuICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uIHx8IHt9O1xuICAgIHJlY29yZC50eXBlID0gXCJub3JtYWxcIjtcbiAgICBkZWxldGUgcmVjb3JkLmFyZztcbiAgICBlbnRyeS5jb21wbGV0aW9uID0gcmVjb3JkO1xuICB9XG5cbiAgZnVuY3Rpb24gQ29udGV4dCh0cnlMb2NzTGlzdCkge1xuICAgIC8vIFRoZSByb290IGVudHJ5IG9iamVjdCAoZWZmZWN0aXZlbHkgYSB0cnkgc3RhdGVtZW50IHdpdGhvdXQgYSBjYXRjaFxuICAgIC8vIG9yIGEgZmluYWxseSBibG9jaykgZ2l2ZXMgdXMgYSBwbGFjZSB0byBzdG9yZSB2YWx1ZXMgdGhyb3duIGZyb21cbiAgICAvLyBsb2NhdGlvbnMgd2hlcmUgdGhlcmUgaXMgbm8gZW5jbG9zaW5nIHRyeSBzdGF0ZW1lbnQuXG4gICAgdGhpcy50cnlFbnRyaWVzID0gW3sgdHJ5TG9jOiBcInJvb3RcIiB9XTtcbiAgICB0cnlMb2NzTGlzdC5mb3JFYWNoKHB1c2hUcnlFbnRyeSwgdGhpcyk7XG4gICAgdGhpcy5yZXNldCh0cnVlKTtcbiAgfVxuXG4gIGV4cG9ydHMua2V5cyA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgfVxuICAgIGtleXMucmV2ZXJzZSgpO1xuXG4gICAgLy8gUmF0aGVyIHRoYW4gcmV0dXJuaW5nIGFuIG9iamVjdCB3aXRoIGEgbmV4dCBtZXRob2QsIHdlIGtlZXBcbiAgICAvLyB0aGluZ3Mgc2ltcGxlIGFuZCByZXR1cm4gdGhlIG5leHQgZnVuY3Rpb24gaXRzZWxmLlxuICAgIHJldHVybiBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgd2hpbGUgKGtleXMubGVuZ3RoKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzLnBvcCgpO1xuICAgICAgICBpZiAoa2V5IGluIG9iamVjdCkge1xuICAgICAgICAgIG5leHQudmFsdWUgPSBrZXk7XG4gICAgICAgICAgbmV4dC5kb25lID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVG8gYXZvaWQgY3JlYXRpbmcgYW4gYWRkaXRpb25hbCBvYmplY3QsIHdlIGp1c3QgaGFuZyB0aGUgLnZhbHVlXG4gICAgICAvLyBhbmQgLmRvbmUgcHJvcGVydGllcyBvZmYgdGhlIG5leHQgZnVuY3Rpb24gb2JqZWN0IGl0c2VsZi4gVGhpc1xuICAgICAgLy8gYWxzbyBlbnN1cmVzIHRoYXQgdGhlIG1pbmlmaWVyIHdpbGwgbm90IGFub255bWl6ZSB0aGUgZnVuY3Rpb24uXG4gICAgICBuZXh0LmRvbmUgPSB0cnVlO1xuICAgICAgcmV0dXJuIG5leHQ7XG4gICAgfTtcbiAgfTtcblxuICBmdW5jdGlvbiB2YWx1ZXMoaXRlcmFibGUpIHtcbiAgICBpZiAoaXRlcmFibGUpIHtcbiAgICAgIHZhciBpdGVyYXRvck1ldGhvZCA9IGl0ZXJhYmxlW2l0ZXJhdG9yU3ltYm9sXTtcbiAgICAgIGlmIChpdGVyYXRvck1ldGhvZCkge1xuICAgICAgICByZXR1cm4gaXRlcmF0b3JNZXRob2QuY2FsbChpdGVyYWJsZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgaXRlcmFibGUubmV4dCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBpdGVyYWJsZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc05hTihpdGVyYWJsZS5sZW5ndGgpKSB7XG4gICAgICAgIHZhciBpID0gLTEsIG5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgICAgIHdoaWxlICgrK2kgPCBpdGVyYWJsZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd24uY2FsbChpdGVyYWJsZSwgaSkpIHtcbiAgICAgICAgICAgICAgbmV4dC52YWx1ZSA9IGl0ZXJhYmxlW2ldO1xuICAgICAgICAgICAgICBuZXh0LmRvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbmV4dC52YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBuZXh0LmRvbmUgPSB0cnVlO1xuXG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIG5leHQubmV4dCA9IG5leHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGFuIGl0ZXJhdG9yIHdpdGggbm8gdmFsdWVzLlxuICAgIHJldHVybiB7IG5leHQ6IGRvbmVSZXN1bHQgfTtcbiAgfVxuICBleHBvcnRzLnZhbHVlcyA9IHZhbHVlcztcblxuICBmdW5jdGlvbiBkb25lUmVzdWx0KCkge1xuICAgIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgfVxuXG4gIENvbnRleHQucHJvdG90eXBlID0ge1xuICAgIGNvbnN0cnVjdG9yOiBDb250ZXh0LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uKHNraXBUZW1wUmVzZXQpIHtcbiAgICAgIHRoaXMucHJldiA9IDA7XG4gICAgICB0aGlzLm5leHQgPSAwO1xuICAgICAgLy8gUmVzZXR0aW5nIGNvbnRleHQuX3NlbnQgZm9yIGxlZ2FjeSBzdXBwb3J0IG9mIEJhYmVsJ3NcbiAgICAgIC8vIGZ1bmN0aW9uLnNlbnQgaW1wbGVtZW50YXRpb24uXG4gICAgICB0aGlzLnNlbnQgPSB0aGlzLl9zZW50ID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5kb25lID0gZmFsc2U7XG4gICAgICB0aGlzLmRlbGVnYXRlID0gbnVsbDtcblxuICAgICAgdGhpcy5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgIHRoaXMuYXJnID0gdW5kZWZpbmVkO1xuXG4gICAgICB0aGlzLnRyeUVudHJpZXMuZm9yRWFjaChyZXNldFRyeUVudHJ5KTtcblxuICAgICAgaWYgKCFza2lwVGVtcFJlc2V0KSB7XG4gICAgICAgIGZvciAodmFyIG5hbWUgaW4gdGhpcykge1xuICAgICAgICAgIC8vIE5vdCBzdXJlIGFib3V0IHRoZSBvcHRpbWFsIG9yZGVyIG9mIHRoZXNlIGNvbmRpdGlvbnM6XG4gICAgICAgICAgaWYgKG5hbWUuY2hhckF0KDApID09PSBcInRcIiAmJlxuICAgICAgICAgICAgICBoYXNPd24uY2FsbCh0aGlzLCBuYW1lKSAmJlxuICAgICAgICAgICAgICAhaXNOYU4oK25hbWUuc2xpY2UoMSkpKSB7XG4gICAgICAgICAgICB0aGlzW25hbWVdID0gdW5kZWZpbmVkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBzdG9wOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuZG9uZSA9IHRydWU7XG5cbiAgICAgIHZhciByb290RW50cnkgPSB0aGlzLnRyeUVudHJpZXNbMF07XG4gICAgICB2YXIgcm9vdFJlY29yZCA9IHJvb3RFbnRyeS5jb21wbGV0aW9uO1xuICAgICAgaWYgKHJvb3RSZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIHRocm93IHJvb3RSZWNvcmQuYXJnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5ydmFsO1xuICAgIH0sXG5cbiAgICBkaXNwYXRjaEV4Y2VwdGlvbjogZnVuY3Rpb24oZXhjZXB0aW9uKSB7XG4gICAgICBpZiAodGhpcy5kb25lKSB7XG4gICAgICAgIHRocm93IGV4Y2VwdGlvbjtcbiAgICAgIH1cblxuICAgICAgdmFyIGNvbnRleHQgPSB0aGlzO1xuICAgICAgZnVuY3Rpb24gaGFuZGxlKGxvYywgY2F1Z2h0KSB7XG4gICAgICAgIHJlY29yZC50eXBlID0gXCJ0aHJvd1wiO1xuICAgICAgICByZWNvcmQuYXJnID0gZXhjZXB0aW9uO1xuICAgICAgICBjb250ZXh0Lm5leHQgPSBsb2M7XG5cbiAgICAgICAgaWYgKGNhdWdodCkge1xuICAgICAgICAgIC8vIElmIHRoZSBkaXNwYXRjaGVkIGV4Y2VwdGlvbiB3YXMgY2F1Z2h0IGJ5IGEgY2F0Y2ggYmxvY2ssXG4gICAgICAgICAgLy8gdGhlbiBsZXQgdGhhdCBjYXRjaCBibG9jayBoYW5kbGUgdGhlIGV4Y2VwdGlvbiBub3JtYWxseS5cbiAgICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICEhIGNhdWdodDtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uO1xuXG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPT09IFwicm9vdFwiKSB7XG4gICAgICAgICAgLy8gRXhjZXB0aW9uIHRocm93biBvdXRzaWRlIG9mIGFueSB0cnkgYmxvY2sgdGhhdCBjb3VsZCBoYW5kbGVcbiAgICAgICAgICAvLyBpdCwgc28gc2V0IHRoZSBjb21wbGV0aW9uIHZhbHVlIG9mIHRoZSBlbnRpcmUgZnVuY3Rpb24gdG9cbiAgICAgICAgICAvLyB0aHJvdyB0aGUgZXhjZXB0aW9uLlxuICAgICAgICAgIHJldHVybiBoYW5kbGUoXCJlbmRcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW50cnkudHJ5TG9jIDw9IHRoaXMucHJldikge1xuICAgICAgICAgIHZhciBoYXNDYXRjaCA9IGhhc093bi5jYWxsKGVudHJ5LCBcImNhdGNoTG9jXCIpO1xuICAgICAgICAgIHZhciBoYXNGaW5hbGx5ID0gaGFzT3duLmNhbGwoZW50cnksIFwiZmluYWxseUxvY1wiKTtcblxuICAgICAgICAgIGlmIChoYXNDYXRjaCAmJiBoYXNGaW5hbGx5KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmV2IDwgZW50cnkuY2F0Y2hMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5jYXRjaExvYywgdHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5maW5hbGx5TG9jKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSBpZiAoaGFzQ2F0Y2gpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXYgPCBlbnRyeS5jYXRjaExvYykge1xuICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlKGVudHJ5LmNhdGNoTG9jLCB0cnVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSBpZiAoaGFzRmluYWxseSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5maW5hbGx5TG9jKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0cnkgc3RhdGVtZW50IHdpdGhvdXQgY2F0Y2ggb3IgZmluYWxseVwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYWJydXB0OiBmdW5jdGlvbih0eXBlLCBhcmcpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICBpZiAoZW50cnkudHJ5TG9jIDw9IHRoaXMucHJldiAmJlxuICAgICAgICAgICAgaGFzT3duLmNhbGwoZW50cnksIFwiZmluYWxseUxvY1wiKSAmJlxuICAgICAgICAgICAgdGhpcy5wcmV2IDwgZW50cnkuZmluYWxseUxvYykge1xuICAgICAgICAgIHZhciBmaW5hbGx5RW50cnkgPSBlbnRyeTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZmluYWxseUVudHJ5ICYmXG4gICAgICAgICAgKHR5cGUgPT09IFwiYnJlYWtcIiB8fFxuICAgICAgICAgICB0eXBlID09PSBcImNvbnRpbnVlXCIpICYmXG4gICAgICAgICAgZmluYWxseUVudHJ5LnRyeUxvYyA8PSBhcmcgJiZcbiAgICAgICAgICBhcmcgPD0gZmluYWxseUVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgLy8gSWdub3JlIHRoZSBmaW5hbGx5IGVudHJ5IGlmIGNvbnRyb2wgaXMgbm90IGp1bXBpbmcgdG8gYVxuICAgICAgICAvLyBsb2NhdGlvbiBvdXRzaWRlIHRoZSB0cnkvY2F0Y2ggYmxvY2suXG4gICAgICAgIGZpbmFsbHlFbnRyeSA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciByZWNvcmQgPSBmaW5hbGx5RW50cnkgPyBmaW5hbGx5RW50cnkuY29tcGxldGlvbiA6IHt9O1xuICAgICAgcmVjb3JkLnR5cGUgPSB0eXBlO1xuICAgICAgcmVjb3JkLmFyZyA9IGFyZztcblxuICAgICAgaWYgKGZpbmFsbHlFbnRyeSkge1xuICAgICAgICB0aGlzLm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICB0aGlzLm5leHQgPSBmaW5hbGx5RW50cnkuZmluYWxseUxvYztcbiAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmNvbXBsZXRlKHJlY29yZCk7XG4gICAgfSxcblxuICAgIGNvbXBsZXRlOiBmdW5jdGlvbihyZWNvcmQsIGFmdGVyTG9jKSB7XG4gICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICB0aHJvdyByZWNvcmQuYXJnO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwiYnJlYWtcIiB8fFxuICAgICAgICAgIHJlY29yZC50eXBlID09PSBcImNvbnRpbnVlXCIpIHtcbiAgICAgICAgdGhpcy5uZXh0ID0gcmVjb3JkLmFyZztcbiAgICAgIH0gZWxzZSBpZiAocmVjb3JkLnR5cGUgPT09IFwicmV0dXJuXCIpIHtcbiAgICAgICAgdGhpcy5ydmFsID0gdGhpcy5hcmcgPSByZWNvcmQuYXJnO1xuICAgICAgICB0aGlzLm1ldGhvZCA9IFwicmV0dXJuXCI7XG4gICAgICAgIHRoaXMubmV4dCA9IFwiZW5kXCI7XG4gICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcIm5vcm1hbFwiICYmIGFmdGVyTG9jKSB7XG4gICAgICAgIHRoaXMubmV4dCA9IGFmdGVyTG9jO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9LFxuXG4gICAgZmluaXNoOiBmdW5jdGlvbihmaW5hbGx5TG9jKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgaWYgKGVudHJ5LmZpbmFsbHlMb2MgPT09IGZpbmFsbHlMb2MpIHtcbiAgICAgICAgICB0aGlzLmNvbXBsZXRlKGVudHJ5LmNvbXBsZXRpb24sIGVudHJ5LmFmdGVyTG9jKTtcbiAgICAgICAgICByZXNldFRyeUVudHJ5KGVudHJ5KTtcbiAgICAgICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBcImNhdGNoXCI6IGZ1bmN0aW9uKHRyeUxvYykge1xuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPT09IHRyeUxvYykge1xuICAgICAgICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uO1xuICAgICAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICB2YXIgdGhyb3duID0gcmVjb3JkLmFyZztcbiAgICAgICAgICAgIHJlc2V0VHJ5RW50cnkoZW50cnkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhyb3duO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRoZSBjb250ZXh0LmNhdGNoIG1ldGhvZCBtdXN0IG9ubHkgYmUgY2FsbGVkIHdpdGggYSBsb2NhdGlvblxuICAgICAgLy8gYXJndW1lbnQgdGhhdCBjb3JyZXNwb25kcyB0byBhIGtub3duIGNhdGNoIGJsb2NrLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaWxsZWdhbCBjYXRjaCBhdHRlbXB0XCIpO1xuICAgIH0sXG5cbiAgICBkZWxlZ2F0ZVlpZWxkOiBmdW5jdGlvbihpdGVyYWJsZSwgcmVzdWx0TmFtZSwgbmV4dExvYykge1xuICAgICAgdGhpcy5kZWxlZ2F0ZSA9IHtcbiAgICAgICAgaXRlcmF0b3I6IHZhbHVlcyhpdGVyYWJsZSksXG4gICAgICAgIHJlc3VsdE5hbWU6IHJlc3VsdE5hbWUsXG4gICAgICAgIG5leHRMb2M6IG5leHRMb2NcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLm1ldGhvZCA9PT0gXCJuZXh0XCIpIHtcbiAgICAgICAgLy8gRGVsaWJlcmF0ZWx5IGZvcmdldCB0aGUgbGFzdCBzZW50IHZhbHVlIHNvIHRoYXQgd2UgZG9uJ3RcbiAgICAgICAgLy8gYWNjaWRlbnRhbGx5IHBhc3MgaXQgb24gdG8gdGhlIGRlbGVnYXRlLlxuICAgICAgICB0aGlzLmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuICB9O1xuXG4gIC8vIFJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGlzIHNjcmlwdCBpcyBleGVjdXRpbmcgYXMgYSBDb21tb25KUyBtb2R1bGVcbiAgLy8gb3Igbm90LCByZXR1cm4gdGhlIHJ1bnRpbWUgb2JqZWN0IHNvIHRoYXQgd2UgY2FuIGRlY2xhcmUgdGhlIHZhcmlhYmxlXG4gIC8vIHJlZ2VuZXJhdG9yUnVudGltZSBpbiB0aGUgb3V0ZXIgc2NvcGUsIHdoaWNoIGFsbG93cyB0aGlzIG1vZHVsZSB0byBiZVxuICAvLyBpbmplY3RlZCBlYXNpbHkgYnkgYGJpbi9yZWdlbmVyYXRvciAtLWluY2x1ZGUtcnVudGltZSBzY3JpcHQuanNgLlxuICByZXR1cm4gZXhwb3J0cztcblxufShcbiAgLy8gSWYgdGhpcyBzY3JpcHQgaXMgZXhlY3V0aW5nIGFzIGEgQ29tbW9uSlMgbW9kdWxlLCB1c2UgbW9kdWxlLmV4cG9ydHNcbiAgLy8gYXMgdGhlIHJlZ2VuZXJhdG9yUnVudGltZSBuYW1lc3BhY2UuIE90aGVyd2lzZSBjcmVhdGUgYSBuZXcgZW1wdHlcbiAgLy8gb2JqZWN0LiBFaXRoZXIgd2F5LCB0aGUgcmVzdWx0aW5nIG9iamVjdCB3aWxsIGJlIHVzZWQgdG8gaW5pdGlhbGl6ZVxuICAvLyB0aGUgcmVnZW5lcmF0b3JSdW50aW1lIHZhcmlhYmxlIGF0IHRoZSB0b3Agb2YgdGhpcyBmaWxlLlxuICB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiID8gbW9kdWxlLmV4cG9ydHMgOiB7fVxuKSk7XG5cbnRyeSB7XG4gIHJlZ2VuZXJhdG9yUnVudGltZSA9IHJ1bnRpbWU7XG59IGNhdGNoIChhY2NpZGVudGFsU3RyaWN0TW9kZSkge1xuICAvLyBUaGlzIG1vZHVsZSBzaG91bGQgbm90IGJlIHJ1bm5pbmcgaW4gc3RyaWN0IG1vZGUsIHNvIHRoZSBhYm92ZVxuICAvLyBhc3NpZ25tZW50IHNob3VsZCBhbHdheXMgd29yayB1bmxlc3Mgc29tZXRoaW5nIGlzIG1pc2NvbmZpZ3VyZWQuIEp1c3RcbiAgLy8gaW4gY2FzZSBydW50aW1lLmpzIGFjY2lkZW50YWxseSBydW5zIGluIHN0cmljdCBtb2RlLCB3ZSBjYW4gZXNjYXBlXG4gIC8vIHN0cmljdCBtb2RlIHVzaW5nIGEgZ2xvYmFsIEZ1bmN0aW9uIGNhbGwuIFRoaXMgY291bGQgY29uY2VpdmFibHkgZmFpbFxuICAvLyBpZiBhIENvbnRlbnQgU2VjdXJpdHkgUG9saWN5IGZvcmJpZHMgdXNpbmcgRnVuY3Rpb24sIGJ1dCBpbiB0aGF0IGNhc2VcbiAgLy8gdGhlIHByb3BlciBzb2x1dGlvbiBpcyB0byBmaXggdGhlIGFjY2lkZW50YWwgc3RyaWN0IG1vZGUgcHJvYmxlbS4gSWZcbiAgLy8geW91J3ZlIG1pc2NvbmZpZ3VyZWQgeW91ciBidW5kbGVyIHRvIGZvcmNlIHN0cmljdCBtb2RlIGFuZCBhcHBsaWVkIGFcbiAgLy8gQ1NQIHRvIGZvcmJpZCBGdW5jdGlvbiwgYW5kIHlvdSdyZSBub3Qgd2lsbGluZyB0byBmaXggZWl0aGVyIG9mIHRob3NlXG4gIC8vIHByb2JsZW1zLCBwbGVhc2UgZGV0YWlsIHlvdXIgdW5pcXVlIHByZWRpY2FtZW50IGluIGEgR2l0SHViIGlzc3VlLlxuICBGdW5jdGlvbihcInJcIiwgXCJyZWdlbmVyYXRvclJ1bnRpbWUgPSByXCIpKHJ1bnRpbWUpO1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5666\n')}}]); |