diff --git "a/demo/ort-phi3/dist/esm/ort.webgl.js" "b/demo/ort-phi3/dist/esm/ort.webgl.js" new file mode 100644--- /dev/null +++ "b/demo/ort-phi3/dist/esm/ort.webgl.js" @@ -0,0 +1,23964 @@ +/*! + * ONNX Runtime Web v1.18.0 + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __esm = (fn, res) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; +}; +var __commonJS = (cb, mod2) => function __require() { + return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports; +}; +var __export = (target, all) => { + for (var name2 in all) + __defProp(target, name2, { get: all[name2], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target, + mod2 +)); +var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2); + +// common/dist/esm/backend-impl.js +var backends, backendsSortedByPriority, registerBackend, tryResolveAndInitializeBackend, resolveBackendAndExecutionProviders; +var init_backend_impl = __esm({ + "common/dist/esm/backend-impl.js"() { + "use strict"; + backends = /* @__PURE__ */ new Map(); + backendsSortedByPriority = []; + registerBackend = (name2, backend2, priority) => { + if (backend2 && typeof backend2.init === "function" && typeof backend2.createInferenceSessionHandler === "function") { + const currentBackend = backends.get(name2); + if (currentBackend === void 0) { + backends.set(name2, { backend: backend2, priority }); + } else if (currentBackend.priority > priority) { + return; + } else if (currentBackend.priority === priority) { + if (currentBackend.backend !== backend2) { + throw new Error(`cannot register backend "${name2}" using priority ${priority}`); + } + } + if (priority >= 0) { + const i = backendsSortedByPriority.indexOf(name2); + if (i !== -1) { + backendsSortedByPriority.splice(i, 1); + } + for (let i2 = 0; i2 < backendsSortedByPriority.length; i2++) { + if (backends.get(backendsSortedByPriority[i2]).priority <= priority) { + backendsSortedByPriority.splice(i2, 0, name2); + return; + } + } + backendsSortedByPriority.push(name2); + } + return; + } + throw new TypeError("not a valid backend"); + }; + tryResolveAndInitializeBackend = async (backendName) => { + const backendInfo = backends.get(backendName); + if (!backendInfo) { + return "backend not found."; + } + if (backendInfo.initialized) { + return backendInfo.backend; + } else if (backendInfo.aborted) { + return backendInfo.error; + } else { + const isInitializing = !!backendInfo.initPromise; + try { + if (!isInitializing) { + backendInfo.initPromise = backendInfo.backend.init(backendName); + } + await backendInfo.initPromise; + backendInfo.initialized = true; + return backendInfo.backend; + } catch (e) { + if (!isInitializing) { + backendInfo.error = `${e}`; + backendInfo.aborted = true; + } + return backendInfo.error; + } finally { + delete backendInfo.initPromise; + } + } + }; + resolveBackendAndExecutionProviders = async (options) => { + const eps = options.executionProviders || []; + const backendHints = eps.map((i) => typeof i === "string" ? i : i.name); + const backendNames = backendHints.length === 0 ? backendsSortedByPriority : backendHints; + let backend2; + const errors = []; + const availableBackendNames = /* @__PURE__ */ new Set(); + for (const backendName of backendNames) { + const resolveResult = await tryResolveAndInitializeBackend(backendName); + if (typeof resolveResult === "string") { + errors.push({ name: backendName, err: resolveResult }); + } else { + if (!backend2) { + backend2 = resolveResult; + } + if (backend2 === resolveResult) { + availableBackendNames.add(backendName); + } + } + } + if (!backend2) { + throw new Error(`no available backend found. ERR: ${errors.map((e) => `[${e.name}] ${e.err}`).join(", ")}`); + } + for (const { name: name2, err } of errors) { + if (backendHints.includes(name2)) { + console.warn(`removing requested execution provider "${name2}" from session options because it is not available: ${err}`); + } + } + const filteredEps = eps.filter((i) => availableBackendNames.has(typeof i === "string" ? i : i.name)); + return [ + backend2, + new Proxy(options, { + get: (target, prop) => { + if (prop === "executionProviders") { + return filteredEps; + } + return Reflect.get(target, prop); + } + }) + ]; + }; + } +}); + +// common/dist/esm/backend.js +var init_backend = __esm({ + "common/dist/esm/backend.js"() { + "use strict"; + init_backend_impl(); + } +}); + +// common/dist/esm/version.js +var version; +var init_version = __esm({ + "common/dist/esm/version.js"() { + "use strict"; + version = "1.18.0"; + } +}); + +// common/dist/esm/env-impl.js +var logLevelValue, env; +var init_env_impl = __esm({ + "common/dist/esm/env-impl.js"() { + "use strict"; + init_version(); + logLevelValue = "warning"; + env = { + wasm: {}, + webgl: {}, + webgpu: {}, + versions: { common: version }, + set logLevel(value) { + if (value === void 0) { + return; + } + if (typeof value !== "string" || ["verbose", "info", "warning", "error", "fatal"].indexOf(value) === -1) { + throw new Error(`Unsupported logging level: ${value}`); + } + logLevelValue = value; + }, + get logLevel() { + return logLevelValue; + } + }; + Object.defineProperty(env, "logLevel", { enumerable: true }); + } +}); + +// common/dist/esm/env.js +var env2; +var init_env = __esm({ + "common/dist/esm/env.js"() { + "use strict"; + init_env_impl(); + env2 = env; + } +}); + +// common/dist/esm/tensor-conversion-impl.js +var tensorToDataURL, tensorToImageData; +var init_tensor_conversion_impl = __esm({ + "common/dist/esm/tensor-conversion-impl.js"() { + "use strict"; + tensorToDataURL = (tensor, options) => { + const canvas = typeof document !== "undefined" ? document.createElement("canvas") : new OffscreenCanvas(1, 1); + canvas.width = tensor.dims[3]; + canvas.height = tensor.dims[2]; + const pixels2DContext = canvas.getContext("2d"); + if (pixels2DContext != null) { + let width; + let height; + if (options?.tensorLayout !== void 0 && options.tensorLayout === "NHWC") { + width = tensor.dims[2]; + height = tensor.dims[3]; + } else { + width = tensor.dims[3]; + height = tensor.dims[2]; + } + const inputformat = options?.format !== void 0 ? options.format : "RGB"; + const norm = options?.norm; + let normMean; + let normBias; + if (norm === void 0 || norm.mean === void 0) { + normMean = [255, 255, 255, 255]; + } else { + if (typeof norm.mean === "number") { + normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; + } else { + normMean = [norm.mean[0], norm.mean[1], norm.mean[2], 0]; + if (norm.mean[3] !== void 0) { + normMean[3] = norm.mean[3]; + } + } + } + if (norm === void 0 || norm.bias === void 0) { + normBias = [0, 0, 0, 0]; + } else { + if (typeof norm.bias === "number") { + normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; + } else { + normBias = [norm.bias[0], norm.bias[1], norm.bias[2], 0]; + if (norm.bias[3] !== void 0) { + normBias[3] = norm.bias[3]; + } + } + } + const stride = height * width; + let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; + if (inputformat === "RGBA") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + aTensorPointer = stride * 3; + } else if (inputformat === "RGB") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + } else if (inputformat === "RBG") { + rTensorPointer = 0; + bTensorPointer = stride; + gTensorPointer = stride * 2; + } + for (let i = 0; i < height; i++) { + for (let j = 0; j < width; j++) { + const R = (tensor.data[rTensorPointer++] - normBias[0]) * normMean[0]; + const G = (tensor.data[gTensorPointer++] - normBias[1]) * normMean[1]; + const B = (tensor.data[bTensorPointer++] - normBias[2]) * normMean[2]; + const A = aTensorPointer === -1 ? 255 : (tensor.data[aTensorPointer++] - normBias[3]) * normMean[3]; + pixels2DContext.fillStyle = "rgba(" + R + "," + G + "," + B + "," + A + ")"; + pixels2DContext.fillRect(j, i, 1, 1); + } + } + if ("toDataURL" in canvas) { + return canvas.toDataURL(); + } else { + throw new Error("toDataURL is not supported"); + } + } else { + throw new Error("Can not access image data"); + } + }; + tensorToImageData = (tensor, options) => { + const pixels2DContext = typeof document !== "undefined" ? document.createElement("canvas").getContext("2d") : new OffscreenCanvas(1, 1).getContext("2d"); + let image; + if (pixels2DContext != null) { + let width; + let height; + let channels; + if (options?.tensorLayout !== void 0 && options.tensorLayout === "NHWC") { + width = tensor.dims[2]; + height = tensor.dims[1]; + channels = tensor.dims[3]; + } else { + width = tensor.dims[3]; + height = tensor.dims[2]; + channels = tensor.dims[1]; + } + const inputformat = options !== void 0 ? options.format !== void 0 ? options.format : "RGB" : "RGB"; + const norm = options?.norm; + let normMean; + let normBias; + if (norm === void 0 || norm.mean === void 0) { + normMean = [255, 255, 255, 255]; + } else { + if (typeof norm.mean === "number") { + normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; + } else { + normMean = [norm.mean[0], norm.mean[1], norm.mean[2], 255]; + if (norm.mean[3] !== void 0) { + normMean[3] = norm.mean[3]; + } + } + } + if (norm === void 0 || norm.bias === void 0) { + normBias = [0, 0, 0, 0]; + } else { + if (typeof norm.bias === "number") { + normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; + } else { + normBias = [norm.bias[0], norm.bias[1], norm.bias[2], 0]; + if (norm.bias[3] !== void 0) { + normBias[3] = norm.bias[3]; + } + } + } + const stride = height * width; + if (options !== void 0) { + if (options.format !== void 0 && (channels === 4 && options.format !== "RGBA") || channels === 3 && (options.format !== "RGB" && options.format !== "BGR")) { + throw new Error("Tensor format doesn't match input tensor dims"); + } + } + const step = 4; + let rImagePointer = 0, gImagePointer = 1, bImagePointer = 2, aImagePointer = 3; + let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; + if (inputformat === "RGBA") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + aTensorPointer = stride * 3; + } else if (inputformat === "RGB") { + rTensorPointer = 0; + gTensorPointer = stride; + bTensorPointer = stride * 2; + } else if (inputformat === "RBG") { + rTensorPointer = 0; + bTensorPointer = stride; + gTensorPointer = stride * 2; + } + image = pixels2DContext.createImageData(width, height); + for (let i = 0; i < height * width; rImagePointer += step, gImagePointer += step, bImagePointer += step, aImagePointer += step, i++) { + image.data[rImagePointer] = (tensor.data[rTensorPointer++] - normBias[0]) * normMean[0]; + image.data[gImagePointer] = (tensor.data[gTensorPointer++] - normBias[1]) * normMean[1]; + image.data[bImagePointer] = (tensor.data[bTensorPointer++] - normBias[2]) * normMean[2]; + image.data[aImagePointer] = aTensorPointer === -1 ? 255 : (tensor.data[aTensorPointer++] - normBias[3]) * normMean[3]; + } + } else { + throw new Error("Can not access image data"); + } + return image; + }; + } +}); + +// common/dist/esm/tensor-factory-impl.js +var bufferToTensor, tensorFromImage, tensorFromTexture, tensorFromGpuBuffer, tensorFromPinnedBuffer; +var init_tensor_factory_impl = __esm({ + "common/dist/esm/tensor-factory-impl.js"() { + "use strict"; + init_tensor_impl(); + bufferToTensor = (buffer, options) => { + if (buffer === void 0) { + throw new Error("Image buffer must be defined"); + } + if (options.height === void 0 || options.width === void 0) { + throw new Error("Image height and width must be defined"); + } + if (options.tensorLayout === "NHWC") { + throw new Error("NHWC Tensor layout is not supported yet"); + } + const { height, width } = options; + const norm = options.norm ?? { mean: 255, bias: 0 }; + let normMean; + let normBias; + if (typeof norm.mean === "number") { + normMean = [norm.mean, norm.mean, norm.mean, norm.mean]; + } else { + normMean = [norm.mean[0], norm.mean[1], norm.mean[2], norm.mean[3] ?? 255]; + } + if (typeof norm.bias === "number") { + normBias = [norm.bias, norm.bias, norm.bias, norm.bias]; + } else { + normBias = [norm.bias[0], norm.bias[1], norm.bias[2], norm.bias[3] ?? 0]; + } + const inputformat = options.format !== void 0 ? options.format : "RGBA"; + const outputformat = options.tensorFormat !== void 0 ? options.tensorFormat !== void 0 ? options.tensorFormat : "RGB" : "RGB"; + const stride = height * width; + const float32Data = outputformat === "RGBA" ? new Float32Array(stride * 4) : new Float32Array(stride * 3); + let step = 4, rImagePointer = 0, gImagePointer = 1, bImagePointer = 2, aImagePointer = 3; + let rTensorPointer = 0, gTensorPointer = stride, bTensorPointer = stride * 2, aTensorPointer = -1; + if (inputformat === "RGB") { + step = 3; + rImagePointer = 0; + gImagePointer = 1; + bImagePointer = 2; + aImagePointer = -1; + } + if (outputformat === "RGBA") { + aTensorPointer = stride * 3; + } else if (outputformat === "RBG") { + rTensorPointer = 0; + bTensorPointer = stride; + gTensorPointer = stride * 2; + } else if (outputformat === "BGR") { + bTensorPointer = 0; + gTensorPointer = stride; + rTensorPointer = stride * 2; + } + for (let i = 0; i < stride; i++, rImagePointer += step, bImagePointer += step, gImagePointer += step, aImagePointer += step) { + float32Data[rTensorPointer++] = (buffer[rImagePointer] + normBias[0]) / normMean[0]; + float32Data[gTensorPointer++] = (buffer[gImagePointer] + normBias[1]) / normMean[1]; + float32Data[bTensorPointer++] = (buffer[bImagePointer] + normBias[2]) / normMean[2]; + if (aTensorPointer !== -1 && aImagePointer !== -1) { + float32Data[aTensorPointer++] = (buffer[aImagePointer] + normBias[3]) / normMean[3]; + } + } + const outputTensor = outputformat === "RGBA" ? new Tensor("float32", float32Data, [1, 4, height, width]) : new Tensor("float32", float32Data, [1, 3, height, width]); + return outputTensor; + }; + tensorFromImage = async (image, options) => { + const isHTMLImageEle = typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement; + const isImageDataEle = typeof ImageData !== "undefined" && image instanceof ImageData; + const isImageBitmap = typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap; + const isString = typeof image === "string"; + let data; + let bufferToTensorOptions = options ?? {}; + const createCanvas2 = () => { + if (typeof document !== "undefined") { + return document.createElement("canvas"); + } else if (typeof OffscreenCanvas !== "undefined") { + return new OffscreenCanvas(1, 1); + } else { + throw new Error("Canvas is not supported"); + } + }; + const createCanvasContext = (canvas) => { + if (canvas instanceof HTMLCanvasElement) { + return canvas.getContext("2d"); + } else if (canvas instanceof OffscreenCanvas) { + return canvas.getContext("2d"); + } else { + return null; + } + }; + if (isHTMLImageEle) { + const canvas = createCanvas2(); + canvas.width = image.width; + canvas.height = image.height; + const pixels2DContext = createCanvasContext(canvas); + if (pixels2DContext != null) { + let height = image.height; + let width = image.width; + if (options !== void 0 && options.resizedHeight !== void 0 && options.resizedWidth !== void 0) { + height = options.resizedHeight; + width = options.resizedWidth; + } + if (options !== void 0) { + bufferToTensorOptions = options; + if (options.tensorFormat !== void 0) { + throw new Error("Image input config format must be RGBA for HTMLImageElement"); + } else { + bufferToTensorOptions.tensorFormat = "RGBA"; + } + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + } else { + bufferToTensorOptions.tensorFormat = "RGBA"; + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + } + pixels2DContext.drawImage(image, 0, 0); + data = pixels2DContext.getImageData(0, 0, width, height).data; + } else { + throw new Error("Can not access image data"); + } + } else if (isImageDataEle) { + let height; + let width; + if (options !== void 0 && options.resizedWidth !== void 0 && options.resizedHeight !== void 0) { + height = options.resizedHeight; + width = options.resizedWidth; + } else { + height = image.height; + width = image.width; + } + if (options !== void 0) { + bufferToTensorOptions = options; + } + bufferToTensorOptions.format = "RGBA"; + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + if (options !== void 0) { + const tempCanvas = createCanvas2(); + tempCanvas.width = width; + tempCanvas.height = height; + const pixels2DContext = createCanvasContext(tempCanvas); + if (pixels2DContext != null) { + pixels2DContext.putImageData(image, 0, 0); + data = pixels2DContext.getImageData(0, 0, width, height).data; + } else { + throw new Error("Can not access image data"); + } + } else { + data = image.data; + } + } else if (isImageBitmap) { + if (options === void 0) { + throw new Error("Please provide image config with format for Imagebitmap"); + } + const canvas = createCanvas2(); + canvas.width = image.width; + canvas.height = image.height; + const pixels2DContext = createCanvasContext(canvas); + if (pixels2DContext != null) { + const height = image.height; + const width = image.width; + pixels2DContext.drawImage(image, 0, 0, width, height); + data = pixels2DContext.getImageData(0, 0, width, height).data; + bufferToTensorOptions.height = height; + bufferToTensorOptions.width = width; + return bufferToTensor(data, bufferToTensorOptions); + } else { + throw new Error("Can not access image data"); + } + } else if (isString) { + return new Promise((resolve, reject) => { + const canvas = createCanvas2(); + const context = createCanvasContext(canvas); + if (!image || !context) { + return reject(); + } + const newImage = new Image(); + newImage.crossOrigin = "Anonymous"; + newImage.src = image; + newImage.onload = () => { + canvas.width = newImage.width; + canvas.height = newImage.height; + context.drawImage(newImage, 0, 0, canvas.width, canvas.height); + const img = context.getImageData(0, 0, canvas.width, canvas.height); + bufferToTensorOptions.height = canvas.height; + bufferToTensorOptions.width = canvas.width; + resolve(bufferToTensor(img.data, bufferToTensorOptions)); + }; + }); + } else { + throw new Error("Input data provided is not supported - aborted tensor creation"); + } + if (data !== void 0) { + return bufferToTensor(data, bufferToTensorOptions); + } else { + throw new Error("Input data provided is not supported - aborted tensor creation"); + } + }; + tensorFromTexture = (texture, options) => { + const { width, height, download, dispose } = options; + const dims = [1, height, width, 4]; + return new Tensor({ location: "texture", type: "float32", texture, dims, download, dispose }); + }; + tensorFromGpuBuffer = (gpuBuffer, options) => { + const { dataType, dims, download, dispose } = options; + return new Tensor({ location: "gpu-buffer", type: dataType ?? "float32", gpuBuffer, dims, download, dispose }); + }; + tensorFromPinnedBuffer = (type, buffer, dims) => new Tensor({ location: "cpu-pinned", type, data: buffer, dims: dims ?? [buffer.length] }); + } +}); + +// common/dist/esm/tensor-impl-type-mapping.js +var NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP, NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP, isTypedArrayChecked, checkTypedArray; +var init_tensor_impl_type_mapping = __esm({ + "common/dist/esm/tensor-impl-type-mapping.js"() { + "use strict"; + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP = /* @__PURE__ */ new Map([ + ["float32", Float32Array], + ["uint8", Uint8Array], + ["int8", Int8Array], + ["uint16", Uint16Array], + ["int16", Int16Array], + ["int32", Int32Array], + ["bool", Uint8Array], + ["float64", Float64Array], + ["uint32", Uint32Array] + ]); + NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP = /* @__PURE__ */ new Map([ + [Float32Array, "float32"], + [Uint8Array, "uint8"], + [Int8Array, "int8"], + [Uint16Array, "uint16"], + [Int16Array, "int16"], + [Int32Array, "int32"], + [Float64Array, "float64"], + [Uint32Array, "uint32"] + ]); + isTypedArrayChecked = false; + checkTypedArray = () => { + if (!isTypedArrayChecked) { + isTypedArrayChecked = true; + const isBigInt64ArrayAvailable = typeof BigInt64Array !== "undefined" && BigInt64Array.from; + const isBigUint64ArrayAvailable = typeof BigUint64Array !== "undefined" && BigUint64Array.from; + const isFloat16ArrayAvailable = typeof Float16Array !== "undefined" && Float16Array.from; + if (isBigInt64ArrayAvailable) { + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("int64", BigInt64Array); + NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(BigInt64Array, "int64"); + } + if (isBigUint64ArrayAvailable) { + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("uint64", BigUint64Array); + NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(BigUint64Array, "uint64"); + } + if (isFloat16ArrayAvailable) { + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("float16", Float16Array); + NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.set(Float16Array, "float16"); + } else { + NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.set("float16", Uint16Array); + } + } + }; + } +}); + +// common/dist/esm/tensor-utils-impl.js +var calculateSize, tensorReshape; +var init_tensor_utils_impl = __esm({ + "common/dist/esm/tensor-utils-impl.js"() { + "use strict"; + init_tensor_impl(); + calculateSize = (dims) => { + let size = 1; + for (let i = 0; i < dims.length; i++) { + const dim = dims[i]; + if (typeof dim !== "number" || !Number.isSafeInteger(dim)) { + throw new TypeError(`dims[${i}] must be an integer, got: ${dim}`); + } + if (dim < 0) { + throw new RangeError(`dims[${i}] must be a non-negative integer, got: ${dim}`); + } + size *= dim; + } + return size; + }; + tensorReshape = (tensor, dims) => { + switch (tensor.location) { + case "cpu": + return new Tensor(tensor.type, tensor.data, dims); + case "cpu-pinned": + return new Tensor({ + location: "cpu-pinned", + data: tensor.data, + type: tensor.type, + dims + }); + case "texture": + return new Tensor({ + location: "texture", + texture: tensor.texture, + type: tensor.type, + dims + }); + case "gpu-buffer": + return new Tensor({ + location: "gpu-buffer", + gpuBuffer: tensor.gpuBuffer, + type: tensor.type, + dims + }); + default: + throw new Error(`tensorReshape: tensor location ${tensor.location} is not supported`); + } + }; + } +}); + +// common/dist/esm/tensor-impl.js +var Tensor; +var init_tensor_impl = __esm({ + "common/dist/esm/tensor-impl.js"() { + "use strict"; + init_tensor_conversion_impl(); + init_tensor_factory_impl(); + init_tensor_impl_type_mapping(); + init_tensor_utils_impl(); + Tensor = class { + /** + * implementation. + */ + constructor(arg0, arg1, arg2) { + checkTypedArray(); + let type; + let dims; + if (typeof arg0 === "object" && "location" in arg0) { + this.dataLocation = arg0.location; + type = arg0.type; + dims = arg0.dims; + switch (arg0.location) { + case "cpu-pinned": { + const expectedTypedArrayConstructor = NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.get(type); + if (!expectedTypedArrayConstructor) { + throw new TypeError(`unsupported type "${type}" to create tensor from pinned buffer`); + } + if (!(arg0.data instanceof expectedTypedArrayConstructor)) { + throw new TypeError(`buffer should be of type ${expectedTypedArrayConstructor.name}`); + } + this.cpuData = arg0.data; + break; + } + case "texture": { + if (type !== "float32") { + throw new TypeError(`unsupported type "${type}" to create tensor from texture`); + } + this.gpuTextureData = arg0.texture; + this.downloader = arg0.download; + this.disposer = arg0.dispose; + break; + } + case "gpu-buffer": { + if (type !== "float32" && type !== "float16" && type !== "int32" && type !== "int64" && type !== "uint32" && type !== "uint8" && type !== "bool") { + throw new TypeError(`unsupported type "${type}" to create tensor from gpu buffer`); + } + this.gpuBufferData = arg0.gpuBuffer; + this.downloader = arg0.download; + this.disposer = arg0.dispose; + break; + } + default: + throw new Error(`Tensor constructor: unsupported location '${this.dataLocation}'`); + } + } else { + let data; + let maybeDims; + if (typeof arg0 === "string") { + type = arg0; + maybeDims = arg2; + if (arg0 === "string") { + if (!Array.isArray(arg1)) { + throw new TypeError("A string tensor's data must be a string array."); + } + data = arg1; + } else { + const typedArrayConstructor = NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.get(arg0); + if (typedArrayConstructor === void 0) { + throw new TypeError(`Unsupported tensor type: ${arg0}.`); + } + if (Array.isArray(arg1)) { + if (arg0 === "float16" && typedArrayConstructor === Uint16Array) { + throw new TypeError("Creating a float16 tensor from number array is not supported. Please use Uint16Array as data."); + } else if (arg0 === "uint64" || arg0 === "int64") { + data = typedArrayConstructor.from(arg1, BigInt); + } else { + data = typedArrayConstructor.from(arg1); + } + } else if (arg1 instanceof typedArrayConstructor) { + data = arg1; + } else { + throw new TypeError(`A ${type} tensor's data must be type of ${typedArrayConstructor}`); + } + } + } else { + maybeDims = arg1; + if (Array.isArray(arg0)) { + if (arg0.length === 0) { + throw new TypeError("Tensor type cannot be inferred from an empty array."); + } + const firstElementType = typeof arg0[0]; + if (firstElementType === "string") { + type = "string"; + data = arg0; + } else if (firstElementType === "boolean") { + type = "bool"; + data = Uint8Array.from(arg0); + } else { + throw new TypeError(`Invalid element type of data array: ${firstElementType}.`); + } + } else { + const mappedType = NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.get(arg0.constructor); + if (mappedType === void 0) { + throw new TypeError(`Unsupported type for tensor data: ${arg0.constructor}.`); + } + type = mappedType; + data = arg0; + } + } + if (maybeDims === void 0) { + maybeDims = [data.length]; + } else if (!Array.isArray(maybeDims)) { + throw new TypeError("A tensor's dims must be a number array"); + } + dims = maybeDims; + this.cpuData = data; + this.dataLocation = "cpu"; + } + const size = calculateSize(dims); + if (this.cpuData && size !== this.cpuData.length) { + throw new Error(`Tensor's size(${size}) does not match data length(${this.cpuData.length}).`); + } + this.type = type; + this.dims = dims; + this.size = size; + } + // #endregion + // #region factory + static async fromImage(image, options) { + return tensorFromImage(image, options); + } + static fromTexture(texture, options) { + return tensorFromTexture(texture, options); + } + static fromGpuBuffer(gpuBuffer, options) { + return tensorFromGpuBuffer(gpuBuffer, options); + } + static fromPinnedBuffer(type, buffer, dims) { + return tensorFromPinnedBuffer(type, buffer, dims); + } + // #endregion + // #region conversions + toDataURL(options) { + return tensorToDataURL(this, options); + } + toImageData(options) { + return tensorToImageData(this, options); + } + // #endregion + // #region properties + get data() { + this.ensureValid(); + if (!this.cpuData) { + throw new Error("The data is not on CPU. Use `getData()` to download GPU data to CPU, or use `texture` or `gpuBuffer` property to access the GPU data directly."); + } + return this.cpuData; + } + get location() { + return this.dataLocation; + } + get texture() { + this.ensureValid(); + if (!this.gpuTextureData) { + throw new Error("The data is not stored as a WebGL texture."); + } + return this.gpuTextureData; + } + get gpuBuffer() { + this.ensureValid(); + if (!this.gpuBufferData) { + throw new Error("The data is not stored as a WebGPU buffer."); + } + return this.gpuBufferData; + } + // #endregion + // #region methods + async getData(releaseData) { + this.ensureValid(); + switch (this.dataLocation) { + case "cpu": + case "cpu-pinned": + return this.data; + case "texture": + case "gpu-buffer": { + if (!this.downloader) { + throw new Error("The current tensor is not created with a specified data downloader."); + } + if (this.isDownloading) { + throw new Error("The current tensor is being downloaded."); + } + try { + this.isDownloading = true; + const data = await this.downloader(); + this.downloader = void 0; + this.dataLocation = "cpu"; + this.cpuData = data; + if (releaseData && this.disposer) { + this.disposer(); + this.disposer = void 0; + } + return data; + } finally { + this.isDownloading = false; + } + } + default: + throw new Error(`cannot get data from location: ${this.dataLocation}`); + } + } + dispose() { + if (this.isDownloading) { + throw new Error("The current tensor is being downloaded."); + } + if (this.disposer) { + this.disposer(); + this.disposer = void 0; + } + this.cpuData = void 0; + this.gpuTextureData = void 0; + this.gpuBufferData = void 0; + this.downloader = void 0; + this.isDownloading = void 0; + this.dataLocation = "none"; + } + // #endregion + // #region tensor utilities + ensureValid() { + if (this.dataLocation === "none") { + throw new Error("The tensor is disposed."); + } + } + reshape(dims) { + this.ensureValid(); + if (this.downloader || this.disposer) { + throw new Error("Cannot reshape a tensor that owns GPU resource."); + } + return tensorReshape(this, dims); + } + }; + } +}); + +// common/dist/esm/tensor.js +var Tensor2; +var init_tensor = __esm({ + "common/dist/esm/tensor.js"() { + "use strict"; + init_tensor_impl(); + Tensor2 = Tensor; + } +}); + +// common/dist/esm/trace.js +var TRACE, TRACE_FUNC, TRACE_FUNC_BEGIN, TRACE_FUNC_END; +var init_trace = __esm({ + "common/dist/esm/trace.js"() { + "use strict"; + init_env_impl(); + TRACE = (deviceType, label) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + console.timeStamp(`${deviceType}::ORT::${label}`); + }; + TRACE_FUNC = (msg, extraMsg) => { + const stack = new Error().stack?.split(/\r\n|\r|\n/g) || []; + let hasTraceFunc = false; + for (let i = 0; i < stack.length; i++) { + if (hasTraceFunc && !stack[i].includes("TRACE_FUNC")) { + let label = `FUNC_${msg}::${stack[i].trim().split(" ")[1]}`; + if (extraMsg) { + label += `::${extraMsg}`; + } + TRACE("CPU", label); + return; + } + if (stack[i].includes("TRACE_FUNC")) { + hasTraceFunc = true; + } + } + }; + TRACE_FUNC_BEGIN = (extraMsg) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + TRACE_FUNC("BEGIN", extraMsg); + }; + TRACE_FUNC_END = (extraMsg) => { + if (typeof env.trace === "undefined" ? !env.wasm.trace : !env.trace) { + return; + } + TRACE_FUNC("END", extraMsg); + }; + } +}); + +// common/dist/esm/inference-session-impl.js +var InferenceSession; +var init_inference_session_impl = __esm({ + "common/dist/esm/inference-session-impl.js"() { + "use strict"; + init_backend_impl(); + init_tensor(); + init_trace(); + InferenceSession = class _InferenceSession { + constructor(handler) { + this.handler = handler; + } + async run(feeds, arg1, arg2) { + TRACE_FUNC_BEGIN(); + const fetches = {}; + let options = {}; + if (typeof feeds !== "object" || feeds === null || feeds instanceof Tensor2 || Array.isArray(feeds)) { + throw new TypeError("'feeds' must be an object that use input names as keys and OnnxValue as corresponding values."); + } + let isFetchesEmpty = true; + if (typeof arg1 === "object") { + if (arg1 === null) { + throw new TypeError("Unexpected argument[1]: cannot be null."); + } + if (arg1 instanceof Tensor2) { + throw new TypeError("'fetches' cannot be a Tensor"); + } + if (Array.isArray(arg1)) { + if (arg1.length === 0) { + throw new TypeError("'fetches' cannot be an empty array."); + } + isFetchesEmpty = false; + for (const name2 of arg1) { + if (typeof name2 !== "string") { + throw new TypeError("'fetches' must be a string array or an object."); + } + if (this.outputNames.indexOf(name2) === -1) { + throw new RangeError(`'fetches' contains invalid output name: ${name2}.`); + } + fetches[name2] = null; + } + if (typeof arg2 === "object" && arg2 !== null) { + options = arg2; + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else { + let isFetches = false; + const arg1Keys = Object.getOwnPropertyNames(arg1); + for (const name2 of this.outputNames) { + if (arg1Keys.indexOf(name2) !== -1) { + const v = arg1[name2]; + if (v === null || v instanceof Tensor2) { + isFetches = true; + isFetchesEmpty = false; + fetches[name2] = v; + } + } + } + if (isFetches) { + if (typeof arg2 === "object" && arg2 !== null) { + options = arg2; + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else { + options = arg1; + } + } + } else if (typeof arg1 !== "undefined") { + throw new TypeError("Unexpected argument[1]: must be 'fetches' or 'options'."); + } + for (const name2 of this.inputNames) { + if (typeof feeds[name2] === "undefined") { + throw new Error(`input '${name2}' is missing in 'feeds'.`); + } + } + if (isFetchesEmpty) { + for (const name2 of this.outputNames) { + fetches[name2] = null; + } + } + const results = await this.handler.run(feeds, fetches, options); + const returnValue = {}; + for (const key in results) { + if (Object.hasOwnProperty.call(results, key)) { + const result = results[key]; + if (result instanceof Tensor2) { + returnValue[key] = result; + } else { + returnValue[key] = new Tensor2(result.type, result.data, result.dims); + } + } + } + TRACE_FUNC_END(); + return returnValue; + } + async release() { + return this.handler.dispose(); + } + static async create(arg0, arg1, arg2, arg3) { + TRACE_FUNC_BEGIN(); + let filePathOrUint8Array; + let options = {}; + if (typeof arg0 === "string") { + filePathOrUint8Array = arg0; + if (typeof arg1 === "object" && arg1 !== null) { + options = arg1; + } else if (typeof arg1 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else if (arg0 instanceof Uint8Array) { + filePathOrUint8Array = arg0; + if (typeof arg1 === "object" && arg1 !== null) { + options = arg1; + } else if (typeof arg1 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else if (arg0 instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && arg0 instanceof SharedArrayBuffer) { + const buffer = arg0; + let byteOffset = 0; + let byteLength = arg0.byteLength; + if (typeof arg1 === "object" && arg1 !== null) { + options = arg1; + } else if (typeof arg1 === "number") { + byteOffset = arg1; + if (!Number.isSafeInteger(byteOffset)) { + throw new RangeError("'byteOffset' must be an integer."); + } + if (byteOffset < 0 || byteOffset >= buffer.byteLength) { + throw new RangeError(`'byteOffset' is out of range [0, ${buffer.byteLength}).`); + } + byteLength = arg0.byteLength - byteOffset; + if (typeof arg2 === "number") { + byteLength = arg2; + if (!Number.isSafeInteger(byteLength)) { + throw new RangeError("'byteLength' must be an integer."); + } + if (byteLength <= 0 || byteOffset + byteLength > buffer.byteLength) { + throw new RangeError(`'byteLength' is out of range (0, ${buffer.byteLength - byteOffset}].`); + } + if (typeof arg3 === "object" && arg3 !== null) { + options = arg3; + } else if (typeof arg3 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'byteLength' must be a number."); + } + } else if (typeof arg1 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + filePathOrUint8Array = new Uint8Array(buffer, byteOffset, byteLength); + } else { + throw new TypeError("Unexpected argument[0]: must be 'path' or 'buffer'."); + } + const [backend2, optionsWithValidatedEPs] = await resolveBackendAndExecutionProviders(options); + const handler = await backend2.createInferenceSessionHandler(filePathOrUint8Array, optionsWithValidatedEPs); + TRACE_FUNC_END(); + return new _InferenceSession(handler); + } + startProfiling() { + this.handler.startProfiling(); + } + endProfiling() { + this.handler.endProfiling(); + } + get inputNames() { + return this.handler.inputNames; + } + get outputNames() { + return this.handler.outputNames; + } + }; + } +}); + +// common/dist/esm/inference-session.js +var InferenceSession2; +var init_inference_session = __esm({ + "common/dist/esm/inference-session.js"() { + "use strict"; + init_inference_session_impl(); + InferenceSession2 = InferenceSession; + } +}); + +// common/dist/esm/tensor-conversion.js +var init_tensor_conversion = __esm({ + "common/dist/esm/tensor-conversion.js"() { + "use strict"; + } +}); + +// common/dist/esm/tensor-factory.js +var init_tensor_factory = __esm({ + "common/dist/esm/tensor-factory.js"() { + "use strict"; + } +}); + +// common/dist/esm/onnx-model.js +var init_onnx_model = __esm({ + "common/dist/esm/onnx-model.js"() { + "use strict"; + } +}); + +// common/dist/esm/onnx-value.js +var init_onnx_value = __esm({ + "common/dist/esm/onnx-value.js"() { + "use strict"; + } +}); + +// common/dist/esm/training-session-impl.js +var noBackendErrMsg, TrainingSession; +var init_training_session_impl = __esm({ + "common/dist/esm/training-session-impl.js"() { + "use strict"; + init_backend_impl(); + init_tensor(); + noBackendErrMsg = "Training backend could not be resolved. Make sure you're using the correct configuration & WebAssembly files."; + TrainingSession = class _TrainingSession { + constructor(handler, hasOptimizerModel, hasEvalModel) { + this.handler = handler; + this.hasOptimizerModel = hasOptimizerModel; + this.hasEvalModel = hasEvalModel; + } + get trainingInputNames() { + return this.handler.inputNames; + } + get trainingOutputNames() { + return this.handler.outputNames; + } + get evalInputNames() { + if (this.hasEvalModel) { + return this.handler.evalInputNames; + } else { + throw new Error("This training session has no evalModel loaded."); + } + } + get evalOutputNames() { + if (this.hasEvalModel) { + return this.handler.evalOutputNames; + } else { + throw new Error("This training session has no evalModel loaded."); + } + } + static async create(trainingOptions, sessionOptions) { + const evalModel = trainingOptions.evalModel || ""; + const optimizerModel = trainingOptions.optimizerModel || ""; + const options = sessionOptions || {}; + const [backend2, optionsWithValidatedEPs] = await resolveBackendAndExecutionProviders(options); + if (backend2.createTrainingSessionHandler) { + const handler = await backend2.createTrainingSessionHandler(trainingOptions.checkpointState, trainingOptions.trainModel, evalModel, optimizerModel, optionsWithValidatedEPs); + return new _TrainingSession(handler, !!trainingOptions.optimizerModel, !!trainingOptions.evalModel); + } else { + throw new Error(noBackendErrMsg); + } + } + /** + * Helper function for runTrainStep and future runStep methods that handles the type-narrowing conversion from + * the given parameters to SessionHandler.FetchesType and RunOptions. + * + * @param inputNames the feeds object is checked that they contain all input names in the provided list of input + * names. + * @param outputNames the fetches object is checked that their keys match up with valid names in the list of output + * names. + * @param feeds the required input + * @param arg1 narrowed & converted into the SessionHandler.FetchesType or RunOptions object + * @param arg2 optional RunOptions object. + * @returns + */ + typeNarrowingForRunStep(inputNames, outputNames, feeds, arg1, arg2) { + const fetches = {}; + let options = {}; + if (typeof feeds !== "object" || feeds === null || feeds instanceof Tensor2 || Array.isArray(feeds)) { + throw new TypeError("'feeds' must be an object that use input names as keys and OnnxValue as corresponding values."); + } + let isFetchesEmpty = true; + if (typeof arg1 === "object") { + if (arg1 === null) { + throw new TypeError("Unexpected argument[1]: cannot be null."); + } + if (arg1 instanceof Tensor2) { + throw new TypeError("'fetches' cannot be a Tensor"); + } + if (Array.isArray(arg1)) { + if (arg1.length === 0) { + throw new TypeError("'fetches' cannot be an empty array."); + } + isFetchesEmpty = false; + for (const name2 of arg1) { + if (typeof name2 !== "string") { + throw new TypeError("'fetches' must be a string array or an object."); + } + if (outputNames.indexOf(name2) === -1) { + throw new RangeError(`'fetches' contains invalid output name: ${name2}.`); + } + fetches[name2] = null; + } + if (typeof arg2 === "object" && arg2 !== null) { + options = arg2; + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else { + let isFetches = false; + const arg1Keys = Object.getOwnPropertyNames(arg1); + for (const name2 of outputNames) { + if (arg1Keys.indexOf(name2) !== -1) { + const v = arg1[name2]; + if (v === null || v instanceof Tensor2) { + isFetches = true; + isFetchesEmpty = false; + fetches[name2] = v; + } + } + } + if (isFetches) { + if (typeof arg2 === "object" && arg2 !== null) { + options = arg2; + } else if (typeof arg2 !== "undefined") { + throw new TypeError("'options' must be an object."); + } + } else { + options = arg1; + } + } + } else if (typeof arg1 !== "undefined") { + throw new TypeError("Unexpected argument[1]: must be 'fetches' or 'options'."); + } + for (const name2 of inputNames) { + if (typeof feeds[name2] === "undefined") { + throw new Error(`input '${name2}' is missing in 'feeds'.`); + } + } + if (isFetchesEmpty) { + for (const name2 of outputNames) { + fetches[name2] = null; + } + } + return [fetches, options]; + } + /** + * Helper method for runTrainStep and any other runStep methods. Takes the ReturnType result from the SessionHandler + * and changes it into a map of Tensors. + * + * @param results + * @returns + */ + convertHandlerReturnTypeToMapOfTensors(results) { + const returnValue = {}; + for (const key in results) { + if (Object.hasOwnProperty.call(results, key)) { + const result = results[key]; + if (result instanceof Tensor2) { + returnValue[key] = result; + } else { + returnValue[key] = new Tensor2(result.type, result.data, result.dims); + } + } + } + return returnValue; + } + async lazyResetGrad() { + await this.handler.lazyResetGrad(); + } + async runTrainStep(feeds, arg1, arg2) { + const [fetches, options] = this.typeNarrowingForRunStep(this.trainingInputNames, this.trainingOutputNames, feeds, arg1, arg2); + const results = await this.handler.runTrainStep(feeds, fetches, options); + return this.convertHandlerReturnTypeToMapOfTensors(results); + } + async runOptimizerStep(options) { + if (this.hasOptimizerModel) { + await this.handler.runOptimizerStep(options || {}); + } else { + throw new Error("This TrainingSession has no OptimizerModel loaded."); + } + } + async runEvalStep(feeds, arg1, arg2) { + if (this.hasEvalModel) { + const [fetches, options] = this.typeNarrowingForRunStep(this.evalInputNames, this.evalOutputNames, feeds, arg1, arg2); + const results = await this.handler.runEvalStep(feeds, fetches, options); + return this.convertHandlerReturnTypeToMapOfTensors(results); + } else { + throw new Error("This TrainingSession has no EvalModel loaded."); + } + } + async getParametersSize(trainableOnly = true) { + return this.handler.getParametersSize(trainableOnly); + } + async loadParametersBuffer(array, trainableOnly = true) { + const paramsSize = await this.getParametersSize(trainableOnly); + if (array.length !== 4 * paramsSize) { + throw new Error("Size of the buffer passed into loadParametersBuffer must match the number of parameters in the model. Please use getParametersSize method to check."); + } + return this.handler.loadParametersBuffer(array, trainableOnly); + } + async getContiguousParameters(trainableOnly = true) { + return this.handler.getContiguousParameters(trainableOnly); + } + async release() { + return this.handler.dispose(); + } + }; + } +}); + +// common/dist/esm/training-session.js +var TrainingSession2; +var init_training_session = __esm({ + "common/dist/esm/training-session.js"() { + "use strict"; + init_training_session_impl(); + TrainingSession2 = TrainingSession; + } +}); + +// common/dist/esm/index.js +var esm_exports = {}; +__export(esm_exports, { + InferenceSession: () => InferenceSession2, + TRACE: () => TRACE, + TRACE_FUNC_BEGIN: () => TRACE_FUNC_BEGIN, + TRACE_FUNC_END: () => TRACE_FUNC_END, + Tensor: () => Tensor2, + TrainingSession: () => TrainingSession2, + env: () => env2, + registerBackend: () => registerBackend +}); +var init_esm = __esm({ + "common/dist/esm/index.js"() { + "use strict"; + init_backend(); + init_env(); + init_inference_session(); + init_tensor(); + init_tensor_conversion(); + init_tensor_factory(); + init_trace(); + init_onnx_model(); + init_onnx_value(); + init_training_session(); + } +}); + +// nodejs-ignore:node:fs/promises +var readFile; +var init_promises = __esm({ + "nodejs-ignore:node:fs/promises"() { + readFile = void 0; + } +}); + +// web/lib/onnxjs/instrument.ts +function log(arg0, arg1, arg2, arg3) { + if (arg1 === void 0) { + return createCategorizedLogger(arg0); + } else if (arg2 === void 0) { + logInternal(arg0, arg1, 1); + } else if (typeof arg2 === "number" && arg3 === void 0) { + logInternal(arg0, arg1, arg2); + } else if (typeof arg2 === "string" && arg3 === void 0) { + logInternal(arg0, arg2, 1, arg1); + } else if (typeof arg2 === "string" && typeof arg3 === "number") { + logInternal(arg0, arg2, arg3, arg1); + } else { + throw new TypeError("input is valid"); + } +} +function createCategorizedLogger(category) { + return { + verbose: log.verbose.bind(null, category), + info: log.info.bind(null, category), + warning: log.warning.bind(null, category), + error: log.error.bind(null, category), + fatal: log.fatal.bind(null, category) + }; +} +function logInternal(severity, content, _stack, category) { + const config = LOGGER_CONFIG_MAP[category || ""] || LOGGER_CONFIG_MAP[""]; + if (SEVERITY_VALUE[severity] < SEVERITY_VALUE[config.minimalSeverity]) { + return; + } + if (config.logDateTime) { + content = `${(/* @__PURE__ */ new Date()).toISOString()}|${content}`; + } + if (config.logSourceLocation) { + } + LOGGER_PROVIDER_MAP[config.provider].log(severity, content, category); +} +var NoOpLoggerProvider, ConsoleLoggerProvider, SEVERITY_VALUE, LOGGER_PROVIDER_MAP, LOGGER_DEFAULT_CONFIG, LOGGER_CONFIG_MAP, Logger, Event, EventRecord, Profiler, now; +var init_instrument = __esm({ + "web/lib/onnxjs/instrument.ts"() { + "use strict"; + NoOpLoggerProvider = class { + log(_severity, _content, _category) { + } + }; + ConsoleLoggerProvider = class { + log(severity, content, category) { + console.log(`${this.color(severity)} ${category ? "\x1B[35m" + category + "\x1B[0m " : ""}${content}`); + } + color(severity) { + switch (severity) { + case "verbose": + return "\x1B[34;40mv\x1B[0m"; + case "info": + return "\x1B[32mi\x1B[0m"; + case "warning": + return "\x1B[30;43mw\x1B[0m"; + case "error": + return "\x1B[31;40me\x1B[0m"; + case "fatal": + return "\x1B[101mf\x1B[0m"; + default: + throw new Error(`unsupported severity: ${severity}`); + } + } + }; + SEVERITY_VALUE = { + verbose: 1e3, + info: 2e3, + warning: 4e3, + error: 5e3, + fatal: 6e3 + }; + LOGGER_PROVIDER_MAP = { + ["none"]: new NoOpLoggerProvider(), + ["console"]: new ConsoleLoggerProvider() + }; + LOGGER_DEFAULT_CONFIG = { + provider: "console", + minimalSeverity: "warning", + logDateTime: true, + logSourceLocation: false + }; + LOGGER_CONFIG_MAP = { [""]: LOGGER_DEFAULT_CONFIG }; + ((log3) => { + function verbose(arg0, arg1) { + log3("verbose", arg0, arg1); + } + log3.verbose = verbose; + function info(arg0, arg1) { + log3("info", arg0, arg1); + } + log3.info = info; + function warning(arg0, arg1) { + log3("warning", arg0, arg1); + } + log3.warning = warning; + function error(arg0, arg1) { + log3("error", arg0, arg1); + } + log3.error = error; + function fatal(arg0, arg1) { + log3("fatal", arg0, arg1); + } + log3.fatal = fatal; + function reset(config) { + LOGGER_CONFIG_MAP = {}; + set("", config || {}); + } + log3.reset = reset; + function set(category, config) { + if (category === "*") { + reset(config); + } else { + const previousConfig = LOGGER_CONFIG_MAP[category] || LOGGER_DEFAULT_CONFIG; + LOGGER_CONFIG_MAP[category] = { + provider: config.provider || previousConfig.provider, + minimalSeverity: config.minimalSeverity || previousConfig.minimalSeverity, + logDateTime: config.logDateTime === void 0 ? previousConfig.logDateTime : config.logDateTime, + logSourceLocation: config.logSourceLocation === void 0 ? previousConfig.logSourceLocation : config.logSourceLocation + }; + } + } + log3.set = set; + function setWithEnv(env3) { + const config = {}; + if (env3.logLevel) { + config.minimalSeverity = env3.logLevel; + } + set("", config); + } + log3.setWithEnv = setWithEnv; + })(log || (log = {})); + Logger = log; + Event = class { + constructor(category, name2, startTime, endCallback, timer, ctx) { + this.category = category; + this.name = name2; + this.startTime = startTime; + this.endCallback = endCallback; + this.timer = timer; + this.ctx = ctx; + } + async end() { + return this.endCallback(this); + } + async checkTimer() { + if (this.ctx === void 0 || this.timer === void 0) { + throw new Error("No webgl timer found"); + } else { + this.ctx.endTimer(); + return this.ctx.waitForQueryAndGetTime(this.timer); + } + } + }; + EventRecord = class { + constructor(category, name2, startTime, endTime) { + this.category = category; + this.name = name2; + this.startTime = startTime; + this.endTime = endTime; + } + }; + Profiler = class { + constructor(maxNumberEvents, flushBatchSize, flushIntervalInMilliseconds) { + this._started = false; + this._flushPointer = 0; + this._started = false; + this._maxNumberEvents = maxNumberEvents === void 0 ? 1e4 : maxNumberEvents; + this._flushBatchSize = flushBatchSize === void 0 ? 10 : flushBatchSize; + this._flushIntervalInMilliseconds = flushIntervalInMilliseconds === void 0 ? 5e3 : flushIntervalInMilliseconds; + } + static create(config) { + if (config === void 0) { + return new this(); + } + return new this(config.maxNumberEvents, config.flushBatchSize, config.flushIntervalInMilliseconds); + } + // start profiling + start() { + this._started = true; + this._timingEvents = []; + this._flushTime = now(); + this._flushPointer = 0; + } + // stop profiling + stop() { + this._started = false; + for (; this._flushPointer < this._timingEvents.length; this._flushPointer++) { + this.logOneEvent(this._timingEvents[this._flushPointer]); + } + } + event(category, name2, func, ctx) { + const event = this._started ? this.begin(category, name2, ctx) : void 0; + let isPromise = false; + const res = func(); + if (res && typeof res.then === "function") { + isPromise = true; + return new Promise((resolve, reject) => { + res.then( + async (value) => { + if (event) { + await event.end(); + } + resolve(value); + }, + async (reason) => { + if (event) { + await event.end(); + } + reject(reason); + } + ); + }); + } + if (!isPromise && event) { + const eventRes = event.end(); + if (eventRes && typeof eventRes.then === "function") { + return new Promise((resolve, reject) => { + eventRes.then( + () => { + resolve(res); + }, + (reason) => { + reject(reason); + } + ); + }); + } + } + return res; + } + // begin an event + begin(category, name2, ctx) { + if (!this._started) { + throw new Error("profiler is not started yet"); + } + if (ctx === void 0) { + const startTime = now(); + this.flush(startTime); + return new Event(category, name2, startTime, (e) => this.endSync(e)); + } else { + const timer = ctx.beginTimer(); + return new Event(category, name2, 0, async (e) => this.end(e), timer, ctx); + } + } + // end the specific event + async end(event) { + const endTime = await event.checkTimer(); + if (this._timingEvents.length < this._maxNumberEvents) { + this._timingEvents.push(new EventRecord(event.category, event.name, event.startTime, endTime)); + this.flush(endTime); + } + } + endSync(event) { + const endTime = now(); + if (this._timingEvents.length < this._maxNumberEvents) { + this._timingEvents.push(new EventRecord(event.category, event.name, event.startTime, endTime)); + this.flush(endTime); + } + } + logOneEvent(event) { + Logger.verbose( + `Profiler.${event.category}`, + `${(event.endTime - event.startTime).toFixed(2)}ms on event '${event.name}' at ${event.endTime.toFixed(2)}` + ); + } + flush(currentTime) { + if (this._timingEvents.length - this._flushPointer >= this._flushBatchSize || currentTime - this._flushTime >= this._flushIntervalInMilliseconds) { + for (const previousPointer = this._flushPointer; this._flushPointer < previousPointer + this._flushBatchSize && this._flushPointer < this._timingEvents.length; this._flushPointer++) { + this.logOneEvent(this._timingEvents[this._flushPointer]); + } + this._flushTime = now(); + } + } + get started() { + return this._started; + } + }; + now = typeof performance !== "undefined" && performance.now ? () => performance.now() : Date.now; + } +}); + +// web/lib/onnxjs/opset.ts +function resolveOperator(node, opsets, rules) { + for (const rule of rules) { + const opType = rule[0]; + const domain = rule[1]; + const versionSelector = rule[2]; + const opImpl = rule[3]; + const opInit = rule[4]; + if (node.opType === opType) { + for (const opset of opsets) { + if (opset.domain === domain || opset.domain === "ai.onnx" && domain === "") { + if (matchSelector(opset.version, versionSelector)) { + return { opImpl, opInit }; + } + } + } + } + } + throw new TypeError(`cannot resolve operator '${node.opType}' with opsets: ${opsets.map((set) => `${set.domain || "ai.onnx"} v${set.version}`).join(", ")}`); +} +function matchSelector(version3, selector) { + if (selector.endsWith("+")) { + const rangeStart = Number.parseInt(selector.substring(0, selector.length - 1), 10); + return !isNaN(rangeStart) && rangeStart <= version3; + } else if (selector.split("-").length === 2) { + const pair = selector.split("-"); + const rangeStart = Number.parseInt(pair[0], 10); + const rangeEnd = Number.parseInt(pair[1], 10); + return !isNaN(rangeStart) && !isNaN(rangeEnd) && rangeStart <= version3 && version3 <= rangeEnd; + } else { + return Number.parseInt(selector, 10) === version3; + } +} +var init_opset = __esm({ + "web/lib/onnxjs/opset.ts"() { + "use strict"; + } +}); + +// web/node_modules/guid-typescript/dist/guid.js +var require_guid = __commonJS({ + "web/node_modules/guid-typescript/dist/guid.js"(exports2) { + "use strict"; + exports2.__esModule = true; + var Guid2 = ( + /** @class */ + function() { + function Guid3(guid) { + if (!guid) { + throw new TypeError("Invalid argument; `value` has no value."); + } + this.value = Guid3.EMPTY; + if (guid && Guid3.isGuid(guid)) { + this.value = guid; + } + } + Guid3.isGuid = function(guid) { + var value = guid.toString(); + return guid && (guid instanceof Guid3 || Guid3.validator.test(value)); + }; + Guid3.create = function() { + return new Guid3([Guid3.gen(2), Guid3.gen(1), Guid3.gen(1), Guid3.gen(1), Guid3.gen(3)].join("-")); + }; + Guid3.createEmpty = function() { + return new Guid3("emptyguid"); + }; + Guid3.parse = function(guid) { + return new Guid3(guid); + }; + Guid3.raw = function() { + return [Guid3.gen(2), Guid3.gen(1), Guid3.gen(1), Guid3.gen(1), Guid3.gen(3)].join("-"); + }; + Guid3.gen = function(count) { + var out = ""; + for (var i = 0; i < count; i++) { + out += ((1 + Math.random()) * 65536 | 0).toString(16).substring(1); + } + return out; + }; + Guid3.prototype.equals = function(other) { + return Guid3.isGuid(other) && this.value === other.toString(); + }; + Guid3.prototype.isEmpty = function() { + return this.value === Guid3.EMPTY; + }; + Guid3.prototype.toString = function() { + return this.value; + }; + Guid3.prototype.toJSON = function() { + return { + value: this.value + }; + }; + Guid3.validator = new RegExp("^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$", "i"); + Guid3.EMPTY = "00000000-0000-0000-0000-000000000000"; + return Guid3; + }() + ); + exports2.Guid = Guid2; + } +}); + +// web/node_modules/long/index.js +function Long(low, high, unsigned) { + this.low = low | 0; + this.high = high | 0; + this.unsigned = !!unsigned; +} +function isLong(obj) { + return (obj && obj["__isLong__"]) === true; +} +function ctz32(value) { + var c = Math.clz32(value & -value); + return value ? 31 - c : c; +} +function fromInt(value, unsigned) { + var obj, cachedObj, cache2; + if (unsigned) { + value >>>= 0; + if (cache2 = 0 <= value && value < 256) { + cachedObj = UINT_CACHE[value]; + if (cachedObj) + return cachedObj; + } + obj = fromBits(value, 0, true); + if (cache2) + UINT_CACHE[value] = obj; + return obj; + } else { + value |= 0; + if (cache2 = -128 <= value && value < 128) { + cachedObj = INT_CACHE[value]; + if (cachedObj) + return cachedObj; + } + obj = fromBits(value, value < 0 ? -1 : 0, false); + if (cache2) + INT_CACHE[value] = obj; + return obj; + } +} +function fromNumber(value, unsigned) { + if (isNaN(value)) + return unsigned ? UZERO : ZERO; + if (unsigned) { + if (value < 0) + return UZERO; + if (value >= TWO_PWR_64_DBL) + return MAX_UNSIGNED_VALUE; + } else { + if (value <= -TWO_PWR_63_DBL) + return MIN_VALUE; + if (value + 1 >= TWO_PWR_63_DBL) + return MAX_VALUE; + } + if (value < 0) + return fromNumber(-value, unsigned).neg(); + return fromBits(value % TWO_PWR_32_DBL | 0, value / TWO_PWR_32_DBL | 0, unsigned); +} +function fromBits(lowBits, highBits, unsigned) { + return new Long(lowBits, highBits, unsigned); +} +function fromString(str, unsigned, radix) { + if (str.length === 0) + throw Error("empty string"); + if (typeof unsigned === "number") { + radix = unsigned; + unsigned = false; + } else { + unsigned = !!unsigned; + } + if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity") + return unsigned ? UZERO : ZERO; + radix = radix || 10; + if (radix < 2 || 36 < radix) + throw RangeError("radix"); + var p; + if ((p = str.indexOf("-")) > 0) + throw Error("interior hyphen"); + else if (p === 0) { + return fromString(str.substring(1), unsigned, radix).neg(); + } + var radixToPower = fromNumber(pow_dbl(radix, 8)); + var result = ZERO; + for (var i = 0; i < str.length; i += 8) { + var size = Math.min(8, str.length - i), value = parseInt(str.substring(i, i + size), radix); + if (size < 8) { + var power = fromNumber(pow_dbl(radix, size)); + result = result.mul(power).add(fromNumber(value)); + } else { + result = result.mul(radixToPower); + result = result.add(fromNumber(value)); + } + } + result.unsigned = unsigned; + return result; +} +function fromValue(val, unsigned) { + if (typeof val === "number") + return fromNumber(val, unsigned); + if (typeof val === "string") + return fromString(val, unsigned); + return fromBits(val.low, val.high, typeof unsigned === "boolean" ? unsigned : val.unsigned); +} +var wasm, INT_CACHE, UINT_CACHE, pow_dbl, TWO_PWR_16_DBL, TWO_PWR_24_DBL, TWO_PWR_32_DBL, TWO_PWR_64_DBL, TWO_PWR_63_DBL, TWO_PWR_24, ZERO, UZERO, ONE, UONE, NEG_ONE, MAX_VALUE, MAX_UNSIGNED_VALUE, MIN_VALUE, LongPrototype, long_default; +var init_long = __esm({ + "web/node_modules/long/index.js"() { + wasm = null; + try { + wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([ + 0, + 97, + 115, + 109, + 1, + 0, + 0, + 0, + 1, + 13, + 2, + 96, + 0, + 1, + 127, + 96, + 4, + 127, + 127, + 127, + 127, + 1, + 127, + 3, + 7, + 6, + 0, + 1, + 1, + 1, + 1, + 1, + 6, + 6, + 1, + 127, + 1, + 65, + 0, + 11, + 7, + 50, + 6, + 3, + 109, + 117, + 108, + 0, + 1, + 5, + 100, + 105, + 118, + 95, + 115, + 0, + 2, + 5, + 100, + 105, + 118, + 95, + 117, + 0, + 3, + 5, + 114, + 101, + 109, + 95, + 115, + 0, + 4, + 5, + 114, + 101, + 109, + 95, + 117, + 0, + 5, + 8, + 103, + 101, + 116, + 95, + 104, + 105, + 103, + 104, + 0, + 0, + 10, + 191, + 1, + 6, + 4, + 0, + 35, + 0, + 11, + 36, + 1, + 1, + 126, + 32, + 0, + 173, + 32, + 1, + 173, + 66, + 32, + 134, + 132, + 32, + 2, + 173, + 32, + 3, + 173, + 66, + 32, + 134, + 132, + 126, + 34, + 4, + 66, + 32, + 135, + 167, + 36, + 0, + 32, + 4, + 167, + 11, + 36, + 1, + 1, + 126, + 32, + 0, + 173, + 32, + 1, + 173, + 66, + 32, + 134, + 132, + 32, + 2, + 173, + 32, + 3, + 173, + 66, + 32, + 134, + 132, + 127, + 34, + 4, + 66, + 32, + 135, + 167, + 36, + 0, + 32, + 4, + 167, + 11, + 36, + 1, + 1, + 126, + 32, + 0, + 173, + 32, + 1, + 173, + 66, + 32, + 134, + 132, + 32, + 2, + 173, + 32, + 3, + 173, + 66, + 32, + 134, + 132, + 128, + 34, + 4, + 66, + 32, + 135, + 167, + 36, + 0, + 32, + 4, + 167, + 11, + 36, + 1, + 1, + 126, + 32, + 0, + 173, + 32, + 1, + 173, + 66, + 32, + 134, + 132, + 32, + 2, + 173, + 32, + 3, + 173, + 66, + 32, + 134, + 132, + 129, + 34, + 4, + 66, + 32, + 135, + 167, + 36, + 0, + 32, + 4, + 167, + 11, + 36, + 1, + 1, + 126, + 32, + 0, + 173, + 32, + 1, + 173, + 66, + 32, + 134, + 132, + 32, + 2, + 173, + 32, + 3, + 173, + 66, + 32, + 134, + 132, + 130, + 34, + 4, + 66, + 32, + 135, + 167, + 36, + 0, + 32, + 4, + 167, + 11 + ])), {}).exports; + } catch (e) { + } + Long.prototype.__isLong__; + Object.defineProperty(Long.prototype, "__isLong__", { value: true }); + Long.isLong = isLong; + INT_CACHE = {}; + UINT_CACHE = {}; + Long.fromInt = fromInt; + Long.fromNumber = fromNumber; + Long.fromBits = fromBits; + pow_dbl = Math.pow; + Long.fromString = fromString; + Long.fromValue = fromValue; + TWO_PWR_16_DBL = 1 << 16; + TWO_PWR_24_DBL = 1 << 24; + TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL; + TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL; + TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2; + TWO_PWR_24 = fromInt(TWO_PWR_24_DBL); + ZERO = fromInt(0); + Long.ZERO = ZERO; + UZERO = fromInt(0, true); + Long.UZERO = UZERO; + ONE = fromInt(1); + Long.ONE = ONE; + UONE = fromInt(1, true); + Long.UONE = UONE; + NEG_ONE = fromInt(-1); + Long.NEG_ONE = NEG_ONE; + MAX_VALUE = fromBits(4294967295 | 0, 2147483647 | 0, false); + Long.MAX_VALUE = MAX_VALUE; + MAX_UNSIGNED_VALUE = fromBits(4294967295 | 0, 4294967295 | 0, true); + Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE; + MIN_VALUE = fromBits(0, 2147483648 | 0, false); + Long.MIN_VALUE = MIN_VALUE; + LongPrototype = Long.prototype; + LongPrototype.toInt = function toInt() { + return this.unsigned ? this.low >>> 0 : this.low; + }; + LongPrototype.toNumber = function toNumber() { + if (this.unsigned) + return (this.high >>> 0) * TWO_PWR_32_DBL + (this.low >>> 0); + return this.high * TWO_PWR_32_DBL + (this.low >>> 0); + }; + LongPrototype.toString = function toString(radix) { + radix = radix || 10; + if (radix < 2 || 36 < radix) + throw RangeError("radix"); + if (this.isZero()) + return "0"; + if (this.isNegative()) { + if (this.eq(MIN_VALUE)) { + var radixLong = fromNumber(radix), div2 = this.div(radixLong), rem1 = div2.mul(radixLong).sub(this); + return div2.toString(radix) + rem1.toInt().toString(radix); + } else + return "-" + this.neg().toString(radix); + } + var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned), rem = this; + var result = ""; + while (true) { + var remDiv = rem.div(radixToPower), intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0, digits = intval.toString(radix); + rem = remDiv; + if (rem.isZero()) + return digits + result; + else { + while (digits.length < 6) + digits = "0" + digits; + result = "" + digits + result; + } + } + }; + LongPrototype.getHighBits = function getHighBits() { + return this.high; + }; + LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() { + return this.high >>> 0; + }; + LongPrototype.getLowBits = function getLowBits() { + return this.low; + }; + LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() { + return this.low >>> 0; + }; + LongPrototype.getNumBitsAbs = function getNumBitsAbs() { + if (this.isNegative()) + return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs(); + var val = this.high != 0 ? this.high : this.low; + for (var bit = 31; bit > 0; bit--) + if ((val & 1 << bit) != 0) + break; + return this.high != 0 ? bit + 33 : bit + 1; + }; + LongPrototype.isZero = function isZero() { + return this.high === 0 && this.low === 0; + }; + LongPrototype.eqz = LongPrototype.isZero; + LongPrototype.isNegative = function isNegative() { + return !this.unsigned && this.high < 0; + }; + LongPrototype.isPositive = function isPositive() { + return this.unsigned || this.high >= 0; + }; + LongPrototype.isOdd = function isOdd() { + return (this.low & 1) === 1; + }; + LongPrototype.isEven = function isEven() { + return (this.low & 1) === 0; + }; + LongPrototype.equals = function equals(other) { + if (!isLong(other)) + other = fromValue(other); + if (this.unsigned !== other.unsigned && this.high >>> 31 === 1 && other.high >>> 31 === 1) + return false; + return this.high === other.high && this.low === other.low; + }; + LongPrototype.eq = LongPrototype.equals; + LongPrototype.notEquals = function notEquals(other) { + return !this.eq( + /* validates */ + other + ); + }; + LongPrototype.neq = LongPrototype.notEquals; + LongPrototype.ne = LongPrototype.notEquals; + LongPrototype.lessThan = function lessThan(other) { + return this.comp( + /* validates */ + other + ) < 0; + }; + LongPrototype.lt = LongPrototype.lessThan; + LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) { + return this.comp( + /* validates */ + other + ) <= 0; + }; + LongPrototype.lte = LongPrototype.lessThanOrEqual; + LongPrototype.le = LongPrototype.lessThanOrEqual; + LongPrototype.greaterThan = function greaterThan(other) { + return this.comp( + /* validates */ + other + ) > 0; + }; + LongPrototype.gt = LongPrototype.greaterThan; + LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) { + return this.comp( + /* validates */ + other + ) >= 0; + }; + LongPrototype.gte = LongPrototype.greaterThanOrEqual; + LongPrototype.ge = LongPrototype.greaterThanOrEqual; + LongPrototype.compare = function compare(other) { + if (!isLong(other)) + other = fromValue(other); + if (this.eq(other)) + return 0; + var thisNeg = this.isNegative(), otherNeg = other.isNegative(); + if (thisNeg && !otherNeg) + return -1; + if (!thisNeg && otherNeg) + return 1; + if (!this.unsigned) + return this.sub(other).isNegative() ? -1 : 1; + return other.high >>> 0 > this.high >>> 0 || other.high === this.high && other.low >>> 0 > this.low >>> 0 ? -1 : 1; + }; + LongPrototype.comp = LongPrototype.compare; + LongPrototype.negate = function negate() { + if (!this.unsigned && this.eq(MIN_VALUE)) + return MIN_VALUE; + return this.not().add(ONE); + }; + LongPrototype.neg = LongPrototype.negate; + LongPrototype.add = function add(addend) { + if (!isLong(addend)) + addend = fromValue(addend); + var a48 = this.high >>> 16; + var a32 = this.high & 65535; + var a16 = this.low >>> 16; + var a00 = this.low & 65535; + var b48 = addend.high >>> 16; + var b32 = addend.high & 65535; + var b16 = addend.low >>> 16; + var b00 = addend.low & 65535; + var c48 = 0, c32 = 0, c16 = 0, c00 = 0; + c00 += a00 + b00; + c16 += c00 >>> 16; + c00 &= 65535; + c16 += a16 + b16; + c32 += c16 >>> 16; + c16 &= 65535; + c32 += a32 + b32; + c48 += c32 >>> 16; + c32 &= 65535; + c48 += a48 + b48; + c48 &= 65535; + return fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); + }; + LongPrototype.subtract = function subtract(subtrahend) { + if (!isLong(subtrahend)) + subtrahend = fromValue(subtrahend); + return this.add(subtrahend.neg()); + }; + LongPrototype.sub = LongPrototype.subtract; + LongPrototype.multiply = function multiply(multiplier) { + if (this.isZero()) + return this; + if (!isLong(multiplier)) + multiplier = fromValue(multiplier); + if (wasm) { + var low = wasm["mul"]( + this.low, + this.high, + multiplier.low, + multiplier.high + ); + return fromBits(low, wasm["get_high"](), this.unsigned); + } + if (multiplier.isZero()) + return this.unsigned ? UZERO : ZERO; + if (this.eq(MIN_VALUE)) + return multiplier.isOdd() ? MIN_VALUE : ZERO; + if (multiplier.eq(MIN_VALUE)) + return this.isOdd() ? MIN_VALUE : ZERO; + if (this.isNegative()) { + if (multiplier.isNegative()) + return this.neg().mul(multiplier.neg()); + else + return this.neg().mul(multiplier).neg(); + } else if (multiplier.isNegative()) + return this.mul(multiplier.neg()).neg(); + if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24)) + return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned); + var a48 = this.high >>> 16; + var a32 = this.high & 65535; + var a16 = this.low >>> 16; + var a00 = this.low & 65535; + var b48 = multiplier.high >>> 16; + var b32 = multiplier.high & 65535; + var b16 = multiplier.low >>> 16; + var b00 = multiplier.low & 65535; + var c48 = 0, c32 = 0, c16 = 0, c00 = 0; + c00 += a00 * b00; + c16 += c00 >>> 16; + c00 &= 65535; + c16 += a16 * b00; + c32 += c16 >>> 16; + c16 &= 65535; + c16 += a00 * b16; + c32 += c16 >>> 16; + c16 &= 65535; + c32 += a32 * b00; + c48 += c32 >>> 16; + c32 &= 65535; + c32 += a16 * b16; + c48 += c32 >>> 16; + c32 &= 65535; + c32 += a00 * b32; + c48 += c32 >>> 16; + c32 &= 65535; + c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; + c48 &= 65535; + return fromBits(c16 << 16 | c00, c48 << 16 | c32, this.unsigned); + }; + LongPrototype.mul = LongPrototype.multiply; + LongPrototype.divide = function divide(divisor) { + if (!isLong(divisor)) + divisor = fromValue(divisor); + if (divisor.isZero()) + throw Error("division by zero"); + if (wasm) { + if (!this.unsigned && this.high === -2147483648 && divisor.low === -1 && divisor.high === -1) { + return this; + } + var low = (this.unsigned ? wasm["div_u"] : wasm["div_s"])( + this.low, + this.high, + divisor.low, + divisor.high + ); + return fromBits(low, wasm["get_high"](), this.unsigned); + } + if (this.isZero()) + return this.unsigned ? UZERO : ZERO; + var approx, rem, res; + if (!this.unsigned) { + if (this.eq(MIN_VALUE)) { + if (divisor.eq(ONE) || divisor.eq(NEG_ONE)) + return MIN_VALUE; + else if (divisor.eq(MIN_VALUE)) + return ONE; + else { + var halfThis = this.shr(1); + approx = halfThis.div(divisor).shl(1); + if (approx.eq(ZERO)) { + return divisor.isNegative() ? ONE : NEG_ONE; + } else { + rem = this.sub(divisor.mul(approx)); + res = approx.add(rem.div(divisor)); + return res; + } + } + } else if (divisor.eq(MIN_VALUE)) + return this.unsigned ? UZERO : ZERO; + if (this.isNegative()) { + if (divisor.isNegative()) + return this.neg().div(divisor.neg()); + return this.neg().div(divisor).neg(); + } else if (divisor.isNegative()) + return this.div(divisor.neg()).neg(); + res = ZERO; + } else { + if (!divisor.unsigned) + divisor = divisor.toUnsigned(); + if (divisor.gt(this)) + return UZERO; + if (divisor.gt(this.shru(1))) + return UONE; + res = UZERO; + } + rem = this; + while (rem.gte(divisor)) { + approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber())); + var log22 = Math.ceil(Math.log(approx) / Math.LN2), delta = log22 <= 48 ? 1 : pow_dbl(2, log22 - 48), approxRes = fromNumber(approx), approxRem = approxRes.mul(divisor); + while (approxRem.isNegative() || approxRem.gt(rem)) { + approx -= delta; + approxRes = fromNumber(approx, this.unsigned); + approxRem = approxRes.mul(divisor); + } + if (approxRes.isZero()) + approxRes = ONE; + res = res.add(approxRes); + rem = rem.sub(approxRem); + } + return res; + }; + LongPrototype.div = LongPrototype.divide; + LongPrototype.modulo = function modulo(divisor) { + if (!isLong(divisor)) + divisor = fromValue(divisor); + if (wasm) { + var low = (this.unsigned ? wasm["rem_u"] : wasm["rem_s"])( + this.low, + this.high, + divisor.low, + divisor.high + ); + return fromBits(low, wasm["get_high"](), this.unsigned); + } + return this.sub(this.div(divisor).mul(divisor)); + }; + LongPrototype.mod = LongPrototype.modulo; + LongPrototype.rem = LongPrototype.modulo; + LongPrototype.not = function not() { + return fromBits(~this.low, ~this.high, this.unsigned); + }; + LongPrototype.countLeadingZeros = function countLeadingZeros() { + return this.high ? Math.clz32(this.high) : Math.clz32(this.low) + 32; + }; + LongPrototype.clz = LongPrototype.countLeadingZeros; + LongPrototype.countTrailingZeros = function countTrailingZeros() { + return this.low ? ctz32(this.low) : ctz32(this.high) + 32; + }; + LongPrototype.ctz = LongPrototype.countTrailingZeros; + LongPrototype.and = function and(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low & other.low, this.high & other.high, this.unsigned); + }; + LongPrototype.or = function or(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low | other.low, this.high | other.high, this.unsigned); + }; + LongPrototype.xor = function xor(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned); + }; + LongPrototype.shiftLeft = function shiftLeft(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + else if (numBits < 32) + return fromBits(this.low << numBits, this.high << numBits | this.low >>> 32 - numBits, this.unsigned); + else + return fromBits(0, this.low << numBits - 32, this.unsigned); + }; + LongPrototype.shl = LongPrototype.shiftLeft; + LongPrototype.shiftRight = function shiftRight(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + else if (numBits < 32) + return fromBits(this.low >>> numBits | this.high << 32 - numBits, this.high >> numBits, this.unsigned); + else + return fromBits(this.high >> numBits - 32, this.high >= 0 ? 0 : -1, this.unsigned); + }; + LongPrototype.shr = LongPrototype.shiftRight; + LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + if (numBits < 32) + return fromBits(this.low >>> numBits | this.high << 32 - numBits, this.high >>> numBits, this.unsigned); + if (numBits === 32) + return fromBits(this.high, 0, this.unsigned); + return fromBits(this.high >>> numBits - 32, 0, this.unsigned); + }; + LongPrototype.shru = LongPrototype.shiftRightUnsigned; + LongPrototype.shr_u = LongPrototype.shiftRightUnsigned; + LongPrototype.rotateLeft = function rotateLeft(numBits) { + var b; + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + if (numBits === 32) + return fromBits(this.high, this.low, this.unsigned); + if (numBits < 32) { + b = 32 - numBits; + return fromBits(this.low << numBits | this.high >>> b, this.high << numBits | this.low >>> b, this.unsigned); + } + numBits -= 32; + b = 32 - numBits; + return fromBits(this.high << numBits | this.low >>> b, this.low << numBits | this.high >>> b, this.unsigned); + }; + LongPrototype.rotl = LongPrototype.rotateLeft; + LongPrototype.rotateRight = function rotateRight(numBits) { + var b; + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + if (numBits === 32) + return fromBits(this.high, this.low, this.unsigned); + if (numBits < 32) { + b = 32 - numBits; + return fromBits(this.high << b | this.low >>> numBits, this.low << b | this.high >>> numBits, this.unsigned); + } + numBits -= 32; + b = 32 - numBits; + return fromBits(this.low << b | this.high >>> numBits, this.high << b | this.low >>> numBits, this.unsigned); + }; + LongPrototype.rotr = LongPrototype.rotateRight; + LongPrototype.toSigned = function toSigned() { + if (!this.unsigned) + return this; + return fromBits(this.low, this.high, false); + }; + LongPrototype.toUnsigned = function toUnsigned() { + if (this.unsigned) + return this; + return fromBits(this.low, this.high, true); + }; + LongPrototype.toBytes = function toBytes(le) { + return le ? this.toBytesLE() : this.toBytesBE(); + }; + LongPrototype.toBytesLE = function toBytesLE() { + var hi = this.high, lo = this.low; + return [ + lo & 255, + lo >>> 8 & 255, + lo >>> 16 & 255, + lo >>> 24, + hi & 255, + hi >>> 8 & 255, + hi >>> 16 & 255, + hi >>> 24 + ]; + }; + LongPrototype.toBytesBE = function toBytesBE() { + var hi = this.high, lo = this.low; + return [ + hi >>> 24, + hi >>> 16 & 255, + hi >>> 8 & 255, + hi & 255, + lo >>> 24, + lo >>> 16 & 255, + lo >>> 8 & 255, + lo & 255 + ]; + }; + Long.fromBytes = function fromBytes(bytes, unsigned, le) { + return le ? Long.fromBytesLE(bytes, unsigned) : Long.fromBytesBE(bytes, unsigned); + }; + Long.fromBytesLE = function fromBytesLE(bytes, unsigned) { + return new Long( + bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24, + bytes[4] | bytes[5] << 8 | bytes[6] << 16 | bytes[7] << 24, + unsigned + ); + }; + Long.fromBytesBE = function fromBytesBE(bytes, unsigned) { + return new Long( + bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7], + bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], + unsigned + ); + }; + long_default = Long; + } +}); + +// web/node_modules/flatbuffers/js/flatbuffers.mjs +var flatbuffers; +var init_flatbuffers = __esm({ + "web/node_modules/flatbuffers/js/flatbuffers.mjs"() { + flatbuffers = {}; + flatbuffers.Offset; + flatbuffers.Table; + flatbuffers.SIZEOF_SHORT = 2; + flatbuffers.SIZEOF_INT = 4; + flatbuffers.FILE_IDENTIFIER_LENGTH = 4; + flatbuffers.SIZE_PREFIX_LENGTH = 4; + flatbuffers.Encoding = { + UTF8_BYTES: 1, + UTF16_STRING: 2 + }; + flatbuffers.int32 = new Int32Array(2); + flatbuffers.float32 = new Float32Array(flatbuffers.int32.buffer); + flatbuffers.float64 = new Float64Array(flatbuffers.int32.buffer); + flatbuffers.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1; + flatbuffers.Long = function(low, high) { + this.low = low | 0; + this.high = high | 0; + }; + flatbuffers.Long.create = function(low, high) { + return low == 0 && high == 0 ? flatbuffers.Long.ZERO : new flatbuffers.Long(low, high); + }; + flatbuffers.Long.prototype.toFloat64 = function() { + return (this.low >>> 0) + this.high * 4294967296; + }; + flatbuffers.Long.prototype.equals = function(other) { + return this.low == other.low && this.high == other.high; + }; + flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0); + flatbuffers.Builder = function(opt_initial_size) { + if (!opt_initial_size) { + var initial_size = 1024; + } else { + var initial_size = opt_initial_size; + } + this.bb = flatbuffers.ByteBuffer.allocate(initial_size); + this.space = initial_size; + this.minalign = 1; + this.vtable = null; + this.vtable_in_use = 0; + this.isNested = false; + this.object_start = 0; + this.vtables = []; + this.vector_num_elems = 0; + this.force_defaults = false; + }; + flatbuffers.Builder.prototype.clear = function() { + this.bb.clear(); + this.space = this.bb.capacity(); + this.minalign = 1; + this.vtable = null; + this.vtable_in_use = 0; + this.isNested = false; + this.object_start = 0; + this.vtables = []; + this.vector_num_elems = 0; + this.force_defaults = false; + }; + flatbuffers.Builder.prototype.forceDefaults = function(forceDefaults) { + this.force_defaults = forceDefaults; + }; + flatbuffers.Builder.prototype.dataBuffer = function() { + return this.bb; + }; + flatbuffers.Builder.prototype.asUint8Array = function() { + return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset()); + }; + flatbuffers.Builder.prototype.prep = function(size, additional_bytes) { + if (size > this.minalign) { + this.minalign = size; + } + var align_size = ~(this.bb.capacity() - this.space + additional_bytes) + 1 & size - 1; + while (this.space < align_size + size + additional_bytes) { + var old_buf_size = this.bb.capacity(); + this.bb = flatbuffers.Builder.growByteBuffer(this.bb); + this.space += this.bb.capacity() - old_buf_size; + } + this.pad(align_size); + }; + flatbuffers.Builder.prototype.pad = function(byte_size) { + for (var i = 0; i < byte_size; i++) { + this.bb.writeInt8(--this.space, 0); + } + }; + flatbuffers.Builder.prototype.writeInt8 = function(value) { + this.bb.writeInt8(this.space -= 1, value); + }; + flatbuffers.Builder.prototype.writeInt16 = function(value) { + this.bb.writeInt16(this.space -= 2, value); + }; + flatbuffers.Builder.prototype.writeInt32 = function(value) { + this.bb.writeInt32(this.space -= 4, value); + }; + flatbuffers.Builder.prototype.writeInt64 = function(value) { + this.bb.writeInt64(this.space -= 8, value); + }; + flatbuffers.Builder.prototype.writeFloat32 = function(value) { + this.bb.writeFloat32(this.space -= 4, value); + }; + flatbuffers.Builder.prototype.writeFloat64 = function(value) { + this.bb.writeFloat64(this.space -= 8, value); + }; + flatbuffers.Builder.prototype.addInt8 = function(value) { + this.prep(1, 0); + this.writeInt8(value); + }; + flatbuffers.Builder.prototype.addInt16 = function(value) { + this.prep(2, 0); + this.writeInt16(value); + }; + flatbuffers.Builder.prototype.addInt32 = function(value) { + this.prep(4, 0); + this.writeInt32(value); + }; + flatbuffers.Builder.prototype.addInt64 = function(value) { + this.prep(8, 0); + this.writeInt64(value); + }; + flatbuffers.Builder.prototype.addFloat32 = function(value) { + this.prep(4, 0); + this.writeFloat32(value); + }; + flatbuffers.Builder.prototype.addFloat64 = function(value) { + this.prep(8, 0); + this.writeFloat64(value); + }; + flatbuffers.Builder.prototype.addFieldInt8 = function(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addInt8(value); + this.slot(voffset); + } + }; + flatbuffers.Builder.prototype.addFieldInt16 = function(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addInt16(value); + this.slot(voffset); + } + }; + flatbuffers.Builder.prototype.addFieldInt32 = function(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addInt32(value); + this.slot(voffset); + } + }; + flatbuffers.Builder.prototype.addFieldInt64 = function(voffset, value, defaultValue) { + if (this.force_defaults || !value.equals(defaultValue)) { + this.addInt64(value); + this.slot(voffset); + } + }; + flatbuffers.Builder.prototype.addFieldFloat32 = function(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addFloat32(value); + this.slot(voffset); + } + }; + flatbuffers.Builder.prototype.addFieldFloat64 = function(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addFloat64(value); + this.slot(voffset); + } + }; + flatbuffers.Builder.prototype.addFieldOffset = function(voffset, value, defaultValue) { + if (this.force_defaults || value != defaultValue) { + this.addOffset(value); + this.slot(voffset); + } + }; + flatbuffers.Builder.prototype.addFieldStruct = function(voffset, value, defaultValue) { + if (value != defaultValue) { + this.nested(value); + this.slot(voffset); + } + }; + flatbuffers.Builder.prototype.nested = function(obj) { + if (obj != this.offset()) { + throw new Error("FlatBuffers: struct must be serialized inline."); + } + }; + flatbuffers.Builder.prototype.notNested = function() { + if (this.isNested) { + throw new Error("FlatBuffers: object serialization must not be nested."); + } + }; + flatbuffers.Builder.prototype.slot = function(voffset) { + this.vtable[voffset] = this.offset(); + }; + flatbuffers.Builder.prototype.offset = function() { + return this.bb.capacity() - this.space; + }; + flatbuffers.Builder.growByteBuffer = function(bb) { + var old_buf_size = bb.capacity(); + if (old_buf_size & 3221225472) { + throw new Error("FlatBuffers: cannot grow buffer beyond 2 gigabytes."); + } + var new_buf_size = old_buf_size << 1; + var nbb = flatbuffers.ByteBuffer.allocate(new_buf_size); + nbb.setPosition(new_buf_size - old_buf_size); + nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size); + return nbb; + }; + flatbuffers.Builder.prototype.addOffset = function(offset) { + this.prep(flatbuffers.SIZEOF_INT, 0); + this.writeInt32(this.offset() - offset + flatbuffers.SIZEOF_INT); + }; + flatbuffers.Builder.prototype.startObject = function(numfields) { + this.notNested(); + if (this.vtable == null) { + this.vtable = []; + } + this.vtable_in_use = numfields; + for (var i = 0; i < numfields; i++) { + this.vtable[i] = 0; + } + this.isNested = true; + this.object_start = this.offset(); + }; + flatbuffers.Builder.prototype.endObject = function() { + if (this.vtable == null || !this.isNested) { + throw new Error("FlatBuffers: endObject called without startObject"); + } + this.addInt32(0); + var vtableloc = this.offset(); + var i = this.vtable_in_use - 1; + for (; i >= 0 && this.vtable[i] == 0; i--) { + } + var trimmed_size = i + 1; + for (; i >= 0; i--) { + this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0); + } + var standard_fields = 2; + this.addInt16(vtableloc - this.object_start); + var len = (trimmed_size + standard_fields) * flatbuffers.SIZEOF_SHORT; + this.addInt16(len); + var existing_vtable = 0; + var vt1 = this.space; + outer_loop: + for (i = 0; i < this.vtables.length; i++) { + var vt2 = this.bb.capacity() - this.vtables[i]; + if (len == this.bb.readInt16(vt2)) { + for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) { + if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) { + continue outer_loop; + } + } + existing_vtable = this.vtables[i]; + break; + } + } + if (existing_vtable) { + this.space = this.bb.capacity() - vtableloc; + this.bb.writeInt32(this.space, existing_vtable - vtableloc); + } else { + this.vtables.push(this.offset()); + this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc); + } + this.isNested = false; + return vtableloc; + }; + flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier, opt_size_prefix) { + var size_prefix = opt_size_prefix ? flatbuffers.SIZE_PREFIX_LENGTH : 0; + if (opt_file_identifier) { + var file_identifier = opt_file_identifier; + this.prep(this.minalign, flatbuffers.SIZEOF_INT + flatbuffers.FILE_IDENTIFIER_LENGTH + size_prefix); + if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) { + throw new Error("FlatBuffers: file identifier must be length " + flatbuffers.FILE_IDENTIFIER_LENGTH); + } + for (var i = flatbuffers.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) { + this.writeInt8(file_identifier.charCodeAt(i)); + } + } + this.prep(this.minalign, flatbuffers.SIZEOF_INT + size_prefix); + this.addOffset(root_table); + if (size_prefix) { + this.addInt32(this.bb.capacity() - this.space); + } + this.bb.setPosition(this.space); + }; + flatbuffers.Builder.prototype.finishSizePrefixed = function(root_table, opt_file_identifier) { + this.finish(root_table, opt_file_identifier, true); + }; + flatbuffers.Builder.prototype.requiredField = function(table, field) { + var table_start = this.bb.capacity() - table; + var vtable_start = table_start - this.bb.readInt32(table_start); + var ok = this.bb.readInt16(vtable_start + field) != 0; + if (!ok) { + throw new Error("FlatBuffers: field " + field + " must be set"); + } + }; + flatbuffers.Builder.prototype.startVector = function(elem_size, num_elems, alignment) { + this.notNested(); + this.vector_num_elems = num_elems; + this.prep(flatbuffers.SIZEOF_INT, elem_size * num_elems); + this.prep(alignment, elem_size * num_elems); + }; + flatbuffers.Builder.prototype.endVector = function() { + this.writeInt32(this.vector_num_elems); + return this.offset(); + }; + flatbuffers.Builder.prototype.createString = function(s) { + if (s instanceof Uint8Array) { + var utf8 = s; + } else { + var utf8 = []; + var i = 0; + while (i < s.length) { + var codePoint; + var a = s.charCodeAt(i++); + if (a < 55296 || a >= 56320) { + codePoint = a; + } else { + var b = s.charCodeAt(i++); + codePoint = (a << 10) + b + (65536 - (55296 << 10) - 56320); + } + if (codePoint < 128) { + utf8.push(codePoint); + } else { + if (codePoint < 2048) { + utf8.push(codePoint >> 6 & 31 | 192); + } else { + if (codePoint < 65536) { + utf8.push(codePoint >> 12 & 15 | 224); + } else { + utf8.push( + codePoint >> 18 & 7 | 240, + codePoint >> 12 & 63 | 128 + ); + } + utf8.push(codePoint >> 6 & 63 | 128); + } + utf8.push(codePoint & 63 | 128); + } + } + } + this.addInt8(0); + this.startVector(1, utf8.length, 1); + this.bb.setPosition(this.space -= utf8.length); + for (var i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) { + bytes[offset++] = utf8[i]; + } + return this.endVector(); + }; + flatbuffers.Builder.prototype.createLong = function(low, high) { + return flatbuffers.Long.create(low, high); + }; + flatbuffers.ByteBuffer = function(bytes) { + this.bytes_ = bytes; + this.position_ = 0; + }; + flatbuffers.ByteBuffer.allocate = function(byte_size) { + return new flatbuffers.ByteBuffer(new Uint8Array(byte_size)); + }; + flatbuffers.ByteBuffer.prototype.clear = function() { + this.position_ = 0; + }; + flatbuffers.ByteBuffer.prototype.bytes = function() { + return this.bytes_; + }; + flatbuffers.ByteBuffer.prototype.position = function() { + return this.position_; + }; + flatbuffers.ByteBuffer.prototype.setPosition = function(position) { + this.position_ = position; + }; + flatbuffers.ByteBuffer.prototype.capacity = function() { + return this.bytes_.length; + }; + flatbuffers.ByteBuffer.prototype.readInt8 = function(offset) { + return this.readUint8(offset) << 24 >> 24; + }; + flatbuffers.ByteBuffer.prototype.readUint8 = function(offset) { + return this.bytes_[offset]; + }; + flatbuffers.ByteBuffer.prototype.readInt16 = function(offset) { + return this.readUint16(offset) << 16 >> 16; + }; + flatbuffers.ByteBuffer.prototype.readUint16 = function(offset) { + return this.bytes_[offset] | this.bytes_[offset + 1] << 8; + }; + flatbuffers.ByteBuffer.prototype.readInt32 = function(offset) { + return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24; + }; + flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) { + return this.readInt32(offset) >>> 0; + }; + flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) { + return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4)); + }; + flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) { + return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4)); + }; + flatbuffers.ByteBuffer.prototype.readFloat32 = function(offset) { + flatbuffers.int32[0] = this.readInt32(offset); + return flatbuffers.float32[0]; + }; + flatbuffers.ByteBuffer.prototype.readFloat64 = function(offset) { + flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1] = this.readInt32(offset); + flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4); + return flatbuffers.float64[0]; + }; + flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) { + this.bytes_[offset] = /** @type {number} */ + value; + }; + flatbuffers.ByteBuffer.prototype.writeUint8 = function(offset, value) { + this.bytes_[offset] = value; + }; + flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) { + this.bytes_[offset] = value; + this.bytes_[offset + 1] = value >> 8; + }; + flatbuffers.ByteBuffer.prototype.writeUint16 = function(offset, value) { + this.bytes_[offset] = value; + this.bytes_[offset + 1] = value >> 8; + }; + flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) { + this.bytes_[offset] = value; + this.bytes_[offset + 1] = value >> 8; + this.bytes_[offset + 2] = value >> 16; + this.bytes_[offset + 3] = value >> 24; + }; + flatbuffers.ByteBuffer.prototype.writeUint32 = function(offset, value) { + this.bytes_[offset] = value; + this.bytes_[offset + 1] = value >> 8; + this.bytes_[offset + 2] = value >> 16; + this.bytes_[offset + 3] = value >> 24; + }; + flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) { + this.writeInt32(offset, value.low); + this.writeInt32(offset + 4, value.high); + }; + flatbuffers.ByteBuffer.prototype.writeUint64 = function(offset, value) { + this.writeUint32(offset, value.low); + this.writeUint32(offset + 4, value.high); + }; + flatbuffers.ByteBuffer.prototype.writeFloat32 = function(offset, value) { + flatbuffers.float32[0] = value; + this.writeInt32(offset, flatbuffers.int32[0]); + }; + flatbuffers.ByteBuffer.prototype.writeFloat64 = function(offset, value) { + flatbuffers.float64[0] = value; + this.writeInt32(offset, flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1]); + this.writeInt32(offset + 4, flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0]); + }; + flatbuffers.ByteBuffer.prototype.getBufferIdentifier = function() { + if (this.bytes_.length < this.position_ + flatbuffers.SIZEOF_INT + flatbuffers.FILE_IDENTIFIER_LENGTH) { + throw new Error( + "FlatBuffers: ByteBuffer is too short to contain an identifier." + ); + } + var result = ""; + for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) { + result += String.fromCharCode( + this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i) + ); + } + return result; + }; + flatbuffers.ByteBuffer.prototype.__offset = function(bb_pos, vtable_offset) { + var vtable = bb_pos - this.readInt32(bb_pos); + return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0; + }; + flatbuffers.ByteBuffer.prototype.__union = function(t, offset) { + t.bb_pos = offset + this.readInt32(offset); + t.bb = this; + return t; + }; + flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) { + offset += this.readInt32(offset); + var length = this.readInt32(offset); + var result = ""; + var i = 0; + offset += flatbuffers.SIZEOF_INT; + if (opt_encoding === flatbuffers.Encoding.UTF8_BYTES) { + return this.bytes_.subarray(offset, offset + length); + } + while (i < length) { + var codePoint; + var a = this.readUint8(offset + i++); + if (a < 192) { + codePoint = a; + } else { + var b = this.readUint8(offset + i++); + if (a < 224) { + codePoint = (a & 31) << 6 | b & 63; + } else { + var c = this.readUint8(offset + i++); + if (a < 240) { + codePoint = (a & 15) << 12 | (b & 63) << 6 | c & 63; + } else { + var d = this.readUint8(offset + i++); + codePoint = (a & 7) << 18 | (b & 63) << 12 | (c & 63) << 6 | d & 63; + } + } + } + if (codePoint < 65536) { + result += String.fromCharCode(codePoint); + } else { + codePoint -= 65536; + result += String.fromCharCode( + (codePoint >> 10) + 55296, + (codePoint & (1 << 10) - 1) + 56320 + ); + } + } + return result; + }; + flatbuffers.ByteBuffer.prototype.__indirect = function(offset) { + return offset + this.readInt32(offset); + }; + flatbuffers.ByteBuffer.prototype.__vector = function(offset) { + return offset + this.readInt32(offset) + flatbuffers.SIZEOF_INT; + }; + flatbuffers.ByteBuffer.prototype.__vector_len = function(offset) { + return this.readInt32(offset + this.readInt32(offset)); + }; + flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) { + if (ident.length != flatbuffers.FILE_IDENTIFIER_LENGTH) { + throw new Error("FlatBuffers: file identifier must be length " + flatbuffers.FILE_IDENTIFIER_LENGTH); + } + for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) { + if (ident.charCodeAt(i) != this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i)) { + return false; + } + } + return true; + }; + flatbuffers.ByteBuffer.prototype.createLong = function(low, high) { + return flatbuffers.Long.create(low, high); + }; + } +}); + +// web/lib/onnxjs/ort-schema/flatbuffers/ort-generated.ts +var onnxruntime; +var init_ort_generated = __esm({ + "web/lib/onnxjs/ort-schema/flatbuffers/ort-generated.ts"() { + "use strict"; + init_flatbuffers(); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + let AttributeType; + ((AttributeType2) => { + AttributeType2[AttributeType2["UNDEFINED"] = 0] = "UNDEFINED"; + AttributeType2[AttributeType2["FLOAT"] = 1] = "FLOAT"; + AttributeType2[AttributeType2["INT"] = 2] = "INT"; + AttributeType2[AttributeType2["STRING"] = 3] = "STRING"; + AttributeType2[AttributeType2["TENSOR"] = 4] = "TENSOR"; + AttributeType2[AttributeType2["GRAPH"] = 5] = "GRAPH"; + AttributeType2[AttributeType2["FLOATS"] = 6] = "FLOATS"; + AttributeType2[AttributeType2["INTS"] = 7] = "INTS"; + AttributeType2[AttributeType2["STRINGS"] = 8] = "STRINGS"; + AttributeType2[AttributeType2["TENSORS"] = 9] = "TENSORS"; + AttributeType2[AttributeType2["GRAPHS"] = 10] = "GRAPHS"; + AttributeType2[AttributeType2["SPARSE_TENSOR"] = 11] = "SPARSE_TENSOR"; + AttributeType2[AttributeType2["SPARSE_TENSORS"] = 12] = "SPARSE_TENSORS"; + })(AttributeType = fbs2.AttributeType || (fbs2.AttributeType = {})); + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + let DimensionValueType; + ((DimensionValueType2) => { + DimensionValueType2[DimensionValueType2["UNKNOWN"] = 0] = "UNKNOWN"; + DimensionValueType2[DimensionValueType2["VALUE"] = 1] = "VALUE"; + DimensionValueType2[DimensionValueType2["PARAM"] = 2] = "PARAM"; + })(DimensionValueType = fbs2.DimensionValueType || (fbs2.DimensionValueType = {})); + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + let TensorDataType; + ((TensorDataType2) => { + TensorDataType2[TensorDataType2["UNDEFINED"] = 0] = "UNDEFINED"; + TensorDataType2[TensorDataType2["FLOAT"] = 1] = "FLOAT"; + TensorDataType2[TensorDataType2["UINT8"] = 2] = "UINT8"; + TensorDataType2[TensorDataType2["INT8"] = 3] = "INT8"; + TensorDataType2[TensorDataType2["UINT16"] = 4] = "UINT16"; + TensorDataType2[TensorDataType2["INT16"] = 5] = "INT16"; + TensorDataType2[TensorDataType2["INT32"] = 6] = "INT32"; + TensorDataType2[TensorDataType2["INT64"] = 7] = "INT64"; + TensorDataType2[TensorDataType2["STRING"] = 8] = "STRING"; + TensorDataType2[TensorDataType2["BOOL"] = 9] = "BOOL"; + TensorDataType2[TensorDataType2["FLOAT16"] = 10] = "FLOAT16"; + TensorDataType2[TensorDataType2["DOUBLE"] = 11] = "DOUBLE"; + TensorDataType2[TensorDataType2["UINT32"] = 12] = "UINT32"; + TensorDataType2[TensorDataType2["UINT64"] = 13] = "UINT64"; + TensorDataType2[TensorDataType2["COMPLEX64"] = 14] = "COMPLEX64"; + TensorDataType2[TensorDataType2["COMPLEX128"] = 15] = "COMPLEX128"; + TensorDataType2[TensorDataType2["BFLOAT16"] = 16] = "BFLOAT16"; + TensorDataType2[TensorDataType2["FLOAT8E4M3FN"] = 17] = "FLOAT8E4M3FN"; + TensorDataType2[TensorDataType2["FLOAT8E4M3FNUZ"] = 18] = "FLOAT8E4M3FNUZ"; + TensorDataType2[TensorDataType2["FLOAT8E5M2"] = 19] = "FLOAT8E5M2"; + TensorDataType2[TensorDataType2["FLOAT8E5M2FNUZ"] = 20] = "FLOAT8E5M2FNUZ"; + })(TensorDataType = fbs2.TensorDataType || (fbs2.TensorDataType = {})); + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + let NodeType; + ((NodeType2) => { + NodeType2[NodeType2["Primitive"] = 0] = "Primitive"; + NodeType2[NodeType2["Fused"] = 1] = "Fused"; + })(NodeType = fbs2.NodeType || (fbs2.NodeType = {})); + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + let TypeInfoValue; + ((TypeInfoValue2) => { + TypeInfoValue2[TypeInfoValue2["NONE"] = 0] = "NONE"; + TypeInfoValue2[TypeInfoValue2["tensor_type"] = 1] = "tensor_type"; + TypeInfoValue2[TypeInfoValue2["sequence_type"] = 2] = "sequence_type"; + TypeInfoValue2[TypeInfoValue2["map_type"] = 3] = "map_type"; + })(TypeInfoValue = fbs2.TypeInfoValue || (fbs2.TypeInfoValue = {})); + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class Shape { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns Shape + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Shape= obj + * @returns Shape + */ + static getRootAsShape(bb, obj) { + return (obj || new Shape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Shape= obj + * @returns Shape + */ + static getSizePrefixedRootAsShape(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Shape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.Dimension= obj + * @returns onnxruntime.experimental.fbs.Dimension + */ + dim(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new onnxruntime2.experimental.fbs.Dimension()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + dimLength() { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param flatbuffers.Builder builder + */ + static startShape(builder) { + builder.startObject(1); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset dimOffset + */ + static addDim(builder, dimOffset) { + builder.addFieldOffset(0, dimOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createDimVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startDimVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endShape(builder) { + let offset = builder.endObject(); + return offset; + } + static createShape(builder, dimOffset) { + Shape.startShape(builder); + Shape.addDim(builder, dimOffset); + return Shape.endShape(builder); + } + } + fbs2.Shape = Shape; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class Dimension { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns Dimension + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Dimension= obj + * @returns Dimension + */ + static getRootAsDimension(bb, obj) { + return (obj || new Dimension()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Dimension= obj + * @returns Dimension + */ + static getSizePrefixedRootAsDimension(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Dimension()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param onnxruntime.experimental.fbs.DimensionValue= obj + * @returns onnxruntime.experimental.fbs.DimensionValue|null + */ + value(obj) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new onnxruntime2.experimental.fbs.DimensionValue()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + denotation(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @param flatbuffers.Builder builder + */ + static startDimension(builder) { + builder.startObject(2); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset valueOffset + */ + static addValue(builder, valueOffset) { + builder.addFieldOffset(0, valueOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset denotationOffset + */ + static addDenotation(builder, denotationOffset) { + builder.addFieldOffset(1, denotationOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endDimension(builder) { + let offset = builder.endObject(); + return offset; + } + static createDimension(builder, valueOffset, denotationOffset) { + Dimension.startDimension(builder); + Dimension.addValue(builder, valueOffset); + Dimension.addDenotation(builder, denotationOffset); + return Dimension.endDimension(builder); + } + } + fbs2.Dimension = Dimension; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class DimensionValue { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns DimensionValue + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param DimensionValue= obj + * @returns DimensionValue + */ + static getRootAsDimensionValue(bb, obj) { + return (obj || new DimensionValue()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param DimensionValue= obj + * @returns DimensionValue + */ + static getSizePrefixedRootAsDimensionValue(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new DimensionValue()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @returns onnxruntime.experimental.fbs.DimensionValueType + */ + dimType() { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? ( + /** */ + this.bb.readInt8(this.bb_pos + offset) + ) : 0 /* UNKNOWN */; + } + /** + * @returns flatbuffers.Long + */ + dimValue() { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0); + } + dimParam(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @param flatbuffers.Builder builder + */ + static startDimensionValue(builder) { + builder.startObject(3); + } + /** + * @param flatbuffers.Builder builder + * @param onnxruntime.experimental.fbs.DimensionValueType dimType + */ + static addDimType(builder, dimType) { + builder.addFieldInt8(0, dimType, 0 /* UNKNOWN */); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Long dimValue + */ + static addDimValue(builder, dimValue) { + builder.addFieldInt64(1, dimValue, builder.createLong(0, 0)); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset dimParamOffset + */ + static addDimParam(builder, dimParamOffset) { + builder.addFieldOffset(2, dimParamOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endDimensionValue(builder) { + let offset = builder.endObject(); + return offset; + } + static createDimensionValue(builder, dimType, dimValue, dimParamOffset) { + DimensionValue.startDimensionValue(builder); + DimensionValue.addDimType(builder, dimType); + DimensionValue.addDimValue(builder, dimValue); + DimensionValue.addDimParam(builder, dimParamOffset); + return DimensionValue.endDimensionValue(builder); + } + } + fbs2.DimensionValue = DimensionValue; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class TensorTypeAndShape { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns TensorTypeAndShape + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param TensorTypeAndShape= obj + * @returns TensorTypeAndShape + */ + static getRootAsTensorTypeAndShape(bb, obj) { + return (obj || new TensorTypeAndShape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param TensorTypeAndShape= obj + * @returns TensorTypeAndShape + */ + static getSizePrefixedRootAsTensorTypeAndShape(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new TensorTypeAndShape()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @returns onnxruntime.experimental.fbs.TensorDataType + */ + elemType() { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? ( + /** */ + this.bb.readInt32(this.bb_pos + offset) + ) : 0 /* UNDEFINED */; + } + /** + * @param onnxruntime.experimental.fbs.Shape= obj + * @returns onnxruntime.experimental.fbs.Shape|null + */ + shape(obj) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new onnxruntime2.experimental.fbs.Shape()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param flatbuffers.Builder builder + */ + static startTensorTypeAndShape(builder) { + builder.startObject(2); + } + /** + * @param flatbuffers.Builder builder + * @param onnxruntime.experimental.fbs.TensorDataType elemType + */ + static addElemType(builder, elemType) { + builder.addFieldInt32(0, elemType, 0 /* UNDEFINED */); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset shapeOffset + */ + static addShape(builder, shapeOffset) { + builder.addFieldOffset(1, shapeOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endTensorTypeAndShape(builder) { + let offset = builder.endObject(); + return offset; + } + static createTensorTypeAndShape(builder, elemType, shapeOffset) { + TensorTypeAndShape.startTensorTypeAndShape(builder); + TensorTypeAndShape.addElemType(builder, elemType); + TensorTypeAndShape.addShape(builder, shapeOffset); + return TensorTypeAndShape.endTensorTypeAndShape(builder); + } + } + fbs2.TensorTypeAndShape = TensorTypeAndShape; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class MapType { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns MapType + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param MapType= obj + * @returns MapType + */ + static getRootAsMapType(bb, obj) { + return (obj || new MapType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param MapType= obj + * @returns MapType + */ + static getSizePrefixedRootAsMapType(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new MapType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @returns onnxruntime.experimental.fbs.TensorDataType + */ + keyType() { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? ( + /** */ + this.bb.readInt32(this.bb_pos + offset) + ) : 0 /* UNDEFINED */; + } + /** + * @param onnxruntime.experimental.fbs.TypeInfo= obj + * @returns onnxruntime.experimental.fbs.TypeInfo|null + */ + valueType(obj) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new onnxruntime2.experimental.fbs.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param flatbuffers.Builder builder + */ + static startMapType(builder) { + builder.startObject(2); + } + /** + * @param flatbuffers.Builder builder + * @param onnxruntime.experimental.fbs.TensorDataType keyType + */ + static addKeyType(builder, keyType) { + builder.addFieldInt32(0, keyType, 0 /* UNDEFINED */); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset valueTypeOffset + */ + static addValueType(builder, valueTypeOffset) { + builder.addFieldOffset(1, valueTypeOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endMapType(builder) { + let offset = builder.endObject(); + return offset; + } + static createMapType(builder, keyType, valueTypeOffset) { + MapType.startMapType(builder); + MapType.addKeyType(builder, keyType); + MapType.addValueType(builder, valueTypeOffset); + return MapType.endMapType(builder); + } + } + fbs2.MapType = MapType; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class SequenceType { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns SequenceType + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param SequenceType= obj + * @returns SequenceType + */ + static getRootAsSequenceType(bb, obj) { + return (obj || new SequenceType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param SequenceType= obj + * @returns SequenceType + */ + static getSizePrefixedRootAsSequenceType(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new SequenceType()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param onnxruntime.experimental.fbs.TypeInfo= obj + * @returns onnxruntime.experimental.fbs.TypeInfo|null + */ + elemType(obj) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new onnxruntime2.experimental.fbs.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param flatbuffers.Builder builder + */ + static startSequenceType(builder) { + builder.startObject(1); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset elemTypeOffset + */ + static addElemType(builder, elemTypeOffset) { + builder.addFieldOffset(0, elemTypeOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endSequenceType(builder) { + let offset = builder.endObject(); + return offset; + } + static createSequenceType(builder, elemTypeOffset) { + SequenceType.startSequenceType(builder); + SequenceType.addElemType(builder, elemTypeOffset); + return SequenceType.endSequenceType(builder); + } + } + fbs2.SequenceType = SequenceType; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class EdgeEnd { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns EdgeEnd + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @returns number + */ + nodeIndex() { + return this.bb.readUint32(this.bb_pos); + } + /** + * @returns number + */ + srcArgIndex() { + return this.bb.readInt32(this.bb_pos + 4); + } + /** + * @returns number + */ + dstArgIndex() { + return this.bb.readInt32(this.bb_pos + 8); + } + /** + * @param flatbuffers.Builder builder + * @param number node_index + * @param number src_arg_index + * @param number dst_arg_index + * @returns flatbuffers.Offset + */ + static createEdgeEnd(builder, node_index, src_arg_index, dst_arg_index) { + builder.prep(4, 12); + builder.writeInt32(dst_arg_index); + builder.writeInt32(src_arg_index); + builder.writeInt32(node_index); + return builder.offset(); + } + } + fbs2.EdgeEnd = EdgeEnd; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class NodeEdge { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns NodeEdge + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param NodeEdge= obj + * @returns NodeEdge + */ + static getRootAsNodeEdge(bb, obj) { + return (obj || new NodeEdge()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param NodeEdge= obj + * @returns NodeEdge + */ + static getSizePrefixedRootAsNodeEdge(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new NodeEdge()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @returns number + */ + nodeIndex() { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.EdgeEnd= obj + * @returns onnxruntime.experimental.fbs.EdgeEnd + */ + inputEdges(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new onnxruntime2.experimental.fbs.EdgeEnd()).__init(this.bb.__vector(this.bb_pos + offset) + index * 12, this.bb) : null; + } + /** + * @returns number + */ + inputEdgesLength() { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.EdgeEnd= obj + * @returns onnxruntime.experimental.fbs.EdgeEnd + */ + outputEdges(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? (obj || new onnxruntime2.experimental.fbs.EdgeEnd()).__init(this.bb.__vector(this.bb_pos + offset) + index * 12, this.bb) : null; + } + /** + * @returns number + */ + outputEdgesLength() { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param flatbuffers.Builder builder + */ + static startNodeEdge(builder) { + builder.startObject(3); + } + /** + * @param flatbuffers.Builder builder + * @param number nodeIndex + */ + static addNodeIndex(builder, nodeIndex) { + builder.addFieldInt32(0, nodeIndex, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset inputEdgesOffset + */ + static addInputEdges(builder, inputEdgesOffset) { + builder.addFieldOffset(1, inputEdgesOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startInputEdgesVector(builder, numElems) { + builder.startVector(12, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset outputEdgesOffset + */ + static addOutputEdges(builder, outputEdgesOffset) { + builder.addFieldOffset(2, outputEdgesOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startOutputEdgesVector(builder, numElems) { + builder.startVector(12, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endNodeEdge(builder) { + let offset = builder.endObject(); + return offset; + } + static createNodeEdge(builder, nodeIndex, inputEdgesOffset, outputEdgesOffset) { + NodeEdge.startNodeEdge(builder); + NodeEdge.addNodeIndex(builder, nodeIndex); + NodeEdge.addInputEdges(builder, inputEdgesOffset); + NodeEdge.addOutputEdges(builder, outputEdgesOffset); + return NodeEdge.endNodeEdge(builder); + } + } + fbs2.NodeEdge = NodeEdge; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class Node2 { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns Node + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Node= obj + * @returns Node + */ + static getRootAsNode(bb, obj) { + return (obj || new Node2()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Node= obj + * @returns Node + */ + static getSizePrefixedRootAsNode(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Node2()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + name(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + docString(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + domain(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @returns number + */ + sinceVersion() { + let offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.readInt32(this.bb_pos + offset) : 0; + } + /** + * @returns number + */ + index() { + let offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + opType(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @returns onnxruntime.experimental.fbs.NodeType + */ + type() { + let offset = this.bb.__offset(this.bb_pos, 16); + return offset ? ( + /** */ + this.bb.readInt32(this.bb_pos + offset) + ) : 0 /* Primitive */; + } + executionProviderType(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 18); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + inputs(index, optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 20); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + /** + * @returns number + */ + inputsLength() { + let offset = this.bb.__offset(this.bb_pos, 20); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + outputs(index, optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 22); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + /** + * @returns number + */ + outputsLength() { + let offset = this.bb.__offset(this.bb_pos, 22); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.Attribute= obj + * @returns onnxruntime.experimental.fbs.Attribute + */ + attributes(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 24); + return offset ? (obj || new onnxruntime2.experimental.fbs.Attribute()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + attributesLength() { + let offset = this.bb.__offset(this.bb_pos, 24); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param number index + * @returns number + */ + inputArgCounts(index) { + let offset = this.bb.__offset(this.bb_pos, 26); + return offset ? this.bb.readInt32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; + } + /** + * @returns number + */ + inputArgCountsLength() { + let offset = this.bb.__offset(this.bb_pos, 26); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @returns Int32Array + */ + inputArgCountsArray() { + let offset = this.bb.__offset(this.bb_pos, 26); + return offset ? new Int32Array( + this.bb.bytes().buffer, + this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), + this.bb.__vector_len(this.bb_pos + offset) + ) : null; + } + implicitInputs(index, optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 28); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + /** + * @returns number + */ + implicitInputsLength() { + let offset = this.bb.__offset(this.bb_pos, 28); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param flatbuffers.Builder builder + */ + static startNode(builder) { + builder.startObject(13); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset nameOffset + */ + static addName(builder, nameOffset) { + builder.addFieldOffset(0, nameOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset docStringOffset + */ + static addDocString(builder, docStringOffset) { + builder.addFieldOffset(1, docStringOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset domainOffset + */ + static addDomain(builder, domainOffset) { + builder.addFieldOffset(2, domainOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param number sinceVersion + */ + static addSinceVersion(builder, sinceVersion) { + builder.addFieldInt32(3, sinceVersion, 0); + } + /** + * @param flatbuffers.Builder builder + * @param number index + */ + static addIndex(builder, index) { + builder.addFieldInt32(4, index, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset opTypeOffset + */ + static addOpType(builder, opTypeOffset) { + builder.addFieldOffset(5, opTypeOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param onnxruntime.experimental.fbs.NodeType type + */ + static addType(builder, type) { + builder.addFieldInt32(6, type, 0 /* Primitive */); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset executionProviderTypeOffset + */ + static addExecutionProviderType(builder, executionProviderTypeOffset) { + builder.addFieldOffset(7, executionProviderTypeOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset inputsOffset + */ + static addInputs(builder, inputsOffset) { + builder.addFieldOffset(8, inputsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createInputsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startInputsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset outputsOffset + */ + static addOutputs(builder, outputsOffset) { + builder.addFieldOffset(9, outputsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createOutputsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startOutputsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset attributesOffset + */ + static addAttributes(builder, attributesOffset) { + builder.addFieldOffset(10, attributesOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createAttributesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startAttributesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset inputArgCountsOffset + */ + static addInputArgCounts(builder, inputArgCountsOffset) { + builder.addFieldOffset(11, inputArgCountsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createInputArgCountsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startInputArgCountsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset implicitInputsOffset + */ + static addImplicitInputs(builder, implicitInputsOffset) { + builder.addFieldOffset(12, implicitInputsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createImplicitInputsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startImplicitInputsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endNode(builder) { + let offset = builder.endObject(); + return offset; + } + static createNode(builder, nameOffset, docStringOffset, domainOffset, sinceVersion, index, opTypeOffset, type, executionProviderTypeOffset, inputsOffset, outputsOffset, attributesOffset, inputArgCountsOffset, implicitInputsOffset) { + Node2.startNode(builder); + Node2.addName(builder, nameOffset); + Node2.addDocString(builder, docStringOffset); + Node2.addDomain(builder, domainOffset); + Node2.addSinceVersion(builder, sinceVersion); + Node2.addIndex(builder, index); + Node2.addOpType(builder, opTypeOffset); + Node2.addType(builder, type); + Node2.addExecutionProviderType(builder, executionProviderTypeOffset); + Node2.addInputs(builder, inputsOffset); + Node2.addOutputs(builder, outputsOffset); + Node2.addAttributes(builder, attributesOffset); + Node2.addInputArgCounts(builder, inputArgCountsOffset); + Node2.addImplicitInputs(builder, implicitInputsOffset); + return Node2.endNode(builder); + } + } + fbs2.Node = Node2; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class ValueInfo { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns ValueInfo + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param ValueInfo= obj + * @returns ValueInfo + */ + static getRootAsValueInfo(bb, obj) { + return (obj || new ValueInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param ValueInfo= obj + * @returns ValueInfo + */ + static getSizePrefixedRootAsValueInfo(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new ValueInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + name(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + docString(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @param onnxruntime.experimental.fbs.TypeInfo= obj + * @returns onnxruntime.experimental.fbs.TypeInfo|null + */ + type(obj) { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? (obj || new onnxruntime2.experimental.fbs.TypeInfo()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param flatbuffers.Builder builder + */ + static startValueInfo(builder) { + builder.startObject(3); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset nameOffset + */ + static addName(builder, nameOffset) { + builder.addFieldOffset(0, nameOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset docStringOffset + */ + static addDocString(builder, docStringOffset) { + builder.addFieldOffset(1, docStringOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset typeOffset + */ + static addType(builder, typeOffset) { + builder.addFieldOffset(2, typeOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endValueInfo(builder) { + let offset = builder.endObject(); + return offset; + } + static createValueInfo(builder, nameOffset, docStringOffset, typeOffset) { + ValueInfo.startValueInfo(builder); + ValueInfo.addName(builder, nameOffset); + ValueInfo.addDocString(builder, docStringOffset); + ValueInfo.addType(builder, typeOffset); + return ValueInfo.endValueInfo(builder); + } + } + fbs2.ValueInfo = ValueInfo; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class TypeInfo { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns TypeInfo + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param TypeInfo= obj + * @returns TypeInfo + */ + static getRootAsTypeInfo(bb, obj) { + return (obj || new TypeInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param TypeInfo= obj + * @returns TypeInfo + */ + static getSizePrefixedRootAsTypeInfo(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new TypeInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + denotation(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @returns onnxruntime.experimental.fbs.TypeInfoValue + */ + valueType() { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? ( + /** */ + this.bb.readUint8(this.bb_pos + offset) + ) : 0 /* NONE */; + } + /** + * @param flatbuffers.Table obj + * @returns ?flatbuffers.Table + */ + value(obj) { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__union(obj, this.bb_pos + offset) : null; + } + /** + * @param flatbuffers.Builder builder + */ + static startTypeInfo(builder) { + builder.startObject(3); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset denotationOffset + */ + static addDenotation(builder, denotationOffset) { + builder.addFieldOffset(0, denotationOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param onnxruntime.experimental.fbs.TypeInfoValue valueType + */ + static addValueType(builder, valueType) { + builder.addFieldInt8(1, valueType, 0 /* NONE */); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset valueOffset + */ + static addValue(builder, valueOffset) { + builder.addFieldOffset(2, valueOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endTypeInfo(builder) { + let offset = builder.endObject(); + return offset; + } + static createTypeInfo(builder, denotationOffset, valueType, valueOffset) { + TypeInfo.startTypeInfo(builder); + TypeInfo.addDenotation(builder, denotationOffset); + TypeInfo.addValueType(builder, valueType); + TypeInfo.addValue(builder, valueOffset); + return TypeInfo.endTypeInfo(builder); + } + } + fbs2.TypeInfo = TypeInfo; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class OperatorSetId { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns OperatorSetId + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param OperatorSetId= obj + * @returns OperatorSetId + */ + static getRootAsOperatorSetId(bb, obj) { + return (obj || new OperatorSetId()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param OperatorSetId= obj + * @returns OperatorSetId + */ + static getSizePrefixedRootAsOperatorSetId(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new OperatorSetId()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + domain(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @returns flatbuffers.Long + */ + version() { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0); + } + /** + * @param flatbuffers.Builder builder + */ + static startOperatorSetId(builder) { + builder.startObject(2); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset domainOffset + */ + static addDomain(builder, domainOffset) { + builder.addFieldOffset(0, domainOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Long version + */ + static addVersion(builder, version3) { + builder.addFieldInt64(1, version3, builder.createLong(0, 0)); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endOperatorSetId(builder) { + let offset = builder.endObject(); + return offset; + } + static createOperatorSetId(builder, domainOffset, version3) { + OperatorSetId.startOperatorSetId(builder); + OperatorSetId.addDomain(builder, domainOffset); + OperatorSetId.addVersion(builder, version3); + return OperatorSetId.endOperatorSetId(builder); + } + } + fbs2.OperatorSetId = OperatorSetId; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class Tensor4 { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns Tensor + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Tensor= obj + * @returns Tensor + */ + static getRootAsTensor(bb, obj) { + return (obj || new Tensor4()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Tensor= obj + * @returns Tensor + */ + static getSizePrefixedRootAsTensor(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Tensor4()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + name(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + docString(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @param number index + * @returns flatbuffers.Long + */ + dims(index) { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0); + } + /** + * @returns number + */ + dimsLength() { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @returns onnxruntime.experimental.fbs.TensorDataType + */ + dataType() { + let offset = this.bb.__offset(this.bb_pos, 10); + return offset ? ( + /** */ + this.bb.readInt32(this.bb_pos + offset) + ) : 0 /* UNDEFINED */; + } + /** + * @param number index + * @returns number + */ + rawData(index) { + let offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0; + } + /** + * @returns number + */ + rawDataLength() { + let offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @returns Uint8Array + */ + rawDataArray() { + let offset = this.bb.__offset(this.bb_pos, 12); + return offset ? new Uint8Array( + this.bb.bytes().buffer, + this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), + this.bb.__vector_len(this.bb_pos + offset) + ) : null; + } + stringData(index, optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + /** + * @returns number + */ + stringDataLength() { + let offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param flatbuffers.Builder builder + */ + static startTensor(builder) { + builder.startObject(6); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset nameOffset + */ + static addName(builder, nameOffset) { + builder.addFieldOffset(0, nameOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset docStringOffset + */ + static addDocString(builder, docStringOffset) { + builder.addFieldOffset(1, docStringOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset dimsOffset + */ + static addDims(builder, dimsOffset) { + builder.addFieldOffset(2, dimsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createDimsVector(builder, data) { + builder.startVector(8, data.length, 8); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt64(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startDimsVector(builder, numElems) { + builder.startVector(8, numElems, 8); + } + /** + * @param flatbuffers.Builder builder + * @param onnxruntime.experimental.fbs.TensorDataType dataType + */ + static addDataType(builder, dataType) { + builder.addFieldInt32(3, dataType, 0 /* UNDEFINED */); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset rawDataOffset + */ + static addRawData(builder, rawDataOffset) { + builder.addFieldOffset(4, rawDataOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createRawDataVector(builder, data) { + builder.startVector(1, data.length, 1); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt8(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startRawDataVector(builder, numElems) { + builder.startVector(1, numElems, 1); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset stringDataOffset + */ + static addStringData(builder, stringDataOffset) { + builder.addFieldOffset(5, stringDataOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createStringDataVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startStringDataVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endTensor(builder) { + let offset = builder.endObject(); + return offset; + } + static createTensor(builder, nameOffset, docStringOffset, dimsOffset, dataType, rawDataOffset, stringDataOffset) { + Tensor4.startTensor(builder); + Tensor4.addName(builder, nameOffset); + Tensor4.addDocString(builder, docStringOffset); + Tensor4.addDims(builder, dimsOffset); + Tensor4.addDataType(builder, dataType); + Tensor4.addRawData(builder, rawDataOffset); + Tensor4.addStringData(builder, stringDataOffset); + return Tensor4.endTensor(builder); + } + } + fbs2.Tensor = Tensor4; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class SparseTensor { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns SparseTensor + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param SparseTensor= obj + * @returns SparseTensor + */ + static getRootAsSparseTensor(bb, obj) { + return (obj || new SparseTensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param SparseTensor= obj + * @returns SparseTensor + */ + static getSizePrefixedRootAsSparseTensor(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new SparseTensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param onnxruntime.experimental.fbs.Tensor= obj + * @returns onnxruntime.experimental.fbs.Tensor|null + */ + values(obj) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new onnxruntime2.experimental.fbs.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param onnxruntime.experimental.fbs.Tensor= obj + * @returns onnxruntime.experimental.fbs.Tensor|null + */ + indices(obj) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new onnxruntime2.experimental.fbs.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param number index + * @returns flatbuffers.Long + */ + dims(index) { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0); + } + /** + * @returns number + */ + dimsLength() { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param flatbuffers.Builder builder + */ + static startSparseTensor(builder) { + builder.startObject(3); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset valuesOffset + */ + static addValues(builder, valuesOffset) { + builder.addFieldOffset(0, valuesOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset indicesOffset + */ + static addIndices(builder, indicesOffset) { + builder.addFieldOffset(1, indicesOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset dimsOffset + */ + static addDims(builder, dimsOffset) { + builder.addFieldOffset(2, dimsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createDimsVector(builder, data) { + builder.startVector(8, data.length, 8); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt64(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startDimsVector(builder, numElems) { + builder.startVector(8, numElems, 8); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endSparseTensor(builder) { + let offset = builder.endObject(); + return offset; + } + static createSparseTensor(builder, valuesOffset, indicesOffset, dimsOffset) { + SparseTensor.startSparseTensor(builder); + SparseTensor.addValues(builder, valuesOffset); + SparseTensor.addIndices(builder, indicesOffset); + SparseTensor.addDims(builder, dimsOffset); + return SparseTensor.endSparseTensor(builder); + } + } + fbs2.SparseTensor = SparseTensor; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class Attribute2 { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns Attribute + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Attribute= obj + * @returns Attribute + */ + static getRootAsAttribute(bb, obj) { + return (obj || new Attribute2()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Attribute= obj + * @returns Attribute + */ + static getSizePrefixedRootAsAttribute(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Attribute2()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + name(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + docString(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @returns onnxruntime.experimental.fbs.AttributeType + */ + type() { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? ( + /** */ + this.bb.readInt32(this.bb_pos + offset) + ) : 0 /* UNDEFINED */; + } + /** + * @returns number + */ + f() { + let offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.readFloat32(this.bb_pos + offset) : 0; + } + /** + * @returns flatbuffers.Long + */ + i() { + let offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0); + } + s(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @param onnxruntime.experimental.fbs.Tensor= obj + * @returns onnxruntime.experimental.fbs.Tensor|null + */ + t(obj) { + let offset = this.bb.__offset(this.bb_pos, 16); + return offset ? (obj || new onnxruntime2.experimental.fbs.Tensor()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param onnxruntime.experimental.fbs.Graph= obj + * @returns onnxruntime.experimental.fbs.Graph|null + */ + g(obj) { + let offset = this.bb.__offset(this.bb_pos, 18); + return offset ? (obj || new onnxruntime2.experimental.fbs.Graph()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param number index + * @returns number + */ + floats(index) { + let offset = this.bb.__offset(this.bb_pos, 20); + return offset ? this.bb.readFloat32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; + } + /** + * @returns number + */ + floatsLength() { + let offset = this.bb.__offset(this.bb_pos, 20); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @returns Float32Array + */ + floatsArray() { + let offset = this.bb.__offset(this.bb_pos, 20); + return offset ? new Float32Array( + this.bb.bytes().buffer, + this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), + this.bb.__vector_len(this.bb_pos + offset) + ) : null; + } + /** + * @param number index + * @returns flatbuffers.Long + */ + ints(index) { + let offset = this.bb.__offset(this.bb_pos, 22); + return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0); + } + /** + * @returns number + */ + intsLength() { + let offset = this.bb.__offset(this.bb_pos, 22); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + strings(index, optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 24); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + /** + * @returns number + */ + stringsLength() { + let offset = this.bb.__offset(this.bb_pos, 24); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.Tensor= obj + * @returns onnxruntime.experimental.fbs.Tensor + */ + tensors(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 26); + return offset ? (obj || new onnxruntime2.experimental.fbs.Tensor()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + tensorsLength() { + let offset = this.bb.__offset(this.bb_pos, 26); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.Graph= obj + * @returns onnxruntime.experimental.fbs.Graph + */ + graphs(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 28); + return offset ? (obj || new onnxruntime2.experimental.fbs.Graph()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + graphsLength() { + let offset = this.bb.__offset(this.bb_pos, 28); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param flatbuffers.Builder builder + */ + static startAttribute(builder) { + builder.startObject(13); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset nameOffset + */ + static addName(builder, nameOffset) { + builder.addFieldOffset(0, nameOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset docStringOffset + */ + static addDocString(builder, docStringOffset) { + builder.addFieldOffset(1, docStringOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param onnxruntime.experimental.fbs.AttributeType type + */ + static addType(builder, type) { + builder.addFieldInt32(2, type, 0 /* UNDEFINED */); + } + /** + * @param flatbuffers.Builder builder + * @param number f + */ + static addF(builder, f) { + builder.addFieldFloat32(3, f, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Long i + */ + static addI(builder, i) { + builder.addFieldInt64(4, i, builder.createLong(0, 0)); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset sOffset + */ + static addS(builder, sOffset) { + builder.addFieldOffset(5, sOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset tOffset + */ + static addT(builder, tOffset) { + builder.addFieldOffset(6, tOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset gOffset + */ + static addG(builder, gOffset) { + builder.addFieldOffset(7, gOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset floatsOffset + */ + static addFloats(builder, floatsOffset) { + builder.addFieldOffset(8, floatsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createFloatsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addFloat32(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startFloatsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset intsOffset + */ + static addInts(builder, intsOffset) { + builder.addFieldOffset(9, intsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createIntsVector(builder, data) { + builder.startVector(8, data.length, 8); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt64(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startIntsVector(builder, numElems) { + builder.startVector(8, numElems, 8); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset stringsOffset + */ + static addStrings(builder, stringsOffset) { + builder.addFieldOffset(10, stringsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createStringsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startStringsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset tensorsOffset + */ + static addTensors(builder, tensorsOffset) { + builder.addFieldOffset(11, tensorsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createTensorsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startTensorsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset graphsOffset + */ + static addGraphs(builder, graphsOffset) { + builder.addFieldOffset(12, graphsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createGraphsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startGraphsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endAttribute(builder) { + let offset = builder.endObject(); + return offset; + } + static createAttribute(builder, nameOffset, docStringOffset, type, f, i, sOffset, tOffset, gOffset, floatsOffset, intsOffset, stringsOffset, tensorsOffset, graphsOffset) { + Attribute2.startAttribute(builder); + Attribute2.addName(builder, nameOffset); + Attribute2.addDocString(builder, docStringOffset); + Attribute2.addType(builder, type); + Attribute2.addF(builder, f); + Attribute2.addI(builder, i); + Attribute2.addS(builder, sOffset); + Attribute2.addT(builder, tOffset); + Attribute2.addG(builder, gOffset); + Attribute2.addFloats(builder, floatsOffset); + Attribute2.addInts(builder, intsOffset); + Attribute2.addStrings(builder, stringsOffset); + Attribute2.addTensors(builder, tensorsOffset); + Attribute2.addGraphs(builder, graphsOffset); + return Attribute2.endAttribute(builder); + } + } + fbs2.Attribute = Attribute2; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class Graph2 { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns Graph + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Graph= obj + * @returns Graph + */ + static getRootAsGraph(bb, obj) { + return (obj || new Graph2()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Graph= obj + * @returns Graph + */ + static getSizePrefixedRootAsGraph(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Graph2()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.Tensor= obj + * @returns onnxruntime.experimental.fbs.Tensor + */ + initializers(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new onnxruntime2.experimental.fbs.Tensor()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + initializersLength() { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.ValueInfo= obj + * @returns onnxruntime.experimental.fbs.ValueInfo + */ + nodeArgs(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new onnxruntime2.experimental.fbs.ValueInfo()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + nodeArgsLength() { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.Node= obj + * @returns onnxruntime.experimental.fbs.Node + */ + nodes(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? (obj || new onnxruntime2.experimental.fbs.Node()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + nodesLength() { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @returns number + */ + maxNodeIndex() { + let offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.readUint32(this.bb_pos + offset) : 0; + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.NodeEdge= obj + * @returns onnxruntime.experimental.fbs.NodeEdge + */ + nodeEdges(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 12); + return offset ? (obj || new onnxruntime2.experimental.fbs.NodeEdge()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + nodeEdgesLength() { + let offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + inputs(index, optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + /** + * @returns number + */ + inputsLength() { + let offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + outputs(index, optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 16); + return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null; + } + /** + * @returns number + */ + outputsLength() { + let offset = this.bb.__offset(this.bb_pos, 16); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.SparseTensor= obj + * @returns onnxruntime.experimental.fbs.SparseTensor + */ + sparseInitializers(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 18); + return offset ? (obj || new onnxruntime2.experimental.fbs.SparseTensor()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + sparseInitializersLength() { + let offset = this.bb.__offset(this.bb_pos, 18); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param flatbuffers.Builder builder + */ + static startGraph(builder) { + builder.startObject(8); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset initializersOffset + */ + static addInitializers(builder, initializersOffset) { + builder.addFieldOffset(0, initializersOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createInitializersVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startInitializersVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset nodeArgsOffset + */ + static addNodeArgs(builder, nodeArgsOffset) { + builder.addFieldOffset(1, nodeArgsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createNodeArgsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startNodeArgsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset nodesOffset + */ + static addNodes(builder, nodesOffset) { + builder.addFieldOffset(2, nodesOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createNodesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startNodesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param number maxNodeIndex + */ + static addMaxNodeIndex(builder, maxNodeIndex) { + builder.addFieldInt32(3, maxNodeIndex, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset nodeEdgesOffset + */ + static addNodeEdges(builder, nodeEdgesOffset) { + builder.addFieldOffset(4, nodeEdgesOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createNodeEdgesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startNodeEdgesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset inputsOffset + */ + static addInputs(builder, inputsOffset) { + builder.addFieldOffset(5, inputsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createInputsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startInputsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset outputsOffset + */ + static addOutputs(builder, outputsOffset) { + builder.addFieldOffset(6, outputsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createOutputsVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startOutputsVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset sparseInitializersOffset + */ + static addSparseInitializers(builder, sparseInitializersOffset) { + builder.addFieldOffset(7, sparseInitializersOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createSparseInitializersVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startSparseInitializersVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endGraph(builder) { + let offset = builder.endObject(); + return offset; + } + static createGraph(builder, initializersOffset, nodeArgsOffset, nodesOffset, maxNodeIndex, nodeEdgesOffset, inputsOffset, outputsOffset, sparseInitializersOffset) { + Graph2.startGraph(builder); + Graph2.addInitializers(builder, initializersOffset); + Graph2.addNodeArgs(builder, nodeArgsOffset); + Graph2.addNodes(builder, nodesOffset); + Graph2.addMaxNodeIndex(builder, maxNodeIndex); + Graph2.addNodeEdges(builder, nodeEdgesOffset); + Graph2.addInputs(builder, inputsOffset); + Graph2.addOutputs(builder, outputsOffset); + Graph2.addSparseInitializers(builder, sparseInitializersOffset); + return Graph2.endGraph(builder); + } + } + fbs2.Graph = Graph2; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class Model2 { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns Model + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Model= obj + * @returns Model + */ + static getRootAsModel(bb, obj) { + return (obj || new Model2()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param Model= obj + * @returns Model + */ + static getSizePrefixedRootAsModel(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Model2()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @returns flatbuffers.Long + */ + irVersion() { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0); + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.OperatorSetId= obj + * @returns onnxruntime.experimental.fbs.OperatorSetId + */ + opsetImport(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new onnxruntime2.experimental.fbs.OperatorSetId()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + opsetImportLength() { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + producerName(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + producerVersion(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 10); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + domain(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 12); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @returns flatbuffers.Long + */ + modelVersion() { + let offset = this.bb.__offset(this.bb_pos, 14); + return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0); + } + docString(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 16); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @param onnxruntime.experimental.fbs.Graph= obj + * @returns onnxruntime.experimental.fbs.Graph|null + */ + graph(obj) { + let offset = this.bb.__offset(this.bb_pos, 18); + return offset ? (obj || new onnxruntime2.experimental.fbs.Graph()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + graphDocString(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 20); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @param flatbuffers.Builder builder + */ + static startModel(builder) { + builder.startObject(9); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Long irVersion + */ + static addIrVersion(builder, irVersion) { + builder.addFieldInt64(0, irVersion, builder.createLong(0, 0)); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset opsetImportOffset + */ + static addOpsetImport(builder, opsetImportOffset) { + builder.addFieldOffset(1, opsetImportOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createOpsetImportVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startOpsetImportVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset producerNameOffset + */ + static addProducerName(builder, producerNameOffset) { + builder.addFieldOffset(2, producerNameOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset producerVersionOffset + */ + static addProducerVersion(builder, producerVersionOffset) { + builder.addFieldOffset(3, producerVersionOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset domainOffset + */ + static addDomain(builder, domainOffset) { + builder.addFieldOffset(4, domainOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Long modelVersion + */ + static addModelVersion(builder, modelVersion) { + builder.addFieldInt64(5, modelVersion, builder.createLong(0, 0)); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset docStringOffset + */ + static addDocString(builder, docStringOffset) { + builder.addFieldOffset(6, docStringOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset graphOffset + */ + static addGraph(builder, graphOffset) { + builder.addFieldOffset(7, graphOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset graphDocStringOffset + */ + static addGraphDocString(builder, graphDocStringOffset) { + builder.addFieldOffset(8, graphDocStringOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endModel(builder) { + let offset = builder.endObject(); + return offset; + } + static createModel(builder, irVersion, opsetImportOffset, producerNameOffset, producerVersionOffset, domainOffset, modelVersion, docStringOffset, graphOffset, graphDocStringOffset) { + Model2.startModel(builder); + Model2.addIrVersion(builder, irVersion); + Model2.addOpsetImport(builder, opsetImportOffset); + Model2.addProducerName(builder, producerNameOffset); + Model2.addProducerVersion(builder, producerVersionOffset); + Model2.addDomain(builder, domainOffset); + Model2.addModelVersion(builder, modelVersion); + Model2.addDocString(builder, docStringOffset); + Model2.addGraph(builder, graphOffset); + Model2.addGraphDocString(builder, graphDocStringOffset); + return Model2.endModel(builder); + } + } + fbs2.Model = Model2; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class KernelCreateInfos { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns KernelCreateInfos + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param KernelCreateInfos= obj + * @returns KernelCreateInfos + */ + static getRootAsKernelCreateInfos(bb, obj) { + return (obj || new KernelCreateInfos()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param KernelCreateInfos= obj + * @returns KernelCreateInfos + */ + static getSizePrefixedRootAsKernelCreateInfos(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new KernelCreateInfos()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param number index + * @returns number + */ + nodeIndices(index) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.readUint32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0; + } + /** + * @returns number + */ + nodeIndicesLength() { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @returns Uint32Array + */ + nodeIndicesArray() { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? new Uint32Array( + this.bb.bytes().buffer, + this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), + this.bb.__vector_len(this.bb_pos + offset) + ) : null; + } + /** + * @param number index + * @returns flatbuffers.Long + */ + kernelDefHashes(index) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0); + } + /** + * @returns number + */ + kernelDefHashesLength() { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param flatbuffers.Builder builder + */ + static startKernelCreateInfos(builder) { + builder.startObject(2); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset nodeIndicesOffset + */ + static addNodeIndices(builder, nodeIndicesOffset) { + builder.addFieldOffset(0, nodeIndicesOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createNodeIndicesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt32(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startNodeIndicesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset kernelDefHashesOffset + */ + static addKernelDefHashes(builder, kernelDefHashesOffset) { + builder.addFieldOffset(1, kernelDefHashesOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createKernelDefHashesVector(builder, data) { + builder.startVector(8, data.length, 8); + for (let i = data.length - 1; i >= 0; i--) { + builder.addInt64(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startKernelDefHashesVector(builder, numElems) { + builder.startVector(8, numElems, 8); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endKernelCreateInfos(builder) { + let offset = builder.endObject(); + return offset; + } + static createKernelCreateInfos(builder, nodeIndicesOffset, kernelDefHashesOffset) { + KernelCreateInfos.startKernelCreateInfos(builder); + KernelCreateInfos.addNodeIndices(builder, nodeIndicesOffset); + KernelCreateInfos.addKernelDefHashes(builder, kernelDefHashesOffset); + return KernelCreateInfos.endKernelCreateInfos(builder); + } + } + fbs2.KernelCreateInfos = KernelCreateInfos; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class SubGraphSessionState { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns SubGraphSessionState + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param SubGraphSessionState= obj + * @returns SubGraphSessionState + */ + static getRootAsSubGraphSessionState(bb, obj) { + return (obj || new SubGraphSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param SubGraphSessionState= obj + * @returns SubGraphSessionState + */ + static getSizePrefixedRootAsSubGraphSessionState(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new SubGraphSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + graphId(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @param onnxruntime.experimental.fbs.SessionState= obj + * @returns onnxruntime.experimental.fbs.SessionState|null + */ + sessionState(obj) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new onnxruntime2.experimental.fbs.SessionState()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param flatbuffers.Builder builder + */ + static startSubGraphSessionState(builder) { + builder.startObject(2); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset graphIdOffset + */ + static addGraphId(builder, graphIdOffset) { + builder.addFieldOffset(0, graphIdOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset sessionStateOffset + */ + static addSessionState(builder, sessionStateOffset) { + builder.addFieldOffset(1, sessionStateOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endSubGraphSessionState(builder) { + let offset = builder.endObject(); + builder.requiredField(offset, 4); + return offset; + } + static createSubGraphSessionState(builder, graphIdOffset, sessionStateOffset) { + SubGraphSessionState.startSubGraphSessionState(builder); + SubGraphSessionState.addGraphId(builder, graphIdOffset); + SubGraphSessionState.addSessionState(builder, sessionStateOffset); + return SubGraphSessionState.endSubGraphSessionState(builder); + } + } + fbs2.SubGraphSessionState = SubGraphSessionState; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class SessionState { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns SessionState + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param SessionState= obj + * @returns SessionState + */ + static getRootAsSessionState(bb, obj) { + return (obj || new SessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param SessionState= obj + * @returns SessionState + */ + static getSizePrefixedRootAsSessionState(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new SessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param onnxruntime.experimental.fbs.KernelCreateInfos= obj + * @returns onnxruntime.experimental.fbs.KernelCreateInfos|null + */ + kernels(obj) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? (obj || new onnxruntime2.experimental.fbs.KernelCreateInfos()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param number index + * @param onnxruntime.experimental.fbs.SubGraphSessionState= obj + * @returns onnxruntime.experimental.fbs.SubGraphSessionState + */ + subGraphSessionStates(index, obj) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new onnxruntime2.experimental.fbs.SubGraphSessionState()).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; + } + /** + * @returns number + */ + subGraphSessionStatesLength() { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; + } + /** + * @param flatbuffers.Builder builder + */ + static startSessionState(builder) { + builder.startObject(2); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset kernelsOffset + */ + static addKernels(builder, kernelsOffset) { + builder.addFieldOffset(0, kernelsOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset subGraphSessionStatesOffset + */ + static addSubGraphSessionStates(builder, subGraphSessionStatesOffset) { + builder.addFieldOffset(1, subGraphSessionStatesOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param Array. data + * @returns flatbuffers.Offset + */ + static createSubGraphSessionStatesVector(builder, data) { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]); + } + return builder.endVector(); + } + /** + * @param flatbuffers.Builder builder + * @param number numElems + */ + static startSubGraphSessionStatesVector(builder, numElems) { + builder.startVector(4, numElems, 4); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endSessionState(builder) { + let offset = builder.endObject(); + return offset; + } + static createSessionState(builder, kernelsOffset, subGraphSessionStatesOffset) { + SessionState.startSessionState(builder); + SessionState.addKernels(builder, kernelsOffset); + SessionState.addSubGraphSessionStates(builder, subGraphSessionStatesOffset); + return SessionState.endSessionState(builder); + } + } + fbs2.SessionState = SessionState; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + ((onnxruntime2) => { + let experimental; + ((experimental2) => { + let fbs; + ((fbs2) => { + class InferenceSession4 { + constructor() { + this.bb = null; + this.bb_pos = 0; + } + /** + * @param number i + * @param flatbuffers.ByteBuffer bb + * @returns InferenceSession + */ + __init(i, bb) { + this.bb_pos = i; + this.bb = bb; + return this; + } + /** + * @param flatbuffers.ByteBuffer bb + * @param InferenceSession= obj + * @returns InferenceSession + */ + static getRootAsInferenceSession(bb, obj) { + return (obj || new InferenceSession4()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @param InferenceSession= obj + * @returns InferenceSession + */ + static getSizePrefixedRootAsInferenceSession(bb, obj) { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new InferenceSession4()).__init(bb.readInt32(bb.position()) + bb.position(), bb); + } + /** + * @param flatbuffers.ByteBuffer bb + * @returns boolean + */ + static bufferHasIdentifier(bb) { + return bb.__has_identifier("ORTM"); + } + ortVersion(optionalEncoding) { + let offset = this.bb.__offset(this.bb_pos, 4); + return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; + } + /** + * @param onnxruntime.experimental.fbs.Model= obj + * @returns onnxruntime.experimental.fbs.Model|null + */ + model(obj) { + let offset = this.bb.__offset(this.bb_pos, 6); + return offset ? (obj || new onnxruntime2.experimental.fbs.Model()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param onnxruntime.experimental.fbs.SessionState= obj + * @returns onnxruntime.experimental.fbs.SessionState|null + */ + sessionState(obj) { + let offset = this.bb.__offset(this.bb_pos, 8); + return offset ? (obj || new onnxruntime2.experimental.fbs.SessionState()).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; + } + /** + * @param flatbuffers.Builder builder + */ + static startInferenceSession(builder) { + builder.startObject(3); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset ortVersionOffset + */ + static addOrtVersion(builder, ortVersionOffset) { + builder.addFieldOffset(0, ortVersionOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset modelOffset + */ + static addModel(builder, modelOffset) { + builder.addFieldOffset(1, modelOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset sessionStateOffset + */ + static addSessionState(builder, sessionStateOffset) { + builder.addFieldOffset(2, sessionStateOffset, 0); + } + /** + * @param flatbuffers.Builder builder + * @returns flatbuffers.Offset + */ + static endInferenceSession(builder) { + let offset = builder.endObject(); + return offset; + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset offset + */ + static finishInferenceSessionBuffer(builder, offset) { + builder.finish(offset, "ORTM"); + } + /** + * @param flatbuffers.Builder builder + * @param flatbuffers.Offset offset + */ + static finishSizePrefixedInferenceSessionBuffer(builder, offset) { + builder.finish(offset, "ORTM", true); + } + static createInferenceSession(builder, ortVersionOffset, modelOffset, sessionStateOffset) { + InferenceSession4.startInferenceSession(builder); + InferenceSession4.addOrtVersion(builder, ortVersionOffset); + InferenceSession4.addModel(builder, modelOffset); + InferenceSession4.addSessionState(builder, sessionStateOffset); + return InferenceSession4.endInferenceSession(builder); + } + } + fbs2.InferenceSession = InferenceSession4; + })(fbs = experimental2.fbs || (experimental2.fbs = {})); + })(experimental = onnxruntime2.experimental || (onnxruntime2.experimental = {})); + })(onnxruntime || (onnxruntime = {})); + } +}); + +// web/node_modules/@protobufjs/aspromise/index.js +var require_aspromise = __commonJS({ + "web/node_modules/@protobufjs/aspromise/index.js"(exports2, module2) { + "use strict"; + module2.exports = asPromise; + function asPromise(fn, ctx) { + var params = new Array(arguments.length - 1), offset = 0, index = 2, pending = true; + while (index < arguments.length) + params[offset++] = arguments[index++]; + return new Promise(function executor(resolve, reject) { + params[offset] = function callback(err) { + if (pending) { + pending = false; + if (err) + reject(err); + else { + var params2 = new Array(arguments.length - 1), offset2 = 0; + while (offset2 < params2.length) + params2[offset2++] = arguments[offset2]; + resolve.apply(null, params2); + } + } + }; + try { + fn.apply(ctx || null, params); + } catch (err) { + if (pending) { + pending = false; + reject(err); + } + } + }); + } + } +}); + +// web/node_modules/@protobufjs/base64/index.js +var require_base64 = __commonJS({ + "web/node_modules/@protobufjs/base64/index.js"(exports2) { + "use strict"; + var base64 = exports2; + base64.length = function length(string) { + var p = string.length; + if (!p) + return 0; + var n = 0; + while (--p % 4 > 1 && string.charAt(p) === "=") + ++n; + return Math.ceil(string.length * 3) / 4 - n; + }; + var b64 = new Array(64); + var s64 = new Array(123); + for (i = 0; i < 64; ) + s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++; + var i; + base64.encode = function encode(buffer, start, end) { + var parts = null, chunk = []; + var i2 = 0, j = 0, t; + while (start < end) { + var b = buffer[start++]; + switch (j) { + case 0: + chunk[i2++] = b64[b >> 2]; + t = (b & 3) << 4; + j = 1; + break; + case 1: + chunk[i2++] = b64[t | b >> 4]; + t = (b & 15) << 2; + j = 2; + break; + case 2: + chunk[i2++] = b64[t | b >> 6]; + chunk[i2++] = b64[b & 63]; + j = 0; + break; + } + if (i2 > 8191) { + (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); + i2 = 0; + } + } + if (j) { + chunk[i2++] = b64[t]; + chunk[i2++] = 61; + if (j === 1) + chunk[i2++] = 61; + } + if (parts) { + if (i2) + parts.push(String.fromCharCode.apply(String, chunk.slice(0, i2))); + return parts.join(""); + } + return String.fromCharCode.apply(String, chunk.slice(0, i2)); + }; + var invalidEncoding = "invalid encoding"; + base64.decode = function decode(string, buffer, offset) { + var start = offset; + var j = 0, t; + for (var i2 = 0; i2 < string.length; ) { + var c = string.charCodeAt(i2++); + if (c === 61 && j > 1) + break; + if ((c = s64[c]) === void 0) + throw Error(invalidEncoding); + switch (j) { + case 0: + t = c; + j = 1; + break; + case 1: + buffer[offset++] = t << 2 | (c & 48) >> 4; + t = c; + j = 2; + break; + case 2: + buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2; + t = c; + j = 3; + break; + case 3: + buffer[offset++] = (t & 3) << 6 | c; + j = 0; + break; + } + } + if (j === 1) + throw Error(invalidEncoding); + return offset - start; + }; + base64.test = function test(string) { + return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string); + }; + } +}); + +// web/node_modules/@protobufjs/eventemitter/index.js +var require_eventemitter = __commonJS({ + "web/node_modules/@protobufjs/eventemitter/index.js"(exports2, module2) { + "use strict"; + module2.exports = EventEmitter; + function EventEmitter() { + this._listeners = {}; + } + EventEmitter.prototype.on = function on(evt, fn, ctx) { + (this._listeners[evt] || (this._listeners[evt] = [])).push({ + fn, + ctx: ctx || this + }); + return this; + }; + EventEmitter.prototype.off = function off(evt, fn) { + if (evt === void 0) + this._listeners = {}; + else { + if (fn === void 0) + this._listeners[evt] = []; + else { + var listeners = this._listeners[evt]; + for (var i = 0; i < listeners.length; ) + if (listeners[i].fn === fn) + listeners.splice(i, 1); + else + ++i; + } + } + return this; + }; + EventEmitter.prototype.emit = function emit(evt) { + var listeners = this._listeners[evt]; + if (listeners) { + var args = [], i = 1; + for (; i < arguments.length; ) + args.push(arguments[i++]); + for (i = 0; i < listeners.length; ) + listeners[i].fn.apply(listeners[i++].ctx, args); + } + return this; + }; + } +}); + +// web/node_modules/@protobufjs/float/index.js +var require_float = __commonJS({ + "web/node_modules/@protobufjs/float/index.js"(exports2, module2) { + "use strict"; + module2.exports = factory(factory); + function factory(exports3) { + if (typeof Float32Array !== "undefined") + (function() { + var f32 = new Float32Array([-0]), f8b = new Uint8Array(f32.buffer), le = f8b[3] === 128; + function writeFloat_f32_cpy(val, buf, pos) { + f32[0] = val; + buf[pos] = f8b[0]; + buf[pos + 1] = f8b[1]; + buf[pos + 2] = f8b[2]; + buf[pos + 3] = f8b[3]; + } + function writeFloat_f32_rev(val, buf, pos) { + f32[0] = val; + buf[pos] = f8b[3]; + buf[pos + 1] = f8b[2]; + buf[pos + 2] = f8b[1]; + buf[pos + 3] = f8b[0]; + } + exports3.writeFloatLE = le ? writeFloat_f32_cpy : writeFloat_f32_rev; + exports3.writeFloatBE = le ? writeFloat_f32_rev : writeFloat_f32_cpy; + function readFloat_f32_cpy(buf, pos) { + f8b[0] = buf[pos]; + f8b[1] = buf[pos + 1]; + f8b[2] = buf[pos + 2]; + f8b[3] = buf[pos + 3]; + return f32[0]; + } + function readFloat_f32_rev(buf, pos) { + f8b[3] = buf[pos]; + f8b[2] = buf[pos + 1]; + f8b[1] = buf[pos + 2]; + f8b[0] = buf[pos + 3]; + return f32[0]; + } + exports3.readFloatLE = le ? readFloat_f32_cpy : readFloat_f32_rev; + exports3.readFloatBE = le ? readFloat_f32_rev : readFloat_f32_cpy; + })(); + else + (function() { + function writeFloat_ieee754(writeUint, val, buf, pos) { + var sign = val < 0 ? 1 : 0; + if (sign) + val = -val; + if (val === 0) + writeUint(1 / val > 0 ? ( + /* positive */ + 0 + ) : ( + /* negative 0 */ + 2147483648 + ), buf, pos); + else if (isNaN(val)) + writeUint(2143289344, buf, pos); + else if (val > 34028234663852886e22) + writeUint((sign << 31 | 2139095040) >>> 0, buf, pos); + else if (val < 11754943508222875e-54) + writeUint((sign << 31 | Math.round(val / 1401298464324817e-60)) >>> 0, buf, pos); + else { + var exponent = Math.floor(Math.log(val) / Math.LN2), mantissa = Math.round(val * Math.pow(2, -exponent) * 8388608) & 8388607; + writeUint((sign << 31 | exponent + 127 << 23 | mantissa) >>> 0, buf, pos); + } + } + exports3.writeFloatLE = writeFloat_ieee754.bind(null, writeUintLE); + exports3.writeFloatBE = writeFloat_ieee754.bind(null, writeUintBE); + function readFloat_ieee754(readUint, buf, pos) { + var uint = readUint(buf, pos), sign = (uint >> 31) * 2 + 1, exponent = uint >>> 23 & 255, mantissa = uint & 8388607; + return exponent === 255 ? mantissa ? NaN : sign * Infinity : exponent === 0 ? sign * 1401298464324817e-60 * mantissa : sign * Math.pow(2, exponent - 150) * (mantissa + 8388608); + } + exports3.readFloatLE = readFloat_ieee754.bind(null, readUintLE); + exports3.readFloatBE = readFloat_ieee754.bind(null, readUintBE); + })(); + if (typeof Float64Array !== "undefined") + (function() { + var f64 = new Float64Array([-0]), f8b = new Uint8Array(f64.buffer), le = f8b[7] === 128; + function writeDouble_f64_cpy(val, buf, pos) { + f64[0] = val; + buf[pos] = f8b[0]; + buf[pos + 1] = f8b[1]; + buf[pos + 2] = f8b[2]; + buf[pos + 3] = f8b[3]; + buf[pos + 4] = f8b[4]; + buf[pos + 5] = f8b[5]; + buf[pos + 6] = f8b[6]; + buf[pos + 7] = f8b[7]; + } + function writeDouble_f64_rev(val, buf, pos) { + f64[0] = val; + buf[pos] = f8b[7]; + buf[pos + 1] = f8b[6]; + buf[pos + 2] = f8b[5]; + buf[pos + 3] = f8b[4]; + buf[pos + 4] = f8b[3]; + buf[pos + 5] = f8b[2]; + buf[pos + 6] = f8b[1]; + buf[pos + 7] = f8b[0]; + } + exports3.writeDoubleLE = le ? writeDouble_f64_cpy : writeDouble_f64_rev; + exports3.writeDoubleBE = le ? writeDouble_f64_rev : writeDouble_f64_cpy; + function readDouble_f64_cpy(buf, pos) { + f8b[0] = buf[pos]; + f8b[1] = buf[pos + 1]; + f8b[2] = buf[pos + 2]; + f8b[3] = buf[pos + 3]; + f8b[4] = buf[pos + 4]; + f8b[5] = buf[pos + 5]; + f8b[6] = buf[pos + 6]; + f8b[7] = buf[pos + 7]; + return f64[0]; + } + function readDouble_f64_rev(buf, pos) { + f8b[7] = buf[pos]; + f8b[6] = buf[pos + 1]; + f8b[5] = buf[pos + 2]; + f8b[4] = buf[pos + 3]; + f8b[3] = buf[pos + 4]; + f8b[2] = buf[pos + 5]; + f8b[1] = buf[pos + 6]; + f8b[0] = buf[pos + 7]; + return f64[0]; + } + exports3.readDoubleLE = le ? readDouble_f64_cpy : readDouble_f64_rev; + exports3.readDoubleBE = le ? readDouble_f64_rev : readDouble_f64_cpy; + })(); + else + (function() { + function writeDouble_ieee754(writeUint, off0, off1, val, buf, pos) { + var sign = val < 0 ? 1 : 0; + if (sign) + val = -val; + if (val === 0) { + writeUint(0, buf, pos + off0); + writeUint(1 / val > 0 ? ( + /* positive */ + 0 + ) : ( + /* negative 0 */ + 2147483648 + ), buf, pos + off1); + } else if (isNaN(val)) { + writeUint(0, buf, pos + off0); + writeUint(2146959360, buf, pos + off1); + } else if (val > 17976931348623157e292) { + writeUint(0, buf, pos + off0); + writeUint((sign << 31 | 2146435072) >>> 0, buf, pos + off1); + } else { + var mantissa; + if (val < 22250738585072014e-324) { + mantissa = val / 5e-324; + writeUint(mantissa >>> 0, buf, pos + off0); + writeUint((sign << 31 | mantissa / 4294967296) >>> 0, buf, pos + off1); + } else { + var exponent = Math.floor(Math.log(val) / Math.LN2); + if (exponent === 1024) + exponent = 1023; + mantissa = val * Math.pow(2, -exponent); + writeUint(mantissa * 4503599627370496 >>> 0, buf, pos + off0); + writeUint((sign << 31 | exponent + 1023 << 20 | mantissa * 1048576 & 1048575) >>> 0, buf, pos + off1); + } + } + } + exports3.writeDoubleLE = writeDouble_ieee754.bind(null, writeUintLE, 0, 4); + exports3.writeDoubleBE = writeDouble_ieee754.bind(null, writeUintBE, 4, 0); + function readDouble_ieee754(readUint, off0, off1, buf, pos) { + var lo = readUint(buf, pos + off0), hi = readUint(buf, pos + off1); + var sign = (hi >> 31) * 2 + 1, exponent = hi >>> 20 & 2047, mantissa = 4294967296 * (hi & 1048575) + lo; + return exponent === 2047 ? mantissa ? NaN : sign * Infinity : exponent === 0 ? sign * 5e-324 * mantissa : sign * Math.pow(2, exponent - 1075) * (mantissa + 4503599627370496); + } + exports3.readDoubleLE = readDouble_ieee754.bind(null, readUintLE, 0, 4); + exports3.readDoubleBE = readDouble_ieee754.bind(null, readUintBE, 4, 0); + })(); + return exports3; + } + function writeUintLE(val, buf, pos) { + buf[pos] = val & 255; + buf[pos + 1] = val >>> 8 & 255; + buf[pos + 2] = val >>> 16 & 255; + buf[pos + 3] = val >>> 24; + } + function writeUintBE(val, buf, pos) { + buf[pos] = val >>> 24; + buf[pos + 1] = val >>> 16 & 255; + buf[pos + 2] = val >>> 8 & 255; + buf[pos + 3] = val & 255; + } + function readUintLE(buf, pos) { + return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16 | buf[pos + 3] << 24) >>> 0; + } + function readUintBE(buf, pos) { + return (buf[pos] << 24 | buf[pos + 1] << 16 | buf[pos + 2] << 8 | buf[pos + 3]) >>> 0; + } + } +}); + +// web/node_modules/@protobufjs/inquire/index.js +var require_inquire = __commonJS({ + "web/node_modules/@protobufjs/inquire/index.js"(exports, module) { + "use strict"; + module.exports = inquire; + function inquire(moduleName) { + try { + var mod = eval("quire".replace(/^/, "re"))(moduleName); + if (mod && (mod.length || Object.keys(mod).length)) + return mod; + } catch (e) { + } + return null; + } + } +}); + +// web/node_modules/@protobufjs/utf8/index.js +var require_utf8 = __commonJS({ + "web/node_modules/@protobufjs/utf8/index.js"(exports2) { + "use strict"; + var utf8 = exports2; + utf8.length = function utf8_length(string) { + var len = 0, c = 0; + for (var i = 0; i < string.length; ++i) { + c = string.charCodeAt(i); + if (c < 128) + len += 1; + else if (c < 2048) + len += 2; + else if ((c & 64512) === 55296 && (string.charCodeAt(i + 1) & 64512) === 56320) { + ++i; + len += 4; + } else + len += 3; + } + return len; + }; + utf8.read = function utf8_read(buffer, start, end) { + var len = end - start; + if (len < 1) + return ""; + var parts = null, chunk = [], i = 0, t; + while (start < end) { + t = buffer[start++]; + if (t < 128) + chunk[i++] = t; + else if (t > 191 && t < 224) + chunk[i++] = (t & 31) << 6 | buffer[start++] & 63; + else if (t > 239 && t < 365) { + t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 65536; + chunk[i++] = 55296 + (t >> 10); + chunk[i++] = 56320 + (t & 1023); + } else + chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63; + if (i > 8191) { + (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); + i = 0; + } + } + if (parts) { + if (i) + parts.push(String.fromCharCode.apply(String, chunk.slice(0, i))); + return parts.join(""); + } + return String.fromCharCode.apply(String, chunk.slice(0, i)); + }; + utf8.write = function utf8_write(string, buffer, offset) { + var start = offset, c1, c2; + for (var i = 0; i < string.length; ++i) { + c1 = string.charCodeAt(i); + if (c1 < 128) { + buffer[offset++] = c1; + } else if (c1 < 2048) { + buffer[offset++] = c1 >> 6 | 192; + buffer[offset++] = c1 & 63 | 128; + } else if ((c1 & 64512) === 55296 && ((c2 = string.charCodeAt(i + 1)) & 64512) === 56320) { + c1 = 65536 + ((c1 & 1023) << 10) + (c2 & 1023); + ++i; + buffer[offset++] = c1 >> 18 | 240; + buffer[offset++] = c1 >> 12 & 63 | 128; + buffer[offset++] = c1 >> 6 & 63 | 128; + buffer[offset++] = c1 & 63 | 128; + } else { + buffer[offset++] = c1 >> 12 | 224; + buffer[offset++] = c1 >> 6 & 63 | 128; + buffer[offset++] = c1 & 63 | 128; + } + } + return offset - start; + }; + } +}); + +// web/node_modules/@protobufjs/pool/index.js +var require_pool = __commonJS({ + "web/node_modules/@protobufjs/pool/index.js"(exports2, module2) { + "use strict"; + module2.exports = pool; + function pool(alloc, slice2, size) { + var SIZE = size || 8192; + var MAX = SIZE >>> 1; + var slab = null; + var offset = SIZE; + return function pool_alloc(size2) { + if (size2 < 1 || size2 > MAX) + return alloc(size2); + if (offset + size2 > SIZE) { + slab = alloc(SIZE); + offset = 0; + } + var buf = slice2.call(slab, offset, offset += size2); + if (offset & 7) + offset = (offset | 7) + 1; + return buf; + }; + } + } +}); + +// web/node_modules/protobufjs/src/util/longbits.js +var require_longbits = __commonJS({ + "web/node_modules/protobufjs/src/util/longbits.js"(exports2, module2) { + "use strict"; + module2.exports = LongBits; + var util = require_minimal(); + function LongBits(lo, hi) { + this.lo = lo >>> 0; + this.hi = hi >>> 0; + } + var zero = LongBits.zero = new LongBits(0, 0); + zero.toNumber = function() { + return 0; + }; + zero.zzEncode = zero.zzDecode = function() { + return this; + }; + zero.length = function() { + return 1; + }; + var zeroHash = LongBits.zeroHash = "\0\0\0\0\0\0\0\0"; + LongBits.fromNumber = function fromNumber2(value) { + if (value === 0) + return zero; + var sign = value < 0; + if (sign) + value = -value; + var lo = value >>> 0, hi = (value - lo) / 4294967296 >>> 0; + if (sign) { + hi = ~hi >>> 0; + lo = ~lo >>> 0; + if (++lo > 4294967295) { + lo = 0; + if (++hi > 4294967295) + hi = 0; + } + } + return new LongBits(lo, hi); + }; + LongBits.from = function from(value) { + if (typeof value === "number") + return LongBits.fromNumber(value); + if (util.isString(value)) { + if (util.Long) + value = util.Long.fromString(value); + else + return LongBits.fromNumber(parseInt(value, 10)); + } + return value.low || value.high ? new LongBits(value.low >>> 0, value.high >>> 0) : zero; + }; + LongBits.prototype.toNumber = function toNumber2(unsigned) { + if (!unsigned && this.hi >>> 31) { + var lo = ~this.lo + 1 >>> 0, hi = ~this.hi >>> 0; + if (!lo) + hi = hi + 1 >>> 0; + return -(lo + hi * 4294967296); + } + return this.lo + this.hi * 4294967296; + }; + LongBits.prototype.toLong = function toLong(unsigned) { + return util.Long ? new util.Long(this.lo | 0, this.hi | 0, Boolean(unsigned)) : { low: this.lo | 0, high: this.hi | 0, unsigned: Boolean(unsigned) }; + }; + var charCodeAt = String.prototype.charCodeAt; + LongBits.fromHash = function fromHash(hash) { + if (hash === zeroHash) + return zero; + return new LongBits( + (charCodeAt.call(hash, 0) | charCodeAt.call(hash, 1) << 8 | charCodeAt.call(hash, 2) << 16 | charCodeAt.call(hash, 3) << 24) >>> 0, + (charCodeAt.call(hash, 4) | charCodeAt.call(hash, 5) << 8 | charCodeAt.call(hash, 6) << 16 | charCodeAt.call(hash, 7) << 24) >>> 0 + ); + }; + LongBits.prototype.toHash = function toHash() { + return String.fromCharCode( + this.lo & 255, + this.lo >>> 8 & 255, + this.lo >>> 16 & 255, + this.lo >>> 24, + this.hi & 255, + this.hi >>> 8 & 255, + this.hi >>> 16 & 255, + this.hi >>> 24 + ); + }; + LongBits.prototype.zzEncode = function zzEncode() { + var mask = this.hi >> 31; + this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0; + this.lo = (this.lo << 1 ^ mask) >>> 0; + return this; + }; + LongBits.prototype.zzDecode = function zzDecode() { + var mask = -(this.lo & 1); + this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0; + this.hi = (this.hi >>> 1 ^ mask) >>> 0; + return this; + }; + LongBits.prototype.length = function length() { + var part0 = this.lo, part1 = (this.lo >>> 28 | this.hi << 4) >>> 0, part2 = this.hi >>> 24; + return part2 === 0 ? part1 === 0 ? part0 < 16384 ? part0 < 128 ? 1 : 2 : part0 < 2097152 ? 3 : 4 : part1 < 16384 ? part1 < 128 ? 5 : 6 : part1 < 2097152 ? 7 : 8 : part2 < 128 ? 9 : 10; + }; + } +}); + +// web/node_modules/protobufjs/src/util/minimal.js +var require_minimal = __commonJS({ + "web/node_modules/protobufjs/src/util/minimal.js"(exports2) { + "use strict"; + var util = exports2; + util.asPromise = require_aspromise(); + util.base64 = require_base64(); + util.EventEmitter = require_eventemitter(); + util.float = require_float(); + util.inquire = require_inquire(); + util.utf8 = require_utf8(); + util.pool = require_pool(); + util.LongBits = require_longbits(); + util.isNode = Boolean(typeof global !== "undefined" && global && global.process && global.process.versions && global.process.versions.node); + util.global = util.isNode && global || typeof window !== "undefined" && window || typeof self !== "undefined" && self || exports2; + util.emptyArray = Object.freeze ? Object.freeze([]) : ( + /* istanbul ignore next */ + [] + ); + util.emptyObject = Object.freeze ? Object.freeze({}) : ( + /* istanbul ignore next */ + {} + ); + util.isInteger = Number.isInteger || /* istanbul ignore next */ + function isInteger(value) { + return typeof value === "number" && isFinite(value) && Math.floor(value) === value; + }; + util.isString = function isString(value) { + return typeof value === "string" || value instanceof String; + }; + util.isObject = function isObject(value) { + return value && typeof value === "object"; + }; + util.isset = /** + * Checks if a property on a message is considered to be present. + * @param {Object} obj Plain object or message instance + * @param {string} prop Property name + * @returns {boolean} `true` if considered to be present, otherwise `false` + */ + util.isSet = function isSet(obj, prop) { + var value = obj[prop]; + if (value != null && obj.hasOwnProperty(prop)) + return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0; + return false; + }; + util.Buffer = function() { + try { + var Buffer2 = util.inquire("buffer").Buffer; + return Buffer2.prototype.utf8Write ? Buffer2 : ( + /* istanbul ignore next */ + null + ); + } catch (e) { + return null; + } + }(); + util._Buffer_from = null; + util._Buffer_allocUnsafe = null; + util.newBuffer = function newBuffer(sizeOrArray) { + return typeof sizeOrArray === "number" ? util.Buffer ? util._Buffer_allocUnsafe(sizeOrArray) : new util.Array(sizeOrArray) : util.Buffer ? util._Buffer_from(sizeOrArray) : typeof Uint8Array === "undefined" ? sizeOrArray : new Uint8Array(sizeOrArray); + }; + util.Array = typeof Uint8Array !== "undefined" ? Uint8Array : Array; + util.Long = /* istanbul ignore next */ + util.global.dcodeIO && /* istanbul ignore next */ + util.global.dcodeIO.Long || /* istanbul ignore next */ + util.global.Long || util.inquire("long"); + util.key2Re = /^true|false|0|1$/; + util.key32Re = /^-?(?:0|[1-9][0-9]*)$/; + util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/; + util.longToHash = function longToHash(value) { + return value ? util.LongBits.from(value).toHash() : util.LongBits.zeroHash; + }; + util.longFromHash = function longFromHash(hash, unsigned) { + var bits = util.LongBits.fromHash(hash); + if (util.Long) + return util.Long.fromBits(bits.lo, bits.hi, unsigned); + return bits.toNumber(Boolean(unsigned)); + }; + function merge(dst, src, ifNotSet) { + for (var keys = Object.keys(src), i = 0; i < keys.length; ++i) + if (dst[keys[i]] === void 0 || !ifNotSet) + dst[keys[i]] = src[keys[i]]; + return dst; + } + util.merge = merge; + util.lcFirst = function lcFirst(str) { + return str.charAt(0).toLowerCase() + str.substring(1); + }; + function newError(name2) { + function CustomError(message, properties) { + if (!(this instanceof CustomError)) + return new CustomError(message, properties); + Object.defineProperty(this, "message", { get: function() { + return message; + } }); + if (Error.captureStackTrace) + Error.captureStackTrace(this, CustomError); + else + Object.defineProperty(this, "stack", { value: new Error().stack || "" }); + if (properties) + merge(this, properties); + } + CustomError.prototype = Object.create(Error.prototype, { + constructor: { + value: CustomError, + writable: true, + enumerable: false, + configurable: true + }, + name: { + get: function get() { + return name2; + }, + set: void 0, + enumerable: false, + // configurable: false would accurately preserve the behavior of + // the original, but I'm guessing that was not intentional. + // For an actual error subclass, this property would + // be configurable. + configurable: true + }, + toString: { + value: function value() { + return this.name + ": " + this.message; + }, + writable: true, + enumerable: false, + configurable: true + } + }); + return CustomError; + } + util.newError = newError; + util.ProtocolError = newError("ProtocolError"); + util.oneOfGetter = function getOneOf(fieldNames) { + var fieldMap = {}; + for (var i = 0; i < fieldNames.length; ++i) + fieldMap[fieldNames[i]] = 1; + return function() { + for (var keys = Object.keys(this), i2 = keys.length - 1; i2 > -1; --i2) + if (fieldMap[keys[i2]] === 1 && this[keys[i2]] !== void 0 && this[keys[i2]] !== null) + return keys[i2]; + }; + }; + util.oneOfSetter = function setOneOf(fieldNames) { + return function(name2) { + for (var i = 0; i < fieldNames.length; ++i) + if (fieldNames[i] !== name2) + delete this[fieldNames[i]]; + }; + }; + util.toJSONOptions = { + longs: String, + enums: String, + bytes: String, + json: true + }; + util._configure = function() { + var Buffer2 = util.Buffer; + if (!Buffer2) { + util._Buffer_from = util._Buffer_allocUnsafe = null; + return; + } + util._Buffer_from = Buffer2.from !== Uint8Array.from && Buffer2.from || /* istanbul ignore next */ + function Buffer_from(value, encoding) { + return new Buffer2(value, encoding); + }; + util._Buffer_allocUnsafe = Buffer2.allocUnsafe || /* istanbul ignore next */ + function Buffer_allocUnsafe(size) { + return new Buffer2(size); + }; + }; + } +}); + +// web/node_modules/protobufjs/src/writer.js +var require_writer = __commonJS({ + "web/node_modules/protobufjs/src/writer.js"(exports2, module2) { + "use strict"; + module2.exports = Writer; + var util = require_minimal(); + var BufferWriter; + var LongBits = util.LongBits; + var base64 = util.base64; + var utf8 = util.utf8; + function Op(fn, len, val) { + this.fn = fn; + this.len = len; + this.next = void 0; + this.val = val; + } + function noop() { + } + function State(writer) { + this.head = writer.head; + this.tail = writer.tail; + this.len = writer.len; + this.next = writer.states; + } + function Writer() { + this.len = 0; + this.head = new Op(noop, 0, 0); + this.tail = this.head; + this.states = null; + } + var create = function create2() { + return util.Buffer ? function create_buffer_setup() { + return (Writer.create = function create_buffer() { + return new BufferWriter(); + })(); + } : function create_array() { + return new Writer(); + }; + }; + Writer.create = create(); + Writer.alloc = function alloc(size) { + return new util.Array(size); + }; + if (util.Array !== Array) + Writer.alloc = util.pool(Writer.alloc, util.Array.prototype.subarray); + Writer.prototype._push = function push(fn, len, val) { + this.tail = this.tail.next = new Op(fn, len, val); + this.len += len; + return this; + }; + function writeByte(val, buf, pos) { + buf[pos] = val & 255; + } + function writeVarint32(val, buf, pos) { + while (val > 127) { + buf[pos++] = val & 127 | 128; + val >>>= 7; + } + buf[pos] = val; + } + function VarintOp(len, val) { + this.len = len; + this.next = void 0; + this.val = val; + } + VarintOp.prototype = Object.create(Op.prototype); + VarintOp.prototype.fn = writeVarint32; + Writer.prototype.uint32 = function write_uint32(value) { + this.len += (this.tail = this.tail.next = new VarintOp( + (value = value >>> 0) < 128 ? 1 : value < 16384 ? 2 : value < 2097152 ? 3 : value < 268435456 ? 4 : 5, + value + )).len; + return this; + }; + Writer.prototype.int32 = function write_int32(value) { + return value < 0 ? this._push(writeVarint64, 10, LongBits.fromNumber(value)) : this.uint32(value); + }; + Writer.prototype.sint32 = function write_sint32(value) { + return this.uint32((value << 1 ^ value >> 31) >>> 0); + }; + function writeVarint64(val, buf, pos) { + while (val.hi) { + buf[pos++] = val.lo & 127 | 128; + val.lo = (val.lo >>> 7 | val.hi << 25) >>> 0; + val.hi >>>= 7; + } + while (val.lo > 127) { + buf[pos++] = val.lo & 127 | 128; + val.lo = val.lo >>> 7; + } + buf[pos++] = val.lo; + } + Writer.prototype.uint64 = function write_uint64(value) { + var bits = LongBits.from(value); + return this._push(writeVarint64, bits.length(), bits); + }; + Writer.prototype.int64 = Writer.prototype.uint64; + Writer.prototype.sint64 = function write_sint64(value) { + var bits = LongBits.from(value).zzEncode(); + return this._push(writeVarint64, bits.length(), bits); + }; + Writer.prototype.bool = function write_bool(value) { + return this._push(writeByte, 1, value ? 1 : 0); + }; + function writeFixed32(val, buf, pos) { + buf[pos] = val & 255; + buf[pos + 1] = val >>> 8 & 255; + buf[pos + 2] = val >>> 16 & 255; + buf[pos + 3] = val >>> 24; + } + Writer.prototype.fixed32 = function write_fixed32(value) { + return this._push(writeFixed32, 4, value >>> 0); + }; + Writer.prototype.sfixed32 = Writer.prototype.fixed32; + Writer.prototype.fixed64 = function write_fixed64(value) { + var bits = LongBits.from(value); + return this._push(writeFixed32, 4, bits.lo)._push(writeFixed32, 4, bits.hi); + }; + Writer.prototype.sfixed64 = Writer.prototype.fixed64; + Writer.prototype.float = function write_float(value) { + return this._push(util.float.writeFloatLE, 4, value); + }; + Writer.prototype.double = function write_double(value) { + return this._push(util.float.writeDoubleLE, 8, value); + }; + var writeBytes = util.Array.prototype.set ? function writeBytes_set(val, buf, pos) { + buf.set(val, pos); + } : function writeBytes_for(val, buf, pos) { + for (var i = 0; i < val.length; ++i) + buf[pos + i] = val[i]; + }; + Writer.prototype.bytes = function write_bytes(value) { + var len = value.length >>> 0; + if (!len) + return this._push(writeByte, 1, 0); + if (util.isString(value)) { + var buf = Writer.alloc(len = base64.length(value)); + base64.decode(value, buf, 0); + value = buf; + } + return this.uint32(len)._push(writeBytes, len, value); + }; + Writer.prototype.string = function write_string(value) { + var len = utf8.length(value); + return len ? this.uint32(len)._push(utf8.write, len, value) : this._push(writeByte, 1, 0); + }; + Writer.prototype.fork = function fork() { + this.states = new State(this); + this.head = this.tail = new Op(noop, 0, 0); + this.len = 0; + return this; + }; + Writer.prototype.reset = function reset() { + if (this.states) { + this.head = this.states.head; + this.tail = this.states.tail; + this.len = this.states.len; + this.states = this.states.next; + } else { + this.head = this.tail = new Op(noop, 0, 0); + this.len = 0; + } + return this; + }; + Writer.prototype.ldelim = function ldelim() { + var head = this.head, tail = this.tail, len = this.len; + this.reset().uint32(len); + if (len) { + this.tail.next = head.next; + this.tail = tail; + this.len += len; + } + return this; + }; + Writer.prototype.finish = function finish() { + var head = this.head.next, buf = this.constructor.alloc(this.len), pos = 0; + while (head) { + head.fn(head.val, buf, pos); + pos += head.len; + head = head.next; + } + return buf; + }; + Writer._configure = function(BufferWriter_) { + BufferWriter = BufferWriter_; + Writer.create = create(); + BufferWriter._configure(); + }; + } +}); + +// web/node_modules/protobufjs/src/writer_buffer.js +var require_writer_buffer = __commonJS({ + "web/node_modules/protobufjs/src/writer_buffer.js"(exports2, module2) { + "use strict"; + module2.exports = BufferWriter; + var Writer = require_writer(); + (BufferWriter.prototype = Object.create(Writer.prototype)).constructor = BufferWriter; + var util = require_minimal(); + function BufferWriter() { + Writer.call(this); + } + BufferWriter._configure = function() { + BufferWriter.alloc = util._Buffer_allocUnsafe; + BufferWriter.writeBytesBuffer = util.Buffer && util.Buffer.prototype instanceof Uint8Array && util.Buffer.prototype.set.name === "set" ? function writeBytesBuffer_set(val, buf, pos) { + buf.set(val, pos); + } : function writeBytesBuffer_copy(val, buf, pos) { + if (val.copy) + val.copy(buf, pos, 0, val.length); + else + for (var i = 0; i < val.length; ) + buf[pos++] = val[i++]; + }; + }; + BufferWriter.prototype.bytes = function write_bytes_buffer(value) { + if (util.isString(value)) + value = util._Buffer_from(value, "base64"); + var len = value.length >>> 0; + this.uint32(len); + if (len) + this._push(BufferWriter.writeBytesBuffer, len, value); + return this; + }; + function writeStringBuffer(val, buf, pos) { + if (val.length < 40) + util.utf8.write(val, buf, pos); + else if (buf.utf8Write) + buf.utf8Write(val, pos); + else + buf.write(val, pos); + } + BufferWriter.prototype.string = function write_string_buffer(value) { + var len = util.Buffer.byteLength(value); + this.uint32(len); + if (len) + this._push(writeStringBuffer, len, value); + return this; + }; + BufferWriter._configure(); + } +}); + +// web/node_modules/protobufjs/src/reader.js +var require_reader = __commonJS({ + "web/node_modules/protobufjs/src/reader.js"(exports2, module2) { + "use strict"; + module2.exports = Reader; + var util = require_minimal(); + var BufferReader; + var LongBits = util.LongBits; + var utf8 = util.utf8; + function indexOutOfRange(reader, writeLength) { + return RangeError("index out of range: " + reader.pos + " + " + (writeLength || 1) + " > " + reader.len); + } + function Reader(buffer) { + this.buf = buffer; + this.pos = 0; + this.len = buffer.length; + } + var create_array = typeof Uint8Array !== "undefined" ? function create_typed_array(buffer) { + if (buffer instanceof Uint8Array || Array.isArray(buffer)) + return new Reader(buffer); + throw Error("illegal buffer"); + } : function create_array2(buffer) { + if (Array.isArray(buffer)) + return new Reader(buffer); + throw Error("illegal buffer"); + }; + var create = function create2() { + return util.Buffer ? function create_buffer_setup(buffer) { + return (Reader.create = function create_buffer(buffer2) { + return util.Buffer.isBuffer(buffer2) ? new BufferReader(buffer2) : create_array(buffer2); + })(buffer); + } : create_array; + }; + Reader.create = create(); + Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore next */ + util.Array.prototype.slice; + Reader.prototype.uint32 = function read_uint32_setup() { + var value = 4294967295; + return function read_uint32() { + value = (this.buf[this.pos] & 127) >>> 0; + if (this.buf[this.pos++] < 128) + return value; + value = (value | (this.buf[this.pos] & 127) << 7) >>> 0; + if (this.buf[this.pos++] < 128) + return value; + value = (value | (this.buf[this.pos] & 127) << 14) >>> 0; + if (this.buf[this.pos++] < 128) + return value; + value = (value | (this.buf[this.pos] & 127) << 21) >>> 0; + if (this.buf[this.pos++] < 128) + return value; + value = (value | (this.buf[this.pos] & 15) << 28) >>> 0; + if (this.buf[this.pos++] < 128) + return value; + if ((this.pos += 5) > this.len) { + this.pos = this.len; + throw indexOutOfRange(this, 10); + } + return value; + }; + }(); + Reader.prototype.int32 = function read_int32() { + return this.uint32() | 0; + }; + Reader.prototype.sint32 = function read_sint32() { + var value = this.uint32(); + return value >>> 1 ^ -(value & 1) | 0; + }; + function readLongVarint() { + var bits = new LongBits(0, 0); + var i = 0; + if (this.len - this.pos > 4) { + for (; i < 4; ++i) { + bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + bits.lo = (bits.lo | (this.buf[this.pos] & 127) << 28) >>> 0; + bits.hi = (bits.hi | (this.buf[this.pos] & 127) >> 4) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + i = 0; + } else { + for (; i < 3; ++i) { + if (this.pos >= this.len) + throw indexOutOfRange(this); + bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + bits.lo = (bits.lo | (this.buf[this.pos++] & 127) << i * 7) >>> 0; + return bits; + } + if (this.len - this.pos > 4) { + for (; i < 5; ++i) { + bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + } else { + for (; i < 5; ++i) { + if (this.pos >= this.len) + throw indexOutOfRange(this); + bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0; + if (this.buf[this.pos++] < 128) + return bits; + } + } + throw Error("invalid varint encoding"); + } + Reader.prototype.bool = function read_bool() { + return this.uint32() !== 0; + }; + function readFixed32_end(buf, end) { + return (buf[end - 4] | buf[end - 3] << 8 | buf[end - 2] << 16 | buf[end - 1] << 24) >>> 0; + } + Reader.prototype.fixed32 = function read_fixed32() { + if (this.pos + 4 > this.len) + throw indexOutOfRange(this, 4); + return readFixed32_end(this.buf, this.pos += 4); + }; + Reader.prototype.sfixed32 = function read_sfixed32() { + if (this.pos + 4 > this.len) + throw indexOutOfRange(this, 4); + return readFixed32_end(this.buf, this.pos += 4) | 0; + }; + function readFixed64() { + if (this.pos + 8 > this.len) + throw indexOutOfRange(this, 8); + return new LongBits(readFixed32_end(this.buf, this.pos += 4), readFixed32_end(this.buf, this.pos += 4)); + } + Reader.prototype.float = function read_float() { + if (this.pos + 4 > this.len) + throw indexOutOfRange(this, 4); + var value = util.float.readFloatLE(this.buf, this.pos); + this.pos += 4; + return value; + }; + Reader.prototype.double = function read_double() { + if (this.pos + 8 > this.len) + throw indexOutOfRange(this, 4); + var value = util.float.readDoubleLE(this.buf, this.pos); + this.pos += 8; + return value; + }; + Reader.prototype.bytes = function read_bytes() { + var length = this.uint32(), start = this.pos, end = this.pos + length; + if (end > this.len) + throw indexOutOfRange(this, length); + this.pos += length; + if (Array.isArray(this.buf)) + return this.buf.slice(start, end); + if (start === end) { + var nativeBuffer = util.Buffer; + return nativeBuffer ? nativeBuffer.alloc(0) : new this.buf.constructor(0); + } + return this._slice.call(this.buf, start, end); + }; + Reader.prototype.string = function read_string() { + var bytes = this.bytes(); + return utf8.read(bytes, 0, bytes.length); + }; + Reader.prototype.skip = function skip(length) { + if (typeof length === "number") { + if (this.pos + length > this.len) + throw indexOutOfRange(this, length); + this.pos += length; + } else { + do { + if (this.pos >= this.len) + throw indexOutOfRange(this); + } while (this.buf[this.pos++] & 128); + } + return this; + }; + Reader.prototype.skipType = function(wireType) { + switch (wireType) { + case 0: + this.skip(); + break; + case 1: + this.skip(8); + break; + case 2: + this.skip(this.uint32()); + break; + case 3: + while ((wireType = this.uint32() & 7) !== 4) { + this.skipType(wireType); + } + break; + case 5: + this.skip(4); + break; + default: + throw Error("invalid wire type " + wireType + " at offset " + this.pos); + } + return this; + }; + Reader._configure = function(BufferReader_) { + BufferReader = BufferReader_; + Reader.create = create(); + BufferReader._configure(); + var fn = util.Long ? "toLong" : ( + /* istanbul ignore next */ + "toNumber" + ); + util.merge(Reader.prototype, { + int64: function read_int64() { + return readLongVarint.call(this)[fn](false); + }, + uint64: function read_uint64() { + return readLongVarint.call(this)[fn](true); + }, + sint64: function read_sint64() { + return readLongVarint.call(this).zzDecode()[fn](false); + }, + fixed64: function read_fixed64() { + return readFixed64.call(this)[fn](true); + }, + sfixed64: function read_sfixed64() { + return readFixed64.call(this)[fn](false); + } + }); + }; + } +}); + +// web/node_modules/protobufjs/src/reader_buffer.js +var require_reader_buffer = __commonJS({ + "web/node_modules/protobufjs/src/reader_buffer.js"(exports2, module2) { + "use strict"; + module2.exports = BufferReader; + var Reader = require_reader(); + (BufferReader.prototype = Object.create(Reader.prototype)).constructor = BufferReader; + var util = require_minimal(); + function BufferReader(buffer) { + Reader.call(this, buffer); + } + BufferReader._configure = function() { + if (util.Buffer) + BufferReader.prototype._slice = util.Buffer.prototype.slice; + }; + BufferReader.prototype.string = function read_string_buffer() { + var len = this.uint32(); + return this.buf.utf8Slice ? this.buf.utf8Slice(this.pos, this.pos = Math.min(this.pos + len, this.len)) : this.buf.toString("utf-8", this.pos, this.pos = Math.min(this.pos + len, this.len)); + }; + BufferReader._configure(); + } +}); + +// web/node_modules/protobufjs/src/rpc/service.js +var require_service = __commonJS({ + "web/node_modules/protobufjs/src/rpc/service.js"(exports2, module2) { + "use strict"; + module2.exports = Service; + var util = require_minimal(); + (Service.prototype = Object.create(util.EventEmitter.prototype)).constructor = Service; + function Service(rpcImpl, requestDelimited, responseDelimited) { + if (typeof rpcImpl !== "function") + throw TypeError("rpcImpl must be a function"); + util.EventEmitter.call(this); + this.rpcImpl = rpcImpl; + this.requestDelimited = Boolean(requestDelimited); + this.responseDelimited = Boolean(responseDelimited); + } + Service.prototype.rpcCall = function rpcCall(method, requestCtor, responseCtor, request, callback) { + if (!request) + throw TypeError("request must be specified"); + var self2 = this; + if (!callback) + return util.asPromise(rpcCall, self2, method, requestCtor, responseCtor, request); + if (!self2.rpcImpl) { + setTimeout(function() { + callback(Error("already ended")); + }, 0); + return void 0; + } + try { + return self2.rpcImpl( + method, + requestCtor[self2.requestDelimited ? "encodeDelimited" : "encode"](request).finish(), + function rpcCallback(err, response) { + if (err) { + self2.emit("error", err, method); + return callback(err); + } + if (response === null) { + self2.end( + /* endedByRPC */ + true + ); + return void 0; + } + if (!(response instanceof responseCtor)) { + try { + response = responseCtor[self2.responseDelimited ? "decodeDelimited" : "decode"](response); + } catch (err2) { + self2.emit("error", err2, method); + return callback(err2); + } + } + self2.emit("data", response, method); + return callback(null, response); + } + ); + } catch (err) { + self2.emit("error", err, method); + setTimeout(function() { + callback(err); + }, 0); + return void 0; + } + }; + Service.prototype.end = function end(endedByRPC) { + if (this.rpcImpl) { + if (!endedByRPC) + this.rpcImpl(null, null, null); + this.rpcImpl = null; + this.emit("end").off(); + } + return this; + }; + } +}); + +// web/node_modules/protobufjs/src/rpc.js +var require_rpc = __commonJS({ + "web/node_modules/protobufjs/src/rpc.js"(exports2) { + "use strict"; + var rpc = exports2; + rpc.Service = require_service(); + } +}); + +// web/node_modules/protobufjs/src/roots.js +var require_roots = __commonJS({ + "web/node_modules/protobufjs/src/roots.js"(exports2, module2) { + "use strict"; + module2.exports = {}; + } +}); + +// web/node_modules/protobufjs/src/index-minimal.js +var require_index_minimal = __commonJS({ + "web/node_modules/protobufjs/src/index-minimal.js"(exports2) { + "use strict"; + var protobuf = exports2; + protobuf.build = "minimal"; + protobuf.Writer = require_writer(); + protobuf.BufferWriter = require_writer_buffer(); + protobuf.Reader = require_reader(); + protobuf.BufferReader = require_reader_buffer(); + protobuf.util = require_minimal(); + protobuf.rpc = require_rpc(); + protobuf.roots = require_roots(); + protobuf.configure = configure; + function configure() { + protobuf.util._configure(); + protobuf.Writer._configure(protobuf.BufferWriter); + protobuf.Reader._configure(protobuf.BufferReader); + } + configure(); + } +}); + +// web/node_modules/protobufjs/minimal.js +var require_minimal2 = __commonJS({ + "web/node_modules/protobufjs/minimal.js"(exports2, module2) { + "use strict"; + module2.exports = require_index_minimal(); + } +}); + +// web/lib/onnxjs/ort-schema/protobuf/onnx.js +var require_onnx = __commonJS({ + "web/lib/onnxjs/ort-schema/protobuf/onnx.js"(exports2, module2) { + "use strict"; + var $protobuf = require_minimal2(); + var $Reader = $protobuf.Reader; + var $Writer = $protobuf.Writer; + var $util = $protobuf.util; + var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); + $root.onnx = function() { + var onnx6 = {}; + onnx6.Version = function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "_START_VERSION"] = 0; + values[valuesById[1] = "IR_VERSION_2017_10_10"] = 1; + values[valuesById[2] = "IR_VERSION_2017_10_30"] = 2; + values[valuesById[3] = "IR_VERSION_2017_11_3"] = 3; + values[valuesById[4] = "IR_VERSION_2019_1_22"] = 4; + values[valuesById[5] = "IR_VERSION_2019_3_18"] = 5; + values[valuesById[6] = "IR_VERSION_2019_9_19"] = 6; + values[valuesById[7] = "IR_VERSION_2020_5_8"] = 7; + values[valuesById[8] = "IR_VERSION_2021_7_30"] = 8; + values[valuesById[9] = "IR_VERSION"] = 9; + return values; + }(); + onnx6.AttributeProto = function() { + function AttributeProto(properties) { + this.floats = []; + this.ints = []; + this.strings = []; + this.tensors = []; + this.graphs = []; + this.sparseTensors = []; + this.typeProtos = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + AttributeProto.prototype.name = ""; + AttributeProto.prototype.refAttrName = ""; + AttributeProto.prototype.docString = ""; + AttributeProto.prototype.type = 0; + AttributeProto.prototype.f = 0; + AttributeProto.prototype.i = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + AttributeProto.prototype.s = $util.newBuffer([]); + AttributeProto.prototype.t = null; + AttributeProto.prototype.g = null; + AttributeProto.prototype.sparseTensor = null; + AttributeProto.prototype.tp = null; + AttributeProto.prototype.floats = $util.emptyArray; + AttributeProto.prototype.ints = $util.emptyArray; + AttributeProto.prototype.strings = $util.emptyArray; + AttributeProto.prototype.tensors = $util.emptyArray; + AttributeProto.prototype.graphs = $util.emptyArray; + AttributeProto.prototype.sparseTensors = $util.emptyArray; + AttributeProto.prototype.typeProtos = $util.emptyArray; + AttributeProto.create = function create(properties) { + return new AttributeProto(properties); + }; + AttributeProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.name); + if (message.f != null && Object.hasOwnProperty.call(message, "f")) + writer.uint32( + /* id 2, wireType 5 =*/ + 21 + ).float(message.f); + if (message.i != null && Object.hasOwnProperty.call(message, "i")) + writer.uint32( + /* id 3, wireType 0 =*/ + 24 + ).int64(message.i); + if (message.s != null && Object.hasOwnProperty.call(message, "s")) + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).bytes(message.s); + if (message.t != null && Object.hasOwnProperty.call(message, "t")) + $root.onnx.TensorProto.encode(message.t, writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).fork()).ldelim(); + if (message.g != null && Object.hasOwnProperty.call(message, "g")) + $root.onnx.GraphProto.encode(message.g, writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).fork()).ldelim(); + if (message.floats != null && message.floats.length) { + writer.uint32( + /* id 7, wireType 2 =*/ + 58 + ).fork(); + for (var i = 0; i < message.floats.length; ++i) + writer.float(message.floats[i]); + writer.ldelim(); + } + if (message.ints != null && message.ints.length) { + writer.uint32( + /* id 8, wireType 2 =*/ + 66 + ).fork(); + for (var i = 0; i < message.ints.length; ++i) + writer.int64(message.ints[i]); + writer.ldelim(); + } + if (message.strings != null && message.strings.length) + for (var i = 0; i < message.strings.length; ++i) + writer.uint32( + /* id 9, wireType 2 =*/ + 74 + ).bytes(message.strings[i]); + if (message.tensors != null && message.tensors.length) + for (var i = 0; i < message.tensors.length; ++i) + $root.onnx.TensorProto.encode(message.tensors[i], writer.uint32( + /* id 10, wireType 2 =*/ + 82 + ).fork()).ldelim(); + if (message.graphs != null && message.graphs.length) + for (var i = 0; i < message.graphs.length; ++i) + $root.onnx.GraphProto.encode(message.graphs[i], writer.uint32( + /* id 11, wireType 2 =*/ + 90 + ).fork()).ldelim(); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 13, wireType 2 =*/ + 106 + ).string(message.docString); + if (message.tp != null && Object.hasOwnProperty.call(message, "tp")) + $root.onnx.TypeProto.encode(message.tp, writer.uint32( + /* id 14, wireType 2 =*/ + 114 + ).fork()).ldelim(); + if (message.typeProtos != null && message.typeProtos.length) + for (var i = 0; i < message.typeProtos.length; ++i) + $root.onnx.TypeProto.encode(message.typeProtos[i], writer.uint32( + /* id 15, wireType 2 =*/ + 122 + ).fork()).ldelim(); + if (message.type != null && Object.hasOwnProperty.call(message, "type")) + writer.uint32( + /* id 20, wireType 0 =*/ + 160 + ).int32(message.type); + if (message.refAttrName != null && Object.hasOwnProperty.call(message, "refAttrName")) + writer.uint32( + /* id 21, wireType 2 =*/ + 170 + ).string(message.refAttrName); + if (message.sparseTensor != null && Object.hasOwnProperty.call(message, "sparseTensor")) + $root.onnx.SparseTensorProto.encode(message.sparseTensor, writer.uint32( + /* id 22, wireType 2 =*/ + 178 + ).fork()).ldelim(); + if (message.sparseTensors != null && message.sparseTensors.length) + for (var i = 0; i < message.sparseTensors.length; ++i) + $root.onnx.SparseTensorProto.encode(message.sparseTensors[i], writer.uint32( + /* id 23, wireType 2 =*/ + 186 + ).fork()).ldelim(); + return writer; + }; + AttributeProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + AttributeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.AttributeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.name = reader.string(); + break; + } + case 21: { + message.refAttrName = reader.string(); + break; + } + case 13: { + message.docString = reader.string(); + break; + } + case 20: { + message.type = reader.int32(); + break; + } + case 2: { + message.f = reader.float(); + break; + } + case 3: { + message.i = reader.int64(); + break; + } + case 4: { + message.s = reader.bytes(); + break; + } + case 5: { + message.t = $root.onnx.TensorProto.decode(reader, reader.uint32()); + break; + } + case 6: { + message.g = $root.onnx.GraphProto.decode(reader, reader.uint32()); + break; + } + case 22: { + message.sparseTensor = $root.onnx.SparseTensorProto.decode(reader, reader.uint32()); + break; + } + case 14: { + message.tp = $root.onnx.TypeProto.decode(reader, reader.uint32()); + break; + } + case 7: { + if (!(message.floats && message.floats.length)) + message.floats = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.floats.push(reader.float()); + } else + message.floats.push(reader.float()); + break; + } + case 8: { + if (!(message.ints && message.ints.length)) + message.ints = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.ints.push(reader.int64()); + } else + message.ints.push(reader.int64()); + break; + } + case 9: { + if (!(message.strings && message.strings.length)) + message.strings = []; + message.strings.push(reader.bytes()); + break; + } + case 10: { + if (!(message.tensors && message.tensors.length)) + message.tensors = []; + message.tensors.push($root.onnx.TensorProto.decode(reader, reader.uint32())); + break; + } + case 11: { + if (!(message.graphs && message.graphs.length)) + message.graphs = []; + message.graphs.push($root.onnx.GraphProto.decode(reader, reader.uint32())); + break; + } + case 23: { + if (!(message.sparseTensors && message.sparseTensors.length)) + message.sparseTensors = []; + message.sparseTensors.push($root.onnx.SparseTensorProto.decode(reader, reader.uint32())); + break; + } + case 15: { + if (!(message.typeProtos && message.typeProtos.length)) + message.typeProtos = []; + message.typeProtos.push($root.onnx.TypeProto.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + AttributeProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + AttributeProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) + return "name: string expected"; + } + if (message.refAttrName != null && message.hasOwnProperty("refAttrName")) { + if (!$util.isString(message.refAttrName)) + return "refAttrName: string expected"; + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) + return "docString: string expected"; + } + if (message.type != null && message.hasOwnProperty("type")) + switch (message.type) { + default: + return "type: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 11: + case 13: + case 6: + case 7: + case 8: + case 9: + case 10: + case 12: + case 14: + break; + } + if (message.f != null && message.hasOwnProperty("f")) { + if (typeof message.f !== "number") + return "f: number expected"; + } + if (message.i != null && message.hasOwnProperty("i")) { + if (!$util.isInteger(message.i) && !(message.i && $util.isInteger(message.i.low) && $util.isInteger(message.i.high))) + return "i: integer|Long expected"; + } + if (message.s != null && message.hasOwnProperty("s")) { + if (!(message.s && typeof message.s.length === "number" || $util.isString(message.s))) + return "s: buffer expected"; + } + if (message.t != null && message.hasOwnProperty("t")) { + var error = $root.onnx.TensorProto.verify(message.t); + if (error) + return "t." + error; + } + if (message.g != null && message.hasOwnProperty("g")) { + var error = $root.onnx.GraphProto.verify(message.g); + if (error) + return "g." + error; + } + if (message.sparseTensor != null && message.hasOwnProperty("sparseTensor")) { + var error = $root.onnx.SparseTensorProto.verify(message.sparseTensor); + if (error) + return "sparseTensor." + error; + } + if (message.tp != null && message.hasOwnProperty("tp")) { + var error = $root.onnx.TypeProto.verify(message.tp); + if (error) + return "tp." + error; + } + if (message.floats != null && message.hasOwnProperty("floats")) { + if (!Array.isArray(message.floats)) + return "floats: array expected"; + for (var i = 0; i < message.floats.length; ++i) + if (typeof message.floats[i] !== "number") + return "floats: number[] expected"; + } + if (message.ints != null && message.hasOwnProperty("ints")) { + if (!Array.isArray(message.ints)) + return "ints: array expected"; + for (var i = 0; i < message.ints.length; ++i) + if (!$util.isInteger(message.ints[i]) && !(message.ints[i] && $util.isInteger(message.ints[i].low) && $util.isInteger(message.ints[i].high))) + return "ints: integer|Long[] expected"; + } + if (message.strings != null && message.hasOwnProperty("strings")) { + if (!Array.isArray(message.strings)) + return "strings: array expected"; + for (var i = 0; i < message.strings.length; ++i) + if (!(message.strings[i] && typeof message.strings[i].length === "number" || $util.isString(message.strings[i]))) + return "strings: buffer[] expected"; + } + if (message.tensors != null && message.hasOwnProperty("tensors")) { + if (!Array.isArray(message.tensors)) + return "tensors: array expected"; + for (var i = 0; i < message.tensors.length; ++i) { + var error = $root.onnx.TensorProto.verify(message.tensors[i]); + if (error) + return "tensors." + error; + } + } + if (message.graphs != null && message.hasOwnProperty("graphs")) { + if (!Array.isArray(message.graphs)) + return "graphs: array expected"; + for (var i = 0; i < message.graphs.length; ++i) { + var error = $root.onnx.GraphProto.verify(message.graphs[i]); + if (error) + return "graphs." + error; + } + } + if (message.sparseTensors != null && message.hasOwnProperty("sparseTensors")) { + if (!Array.isArray(message.sparseTensors)) + return "sparseTensors: array expected"; + for (var i = 0; i < message.sparseTensors.length; ++i) { + var error = $root.onnx.SparseTensorProto.verify(message.sparseTensors[i]); + if (error) + return "sparseTensors." + error; + } + } + if (message.typeProtos != null && message.hasOwnProperty("typeProtos")) { + if (!Array.isArray(message.typeProtos)) + return "typeProtos: array expected"; + for (var i = 0; i < message.typeProtos.length; ++i) { + var error = $root.onnx.TypeProto.verify(message.typeProtos[i]); + if (error) + return "typeProtos." + error; + } + } + return null; + }; + AttributeProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.AttributeProto) + return object; + var message = new $root.onnx.AttributeProto(); + if (object.name != null) + message.name = String(object.name); + if (object.refAttrName != null) + message.refAttrName = String(object.refAttrName); + if (object.docString != null) + message.docString = String(object.docString); + switch (object.type) { + default: + if (typeof object.type === "number") { + message.type = object.type; + break; + } + break; + case "UNDEFINED": + case 0: + message.type = 0; + break; + case "FLOAT": + case 1: + message.type = 1; + break; + case "INT": + case 2: + message.type = 2; + break; + case "STRING": + case 3: + message.type = 3; + break; + case "TENSOR": + case 4: + message.type = 4; + break; + case "GRAPH": + case 5: + message.type = 5; + break; + case "SPARSE_TENSOR": + case 11: + message.type = 11; + break; + case "TYPE_PROTO": + case 13: + message.type = 13; + break; + case "FLOATS": + case 6: + message.type = 6; + break; + case "INTS": + case 7: + message.type = 7; + break; + case "STRINGS": + case 8: + message.type = 8; + break; + case "TENSORS": + case 9: + message.type = 9; + break; + case "GRAPHS": + case 10: + message.type = 10; + break; + case "SPARSE_TENSORS": + case 12: + message.type = 12; + break; + case "TYPE_PROTOS": + case 14: + message.type = 14; + break; + } + if (object.f != null) + message.f = Number(object.f); + if (object.i != null) { + if ($util.Long) + (message.i = $util.Long.fromValue(object.i)).unsigned = false; + else if (typeof object.i === "string") + message.i = parseInt(object.i, 10); + else if (typeof object.i === "number") + message.i = object.i; + else if (typeof object.i === "object") + message.i = new $util.LongBits(object.i.low >>> 0, object.i.high >>> 0).toNumber(); + } + if (object.s != null) { + if (typeof object.s === "string") + $util.base64.decode(object.s, message.s = $util.newBuffer($util.base64.length(object.s)), 0); + else if (object.s.length >= 0) + message.s = object.s; + } + if (object.t != null) { + if (typeof object.t !== "object") + throw TypeError(".onnx.AttributeProto.t: object expected"); + message.t = $root.onnx.TensorProto.fromObject(object.t); + } + if (object.g != null) { + if (typeof object.g !== "object") + throw TypeError(".onnx.AttributeProto.g: object expected"); + message.g = $root.onnx.GraphProto.fromObject(object.g); + } + if (object.sparseTensor != null) { + if (typeof object.sparseTensor !== "object") + throw TypeError(".onnx.AttributeProto.sparseTensor: object expected"); + message.sparseTensor = $root.onnx.SparseTensorProto.fromObject(object.sparseTensor); + } + if (object.tp != null) { + if (typeof object.tp !== "object") + throw TypeError(".onnx.AttributeProto.tp: object expected"); + message.tp = $root.onnx.TypeProto.fromObject(object.tp); + } + if (object.floats) { + if (!Array.isArray(object.floats)) + throw TypeError(".onnx.AttributeProto.floats: array expected"); + message.floats = []; + for (var i = 0; i < object.floats.length; ++i) + message.floats[i] = Number(object.floats[i]); + } + if (object.ints) { + if (!Array.isArray(object.ints)) + throw TypeError(".onnx.AttributeProto.ints: array expected"); + message.ints = []; + for (var i = 0; i < object.ints.length; ++i) + if ($util.Long) + (message.ints[i] = $util.Long.fromValue(object.ints[i])).unsigned = false; + else if (typeof object.ints[i] === "string") + message.ints[i] = parseInt(object.ints[i], 10); + else if (typeof object.ints[i] === "number") + message.ints[i] = object.ints[i]; + else if (typeof object.ints[i] === "object") + message.ints[i] = new $util.LongBits(object.ints[i].low >>> 0, object.ints[i].high >>> 0).toNumber(); + } + if (object.strings) { + if (!Array.isArray(object.strings)) + throw TypeError(".onnx.AttributeProto.strings: array expected"); + message.strings = []; + for (var i = 0; i < object.strings.length; ++i) + if (typeof object.strings[i] === "string") + $util.base64.decode(object.strings[i], message.strings[i] = $util.newBuffer($util.base64.length(object.strings[i])), 0); + else if (object.strings[i].length >= 0) + message.strings[i] = object.strings[i]; + } + if (object.tensors) { + if (!Array.isArray(object.tensors)) + throw TypeError(".onnx.AttributeProto.tensors: array expected"); + message.tensors = []; + for (var i = 0; i < object.tensors.length; ++i) { + if (typeof object.tensors[i] !== "object") + throw TypeError(".onnx.AttributeProto.tensors: object expected"); + message.tensors[i] = $root.onnx.TensorProto.fromObject(object.tensors[i]); + } + } + if (object.graphs) { + if (!Array.isArray(object.graphs)) + throw TypeError(".onnx.AttributeProto.graphs: array expected"); + message.graphs = []; + for (var i = 0; i < object.graphs.length; ++i) { + if (typeof object.graphs[i] !== "object") + throw TypeError(".onnx.AttributeProto.graphs: object expected"); + message.graphs[i] = $root.onnx.GraphProto.fromObject(object.graphs[i]); + } + } + if (object.sparseTensors) { + if (!Array.isArray(object.sparseTensors)) + throw TypeError(".onnx.AttributeProto.sparseTensors: array expected"); + message.sparseTensors = []; + for (var i = 0; i < object.sparseTensors.length; ++i) { + if (typeof object.sparseTensors[i] !== "object") + throw TypeError(".onnx.AttributeProto.sparseTensors: object expected"); + message.sparseTensors[i] = $root.onnx.SparseTensorProto.fromObject(object.sparseTensors[i]); + } + } + if (object.typeProtos) { + if (!Array.isArray(object.typeProtos)) + throw TypeError(".onnx.AttributeProto.typeProtos: array expected"); + message.typeProtos = []; + for (var i = 0; i < object.typeProtos.length; ++i) { + if (typeof object.typeProtos[i] !== "object") + throw TypeError(".onnx.AttributeProto.typeProtos: object expected"); + message.typeProtos[i] = $root.onnx.TypeProto.fromObject(object.typeProtos[i]); + } + } + return message; + }; + AttributeProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.floats = []; + object.ints = []; + object.strings = []; + object.tensors = []; + object.graphs = []; + object.typeProtos = []; + object.sparseTensors = []; + } + if (options.defaults) { + object.name = ""; + object.f = 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.i = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.i = options.longs === String ? "0" : 0; + if (options.bytes === String) + object.s = ""; + else { + object.s = []; + if (options.bytes !== Array) + object.s = $util.newBuffer(object.s); + } + object.t = null; + object.g = null; + object.docString = ""; + object.tp = null; + object.type = options.enums === String ? "UNDEFINED" : 0; + object.refAttrName = ""; + object.sparseTensor = null; + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.f != null && message.hasOwnProperty("f")) + object.f = options.json && !isFinite(message.f) ? String(message.f) : message.f; + if (message.i != null && message.hasOwnProperty("i")) + if (typeof message.i === "number") + object.i = options.longs === String ? String(message.i) : message.i; + else + object.i = options.longs === String ? $util.Long.prototype.toString.call(message.i) : options.longs === Number ? new $util.LongBits(message.i.low >>> 0, message.i.high >>> 0).toNumber() : message.i; + if (message.s != null && message.hasOwnProperty("s")) + object.s = options.bytes === String ? $util.base64.encode(message.s, 0, message.s.length) : options.bytes === Array ? Array.prototype.slice.call(message.s) : message.s; + if (message.t != null && message.hasOwnProperty("t")) + object.t = $root.onnx.TensorProto.toObject(message.t, options); + if (message.g != null && message.hasOwnProperty("g")) + object.g = $root.onnx.GraphProto.toObject(message.g, options); + if (message.floats && message.floats.length) { + object.floats = []; + for (var j = 0; j < message.floats.length; ++j) + object.floats[j] = options.json && !isFinite(message.floats[j]) ? String(message.floats[j]) : message.floats[j]; + } + if (message.ints && message.ints.length) { + object.ints = []; + for (var j = 0; j < message.ints.length; ++j) + if (typeof message.ints[j] === "number") + object.ints[j] = options.longs === String ? String(message.ints[j]) : message.ints[j]; + else + object.ints[j] = options.longs === String ? $util.Long.prototype.toString.call(message.ints[j]) : options.longs === Number ? new $util.LongBits(message.ints[j].low >>> 0, message.ints[j].high >>> 0).toNumber() : message.ints[j]; + } + if (message.strings && message.strings.length) { + object.strings = []; + for (var j = 0; j < message.strings.length; ++j) + object.strings[j] = options.bytes === String ? $util.base64.encode(message.strings[j], 0, message.strings[j].length) : options.bytes === Array ? Array.prototype.slice.call(message.strings[j]) : message.strings[j]; + } + if (message.tensors && message.tensors.length) { + object.tensors = []; + for (var j = 0; j < message.tensors.length; ++j) + object.tensors[j] = $root.onnx.TensorProto.toObject(message.tensors[j], options); + } + if (message.graphs && message.graphs.length) { + object.graphs = []; + for (var j = 0; j < message.graphs.length; ++j) + object.graphs[j] = $root.onnx.GraphProto.toObject(message.graphs[j], options); + } + if (message.docString != null && message.hasOwnProperty("docString")) + object.docString = message.docString; + if (message.tp != null && message.hasOwnProperty("tp")) + object.tp = $root.onnx.TypeProto.toObject(message.tp, options); + if (message.typeProtos && message.typeProtos.length) { + object.typeProtos = []; + for (var j = 0; j < message.typeProtos.length; ++j) + object.typeProtos[j] = $root.onnx.TypeProto.toObject(message.typeProtos[j], options); + } + if (message.type != null && message.hasOwnProperty("type")) + object.type = options.enums === String ? $root.onnx.AttributeProto.AttributeType[message.type] === void 0 ? message.type : $root.onnx.AttributeProto.AttributeType[message.type] : message.type; + if (message.refAttrName != null && message.hasOwnProperty("refAttrName")) + object.refAttrName = message.refAttrName; + if (message.sparseTensor != null && message.hasOwnProperty("sparseTensor")) + object.sparseTensor = $root.onnx.SparseTensorProto.toObject(message.sparseTensor, options); + if (message.sparseTensors && message.sparseTensors.length) { + object.sparseTensors = []; + for (var j = 0; j < message.sparseTensors.length; ++j) + object.sparseTensors[j] = $root.onnx.SparseTensorProto.toObject(message.sparseTensors[j], options); + } + return object; + }; + AttributeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + AttributeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.AttributeProto"; + }; + AttributeProto.AttributeType = function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNDEFINED"] = 0; + values[valuesById[1] = "FLOAT"] = 1; + values[valuesById[2] = "INT"] = 2; + values[valuesById[3] = "STRING"] = 3; + values[valuesById[4] = "TENSOR"] = 4; + values[valuesById[5] = "GRAPH"] = 5; + values[valuesById[11] = "SPARSE_TENSOR"] = 11; + values[valuesById[13] = "TYPE_PROTO"] = 13; + values[valuesById[6] = "FLOATS"] = 6; + values[valuesById[7] = "INTS"] = 7; + values[valuesById[8] = "STRINGS"] = 8; + values[valuesById[9] = "TENSORS"] = 9; + values[valuesById[10] = "GRAPHS"] = 10; + values[valuesById[12] = "SPARSE_TENSORS"] = 12; + values[valuesById[14] = "TYPE_PROTOS"] = 14; + return values; + }(); + return AttributeProto; + }(); + onnx6.ValueInfoProto = function() { + function ValueInfoProto(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + ValueInfoProto.prototype.name = ""; + ValueInfoProto.prototype.type = null; + ValueInfoProto.prototype.docString = ""; + ValueInfoProto.create = function create(properties) { + return new ValueInfoProto(properties); + }; + ValueInfoProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.name); + if (message.type != null && Object.hasOwnProperty.call(message, "type")) + $root.onnx.TypeProto.encode(message.type, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).string(message.docString); + return writer; + }; + ValueInfoProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + ValueInfoProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.ValueInfoProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.name = reader.string(); + break; + } + case 2: { + message.type = $root.onnx.TypeProto.decode(reader, reader.uint32()); + break; + } + case 3: { + message.docString = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + ValueInfoProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + ValueInfoProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) + return "name: string expected"; + } + if (message.type != null && message.hasOwnProperty("type")) { + var error = $root.onnx.TypeProto.verify(message.type); + if (error) + return "type." + error; + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) + return "docString: string expected"; + } + return null; + }; + ValueInfoProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.ValueInfoProto) + return object; + var message = new $root.onnx.ValueInfoProto(); + if (object.name != null) + message.name = String(object.name); + if (object.type != null) { + if (typeof object.type !== "object") + throw TypeError(".onnx.ValueInfoProto.type: object expected"); + message.type = $root.onnx.TypeProto.fromObject(object.type); + } + if (object.docString != null) + message.docString = String(object.docString); + return message; + }; + ValueInfoProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.name = ""; + object.type = null; + object.docString = ""; + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.type != null && message.hasOwnProperty("type")) + object.type = $root.onnx.TypeProto.toObject(message.type, options); + if (message.docString != null && message.hasOwnProperty("docString")) + object.docString = message.docString; + return object; + }; + ValueInfoProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + ValueInfoProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.ValueInfoProto"; + }; + return ValueInfoProto; + }(); + onnx6.NodeProto = function() { + function NodeProto(properties) { + this.input = []; + this.output = []; + this.attribute = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + NodeProto.prototype.input = $util.emptyArray; + NodeProto.prototype.output = $util.emptyArray; + NodeProto.prototype.name = ""; + NodeProto.prototype.opType = ""; + NodeProto.prototype.domain = ""; + NodeProto.prototype.attribute = $util.emptyArray; + NodeProto.prototype.docString = ""; + NodeProto.create = function create(properties) { + return new NodeProto(properties); + }; + NodeProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.input != null && message.input.length) + for (var i = 0; i < message.input.length; ++i) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.input[i]); + if (message.output != null && message.output.length) + for (var i = 0; i < message.output.length; ++i) + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).string(message.output[i]); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).string(message.name); + if (message.opType != null && Object.hasOwnProperty.call(message, "opType")) + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).string(message.opType); + if (message.attribute != null && message.attribute.length) + for (var i = 0; i < message.attribute.length; ++i) + $root.onnx.AttributeProto.encode(message.attribute[i], writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).fork()).ldelim(); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).string(message.docString); + if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) + writer.uint32( + /* id 7, wireType 2 =*/ + 58 + ).string(message.domain); + return writer; + }; + NodeProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + NodeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.NodeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (!(message.input && message.input.length)) + message.input = []; + message.input.push(reader.string()); + break; + } + case 2: { + if (!(message.output && message.output.length)) + message.output = []; + message.output.push(reader.string()); + break; + } + case 3: { + message.name = reader.string(); + break; + } + case 4: { + message.opType = reader.string(); + break; + } + case 7: { + message.domain = reader.string(); + break; + } + case 5: { + if (!(message.attribute && message.attribute.length)) + message.attribute = []; + message.attribute.push($root.onnx.AttributeProto.decode(reader, reader.uint32())); + break; + } + case 6: { + message.docString = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + NodeProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + NodeProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.input != null && message.hasOwnProperty("input")) { + if (!Array.isArray(message.input)) + return "input: array expected"; + for (var i = 0; i < message.input.length; ++i) + if (!$util.isString(message.input[i])) + return "input: string[] expected"; + } + if (message.output != null && message.hasOwnProperty("output")) { + if (!Array.isArray(message.output)) + return "output: array expected"; + for (var i = 0; i < message.output.length; ++i) + if (!$util.isString(message.output[i])) + return "output: string[] expected"; + } + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) + return "name: string expected"; + } + if (message.opType != null && message.hasOwnProperty("opType")) { + if (!$util.isString(message.opType)) + return "opType: string expected"; + } + if (message.domain != null && message.hasOwnProperty("domain")) { + if (!$util.isString(message.domain)) + return "domain: string expected"; + } + if (message.attribute != null && message.hasOwnProperty("attribute")) { + if (!Array.isArray(message.attribute)) + return "attribute: array expected"; + for (var i = 0; i < message.attribute.length; ++i) { + var error = $root.onnx.AttributeProto.verify(message.attribute[i]); + if (error) + return "attribute." + error; + } + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) + return "docString: string expected"; + } + return null; + }; + NodeProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.NodeProto) + return object; + var message = new $root.onnx.NodeProto(); + if (object.input) { + if (!Array.isArray(object.input)) + throw TypeError(".onnx.NodeProto.input: array expected"); + message.input = []; + for (var i = 0; i < object.input.length; ++i) + message.input[i] = String(object.input[i]); + } + if (object.output) { + if (!Array.isArray(object.output)) + throw TypeError(".onnx.NodeProto.output: array expected"); + message.output = []; + for (var i = 0; i < object.output.length; ++i) + message.output[i] = String(object.output[i]); + } + if (object.name != null) + message.name = String(object.name); + if (object.opType != null) + message.opType = String(object.opType); + if (object.domain != null) + message.domain = String(object.domain); + if (object.attribute) { + if (!Array.isArray(object.attribute)) + throw TypeError(".onnx.NodeProto.attribute: array expected"); + message.attribute = []; + for (var i = 0; i < object.attribute.length; ++i) { + if (typeof object.attribute[i] !== "object") + throw TypeError(".onnx.NodeProto.attribute: object expected"); + message.attribute[i] = $root.onnx.AttributeProto.fromObject(object.attribute[i]); + } + } + if (object.docString != null) + message.docString = String(object.docString); + return message; + }; + NodeProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.input = []; + object.output = []; + object.attribute = []; + } + if (options.defaults) { + object.name = ""; + object.opType = ""; + object.docString = ""; + object.domain = ""; + } + if (message.input && message.input.length) { + object.input = []; + for (var j = 0; j < message.input.length; ++j) + object.input[j] = message.input[j]; + } + if (message.output && message.output.length) { + object.output = []; + for (var j = 0; j < message.output.length; ++j) + object.output[j] = message.output[j]; + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.opType != null && message.hasOwnProperty("opType")) + object.opType = message.opType; + if (message.attribute && message.attribute.length) { + object.attribute = []; + for (var j = 0; j < message.attribute.length; ++j) + object.attribute[j] = $root.onnx.AttributeProto.toObject(message.attribute[j], options); + } + if (message.docString != null && message.hasOwnProperty("docString")) + object.docString = message.docString; + if (message.domain != null && message.hasOwnProperty("domain")) + object.domain = message.domain; + return object; + }; + NodeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + NodeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.NodeProto"; + }; + return NodeProto; + }(); + onnx6.TrainingInfoProto = function() { + function TrainingInfoProto(properties) { + this.initializationBinding = []; + this.updateBinding = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + TrainingInfoProto.prototype.initialization = null; + TrainingInfoProto.prototype.algorithm = null; + TrainingInfoProto.prototype.initializationBinding = $util.emptyArray; + TrainingInfoProto.prototype.updateBinding = $util.emptyArray; + TrainingInfoProto.create = function create(properties) { + return new TrainingInfoProto(properties); + }; + TrainingInfoProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.initialization != null && Object.hasOwnProperty.call(message, "initialization")) + $root.onnx.GraphProto.encode(message.initialization, writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + if (message.algorithm != null && Object.hasOwnProperty.call(message, "algorithm")) + $root.onnx.GraphProto.encode(message.algorithm, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + if (message.initializationBinding != null && message.initializationBinding.length) + for (var i = 0; i < message.initializationBinding.length; ++i) + $root.onnx.StringStringEntryProto.encode(message.initializationBinding[i], writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).fork()).ldelim(); + if (message.updateBinding != null && message.updateBinding.length) + for (var i = 0; i < message.updateBinding.length; ++i) + $root.onnx.StringStringEntryProto.encode(message.updateBinding[i], writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).fork()).ldelim(); + return writer; + }; + TrainingInfoProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + TrainingInfoProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TrainingInfoProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.initialization = $root.onnx.GraphProto.decode(reader, reader.uint32()); + break; + } + case 2: { + message.algorithm = $root.onnx.GraphProto.decode(reader, reader.uint32()); + break; + } + case 3: { + if (!(message.initializationBinding && message.initializationBinding.length)) + message.initializationBinding = []; + message.initializationBinding.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); + break; + } + case 4: { + if (!(message.updateBinding && message.updateBinding.length)) + message.updateBinding = []; + message.updateBinding.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + TrainingInfoProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + TrainingInfoProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.initialization != null && message.hasOwnProperty("initialization")) { + var error = $root.onnx.GraphProto.verify(message.initialization); + if (error) + return "initialization." + error; + } + if (message.algorithm != null && message.hasOwnProperty("algorithm")) { + var error = $root.onnx.GraphProto.verify(message.algorithm); + if (error) + return "algorithm." + error; + } + if (message.initializationBinding != null && message.hasOwnProperty("initializationBinding")) { + if (!Array.isArray(message.initializationBinding)) + return "initializationBinding: array expected"; + for (var i = 0; i < message.initializationBinding.length; ++i) { + var error = $root.onnx.StringStringEntryProto.verify(message.initializationBinding[i]); + if (error) + return "initializationBinding." + error; + } + } + if (message.updateBinding != null && message.hasOwnProperty("updateBinding")) { + if (!Array.isArray(message.updateBinding)) + return "updateBinding: array expected"; + for (var i = 0; i < message.updateBinding.length; ++i) { + var error = $root.onnx.StringStringEntryProto.verify(message.updateBinding[i]); + if (error) + return "updateBinding." + error; + } + } + return null; + }; + TrainingInfoProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TrainingInfoProto) + return object; + var message = new $root.onnx.TrainingInfoProto(); + if (object.initialization != null) { + if (typeof object.initialization !== "object") + throw TypeError(".onnx.TrainingInfoProto.initialization: object expected"); + message.initialization = $root.onnx.GraphProto.fromObject(object.initialization); + } + if (object.algorithm != null) { + if (typeof object.algorithm !== "object") + throw TypeError(".onnx.TrainingInfoProto.algorithm: object expected"); + message.algorithm = $root.onnx.GraphProto.fromObject(object.algorithm); + } + if (object.initializationBinding) { + if (!Array.isArray(object.initializationBinding)) + throw TypeError(".onnx.TrainingInfoProto.initializationBinding: array expected"); + message.initializationBinding = []; + for (var i = 0; i < object.initializationBinding.length; ++i) { + if (typeof object.initializationBinding[i] !== "object") + throw TypeError(".onnx.TrainingInfoProto.initializationBinding: object expected"); + message.initializationBinding[i] = $root.onnx.StringStringEntryProto.fromObject(object.initializationBinding[i]); + } + } + if (object.updateBinding) { + if (!Array.isArray(object.updateBinding)) + throw TypeError(".onnx.TrainingInfoProto.updateBinding: array expected"); + message.updateBinding = []; + for (var i = 0; i < object.updateBinding.length; ++i) { + if (typeof object.updateBinding[i] !== "object") + throw TypeError(".onnx.TrainingInfoProto.updateBinding: object expected"); + message.updateBinding[i] = $root.onnx.StringStringEntryProto.fromObject(object.updateBinding[i]); + } + } + return message; + }; + TrainingInfoProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.initializationBinding = []; + object.updateBinding = []; + } + if (options.defaults) { + object.initialization = null; + object.algorithm = null; + } + if (message.initialization != null && message.hasOwnProperty("initialization")) + object.initialization = $root.onnx.GraphProto.toObject(message.initialization, options); + if (message.algorithm != null && message.hasOwnProperty("algorithm")) + object.algorithm = $root.onnx.GraphProto.toObject(message.algorithm, options); + if (message.initializationBinding && message.initializationBinding.length) { + object.initializationBinding = []; + for (var j = 0; j < message.initializationBinding.length; ++j) + object.initializationBinding[j] = $root.onnx.StringStringEntryProto.toObject(message.initializationBinding[j], options); + } + if (message.updateBinding && message.updateBinding.length) { + object.updateBinding = []; + for (var j = 0; j < message.updateBinding.length; ++j) + object.updateBinding[j] = $root.onnx.StringStringEntryProto.toObject(message.updateBinding[j], options); + } + return object; + }; + TrainingInfoProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + TrainingInfoProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TrainingInfoProto"; + }; + return TrainingInfoProto; + }(); + onnx6.ModelProto = function() { + function ModelProto(properties) { + this.opsetImport = []; + this.metadataProps = []; + this.trainingInfo = []; + this.functions = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + ModelProto.prototype.irVersion = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + ModelProto.prototype.opsetImport = $util.emptyArray; + ModelProto.prototype.producerName = ""; + ModelProto.prototype.producerVersion = ""; + ModelProto.prototype.domain = ""; + ModelProto.prototype.modelVersion = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + ModelProto.prototype.docString = ""; + ModelProto.prototype.graph = null; + ModelProto.prototype.metadataProps = $util.emptyArray; + ModelProto.prototype.trainingInfo = $util.emptyArray; + ModelProto.prototype.functions = $util.emptyArray; + ModelProto.create = function create(properties) { + return new ModelProto(properties); + }; + ModelProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.irVersion != null && Object.hasOwnProperty.call(message, "irVersion")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int64(message.irVersion); + if (message.producerName != null && Object.hasOwnProperty.call(message, "producerName")) + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).string(message.producerName); + if (message.producerVersion != null && Object.hasOwnProperty.call(message, "producerVersion")) + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).string(message.producerVersion); + if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).string(message.domain); + if (message.modelVersion != null && Object.hasOwnProperty.call(message, "modelVersion")) + writer.uint32( + /* id 5, wireType 0 =*/ + 40 + ).int64(message.modelVersion); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).string(message.docString); + if (message.graph != null && Object.hasOwnProperty.call(message, "graph")) + $root.onnx.GraphProto.encode(message.graph, writer.uint32( + /* id 7, wireType 2 =*/ + 58 + ).fork()).ldelim(); + if (message.opsetImport != null && message.opsetImport.length) + for (var i = 0; i < message.opsetImport.length; ++i) + $root.onnx.OperatorSetIdProto.encode(message.opsetImport[i], writer.uint32( + /* id 8, wireType 2 =*/ + 66 + ).fork()).ldelim(); + if (message.metadataProps != null && message.metadataProps.length) + for (var i = 0; i < message.metadataProps.length; ++i) + $root.onnx.StringStringEntryProto.encode(message.metadataProps[i], writer.uint32( + /* id 14, wireType 2 =*/ + 114 + ).fork()).ldelim(); + if (message.trainingInfo != null && message.trainingInfo.length) + for (var i = 0; i < message.trainingInfo.length; ++i) + $root.onnx.TrainingInfoProto.encode(message.trainingInfo[i], writer.uint32( + /* id 20, wireType 2 =*/ + 162 + ).fork()).ldelim(); + if (message.functions != null && message.functions.length) + for (var i = 0; i < message.functions.length; ++i) + $root.onnx.FunctionProto.encode(message.functions[i], writer.uint32( + /* id 25, wireType 2 =*/ + 202 + ).fork()).ldelim(); + return writer; + }; + ModelProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + ModelProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.ModelProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.irVersion = reader.int64(); + break; + } + case 8: { + if (!(message.opsetImport && message.opsetImport.length)) + message.opsetImport = []; + message.opsetImport.push($root.onnx.OperatorSetIdProto.decode(reader, reader.uint32())); + break; + } + case 2: { + message.producerName = reader.string(); + break; + } + case 3: { + message.producerVersion = reader.string(); + break; + } + case 4: { + message.domain = reader.string(); + break; + } + case 5: { + message.modelVersion = reader.int64(); + break; + } + case 6: { + message.docString = reader.string(); + break; + } + case 7: { + message.graph = $root.onnx.GraphProto.decode(reader, reader.uint32()); + break; + } + case 14: { + if (!(message.metadataProps && message.metadataProps.length)) + message.metadataProps = []; + message.metadataProps.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); + break; + } + case 20: { + if (!(message.trainingInfo && message.trainingInfo.length)) + message.trainingInfo = []; + message.trainingInfo.push($root.onnx.TrainingInfoProto.decode(reader, reader.uint32())); + break; + } + case 25: { + if (!(message.functions && message.functions.length)) + message.functions = []; + message.functions.push($root.onnx.FunctionProto.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + ModelProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + ModelProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.irVersion != null && message.hasOwnProperty("irVersion")) { + if (!$util.isInteger(message.irVersion) && !(message.irVersion && $util.isInteger(message.irVersion.low) && $util.isInteger(message.irVersion.high))) + return "irVersion: integer|Long expected"; + } + if (message.opsetImport != null && message.hasOwnProperty("opsetImport")) { + if (!Array.isArray(message.opsetImport)) + return "opsetImport: array expected"; + for (var i = 0; i < message.opsetImport.length; ++i) { + var error = $root.onnx.OperatorSetIdProto.verify(message.opsetImport[i]); + if (error) + return "opsetImport." + error; + } + } + if (message.producerName != null && message.hasOwnProperty("producerName")) { + if (!$util.isString(message.producerName)) + return "producerName: string expected"; + } + if (message.producerVersion != null && message.hasOwnProperty("producerVersion")) { + if (!$util.isString(message.producerVersion)) + return "producerVersion: string expected"; + } + if (message.domain != null && message.hasOwnProperty("domain")) { + if (!$util.isString(message.domain)) + return "domain: string expected"; + } + if (message.modelVersion != null && message.hasOwnProperty("modelVersion")) { + if (!$util.isInteger(message.modelVersion) && !(message.modelVersion && $util.isInteger(message.modelVersion.low) && $util.isInteger(message.modelVersion.high))) + return "modelVersion: integer|Long expected"; + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) + return "docString: string expected"; + } + if (message.graph != null && message.hasOwnProperty("graph")) { + var error = $root.onnx.GraphProto.verify(message.graph); + if (error) + return "graph." + error; + } + if (message.metadataProps != null && message.hasOwnProperty("metadataProps")) { + if (!Array.isArray(message.metadataProps)) + return "metadataProps: array expected"; + for (var i = 0; i < message.metadataProps.length; ++i) { + var error = $root.onnx.StringStringEntryProto.verify(message.metadataProps[i]); + if (error) + return "metadataProps." + error; + } + } + if (message.trainingInfo != null && message.hasOwnProperty("trainingInfo")) { + if (!Array.isArray(message.trainingInfo)) + return "trainingInfo: array expected"; + for (var i = 0; i < message.trainingInfo.length; ++i) { + var error = $root.onnx.TrainingInfoProto.verify(message.trainingInfo[i]); + if (error) + return "trainingInfo." + error; + } + } + if (message.functions != null && message.hasOwnProperty("functions")) { + if (!Array.isArray(message.functions)) + return "functions: array expected"; + for (var i = 0; i < message.functions.length; ++i) { + var error = $root.onnx.FunctionProto.verify(message.functions[i]); + if (error) + return "functions." + error; + } + } + return null; + }; + ModelProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.ModelProto) + return object; + var message = new $root.onnx.ModelProto(); + if (object.irVersion != null) { + if ($util.Long) + (message.irVersion = $util.Long.fromValue(object.irVersion)).unsigned = false; + else if (typeof object.irVersion === "string") + message.irVersion = parseInt(object.irVersion, 10); + else if (typeof object.irVersion === "number") + message.irVersion = object.irVersion; + else if (typeof object.irVersion === "object") + message.irVersion = new $util.LongBits(object.irVersion.low >>> 0, object.irVersion.high >>> 0).toNumber(); + } + if (object.opsetImport) { + if (!Array.isArray(object.opsetImport)) + throw TypeError(".onnx.ModelProto.opsetImport: array expected"); + message.opsetImport = []; + for (var i = 0; i < object.opsetImport.length; ++i) { + if (typeof object.opsetImport[i] !== "object") + throw TypeError(".onnx.ModelProto.opsetImport: object expected"); + message.opsetImport[i] = $root.onnx.OperatorSetIdProto.fromObject(object.opsetImport[i]); + } + } + if (object.producerName != null) + message.producerName = String(object.producerName); + if (object.producerVersion != null) + message.producerVersion = String(object.producerVersion); + if (object.domain != null) + message.domain = String(object.domain); + if (object.modelVersion != null) { + if ($util.Long) + (message.modelVersion = $util.Long.fromValue(object.modelVersion)).unsigned = false; + else if (typeof object.modelVersion === "string") + message.modelVersion = parseInt(object.modelVersion, 10); + else if (typeof object.modelVersion === "number") + message.modelVersion = object.modelVersion; + else if (typeof object.modelVersion === "object") + message.modelVersion = new $util.LongBits(object.modelVersion.low >>> 0, object.modelVersion.high >>> 0).toNumber(); + } + if (object.docString != null) + message.docString = String(object.docString); + if (object.graph != null) { + if (typeof object.graph !== "object") + throw TypeError(".onnx.ModelProto.graph: object expected"); + message.graph = $root.onnx.GraphProto.fromObject(object.graph); + } + if (object.metadataProps) { + if (!Array.isArray(object.metadataProps)) + throw TypeError(".onnx.ModelProto.metadataProps: array expected"); + message.metadataProps = []; + for (var i = 0; i < object.metadataProps.length; ++i) { + if (typeof object.metadataProps[i] !== "object") + throw TypeError(".onnx.ModelProto.metadataProps: object expected"); + message.metadataProps[i] = $root.onnx.StringStringEntryProto.fromObject(object.metadataProps[i]); + } + } + if (object.trainingInfo) { + if (!Array.isArray(object.trainingInfo)) + throw TypeError(".onnx.ModelProto.trainingInfo: array expected"); + message.trainingInfo = []; + for (var i = 0; i < object.trainingInfo.length; ++i) { + if (typeof object.trainingInfo[i] !== "object") + throw TypeError(".onnx.ModelProto.trainingInfo: object expected"); + message.trainingInfo[i] = $root.onnx.TrainingInfoProto.fromObject(object.trainingInfo[i]); + } + } + if (object.functions) { + if (!Array.isArray(object.functions)) + throw TypeError(".onnx.ModelProto.functions: array expected"); + message.functions = []; + for (var i = 0; i < object.functions.length; ++i) { + if (typeof object.functions[i] !== "object") + throw TypeError(".onnx.ModelProto.functions: object expected"); + message.functions[i] = $root.onnx.FunctionProto.fromObject(object.functions[i]); + } + } + return message; + }; + ModelProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.opsetImport = []; + object.metadataProps = []; + object.trainingInfo = []; + object.functions = []; + } + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.irVersion = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.irVersion = options.longs === String ? "0" : 0; + object.producerName = ""; + object.producerVersion = ""; + object.domain = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.modelVersion = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.modelVersion = options.longs === String ? "0" : 0; + object.docString = ""; + object.graph = null; + } + if (message.irVersion != null && message.hasOwnProperty("irVersion")) + if (typeof message.irVersion === "number") + object.irVersion = options.longs === String ? String(message.irVersion) : message.irVersion; + else + object.irVersion = options.longs === String ? $util.Long.prototype.toString.call(message.irVersion) : options.longs === Number ? new $util.LongBits(message.irVersion.low >>> 0, message.irVersion.high >>> 0).toNumber() : message.irVersion; + if (message.producerName != null && message.hasOwnProperty("producerName")) + object.producerName = message.producerName; + if (message.producerVersion != null && message.hasOwnProperty("producerVersion")) + object.producerVersion = message.producerVersion; + if (message.domain != null && message.hasOwnProperty("domain")) + object.domain = message.domain; + if (message.modelVersion != null && message.hasOwnProperty("modelVersion")) + if (typeof message.modelVersion === "number") + object.modelVersion = options.longs === String ? String(message.modelVersion) : message.modelVersion; + else + object.modelVersion = options.longs === String ? $util.Long.prototype.toString.call(message.modelVersion) : options.longs === Number ? new $util.LongBits(message.modelVersion.low >>> 0, message.modelVersion.high >>> 0).toNumber() : message.modelVersion; + if (message.docString != null && message.hasOwnProperty("docString")) + object.docString = message.docString; + if (message.graph != null && message.hasOwnProperty("graph")) + object.graph = $root.onnx.GraphProto.toObject(message.graph, options); + if (message.opsetImport && message.opsetImport.length) { + object.opsetImport = []; + for (var j = 0; j < message.opsetImport.length; ++j) + object.opsetImport[j] = $root.onnx.OperatorSetIdProto.toObject(message.opsetImport[j], options); + } + if (message.metadataProps && message.metadataProps.length) { + object.metadataProps = []; + for (var j = 0; j < message.metadataProps.length; ++j) + object.metadataProps[j] = $root.onnx.StringStringEntryProto.toObject(message.metadataProps[j], options); + } + if (message.trainingInfo && message.trainingInfo.length) { + object.trainingInfo = []; + for (var j = 0; j < message.trainingInfo.length; ++j) + object.trainingInfo[j] = $root.onnx.TrainingInfoProto.toObject(message.trainingInfo[j], options); + } + if (message.functions && message.functions.length) { + object.functions = []; + for (var j = 0; j < message.functions.length; ++j) + object.functions[j] = $root.onnx.FunctionProto.toObject(message.functions[j], options); + } + return object; + }; + ModelProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + ModelProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.ModelProto"; + }; + return ModelProto; + }(); + onnx6.StringStringEntryProto = function() { + function StringStringEntryProto(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + StringStringEntryProto.prototype.key = ""; + StringStringEntryProto.prototype.value = ""; + StringStringEntryProto.create = function create(properties) { + return new StringStringEntryProto(properties); + }; + StringStringEntryProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.key != null && Object.hasOwnProperty.call(message, "key")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.key); + if (message.value != null && Object.hasOwnProperty.call(message, "value")) + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).string(message.value); + return writer; + }; + StringStringEntryProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + StringStringEntryProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.StringStringEntryProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.key = reader.string(); + break; + } + case 2: { + message.value = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + StringStringEntryProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + StringStringEntryProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.key != null && message.hasOwnProperty("key")) { + if (!$util.isString(message.key)) + return "key: string expected"; + } + if (message.value != null && message.hasOwnProperty("value")) { + if (!$util.isString(message.value)) + return "value: string expected"; + } + return null; + }; + StringStringEntryProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.StringStringEntryProto) + return object; + var message = new $root.onnx.StringStringEntryProto(); + if (object.key != null) + message.key = String(object.key); + if (object.value != null) + message.value = String(object.value); + return message; + }; + StringStringEntryProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.key = ""; + object.value = ""; + } + if (message.key != null && message.hasOwnProperty("key")) + object.key = message.key; + if (message.value != null && message.hasOwnProperty("value")) + object.value = message.value; + return object; + }; + StringStringEntryProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + StringStringEntryProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.StringStringEntryProto"; + }; + return StringStringEntryProto; + }(); + onnx6.TensorAnnotation = function() { + function TensorAnnotation(properties) { + this.quantParameterTensorNames = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + TensorAnnotation.prototype.tensorName = ""; + TensorAnnotation.prototype.quantParameterTensorNames = $util.emptyArray; + TensorAnnotation.create = function create(properties) { + return new TensorAnnotation(properties); + }; + TensorAnnotation.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.tensorName != null && Object.hasOwnProperty.call(message, "tensorName")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.tensorName); + if (message.quantParameterTensorNames != null && message.quantParameterTensorNames.length) + for (var i = 0; i < message.quantParameterTensorNames.length; ++i) + $root.onnx.StringStringEntryProto.encode(message.quantParameterTensorNames[i], writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + return writer; + }; + TensorAnnotation.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + TensorAnnotation.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorAnnotation(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.tensorName = reader.string(); + break; + } + case 2: { + if (!(message.quantParameterTensorNames && message.quantParameterTensorNames.length)) + message.quantParameterTensorNames = []; + message.quantParameterTensorNames.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + TensorAnnotation.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + TensorAnnotation.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.tensorName != null && message.hasOwnProperty("tensorName")) { + if (!$util.isString(message.tensorName)) + return "tensorName: string expected"; + } + if (message.quantParameterTensorNames != null && message.hasOwnProperty("quantParameterTensorNames")) { + if (!Array.isArray(message.quantParameterTensorNames)) + return "quantParameterTensorNames: array expected"; + for (var i = 0; i < message.quantParameterTensorNames.length; ++i) { + var error = $root.onnx.StringStringEntryProto.verify(message.quantParameterTensorNames[i]); + if (error) + return "quantParameterTensorNames." + error; + } + } + return null; + }; + TensorAnnotation.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TensorAnnotation) + return object; + var message = new $root.onnx.TensorAnnotation(); + if (object.tensorName != null) + message.tensorName = String(object.tensorName); + if (object.quantParameterTensorNames) { + if (!Array.isArray(object.quantParameterTensorNames)) + throw TypeError(".onnx.TensorAnnotation.quantParameterTensorNames: array expected"); + message.quantParameterTensorNames = []; + for (var i = 0; i < object.quantParameterTensorNames.length; ++i) { + if (typeof object.quantParameterTensorNames[i] !== "object") + throw TypeError(".onnx.TensorAnnotation.quantParameterTensorNames: object expected"); + message.quantParameterTensorNames[i] = $root.onnx.StringStringEntryProto.fromObject(object.quantParameterTensorNames[i]); + } + } + return message; + }; + TensorAnnotation.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.quantParameterTensorNames = []; + if (options.defaults) + object.tensorName = ""; + if (message.tensorName != null && message.hasOwnProperty("tensorName")) + object.tensorName = message.tensorName; + if (message.quantParameterTensorNames && message.quantParameterTensorNames.length) { + object.quantParameterTensorNames = []; + for (var j = 0; j < message.quantParameterTensorNames.length; ++j) + object.quantParameterTensorNames[j] = $root.onnx.StringStringEntryProto.toObject(message.quantParameterTensorNames[j], options); + } + return object; + }; + TensorAnnotation.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + TensorAnnotation.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TensorAnnotation"; + }; + return TensorAnnotation; + }(); + onnx6.GraphProto = function() { + function GraphProto(properties) { + this.node = []; + this.initializer = []; + this.sparseInitializer = []; + this.input = []; + this.output = []; + this.valueInfo = []; + this.quantizationAnnotation = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + GraphProto.prototype.node = $util.emptyArray; + GraphProto.prototype.name = ""; + GraphProto.prototype.initializer = $util.emptyArray; + GraphProto.prototype.sparseInitializer = $util.emptyArray; + GraphProto.prototype.docString = ""; + GraphProto.prototype.input = $util.emptyArray; + GraphProto.prototype.output = $util.emptyArray; + GraphProto.prototype.valueInfo = $util.emptyArray; + GraphProto.prototype.quantizationAnnotation = $util.emptyArray; + GraphProto.create = function create(properties) { + return new GraphProto(properties); + }; + GraphProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.node != null && message.node.length) + for (var i = 0; i < message.node.length; ++i) + $root.onnx.NodeProto.encode(message.node[i], writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).string(message.name); + if (message.initializer != null && message.initializer.length) + for (var i = 0; i < message.initializer.length; ++i) + $root.onnx.TensorProto.encode(message.initializer[i], writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).fork()).ldelim(); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 10, wireType 2 =*/ + 82 + ).string(message.docString); + if (message.input != null && message.input.length) + for (var i = 0; i < message.input.length; ++i) + $root.onnx.ValueInfoProto.encode(message.input[i], writer.uint32( + /* id 11, wireType 2 =*/ + 90 + ).fork()).ldelim(); + if (message.output != null && message.output.length) + for (var i = 0; i < message.output.length; ++i) + $root.onnx.ValueInfoProto.encode(message.output[i], writer.uint32( + /* id 12, wireType 2 =*/ + 98 + ).fork()).ldelim(); + if (message.valueInfo != null && message.valueInfo.length) + for (var i = 0; i < message.valueInfo.length; ++i) + $root.onnx.ValueInfoProto.encode(message.valueInfo[i], writer.uint32( + /* id 13, wireType 2 =*/ + 106 + ).fork()).ldelim(); + if (message.quantizationAnnotation != null && message.quantizationAnnotation.length) + for (var i = 0; i < message.quantizationAnnotation.length; ++i) + $root.onnx.TensorAnnotation.encode(message.quantizationAnnotation[i], writer.uint32( + /* id 14, wireType 2 =*/ + 114 + ).fork()).ldelim(); + if (message.sparseInitializer != null && message.sparseInitializer.length) + for (var i = 0; i < message.sparseInitializer.length; ++i) + $root.onnx.SparseTensorProto.encode(message.sparseInitializer[i], writer.uint32( + /* id 15, wireType 2 =*/ + 122 + ).fork()).ldelim(); + return writer; + }; + GraphProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + GraphProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.GraphProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (!(message.node && message.node.length)) + message.node = []; + message.node.push($root.onnx.NodeProto.decode(reader, reader.uint32())); + break; + } + case 2: { + message.name = reader.string(); + break; + } + case 5: { + if (!(message.initializer && message.initializer.length)) + message.initializer = []; + message.initializer.push($root.onnx.TensorProto.decode(reader, reader.uint32())); + break; + } + case 15: { + if (!(message.sparseInitializer && message.sparseInitializer.length)) + message.sparseInitializer = []; + message.sparseInitializer.push($root.onnx.SparseTensorProto.decode(reader, reader.uint32())); + break; + } + case 10: { + message.docString = reader.string(); + break; + } + case 11: { + if (!(message.input && message.input.length)) + message.input = []; + message.input.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32())); + break; + } + case 12: { + if (!(message.output && message.output.length)) + message.output = []; + message.output.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32())); + break; + } + case 13: { + if (!(message.valueInfo && message.valueInfo.length)) + message.valueInfo = []; + message.valueInfo.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32())); + break; + } + case 14: { + if (!(message.quantizationAnnotation && message.quantizationAnnotation.length)) + message.quantizationAnnotation = []; + message.quantizationAnnotation.push($root.onnx.TensorAnnotation.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + GraphProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + GraphProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.node != null && message.hasOwnProperty("node")) { + if (!Array.isArray(message.node)) + return "node: array expected"; + for (var i = 0; i < message.node.length; ++i) { + var error = $root.onnx.NodeProto.verify(message.node[i]); + if (error) + return "node." + error; + } + } + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) + return "name: string expected"; + } + if (message.initializer != null && message.hasOwnProperty("initializer")) { + if (!Array.isArray(message.initializer)) + return "initializer: array expected"; + for (var i = 0; i < message.initializer.length; ++i) { + var error = $root.onnx.TensorProto.verify(message.initializer[i]); + if (error) + return "initializer." + error; + } + } + if (message.sparseInitializer != null && message.hasOwnProperty("sparseInitializer")) { + if (!Array.isArray(message.sparseInitializer)) + return "sparseInitializer: array expected"; + for (var i = 0; i < message.sparseInitializer.length; ++i) { + var error = $root.onnx.SparseTensorProto.verify(message.sparseInitializer[i]); + if (error) + return "sparseInitializer." + error; + } + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) + return "docString: string expected"; + } + if (message.input != null && message.hasOwnProperty("input")) { + if (!Array.isArray(message.input)) + return "input: array expected"; + for (var i = 0; i < message.input.length; ++i) { + var error = $root.onnx.ValueInfoProto.verify(message.input[i]); + if (error) + return "input." + error; + } + } + if (message.output != null && message.hasOwnProperty("output")) { + if (!Array.isArray(message.output)) + return "output: array expected"; + for (var i = 0; i < message.output.length; ++i) { + var error = $root.onnx.ValueInfoProto.verify(message.output[i]); + if (error) + return "output." + error; + } + } + if (message.valueInfo != null && message.hasOwnProperty("valueInfo")) { + if (!Array.isArray(message.valueInfo)) + return "valueInfo: array expected"; + for (var i = 0; i < message.valueInfo.length; ++i) { + var error = $root.onnx.ValueInfoProto.verify(message.valueInfo[i]); + if (error) + return "valueInfo." + error; + } + } + if (message.quantizationAnnotation != null && message.hasOwnProperty("quantizationAnnotation")) { + if (!Array.isArray(message.quantizationAnnotation)) + return "quantizationAnnotation: array expected"; + for (var i = 0; i < message.quantizationAnnotation.length; ++i) { + var error = $root.onnx.TensorAnnotation.verify(message.quantizationAnnotation[i]); + if (error) + return "quantizationAnnotation." + error; + } + } + return null; + }; + GraphProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.GraphProto) + return object; + var message = new $root.onnx.GraphProto(); + if (object.node) { + if (!Array.isArray(object.node)) + throw TypeError(".onnx.GraphProto.node: array expected"); + message.node = []; + for (var i = 0; i < object.node.length; ++i) { + if (typeof object.node[i] !== "object") + throw TypeError(".onnx.GraphProto.node: object expected"); + message.node[i] = $root.onnx.NodeProto.fromObject(object.node[i]); + } + } + if (object.name != null) + message.name = String(object.name); + if (object.initializer) { + if (!Array.isArray(object.initializer)) + throw TypeError(".onnx.GraphProto.initializer: array expected"); + message.initializer = []; + for (var i = 0; i < object.initializer.length; ++i) { + if (typeof object.initializer[i] !== "object") + throw TypeError(".onnx.GraphProto.initializer: object expected"); + message.initializer[i] = $root.onnx.TensorProto.fromObject(object.initializer[i]); + } + } + if (object.sparseInitializer) { + if (!Array.isArray(object.sparseInitializer)) + throw TypeError(".onnx.GraphProto.sparseInitializer: array expected"); + message.sparseInitializer = []; + for (var i = 0; i < object.sparseInitializer.length; ++i) { + if (typeof object.sparseInitializer[i] !== "object") + throw TypeError(".onnx.GraphProto.sparseInitializer: object expected"); + message.sparseInitializer[i] = $root.onnx.SparseTensorProto.fromObject(object.sparseInitializer[i]); + } + } + if (object.docString != null) + message.docString = String(object.docString); + if (object.input) { + if (!Array.isArray(object.input)) + throw TypeError(".onnx.GraphProto.input: array expected"); + message.input = []; + for (var i = 0; i < object.input.length; ++i) { + if (typeof object.input[i] !== "object") + throw TypeError(".onnx.GraphProto.input: object expected"); + message.input[i] = $root.onnx.ValueInfoProto.fromObject(object.input[i]); + } + } + if (object.output) { + if (!Array.isArray(object.output)) + throw TypeError(".onnx.GraphProto.output: array expected"); + message.output = []; + for (var i = 0; i < object.output.length; ++i) { + if (typeof object.output[i] !== "object") + throw TypeError(".onnx.GraphProto.output: object expected"); + message.output[i] = $root.onnx.ValueInfoProto.fromObject(object.output[i]); + } + } + if (object.valueInfo) { + if (!Array.isArray(object.valueInfo)) + throw TypeError(".onnx.GraphProto.valueInfo: array expected"); + message.valueInfo = []; + for (var i = 0; i < object.valueInfo.length; ++i) { + if (typeof object.valueInfo[i] !== "object") + throw TypeError(".onnx.GraphProto.valueInfo: object expected"); + message.valueInfo[i] = $root.onnx.ValueInfoProto.fromObject(object.valueInfo[i]); + } + } + if (object.quantizationAnnotation) { + if (!Array.isArray(object.quantizationAnnotation)) + throw TypeError(".onnx.GraphProto.quantizationAnnotation: array expected"); + message.quantizationAnnotation = []; + for (var i = 0; i < object.quantizationAnnotation.length; ++i) { + if (typeof object.quantizationAnnotation[i] !== "object") + throw TypeError(".onnx.GraphProto.quantizationAnnotation: object expected"); + message.quantizationAnnotation[i] = $root.onnx.TensorAnnotation.fromObject(object.quantizationAnnotation[i]); + } + } + return message; + }; + GraphProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.node = []; + object.initializer = []; + object.input = []; + object.output = []; + object.valueInfo = []; + object.quantizationAnnotation = []; + object.sparseInitializer = []; + } + if (options.defaults) { + object.name = ""; + object.docString = ""; + } + if (message.node && message.node.length) { + object.node = []; + for (var j = 0; j < message.node.length; ++j) + object.node[j] = $root.onnx.NodeProto.toObject(message.node[j], options); + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.initializer && message.initializer.length) { + object.initializer = []; + for (var j = 0; j < message.initializer.length; ++j) + object.initializer[j] = $root.onnx.TensorProto.toObject(message.initializer[j], options); + } + if (message.docString != null && message.hasOwnProperty("docString")) + object.docString = message.docString; + if (message.input && message.input.length) { + object.input = []; + for (var j = 0; j < message.input.length; ++j) + object.input[j] = $root.onnx.ValueInfoProto.toObject(message.input[j], options); + } + if (message.output && message.output.length) { + object.output = []; + for (var j = 0; j < message.output.length; ++j) + object.output[j] = $root.onnx.ValueInfoProto.toObject(message.output[j], options); + } + if (message.valueInfo && message.valueInfo.length) { + object.valueInfo = []; + for (var j = 0; j < message.valueInfo.length; ++j) + object.valueInfo[j] = $root.onnx.ValueInfoProto.toObject(message.valueInfo[j], options); + } + if (message.quantizationAnnotation && message.quantizationAnnotation.length) { + object.quantizationAnnotation = []; + for (var j = 0; j < message.quantizationAnnotation.length; ++j) + object.quantizationAnnotation[j] = $root.onnx.TensorAnnotation.toObject(message.quantizationAnnotation[j], options); + } + if (message.sparseInitializer && message.sparseInitializer.length) { + object.sparseInitializer = []; + for (var j = 0; j < message.sparseInitializer.length; ++j) + object.sparseInitializer[j] = $root.onnx.SparseTensorProto.toObject(message.sparseInitializer[j], options); + } + return object; + }; + GraphProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + GraphProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.GraphProto"; + }; + return GraphProto; + }(); + onnx6.TensorProto = function() { + function TensorProto(properties) { + this.dims = []; + this.floatData = []; + this.int32Data = []; + this.stringData = []; + this.int64Data = []; + this.externalData = []; + this.doubleData = []; + this.uint64Data = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + TensorProto.prototype.dims = $util.emptyArray; + TensorProto.prototype.dataType = 0; + TensorProto.prototype.segment = null; + TensorProto.prototype.floatData = $util.emptyArray; + TensorProto.prototype.int32Data = $util.emptyArray; + TensorProto.prototype.stringData = $util.emptyArray; + TensorProto.prototype.int64Data = $util.emptyArray; + TensorProto.prototype.name = ""; + TensorProto.prototype.docString = ""; + TensorProto.prototype.rawData = $util.newBuffer([]); + TensorProto.prototype.externalData = $util.emptyArray; + TensorProto.prototype.dataLocation = 0; + TensorProto.prototype.doubleData = $util.emptyArray; + TensorProto.prototype.uint64Data = $util.emptyArray; + TensorProto.create = function create(properties) { + return new TensorProto(properties); + }; + TensorProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.dims != null && message.dims.length) { + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork(); + for (var i = 0; i < message.dims.length; ++i) + writer.int64(message.dims[i]); + writer.ldelim(); + } + if (message.dataType != null && Object.hasOwnProperty.call(message, "dataType")) + writer.uint32( + /* id 2, wireType 0 =*/ + 16 + ).int32(message.dataType); + if (message.segment != null && Object.hasOwnProperty.call(message, "segment")) + $root.onnx.TensorProto.Segment.encode(message.segment, writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).fork()).ldelim(); + if (message.floatData != null && message.floatData.length) { + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).fork(); + for (var i = 0; i < message.floatData.length; ++i) + writer.float(message.floatData[i]); + writer.ldelim(); + } + if (message.int32Data != null && message.int32Data.length) { + writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).fork(); + for (var i = 0; i < message.int32Data.length; ++i) + writer.int32(message.int32Data[i]); + writer.ldelim(); + } + if (message.stringData != null && message.stringData.length) + for (var i = 0; i < message.stringData.length; ++i) + writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).bytes(message.stringData[i]); + if (message.int64Data != null && message.int64Data.length) { + writer.uint32( + /* id 7, wireType 2 =*/ + 58 + ).fork(); + for (var i = 0; i < message.int64Data.length; ++i) + writer.int64(message.int64Data[i]); + writer.ldelim(); + } + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 8, wireType 2 =*/ + 66 + ).string(message.name); + if (message.rawData != null && Object.hasOwnProperty.call(message, "rawData")) + writer.uint32( + /* id 9, wireType 2 =*/ + 74 + ).bytes(message.rawData); + if (message.doubleData != null && message.doubleData.length) { + writer.uint32( + /* id 10, wireType 2 =*/ + 82 + ).fork(); + for (var i = 0; i < message.doubleData.length; ++i) + writer.double(message.doubleData[i]); + writer.ldelim(); + } + if (message.uint64Data != null && message.uint64Data.length) { + writer.uint32( + /* id 11, wireType 2 =*/ + 90 + ).fork(); + for (var i = 0; i < message.uint64Data.length; ++i) + writer.uint64(message.uint64Data[i]); + writer.ldelim(); + } + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 12, wireType 2 =*/ + 98 + ).string(message.docString); + if (message.externalData != null && message.externalData.length) + for (var i = 0; i < message.externalData.length; ++i) + $root.onnx.StringStringEntryProto.encode(message.externalData[i], writer.uint32( + /* id 13, wireType 2 =*/ + 106 + ).fork()).ldelim(); + if (message.dataLocation != null && Object.hasOwnProperty.call(message, "dataLocation")) + writer.uint32( + /* id 14, wireType 0 =*/ + 112 + ).int32(message.dataLocation); + return writer; + }; + TensorProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + TensorProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (!(message.dims && message.dims.length)) + message.dims = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.dims.push(reader.int64()); + } else + message.dims.push(reader.int64()); + break; + } + case 2: { + message.dataType = reader.int32(); + break; + } + case 3: { + message.segment = $root.onnx.TensorProto.Segment.decode(reader, reader.uint32()); + break; + } + case 4: { + if (!(message.floatData && message.floatData.length)) + message.floatData = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.floatData.push(reader.float()); + } else + message.floatData.push(reader.float()); + break; + } + case 5: { + if (!(message.int32Data && message.int32Data.length)) + message.int32Data = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.int32Data.push(reader.int32()); + } else + message.int32Data.push(reader.int32()); + break; + } + case 6: { + if (!(message.stringData && message.stringData.length)) + message.stringData = []; + message.stringData.push(reader.bytes()); + break; + } + case 7: { + if (!(message.int64Data && message.int64Data.length)) + message.int64Data = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.int64Data.push(reader.int64()); + } else + message.int64Data.push(reader.int64()); + break; + } + case 8: { + message.name = reader.string(); + break; + } + case 12: { + message.docString = reader.string(); + break; + } + case 9: { + message.rawData = reader.bytes(); + break; + } + case 13: { + if (!(message.externalData && message.externalData.length)) + message.externalData = []; + message.externalData.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32())); + break; + } + case 14: { + message.dataLocation = reader.int32(); + break; + } + case 10: { + if (!(message.doubleData && message.doubleData.length)) + message.doubleData = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.doubleData.push(reader.double()); + } else + message.doubleData.push(reader.double()); + break; + } + case 11: { + if (!(message.uint64Data && message.uint64Data.length)) + message.uint64Data = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.uint64Data.push(reader.uint64()); + } else + message.uint64Data.push(reader.uint64()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + TensorProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + TensorProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.dims != null && message.hasOwnProperty("dims")) { + if (!Array.isArray(message.dims)) + return "dims: array expected"; + for (var i = 0; i < message.dims.length; ++i) + if (!$util.isInteger(message.dims[i]) && !(message.dims[i] && $util.isInteger(message.dims[i].low) && $util.isInteger(message.dims[i].high))) + return "dims: integer|Long[] expected"; + } + if (message.dataType != null && message.hasOwnProperty("dataType")) { + if (!$util.isInteger(message.dataType)) + return "dataType: integer expected"; + } + if (message.segment != null && message.hasOwnProperty("segment")) { + var error = $root.onnx.TensorProto.Segment.verify(message.segment); + if (error) + return "segment." + error; + } + if (message.floatData != null && message.hasOwnProperty("floatData")) { + if (!Array.isArray(message.floatData)) + return "floatData: array expected"; + for (var i = 0; i < message.floatData.length; ++i) + if (typeof message.floatData[i] !== "number") + return "floatData: number[] expected"; + } + if (message.int32Data != null && message.hasOwnProperty("int32Data")) { + if (!Array.isArray(message.int32Data)) + return "int32Data: array expected"; + for (var i = 0; i < message.int32Data.length; ++i) + if (!$util.isInteger(message.int32Data[i])) + return "int32Data: integer[] expected"; + } + if (message.stringData != null && message.hasOwnProperty("stringData")) { + if (!Array.isArray(message.stringData)) + return "stringData: array expected"; + for (var i = 0; i < message.stringData.length; ++i) + if (!(message.stringData[i] && typeof message.stringData[i].length === "number" || $util.isString(message.stringData[i]))) + return "stringData: buffer[] expected"; + } + if (message.int64Data != null && message.hasOwnProperty("int64Data")) { + if (!Array.isArray(message.int64Data)) + return "int64Data: array expected"; + for (var i = 0; i < message.int64Data.length; ++i) + if (!$util.isInteger(message.int64Data[i]) && !(message.int64Data[i] && $util.isInteger(message.int64Data[i].low) && $util.isInteger(message.int64Data[i].high))) + return "int64Data: integer|Long[] expected"; + } + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) + return "name: string expected"; + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) + return "docString: string expected"; + } + if (message.rawData != null && message.hasOwnProperty("rawData")) { + if (!(message.rawData && typeof message.rawData.length === "number" || $util.isString(message.rawData))) + return "rawData: buffer expected"; + } + if (message.externalData != null && message.hasOwnProperty("externalData")) { + if (!Array.isArray(message.externalData)) + return "externalData: array expected"; + for (var i = 0; i < message.externalData.length; ++i) { + var error = $root.onnx.StringStringEntryProto.verify(message.externalData[i]); + if (error) + return "externalData." + error; + } + } + if (message.dataLocation != null && message.hasOwnProperty("dataLocation")) + switch (message.dataLocation) { + default: + return "dataLocation: enum value expected"; + case 0: + case 1: + break; + } + if (message.doubleData != null && message.hasOwnProperty("doubleData")) { + if (!Array.isArray(message.doubleData)) + return "doubleData: array expected"; + for (var i = 0; i < message.doubleData.length; ++i) + if (typeof message.doubleData[i] !== "number") + return "doubleData: number[] expected"; + } + if (message.uint64Data != null && message.hasOwnProperty("uint64Data")) { + if (!Array.isArray(message.uint64Data)) + return "uint64Data: array expected"; + for (var i = 0; i < message.uint64Data.length; ++i) + if (!$util.isInteger(message.uint64Data[i]) && !(message.uint64Data[i] && $util.isInteger(message.uint64Data[i].low) && $util.isInteger(message.uint64Data[i].high))) + return "uint64Data: integer|Long[] expected"; + } + return null; + }; + TensorProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TensorProto) + return object; + var message = new $root.onnx.TensorProto(); + if (object.dims) { + if (!Array.isArray(object.dims)) + throw TypeError(".onnx.TensorProto.dims: array expected"); + message.dims = []; + for (var i = 0; i < object.dims.length; ++i) + if ($util.Long) + (message.dims[i] = $util.Long.fromValue(object.dims[i])).unsigned = false; + else if (typeof object.dims[i] === "string") + message.dims[i] = parseInt(object.dims[i], 10); + else if (typeof object.dims[i] === "number") + message.dims[i] = object.dims[i]; + else if (typeof object.dims[i] === "object") + message.dims[i] = new $util.LongBits(object.dims[i].low >>> 0, object.dims[i].high >>> 0).toNumber(); + } + if (object.dataType != null) + message.dataType = object.dataType | 0; + if (object.segment != null) { + if (typeof object.segment !== "object") + throw TypeError(".onnx.TensorProto.segment: object expected"); + message.segment = $root.onnx.TensorProto.Segment.fromObject(object.segment); + } + if (object.floatData) { + if (!Array.isArray(object.floatData)) + throw TypeError(".onnx.TensorProto.floatData: array expected"); + message.floatData = []; + for (var i = 0; i < object.floatData.length; ++i) + message.floatData[i] = Number(object.floatData[i]); + } + if (object.int32Data) { + if (!Array.isArray(object.int32Data)) + throw TypeError(".onnx.TensorProto.int32Data: array expected"); + message.int32Data = []; + for (var i = 0; i < object.int32Data.length; ++i) + message.int32Data[i] = object.int32Data[i] | 0; + } + if (object.stringData) { + if (!Array.isArray(object.stringData)) + throw TypeError(".onnx.TensorProto.stringData: array expected"); + message.stringData = []; + for (var i = 0; i < object.stringData.length; ++i) + if (typeof object.stringData[i] === "string") + $util.base64.decode(object.stringData[i], message.stringData[i] = $util.newBuffer($util.base64.length(object.stringData[i])), 0); + else if (object.stringData[i].length >= 0) + message.stringData[i] = object.stringData[i]; + } + if (object.int64Data) { + if (!Array.isArray(object.int64Data)) + throw TypeError(".onnx.TensorProto.int64Data: array expected"); + message.int64Data = []; + for (var i = 0; i < object.int64Data.length; ++i) + if ($util.Long) + (message.int64Data[i] = $util.Long.fromValue(object.int64Data[i])).unsigned = false; + else if (typeof object.int64Data[i] === "string") + message.int64Data[i] = parseInt(object.int64Data[i], 10); + else if (typeof object.int64Data[i] === "number") + message.int64Data[i] = object.int64Data[i]; + else if (typeof object.int64Data[i] === "object") + message.int64Data[i] = new $util.LongBits(object.int64Data[i].low >>> 0, object.int64Data[i].high >>> 0).toNumber(); + } + if (object.name != null) + message.name = String(object.name); + if (object.docString != null) + message.docString = String(object.docString); + if (object.rawData != null) { + if (typeof object.rawData === "string") + $util.base64.decode(object.rawData, message.rawData = $util.newBuffer($util.base64.length(object.rawData)), 0); + else if (object.rawData.length >= 0) + message.rawData = object.rawData; + } + if (object.externalData) { + if (!Array.isArray(object.externalData)) + throw TypeError(".onnx.TensorProto.externalData: array expected"); + message.externalData = []; + for (var i = 0; i < object.externalData.length; ++i) { + if (typeof object.externalData[i] !== "object") + throw TypeError(".onnx.TensorProto.externalData: object expected"); + message.externalData[i] = $root.onnx.StringStringEntryProto.fromObject(object.externalData[i]); + } + } + switch (object.dataLocation) { + default: + if (typeof object.dataLocation === "number") { + message.dataLocation = object.dataLocation; + break; + } + break; + case "DEFAULT": + case 0: + message.dataLocation = 0; + break; + case "EXTERNAL": + case 1: + message.dataLocation = 1; + break; + } + if (object.doubleData) { + if (!Array.isArray(object.doubleData)) + throw TypeError(".onnx.TensorProto.doubleData: array expected"); + message.doubleData = []; + for (var i = 0; i < object.doubleData.length; ++i) + message.doubleData[i] = Number(object.doubleData[i]); + } + if (object.uint64Data) { + if (!Array.isArray(object.uint64Data)) + throw TypeError(".onnx.TensorProto.uint64Data: array expected"); + message.uint64Data = []; + for (var i = 0; i < object.uint64Data.length; ++i) + if ($util.Long) + (message.uint64Data[i] = $util.Long.fromValue(object.uint64Data[i])).unsigned = true; + else if (typeof object.uint64Data[i] === "string") + message.uint64Data[i] = parseInt(object.uint64Data[i], 10); + else if (typeof object.uint64Data[i] === "number") + message.uint64Data[i] = object.uint64Data[i]; + else if (typeof object.uint64Data[i] === "object") + message.uint64Data[i] = new $util.LongBits(object.uint64Data[i].low >>> 0, object.uint64Data[i].high >>> 0).toNumber(true); + } + return message; + }; + TensorProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.dims = []; + object.floatData = []; + object.int32Data = []; + object.stringData = []; + object.int64Data = []; + object.doubleData = []; + object.uint64Data = []; + object.externalData = []; + } + if (options.defaults) { + object.dataType = 0; + object.segment = null; + object.name = ""; + if (options.bytes === String) + object.rawData = ""; + else { + object.rawData = []; + if (options.bytes !== Array) + object.rawData = $util.newBuffer(object.rawData); + } + object.docString = ""; + object.dataLocation = options.enums === String ? "DEFAULT" : 0; + } + if (message.dims && message.dims.length) { + object.dims = []; + for (var j = 0; j < message.dims.length; ++j) + if (typeof message.dims[j] === "number") + object.dims[j] = options.longs === String ? String(message.dims[j]) : message.dims[j]; + else + object.dims[j] = options.longs === String ? $util.Long.prototype.toString.call(message.dims[j]) : options.longs === Number ? new $util.LongBits(message.dims[j].low >>> 0, message.dims[j].high >>> 0).toNumber() : message.dims[j]; + } + if (message.dataType != null && message.hasOwnProperty("dataType")) + object.dataType = message.dataType; + if (message.segment != null && message.hasOwnProperty("segment")) + object.segment = $root.onnx.TensorProto.Segment.toObject(message.segment, options); + if (message.floatData && message.floatData.length) { + object.floatData = []; + for (var j = 0; j < message.floatData.length; ++j) + object.floatData[j] = options.json && !isFinite(message.floatData[j]) ? String(message.floatData[j]) : message.floatData[j]; + } + if (message.int32Data && message.int32Data.length) { + object.int32Data = []; + for (var j = 0; j < message.int32Data.length; ++j) + object.int32Data[j] = message.int32Data[j]; + } + if (message.stringData && message.stringData.length) { + object.stringData = []; + for (var j = 0; j < message.stringData.length; ++j) + object.stringData[j] = options.bytes === String ? $util.base64.encode(message.stringData[j], 0, message.stringData[j].length) : options.bytes === Array ? Array.prototype.slice.call(message.stringData[j]) : message.stringData[j]; + } + if (message.int64Data && message.int64Data.length) { + object.int64Data = []; + for (var j = 0; j < message.int64Data.length; ++j) + if (typeof message.int64Data[j] === "number") + object.int64Data[j] = options.longs === String ? String(message.int64Data[j]) : message.int64Data[j]; + else + object.int64Data[j] = options.longs === String ? $util.Long.prototype.toString.call(message.int64Data[j]) : options.longs === Number ? new $util.LongBits(message.int64Data[j].low >>> 0, message.int64Data[j].high >>> 0).toNumber() : message.int64Data[j]; + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.rawData != null && message.hasOwnProperty("rawData")) + object.rawData = options.bytes === String ? $util.base64.encode(message.rawData, 0, message.rawData.length) : options.bytes === Array ? Array.prototype.slice.call(message.rawData) : message.rawData; + if (message.doubleData && message.doubleData.length) { + object.doubleData = []; + for (var j = 0; j < message.doubleData.length; ++j) + object.doubleData[j] = options.json && !isFinite(message.doubleData[j]) ? String(message.doubleData[j]) : message.doubleData[j]; + } + if (message.uint64Data && message.uint64Data.length) { + object.uint64Data = []; + for (var j = 0; j < message.uint64Data.length; ++j) + if (typeof message.uint64Data[j] === "number") + object.uint64Data[j] = options.longs === String ? String(message.uint64Data[j]) : message.uint64Data[j]; + else + object.uint64Data[j] = options.longs === String ? $util.Long.prototype.toString.call(message.uint64Data[j]) : options.longs === Number ? new $util.LongBits(message.uint64Data[j].low >>> 0, message.uint64Data[j].high >>> 0).toNumber(true) : message.uint64Data[j]; + } + if (message.docString != null && message.hasOwnProperty("docString")) + object.docString = message.docString; + if (message.externalData && message.externalData.length) { + object.externalData = []; + for (var j = 0; j < message.externalData.length; ++j) + object.externalData[j] = $root.onnx.StringStringEntryProto.toObject(message.externalData[j], options); + } + if (message.dataLocation != null && message.hasOwnProperty("dataLocation")) + object.dataLocation = options.enums === String ? $root.onnx.TensorProto.DataLocation[message.dataLocation] === void 0 ? message.dataLocation : $root.onnx.TensorProto.DataLocation[message.dataLocation] : message.dataLocation; + return object; + }; + TensorProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + TensorProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TensorProto"; + }; + TensorProto.DataType = function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNDEFINED"] = 0; + values[valuesById[1] = "FLOAT"] = 1; + values[valuesById[2] = "UINT8"] = 2; + values[valuesById[3] = "INT8"] = 3; + values[valuesById[4] = "UINT16"] = 4; + values[valuesById[5] = "INT16"] = 5; + values[valuesById[6] = "INT32"] = 6; + values[valuesById[7] = "INT64"] = 7; + values[valuesById[8] = "STRING"] = 8; + values[valuesById[9] = "BOOL"] = 9; + values[valuesById[10] = "FLOAT16"] = 10; + values[valuesById[11] = "DOUBLE"] = 11; + values[valuesById[12] = "UINT32"] = 12; + values[valuesById[13] = "UINT64"] = 13; + values[valuesById[14] = "COMPLEX64"] = 14; + values[valuesById[15] = "COMPLEX128"] = 15; + values[valuesById[16] = "BFLOAT16"] = 16; + values[valuesById[17] = "FLOAT8E4M3FN"] = 17; + values[valuesById[18] = "FLOAT8E4M3FNUZ"] = 18; + values[valuesById[19] = "FLOAT8E5M2"] = 19; + values[valuesById[20] = "FLOAT8E5M2FNUZ"] = 20; + return values; + }(); + TensorProto.Segment = function() { + function Segment(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + Segment.prototype.begin = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + Segment.prototype.end = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + Segment.create = function create(properties) { + return new Segment(properties); + }; + Segment.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.begin != null && Object.hasOwnProperty.call(message, "begin")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int64(message.begin); + if (message.end != null && Object.hasOwnProperty.call(message, "end")) + writer.uint32( + /* id 2, wireType 0 =*/ + 16 + ).int64(message.end); + return writer; + }; + Segment.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Segment.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorProto.Segment(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.begin = reader.int64(); + break; + } + case 2: { + message.end = reader.int64(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Segment.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Segment.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.begin != null && message.hasOwnProperty("begin")) { + if (!$util.isInteger(message.begin) && !(message.begin && $util.isInteger(message.begin.low) && $util.isInteger(message.begin.high))) + return "begin: integer|Long expected"; + } + if (message.end != null && message.hasOwnProperty("end")) { + if (!$util.isInteger(message.end) && !(message.end && $util.isInteger(message.end.low) && $util.isInteger(message.end.high))) + return "end: integer|Long expected"; + } + return null; + }; + Segment.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TensorProto.Segment) + return object; + var message = new $root.onnx.TensorProto.Segment(); + if (object.begin != null) { + if ($util.Long) + (message.begin = $util.Long.fromValue(object.begin)).unsigned = false; + else if (typeof object.begin === "string") + message.begin = parseInt(object.begin, 10); + else if (typeof object.begin === "number") + message.begin = object.begin; + else if (typeof object.begin === "object") + message.begin = new $util.LongBits(object.begin.low >>> 0, object.begin.high >>> 0).toNumber(); + } + if (object.end != null) { + if ($util.Long) + (message.end = $util.Long.fromValue(object.end)).unsigned = false; + else if (typeof object.end === "string") + message.end = parseInt(object.end, 10); + else if (typeof object.end === "number") + message.end = object.end; + else if (typeof object.end === "object") + message.end = new $util.LongBits(object.end.low >>> 0, object.end.high >>> 0).toNumber(); + } + return message; + }; + Segment.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.begin = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.begin = options.longs === String ? "0" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.end = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.end = options.longs === String ? "0" : 0; + } + if (message.begin != null && message.hasOwnProperty("begin")) + if (typeof message.begin === "number") + object.begin = options.longs === String ? String(message.begin) : message.begin; + else + object.begin = options.longs === String ? $util.Long.prototype.toString.call(message.begin) : options.longs === Number ? new $util.LongBits(message.begin.low >>> 0, message.begin.high >>> 0).toNumber() : message.begin; + if (message.end != null && message.hasOwnProperty("end")) + if (typeof message.end === "number") + object.end = options.longs === String ? String(message.end) : message.end; + else + object.end = options.longs === String ? $util.Long.prototype.toString.call(message.end) : options.longs === Number ? new $util.LongBits(message.end.low >>> 0, message.end.high >>> 0).toNumber() : message.end; + return object; + }; + Segment.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Segment.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TensorProto.Segment"; + }; + return Segment; + }(); + TensorProto.DataLocation = function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "DEFAULT"] = 0; + values[valuesById[1] = "EXTERNAL"] = 1; + return values; + }(); + return TensorProto; + }(); + onnx6.SparseTensorProto = function() { + function SparseTensorProto(properties) { + this.dims = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + SparseTensorProto.prototype.values = null; + SparseTensorProto.prototype.indices = null; + SparseTensorProto.prototype.dims = $util.emptyArray; + SparseTensorProto.create = function create(properties) { + return new SparseTensorProto(properties); + }; + SparseTensorProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.values != null && Object.hasOwnProperty.call(message, "values")) + $root.onnx.TensorProto.encode(message.values, writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + if (message.indices != null && Object.hasOwnProperty.call(message, "indices")) + $root.onnx.TensorProto.encode(message.indices, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + if (message.dims != null && message.dims.length) { + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).fork(); + for (var i = 0; i < message.dims.length; ++i) + writer.int64(message.dims[i]); + writer.ldelim(); + } + return writer; + }; + SparseTensorProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + SparseTensorProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.SparseTensorProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.values = $root.onnx.TensorProto.decode(reader, reader.uint32()); + break; + } + case 2: { + message.indices = $root.onnx.TensorProto.decode(reader, reader.uint32()); + break; + } + case 3: { + if (!(message.dims && message.dims.length)) + message.dims = []; + if ((tag & 7) === 2) { + var end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.dims.push(reader.int64()); + } else + message.dims.push(reader.int64()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + SparseTensorProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + SparseTensorProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.values != null && message.hasOwnProperty("values")) { + var error = $root.onnx.TensorProto.verify(message.values); + if (error) + return "values." + error; + } + if (message.indices != null && message.hasOwnProperty("indices")) { + var error = $root.onnx.TensorProto.verify(message.indices); + if (error) + return "indices." + error; + } + if (message.dims != null && message.hasOwnProperty("dims")) { + if (!Array.isArray(message.dims)) + return "dims: array expected"; + for (var i = 0; i < message.dims.length; ++i) + if (!$util.isInteger(message.dims[i]) && !(message.dims[i] && $util.isInteger(message.dims[i].low) && $util.isInteger(message.dims[i].high))) + return "dims: integer|Long[] expected"; + } + return null; + }; + SparseTensorProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.SparseTensorProto) + return object; + var message = new $root.onnx.SparseTensorProto(); + if (object.values != null) { + if (typeof object.values !== "object") + throw TypeError(".onnx.SparseTensorProto.values: object expected"); + message.values = $root.onnx.TensorProto.fromObject(object.values); + } + if (object.indices != null) { + if (typeof object.indices !== "object") + throw TypeError(".onnx.SparseTensorProto.indices: object expected"); + message.indices = $root.onnx.TensorProto.fromObject(object.indices); + } + if (object.dims) { + if (!Array.isArray(object.dims)) + throw TypeError(".onnx.SparseTensorProto.dims: array expected"); + message.dims = []; + for (var i = 0; i < object.dims.length; ++i) + if ($util.Long) + (message.dims[i] = $util.Long.fromValue(object.dims[i])).unsigned = false; + else if (typeof object.dims[i] === "string") + message.dims[i] = parseInt(object.dims[i], 10); + else if (typeof object.dims[i] === "number") + message.dims[i] = object.dims[i]; + else if (typeof object.dims[i] === "object") + message.dims[i] = new $util.LongBits(object.dims[i].low >>> 0, object.dims[i].high >>> 0).toNumber(); + } + return message; + }; + SparseTensorProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.dims = []; + if (options.defaults) { + object.values = null; + object.indices = null; + } + if (message.values != null && message.hasOwnProperty("values")) + object.values = $root.onnx.TensorProto.toObject(message.values, options); + if (message.indices != null && message.hasOwnProperty("indices")) + object.indices = $root.onnx.TensorProto.toObject(message.indices, options); + if (message.dims && message.dims.length) { + object.dims = []; + for (var j = 0; j < message.dims.length; ++j) + if (typeof message.dims[j] === "number") + object.dims[j] = options.longs === String ? String(message.dims[j]) : message.dims[j]; + else + object.dims[j] = options.longs === String ? $util.Long.prototype.toString.call(message.dims[j]) : options.longs === Number ? new $util.LongBits(message.dims[j].low >>> 0, message.dims[j].high >>> 0).toNumber() : message.dims[j]; + } + return object; + }; + SparseTensorProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + SparseTensorProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.SparseTensorProto"; + }; + return SparseTensorProto; + }(); + onnx6.TensorShapeProto = function() { + function TensorShapeProto(properties) { + this.dim = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + TensorShapeProto.prototype.dim = $util.emptyArray; + TensorShapeProto.create = function create(properties) { + return new TensorShapeProto(properties); + }; + TensorShapeProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.dim != null && message.dim.length) + for (var i = 0; i < message.dim.length; ++i) + $root.onnx.TensorShapeProto.Dimension.encode(message.dim[i], writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + return writer; + }; + TensorShapeProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + TensorShapeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorShapeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (!(message.dim && message.dim.length)) + message.dim = []; + message.dim.push($root.onnx.TensorShapeProto.Dimension.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + TensorShapeProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + TensorShapeProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.dim != null && message.hasOwnProperty("dim")) { + if (!Array.isArray(message.dim)) + return "dim: array expected"; + for (var i = 0; i < message.dim.length; ++i) { + var error = $root.onnx.TensorShapeProto.Dimension.verify(message.dim[i]); + if (error) + return "dim." + error; + } + } + return null; + }; + TensorShapeProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TensorShapeProto) + return object; + var message = new $root.onnx.TensorShapeProto(); + if (object.dim) { + if (!Array.isArray(object.dim)) + throw TypeError(".onnx.TensorShapeProto.dim: array expected"); + message.dim = []; + for (var i = 0; i < object.dim.length; ++i) { + if (typeof object.dim[i] !== "object") + throw TypeError(".onnx.TensorShapeProto.dim: object expected"); + message.dim[i] = $root.onnx.TensorShapeProto.Dimension.fromObject(object.dim[i]); + } + } + return message; + }; + TensorShapeProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.dim = []; + if (message.dim && message.dim.length) { + object.dim = []; + for (var j = 0; j < message.dim.length; ++j) + object.dim[j] = $root.onnx.TensorShapeProto.Dimension.toObject(message.dim[j], options); + } + return object; + }; + TensorShapeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + TensorShapeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TensorShapeProto"; + }; + TensorShapeProto.Dimension = function() { + function Dimension(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + Dimension.prototype.dimValue = null; + Dimension.prototype.dimParam = null; + Dimension.prototype.denotation = ""; + var $oneOfFields; + Object.defineProperty(Dimension.prototype, "value", { + get: $util.oneOfGetter($oneOfFields = ["dimValue", "dimParam"]), + set: $util.oneOfSetter($oneOfFields) + }); + Dimension.create = function create(properties) { + return new Dimension(properties); + }; + Dimension.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.dimValue != null && Object.hasOwnProperty.call(message, "dimValue")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int64(message.dimValue); + if (message.dimParam != null && Object.hasOwnProperty.call(message, "dimParam")) + writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).string(message.dimParam); + if (message.denotation != null && Object.hasOwnProperty.call(message, "denotation")) + writer.uint32( + /* id 3, wireType 2 =*/ + 26 + ).string(message.denotation); + return writer; + }; + Dimension.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Dimension.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TensorShapeProto.Dimension(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.dimValue = reader.int64(); + break; + } + case 2: { + message.dimParam = reader.string(); + break; + } + case 3: { + message.denotation = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Dimension.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Dimension.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.dimValue != null && message.hasOwnProperty("dimValue")) { + properties.value = 1; + if (!$util.isInteger(message.dimValue) && !(message.dimValue && $util.isInteger(message.dimValue.low) && $util.isInteger(message.dimValue.high))) + return "dimValue: integer|Long expected"; + } + if (message.dimParam != null && message.hasOwnProperty("dimParam")) { + if (properties.value === 1) + return "value: multiple values"; + properties.value = 1; + if (!$util.isString(message.dimParam)) + return "dimParam: string expected"; + } + if (message.denotation != null && message.hasOwnProperty("denotation")) { + if (!$util.isString(message.denotation)) + return "denotation: string expected"; + } + return null; + }; + Dimension.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TensorShapeProto.Dimension) + return object; + var message = new $root.onnx.TensorShapeProto.Dimension(); + if (object.dimValue != null) { + if ($util.Long) + (message.dimValue = $util.Long.fromValue(object.dimValue)).unsigned = false; + else if (typeof object.dimValue === "string") + message.dimValue = parseInt(object.dimValue, 10); + else if (typeof object.dimValue === "number") + message.dimValue = object.dimValue; + else if (typeof object.dimValue === "object") + message.dimValue = new $util.LongBits(object.dimValue.low >>> 0, object.dimValue.high >>> 0).toNumber(); + } + if (object.dimParam != null) + message.dimParam = String(object.dimParam); + if (object.denotation != null) + message.denotation = String(object.denotation); + return message; + }; + Dimension.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.denotation = ""; + if (message.dimValue != null && message.hasOwnProperty("dimValue")) { + if (typeof message.dimValue === "number") + object.dimValue = options.longs === String ? String(message.dimValue) : message.dimValue; + else + object.dimValue = options.longs === String ? $util.Long.prototype.toString.call(message.dimValue) : options.longs === Number ? new $util.LongBits(message.dimValue.low >>> 0, message.dimValue.high >>> 0).toNumber() : message.dimValue; + if (options.oneofs) + object.value = "dimValue"; + } + if (message.dimParam != null && message.hasOwnProperty("dimParam")) { + object.dimParam = message.dimParam; + if (options.oneofs) + object.value = "dimParam"; + } + if (message.denotation != null && message.hasOwnProperty("denotation")) + object.denotation = message.denotation; + return object; + }; + Dimension.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Dimension.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TensorShapeProto.Dimension"; + }; + return Dimension; + }(); + return TensorShapeProto; + }(); + onnx6.TypeProto = function() { + function TypeProto(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + TypeProto.prototype.tensorType = null; + TypeProto.prototype.sequenceType = null; + TypeProto.prototype.mapType = null; + TypeProto.prototype.optionalType = null; + TypeProto.prototype.sparseTensorType = null; + TypeProto.prototype.denotation = ""; + var $oneOfFields; + Object.defineProperty(TypeProto.prototype, "value", { + get: $util.oneOfGetter($oneOfFields = ["tensorType", "sequenceType", "mapType", "optionalType", "sparseTensorType"]), + set: $util.oneOfSetter($oneOfFields) + }); + TypeProto.create = function create(properties) { + return new TypeProto(properties); + }; + TypeProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.tensorType != null && Object.hasOwnProperty.call(message, "tensorType")) + $root.onnx.TypeProto.Tensor.encode(message.tensorType, writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + if (message.sequenceType != null && Object.hasOwnProperty.call(message, "sequenceType")) + $root.onnx.TypeProto.Sequence.encode(message.sequenceType, writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).fork()).ldelim(); + if (message.mapType != null && Object.hasOwnProperty.call(message, "mapType")) + $root.onnx.TypeProto.Map.encode(message.mapType, writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).fork()).ldelim(); + if (message.denotation != null && Object.hasOwnProperty.call(message, "denotation")) + writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).string(message.denotation); + if (message.sparseTensorType != null && Object.hasOwnProperty.call(message, "sparseTensorType")) + $root.onnx.TypeProto.SparseTensor.encode(message.sparseTensorType, writer.uint32( + /* id 8, wireType 2 =*/ + 66 + ).fork()).ldelim(); + if (message.optionalType != null && Object.hasOwnProperty.call(message, "optionalType")) + $root.onnx.TypeProto.Optional.encode(message.optionalType, writer.uint32( + /* id 9, wireType 2 =*/ + 74 + ).fork()).ldelim(); + return writer; + }; + TypeProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + TypeProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.tensorType = $root.onnx.TypeProto.Tensor.decode(reader, reader.uint32()); + break; + } + case 4: { + message.sequenceType = $root.onnx.TypeProto.Sequence.decode(reader, reader.uint32()); + break; + } + case 5: { + message.mapType = $root.onnx.TypeProto.Map.decode(reader, reader.uint32()); + break; + } + case 9: { + message.optionalType = $root.onnx.TypeProto.Optional.decode(reader, reader.uint32()); + break; + } + case 8: { + message.sparseTensorType = $root.onnx.TypeProto.SparseTensor.decode(reader, reader.uint32()); + break; + } + case 6: { + message.denotation = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + TypeProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + TypeProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + var properties = {}; + if (message.tensorType != null && message.hasOwnProperty("tensorType")) { + properties.value = 1; + { + var error = $root.onnx.TypeProto.Tensor.verify(message.tensorType); + if (error) + return "tensorType." + error; + } + } + if (message.sequenceType != null && message.hasOwnProperty("sequenceType")) { + if (properties.value === 1) + return "value: multiple values"; + properties.value = 1; + { + var error = $root.onnx.TypeProto.Sequence.verify(message.sequenceType); + if (error) + return "sequenceType." + error; + } + } + if (message.mapType != null && message.hasOwnProperty("mapType")) { + if (properties.value === 1) + return "value: multiple values"; + properties.value = 1; + { + var error = $root.onnx.TypeProto.Map.verify(message.mapType); + if (error) + return "mapType." + error; + } + } + if (message.optionalType != null && message.hasOwnProperty("optionalType")) { + if (properties.value === 1) + return "value: multiple values"; + properties.value = 1; + { + var error = $root.onnx.TypeProto.Optional.verify(message.optionalType); + if (error) + return "optionalType." + error; + } + } + if (message.sparseTensorType != null && message.hasOwnProperty("sparseTensorType")) { + if (properties.value === 1) + return "value: multiple values"; + properties.value = 1; + { + var error = $root.onnx.TypeProto.SparseTensor.verify(message.sparseTensorType); + if (error) + return "sparseTensorType." + error; + } + } + if (message.denotation != null && message.hasOwnProperty("denotation")) { + if (!$util.isString(message.denotation)) + return "denotation: string expected"; + } + return null; + }; + TypeProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto) + return object; + var message = new $root.onnx.TypeProto(); + if (object.tensorType != null) { + if (typeof object.tensorType !== "object") + throw TypeError(".onnx.TypeProto.tensorType: object expected"); + message.tensorType = $root.onnx.TypeProto.Tensor.fromObject(object.tensorType); + } + if (object.sequenceType != null) { + if (typeof object.sequenceType !== "object") + throw TypeError(".onnx.TypeProto.sequenceType: object expected"); + message.sequenceType = $root.onnx.TypeProto.Sequence.fromObject(object.sequenceType); + } + if (object.mapType != null) { + if (typeof object.mapType !== "object") + throw TypeError(".onnx.TypeProto.mapType: object expected"); + message.mapType = $root.onnx.TypeProto.Map.fromObject(object.mapType); + } + if (object.optionalType != null) { + if (typeof object.optionalType !== "object") + throw TypeError(".onnx.TypeProto.optionalType: object expected"); + message.optionalType = $root.onnx.TypeProto.Optional.fromObject(object.optionalType); + } + if (object.sparseTensorType != null) { + if (typeof object.sparseTensorType !== "object") + throw TypeError(".onnx.TypeProto.sparseTensorType: object expected"); + message.sparseTensorType = $root.onnx.TypeProto.SparseTensor.fromObject(object.sparseTensorType); + } + if (object.denotation != null) + message.denotation = String(object.denotation); + return message; + }; + TypeProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.denotation = ""; + if (message.tensorType != null && message.hasOwnProperty("tensorType")) { + object.tensorType = $root.onnx.TypeProto.Tensor.toObject(message.tensorType, options); + if (options.oneofs) + object.value = "tensorType"; + } + if (message.sequenceType != null && message.hasOwnProperty("sequenceType")) { + object.sequenceType = $root.onnx.TypeProto.Sequence.toObject(message.sequenceType, options); + if (options.oneofs) + object.value = "sequenceType"; + } + if (message.mapType != null && message.hasOwnProperty("mapType")) { + object.mapType = $root.onnx.TypeProto.Map.toObject(message.mapType, options); + if (options.oneofs) + object.value = "mapType"; + } + if (message.denotation != null && message.hasOwnProperty("denotation")) + object.denotation = message.denotation; + if (message.sparseTensorType != null && message.hasOwnProperty("sparseTensorType")) { + object.sparseTensorType = $root.onnx.TypeProto.SparseTensor.toObject(message.sparseTensorType, options); + if (options.oneofs) + object.value = "sparseTensorType"; + } + if (message.optionalType != null && message.hasOwnProperty("optionalType")) { + object.optionalType = $root.onnx.TypeProto.Optional.toObject(message.optionalType, options); + if (options.oneofs) + object.value = "optionalType"; + } + return object; + }; + TypeProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + TypeProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto"; + }; + TypeProto.Tensor = function() { + function Tensor4(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + Tensor4.prototype.elemType = 0; + Tensor4.prototype.shape = null; + Tensor4.create = function create(properties) { + return new Tensor4(properties); + }; + Tensor4.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int32(message.elemType); + if (message.shape != null && Object.hasOwnProperty.call(message, "shape")) + $root.onnx.TensorShapeProto.encode(message.shape, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + return writer; + }; + Tensor4.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Tensor4.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Tensor(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.elemType = reader.int32(); + break; + } + case 2: { + message.shape = $root.onnx.TensorShapeProto.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Tensor4.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Tensor4.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.elemType != null && message.hasOwnProperty("elemType")) { + if (!$util.isInteger(message.elemType)) + return "elemType: integer expected"; + } + if (message.shape != null && message.hasOwnProperty("shape")) { + var error = $root.onnx.TensorShapeProto.verify(message.shape); + if (error) + return "shape." + error; + } + return null; + }; + Tensor4.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto.Tensor) + return object; + var message = new $root.onnx.TypeProto.Tensor(); + if (object.elemType != null) + message.elemType = object.elemType | 0; + if (object.shape != null) { + if (typeof object.shape !== "object") + throw TypeError(".onnx.TypeProto.Tensor.shape: object expected"); + message.shape = $root.onnx.TensorShapeProto.fromObject(object.shape); + } + return message; + }; + Tensor4.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.elemType = 0; + object.shape = null; + } + if (message.elemType != null && message.hasOwnProperty("elemType")) + object.elemType = message.elemType; + if (message.shape != null && message.hasOwnProperty("shape")) + object.shape = $root.onnx.TensorShapeProto.toObject(message.shape, options); + return object; + }; + Tensor4.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Tensor4.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto.Tensor"; + }; + return Tensor4; + }(); + TypeProto.Sequence = function() { + function Sequence(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + Sequence.prototype.elemType = null; + Sequence.create = function create(properties) { + return new Sequence(properties); + }; + Sequence.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) + $root.onnx.TypeProto.encode(message.elemType, writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + return writer; + }; + Sequence.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Sequence.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Sequence(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.elemType = $root.onnx.TypeProto.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Sequence.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Sequence.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.elemType != null && message.hasOwnProperty("elemType")) { + var error = $root.onnx.TypeProto.verify(message.elemType); + if (error) + return "elemType." + error; + } + return null; + }; + Sequence.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto.Sequence) + return object; + var message = new $root.onnx.TypeProto.Sequence(); + if (object.elemType != null) { + if (typeof object.elemType !== "object") + throw TypeError(".onnx.TypeProto.Sequence.elemType: object expected"); + message.elemType = $root.onnx.TypeProto.fromObject(object.elemType); + } + return message; + }; + Sequence.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.elemType = null; + if (message.elemType != null && message.hasOwnProperty("elemType")) + object.elemType = $root.onnx.TypeProto.toObject(message.elemType, options); + return object; + }; + Sequence.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Sequence.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto.Sequence"; + }; + return Sequence; + }(); + TypeProto.Map = function() { + function Map2(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + Map2.prototype.keyType = 0; + Map2.prototype.valueType = null; + Map2.create = function create(properties) { + return new Map2(properties); + }; + Map2.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.keyType != null && Object.hasOwnProperty.call(message, "keyType")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int32(message.keyType); + if (message.valueType != null && Object.hasOwnProperty.call(message, "valueType")) + $root.onnx.TypeProto.encode(message.valueType, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + return writer; + }; + Map2.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Map2.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Map(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.keyType = reader.int32(); + break; + } + case 2: { + message.valueType = $root.onnx.TypeProto.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Map2.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Map2.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.keyType != null && message.hasOwnProperty("keyType")) { + if (!$util.isInteger(message.keyType)) + return "keyType: integer expected"; + } + if (message.valueType != null && message.hasOwnProperty("valueType")) { + var error = $root.onnx.TypeProto.verify(message.valueType); + if (error) + return "valueType." + error; + } + return null; + }; + Map2.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto.Map) + return object; + var message = new $root.onnx.TypeProto.Map(); + if (object.keyType != null) + message.keyType = object.keyType | 0; + if (object.valueType != null) { + if (typeof object.valueType !== "object") + throw TypeError(".onnx.TypeProto.Map.valueType: object expected"); + message.valueType = $root.onnx.TypeProto.fromObject(object.valueType); + } + return message; + }; + Map2.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.keyType = 0; + object.valueType = null; + } + if (message.keyType != null && message.hasOwnProperty("keyType")) + object.keyType = message.keyType; + if (message.valueType != null && message.hasOwnProperty("valueType")) + object.valueType = $root.onnx.TypeProto.toObject(message.valueType, options); + return object; + }; + Map2.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Map2.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto.Map"; + }; + return Map2; + }(); + TypeProto.Optional = function() { + function Optional(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + Optional.prototype.elemType = null; + Optional.create = function create(properties) { + return new Optional(properties); + }; + Optional.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) + $root.onnx.TypeProto.encode(message.elemType, writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).fork()).ldelim(); + return writer; + }; + Optional.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + Optional.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Optional(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.elemType = $root.onnx.TypeProto.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + Optional.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + Optional.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.elemType != null && message.hasOwnProperty("elemType")) { + var error = $root.onnx.TypeProto.verify(message.elemType); + if (error) + return "elemType." + error; + } + return null; + }; + Optional.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto.Optional) + return object; + var message = new $root.onnx.TypeProto.Optional(); + if (object.elemType != null) { + if (typeof object.elemType !== "object") + throw TypeError(".onnx.TypeProto.Optional.elemType: object expected"); + message.elemType = $root.onnx.TypeProto.fromObject(object.elemType); + } + return message; + }; + Optional.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.elemType = null; + if (message.elemType != null && message.hasOwnProperty("elemType")) + object.elemType = $root.onnx.TypeProto.toObject(message.elemType, options); + return object; + }; + Optional.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + Optional.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto.Optional"; + }; + return Optional; + }(); + TypeProto.SparseTensor = function() { + function SparseTensor(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + SparseTensor.prototype.elemType = 0; + SparseTensor.prototype.shape = null; + SparseTensor.create = function create(properties) { + return new SparseTensor(properties); + }; + SparseTensor.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.elemType != null && Object.hasOwnProperty.call(message, "elemType")) + writer.uint32( + /* id 1, wireType 0 =*/ + 8 + ).int32(message.elemType); + if (message.shape != null && Object.hasOwnProperty.call(message, "shape")) + $root.onnx.TensorShapeProto.encode(message.shape, writer.uint32( + /* id 2, wireType 2 =*/ + 18 + ).fork()).ldelim(); + return writer; + }; + SparseTensor.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + SparseTensor.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.SparseTensor(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.elemType = reader.int32(); + break; + } + case 2: { + message.shape = $root.onnx.TensorShapeProto.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + SparseTensor.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + SparseTensor.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.elemType != null && message.hasOwnProperty("elemType")) { + if (!$util.isInteger(message.elemType)) + return "elemType: integer expected"; + } + if (message.shape != null && message.hasOwnProperty("shape")) { + var error = $root.onnx.TensorShapeProto.verify(message.shape); + if (error) + return "shape." + error; + } + return null; + }; + SparseTensor.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.TypeProto.SparseTensor) + return object; + var message = new $root.onnx.TypeProto.SparseTensor(); + if (object.elemType != null) + message.elemType = object.elemType | 0; + if (object.shape != null) { + if (typeof object.shape !== "object") + throw TypeError(".onnx.TypeProto.SparseTensor.shape: object expected"); + message.shape = $root.onnx.TensorShapeProto.fromObject(object.shape); + } + return message; + }; + SparseTensor.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.elemType = 0; + object.shape = null; + } + if (message.elemType != null && message.hasOwnProperty("elemType")) + object.elemType = message.elemType; + if (message.shape != null && message.hasOwnProperty("shape")) + object.shape = $root.onnx.TensorShapeProto.toObject(message.shape, options); + return object; + }; + SparseTensor.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + SparseTensor.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.TypeProto.SparseTensor"; + }; + return SparseTensor; + }(); + return TypeProto; + }(); + onnx6.OperatorSetIdProto = function() { + function OperatorSetIdProto(properties) { + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + OperatorSetIdProto.prototype.domain = ""; + OperatorSetIdProto.prototype.version = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + OperatorSetIdProto.create = function create(properties) { + return new OperatorSetIdProto(properties); + }; + OperatorSetIdProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.domain); + if (message.version != null && Object.hasOwnProperty.call(message, "version")) + writer.uint32( + /* id 2, wireType 0 =*/ + 16 + ).int64(message.version); + return writer; + }; + OperatorSetIdProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + OperatorSetIdProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.OperatorSetIdProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.domain = reader.string(); + break; + } + case 2: { + message.version = reader.int64(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + OperatorSetIdProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + OperatorSetIdProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.domain != null && message.hasOwnProperty("domain")) { + if (!$util.isString(message.domain)) + return "domain: string expected"; + } + if (message.version != null && message.hasOwnProperty("version")) { + if (!$util.isInteger(message.version) && !(message.version && $util.isInteger(message.version.low) && $util.isInteger(message.version.high))) + return "version: integer|Long expected"; + } + return null; + }; + OperatorSetIdProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.OperatorSetIdProto) + return object; + var message = new $root.onnx.OperatorSetIdProto(); + if (object.domain != null) + message.domain = String(object.domain); + if (object.version != null) { + if ($util.Long) + (message.version = $util.Long.fromValue(object.version)).unsigned = false; + else if (typeof object.version === "string") + message.version = parseInt(object.version, 10); + else if (typeof object.version === "number") + message.version = object.version; + else if (typeof object.version === "object") + message.version = new $util.LongBits(object.version.low >>> 0, object.version.high >>> 0).toNumber(); + } + return message; + }; + OperatorSetIdProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.domain = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.version = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.version = options.longs === String ? "0" : 0; + } + if (message.domain != null && message.hasOwnProperty("domain")) + object.domain = message.domain; + if (message.version != null && message.hasOwnProperty("version")) + if (typeof message.version === "number") + object.version = options.longs === String ? String(message.version) : message.version; + else + object.version = options.longs === String ? $util.Long.prototype.toString.call(message.version) : options.longs === Number ? new $util.LongBits(message.version.low >>> 0, message.version.high >>> 0).toNumber() : message.version; + return object; + }; + OperatorSetIdProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + OperatorSetIdProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.OperatorSetIdProto"; + }; + return OperatorSetIdProto; + }(); + onnx6.OperatorStatus = function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "EXPERIMENTAL"] = 0; + values[valuesById[1] = "STABLE"] = 1; + return values; + }(); + onnx6.FunctionProto = function() { + function FunctionProto(properties) { + this.input = []; + this.output = []; + this.attribute = []; + this.attributeProto = []; + this.node = []; + this.opsetImport = []; + if (properties) { + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + } + FunctionProto.prototype.name = ""; + FunctionProto.prototype.input = $util.emptyArray; + FunctionProto.prototype.output = $util.emptyArray; + FunctionProto.prototype.attribute = $util.emptyArray; + FunctionProto.prototype.attributeProto = $util.emptyArray; + FunctionProto.prototype.node = $util.emptyArray; + FunctionProto.prototype.docString = ""; + FunctionProto.prototype.opsetImport = $util.emptyArray; + FunctionProto.prototype.domain = ""; + FunctionProto.create = function create(properties) { + return new FunctionProto(properties); + }; + FunctionProto.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32( + /* id 1, wireType 2 =*/ + 10 + ).string(message.name); + if (message.input != null && message.input.length) + for (var i = 0; i < message.input.length; ++i) + writer.uint32( + /* id 4, wireType 2 =*/ + 34 + ).string(message.input[i]); + if (message.output != null && message.output.length) + for (var i = 0; i < message.output.length; ++i) + writer.uint32( + /* id 5, wireType 2 =*/ + 42 + ).string(message.output[i]); + if (message.attribute != null && message.attribute.length) + for (var i = 0; i < message.attribute.length; ++i) + writer.uint32( + /* id 6, wireType 2 =*/ + 50 + ).string(message.attribute[i]); + if (message.node != null && message.node.length) + for (var i = 0; i < message.node.length; ++i) + $root.onnx.NodeProto.encode(message.node[i], writer.uint32( + /* id 7, wireType 2 =*/ + 58 + ).fork()).ldelim(); + if (message.docString != null && Object.hasOwnProperty.call(message, "docString")) + writer.uint32( + /* id 8, wireType 2 =*/ + 66 + ).string(message.docString); + if (message.opsetImport != null && message.opsetImport.length) + for (var i = 0; i < message.opsetImport.length; ++i) + $root.onnx.OperatorSetIdProto.encode(message.opsetImport[i], writer.uint32( + /* id 9, wireType 2 =*/ + 74 + ).fork()).ldelim(); + if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) + writer.uint32( + /* id 10, wireType 2 =*/ + 82 + ).string(message.domain); + if (message.attributeProto != null && message.attributeProto.length) + for (var i = 0; i < message.attributeProto.length; ++i) + $root.onnx.AttributeProto.encode(message.attributeProto[i], writer.uint32( + /* id 11, wireType 2 =*/ + 90 + ).fork()).ldelim(); + return writer; + }; + FunctionProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + FunctionProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === void 0 ? reader.len : reader.pos + length, message = new $root.onnx.FunctionProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.name = reader.string(); + break; + } + case 4: { + if (!(message.input && message.input.length)) + message.input = []; + message.input.push(reader.string()); + break; + } + case 5: { + if (!(message.output && message.output.length)) + message.output = []; + message.output.push(reader.string()); + break; + } + case 6: { + if (!(message.attribute && message.attribute.length)) + message.attribute = []; + message.attribute.push(reader.string()); + break; + } + case 11: { + if (!(message.attributeProto && message.attributeProto.length)) + message.attributeProto = []; + message.attributeProto.push($root.onnx.AttributeProto.decode(reader, reader.uint32())); + break; + } + case 7: { + if (!(message.node && message.node.length)) + message.node = []; + message.node.push($root.onnx.NodeProto.decode(reader, reader.uint32())); + break; + } + case 8: { + message.docString = reader.string(); + break; + } + case 9: { + if (!(message.opsetImport && message.opsetImport.length)) + message.opsetImport = []; + message.opsetImport.push($root.onnx.OperatorSetIdProto.decode(reader, reader.uint32())); + break; + } + case 10: { + message.domain = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + FunctionProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + FunctionProto.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) { + if (!$util.isString(message.name)) + return "name: string expected"; + } + if (message.input != null && message.hasOwnProperty("input")) { + if (!Array.isArray(message.input)) + return "input: array expected"; + for (var i = 0; i < message.input.length; ++i) + if (!$util.isString(message.input[i])) + return "input: string[] expected"; + } + if (message.output != null && message.hasOwnProperty("output")) { + if (!Array.isArray(message.output)) + return "output: array expected"; + for (var i = 0; i < message.output.length; ++i) + if (!$util.isString(message.output[i])) + return "output: string[] expected"; + } + if (message.attribute != null && message.hasOwnProperty("attribute")) { + if (!Array.isArray(message.attribute)) + return "attribute: array expected"; + for (var i = 0; i < message.attribute.length; ++i) + if (!$util.isString(message.attribute[i])) + return "attribute: string[] expected"; + } + if (message.attributeProto != null && message.hasOwnProperty("attributeProto")) { + if (!Array.isArray(message.attributeProto)) + return "attributeProto: array expected"; + for (var i = 0; i < message.attributeProto.length; ++i) { + var error = $root.onnx.AttributeProto.verify(message.attributeProto[i]); + if (error) + return "attributeProto." + error; + } + } + if (message.node != null && message.hasOwnProperty("node")) { + if (!Array.isArray(message.node)) + return "node: array expected"; + for (var i = 0; i < message.node.length; ++i) { + var error = $root.onnx.NodeProto.verify(message.node[i]); + if (error) + return "node." + error; + } + } + if (message.docString != null && message.hasOwnProperty("docString")) { + if (!$util.isString(message.docString)) + return "docString: string expected"; + } + if (message.opsetImport != null && message.hasOwnProperty("opsetImport")) { + if (!Array.isArray(message.opsetImport)) + return "opsetImport: array expected"; + for (var i = 0; i < message.opsetImport.length; ++i) { + var error = $root.onnx.OperatorSetIdProto.verify(message.opsetImport[i]); + if (error) + return "opsetImport." + error; + } + } + if (message.domain != null && message.hasOwnProperty("domain")) { + if (!$util.isString(message.domain)) + return "domain: string expected"; + } + return null; + }; + FunctionProto.fromObject = function fromObject(object) { + if (object instanceof $root.onnx.FunctionProto) + return object; + var message = new $root.onnx.FunctionProto(); + if (object.name != null) + message.name = String(object.name); + if (object.input) { + if (!Array.isArray(object.input)) + throw TypeError(".onnx.FunctionProto.input: array expected"); + message.input = []; + for (var i = 0; i < object.input.length; ++i) + message.input[i] = String(object.input[i]); + } + if (object.output) { + if (!Array.isArray(object.output)) + throw TypeError(".onnx.FunctionProto.output: array expected"); + message.output = []; + for (var i = 0; i < object.output.length; ++i) + message.output[i] = String(object.output[i]); + } + if (object.attribute) { + if (!Array.isArray(object.attribute)) + throw TypeError(".onnx.FunctionProto.attribute: array expected"); + message.attribute = []; + for (var i = 0; i < object.attribute.length; ++i) + message.attribute[i] = String(object.attribute[i]); + } + if (object.attributeProto) { + if (!Array.isArray(object.attributeProto)) + throw TypeError(".onnx.FunctionProto.attributeProto: array expected"); + message.attributeProto = []; + for (var i = 0; i < object.attributeProto.length; ++i) { + if (typeof object.attributeProto[i] !== "object") + throw TypeError(".onnx.FunctionProto.attributeProto: object expected"); + message.attributeProto[i] = $root.onnx.AttributeProto.fromObject(object.attributeProto[i]); + } + } + if (object.node) { + if (!Array.isArray(object.node)) + throw TypeError(".onnx.FunctionProto.node: array expected"); + message.node = []; + for (var i = 0; i < object.node.length; ++i) { + if (typeof object.node[i] !== "object") + throw TypeError(".onnx.FunctionProto.node: object expected"); + message.node[i] = $root.onnx.NodeProto.fromObject(object.node[i]); + } + } + if (object.docString != null) + message.docString = String(object.docString); + if (object.opsetImport) { + if (!Array.isArray(object.opsetImport)) + throw TypeError(".onnx.FunctionProto.opsetImport: array expected"); + message.opsetImport = []; + for (var i = 0; i < object.opsetImport.length; ++i) { + if (typeof object.opsetImport[i] !== "object") + throw TypeError(".onnx.FunctionProto.opsetImport: object expected"); + message.opsetImport[i] = $root.onnx.OperatorSetIdProto.fromObject(object.opsetImport[i]); + } + } + if (object.domain != null) + message.domain = String(object.domain); + return message; + }; + FunctionProto.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.input = []; + object.output = []; + object.attribute = []; + object.node = []; + object.opsetImport = []; + object.attributeProto = []; + } + if (options.defaults) { + object.name = ""; + object.docString = ""; + object.domain = ""; + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.input && message.input.length) { + object.input = []; + for (var j = 0; j < message.input.length; ++j) + object.input[j] = message.input[j]; + } + if (message.output && message.output.length) { + object.output = []; + for (var j = 0; j < message.output.length; ++j) + object.output[j] = message.output[j]; + } + if (message.attribute && message.attribute.length) { + object.attribute = []; + for (var j = 0; j < message.attribute.length; ++j) + object.attribute[j] = message.attribute[j]; + } + if (message.node && message.node.length) { + object.node = []; + for (var j = 0; j < message.node.length; ++j) + object.node[j] = $root.onnx.NodeProto.toObject(message.node[j], options); + } + if (message.docString != null && message.hasOwnProperty("docString")) + object.docString = message.docString; + if (message.opsetImport && message.opsetImport.length) { + object.opsetImport = []; + for (var j = 0; j < message.opsetImport.length; ++j) + object.opsetImport[j] = $root.onnx.OperatorSetIdProto.toObject(message.opsetImport[j], options); + } + if (message.domain != null && message.hasOwnProperty("domain")) + object.domain = message.domain; + if (message.attributeProto && message.attributeProto.length) { + object.attributeProto = []; + for (var j = 0; j < message.attributeProto.length; ++j) + object.attributeProto[j] = $root.onnx.AttributeProto.toObject(message.attributeProto[j], options); + } + return object; + }; + FunctionProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + FunctionProto.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === void 0) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/onnx.FunctionProto"; + }; + return FunctionProto; + }(); + return onnx6; + }(); + module2.exports = $root; + } +}); + +// web/lib/onnxjs/util.ts +function assert(expr, msg) { + if (!expr) { + throw new Error(typeof msg === "string" ? msg : msg()); + } +} +function decodeUtf8String(buffer) { + return new TextDecoder().decode(buffer); +} +var import_onnx, ArrayUtil, MatMulUtil, BroadcastUtil, GemmUtil, ProtoUtil, LongUtil, ShapeUtil, SplitUtil, PoolConvUtil, MIN_CLIP, MAX_CLIP; +var init_util = __esm({ + "web/lib/onnxjs/util.ts"() { + "use strict"; + init_flatbuffers(); + init_long(); + import_onnx = __toESM(require_onnx()); + init_tensor2(); + ArrayUtil = class { + /** + * Verifies if 2 input arrays contain the same elements. + * @param n1 Array 1 + * @param n2 Array 2 + * @returns Whether these 2 are equal + */ + static arraysEqual(n1, n2) { + if (n1.length !== n2.length) { + return false; + } + for (let i = 0; i < n1.length; i++) { + if (n1[i] !== n2[i]) { + return false; + } + } + return true; + } + }; + MatMulUtil = class { + /** + * Fix the input shapes for MatMul operation if they need fixing + * @param dimsA The shape of tensor A. Should be an array of positive integers + * @param dimsB The shape of tensor B. Should be an array of positive integers + * @returns A tuple containing the preprocessed input shapes as required by ONNX specifications + */ + static preprocessInputShapes(dimsA, dimsB) { + const a = dimsA.length === 1 ? [1, dimsA[0]] : dimsA; + const b = dimsB.length === 1 ? [dimsB[0], 1] : dimsB; + return [a, b]; + } + /** + * Fix the output shape computed for MatMul operation if it needs fixing + * @param outputShape The computed outputShape. Should be an array (atleast of length 2) of positive integers. + * This will be mutated. + * @param aRank The rank of tensor A. + * @param bRank The rank of tensor B. + */ + static postprocessOutputShape(outputShape, aRank, bRank) { + if (aRank === 1) { + outputShape.splice(outputShape.length - 2, 1); + } + if (bRank === 1) { + outputShape.pop(); + } + } + /** + * Calculate the expected shape when matrix multiplication + * @param a The shape of tensor A. Should be a tuple of 2 positive integers + * @param b The shape of tensor B. Should be a tuple of 2 positive integers + * @returns The expected shape of the result, or undefined if N/A + */ + static calcMatMulShape(a, b) { + return a[1] !== b[0] ? void 0 : [a[0], b[1]]; + } + }; + BroadcastUtil = class _BroadcastUtil { + /** + * Calculate the expected shape when broadcasting 2 tensors + * @param a The shape of tensor A. Should be an array of positive integers + * @param b The shape of tensor B. Should be an array of positive integers + * @param isMatMul Whether the operation is MatMul + * @returns The expected shape of the result, or undefined if N/A + */ + static calcShape(adims, bdims, isMatMul = false) { + const arank = adims.length; + const brank = bdims.length; + if (arank === 0) { + return bdims; + } + if (brank === 0) { + return adims; + } + const crank = Math.max(adims.length, bdims.length); + const cdims = new Array(crank); + if (isMatMul) { + if (arank < 2 || brank < 2) { + return void 0; + } + const cShapeMatMul = MatMulUtil.calcMatMulShape([adims[arank - 2], adims[arank - 1]], [bdims[brank - 2], bdims[brank - 1]]); + if (cShapeMatMul === void 0) { + return void 0; + } + [cdims[crank - 2], cdims[crank - 1]] = cShapeMatMul; + } + for (let i = isMatMul ? 3 : 1; i <= crank; i++) { + const aLen = arank - i < 0 ? 1 : adims[arank - i]; + const bLen = brank - i < 0 ? 1 : bdims[brank - i]; + if (aLen !== bLen && aLen > 1 && bLen > 1) { + return void 0; + } + cdims[crank - i] = Math.max(aLen, bLen); + } + return cdims; + } + /** + * Given the indices of a broadcasted tensor, calculate the original indices + * @param broadcastedIndices The given indices of the broadcasted tensor. + * @param originalShape The original shape of the tensor before broadcas + * @returns The calculated indices that maps to the original tensor. + */ + static index(broadcastedIndices, originalShape) { + const originalIndices = new Array(originalShape.length); + _BroadcastUtil.fillIndex(broadcastedIndices, originalShape, originalIndices); + return originalIndices; + } + /** + * Given the indices of a broadcasted tensor, calculate the original indices + * @param broadcastedIndices The given indices of the broadcasted tensor. + * @param originalShape The original shape of the tensor before broadcast + * @param originalIndices The mapping of broadcastedIndices to the originalIndices (output parameter - will be + * mutated). + */ + static fillIndex(broadcastedIndices, originalShape, originalIndices) { + const dimOffset = broadcastedIndices.length - originalShape.length; + for (let i = 0; i < originalShape.length; i++) { + originalIndices[i] = broadcastedIndices[dimOffset + i] % originalShape[i]; + } + } + /** + * Perform the broadcasting operation on the specific operator + * @param a The input tensor A + * @param b The input tensor B + * @param op The operator lambda function + * @param inplace Whether to write the result back to A. + * @returns The result tensor, or undefined if input not broadcastable. + */ + static calc(a, b, op, inplace, resultType) { + const outputShape = _BroadcastUtil.calcShape(a.dims, b.dims); + if (outputShape) { + if (inplace && !ShapeUtil.areEqual(outputShape, a.dims)) { + return void 0; + } + const size = ShapeUtil.size(outputShape); + const c = inplace ? a : new Tensor3(outputShape, resultType || a.type); + if (outputShape.length === 0) { + c.set([], op(a.get([]), b.get([]))); + } else { + const outputIndices = new Array(outputShape.length); + const originalIndicesA = new Array(a.dims.length); + const originalIndicesB = new Array(b.dims.length); + let valA = 0; + let valB = 0; + let isAScalar = false; + let isBScalar = false; + if (a.dims.length === 0) { + valA = a.get([]); + isAScalar = true; + } + if (b.dims.length === 0) { + valB = b.get([]); + isBScalar = true; + } + let rest; + for (let i = 0; i < size; i++) { + rest = i; + for (let j = outputShape.length - 1; j >= 0; j--) { + outputIndices[j] = rest % outputShape[j]; + rest = Math.floor(rest / outputShape[j]); + } + if (!isAScalar) { + _BroadcastUtil.fillIndex(outputIndices, a.dims, originalIndicesA); + valA = a.get(originalIndicesA); + } + if (!isBScalar) { + _BroadcastUtil.fillIndex(outputIndices, b.dims, originalIndicesB); + valB = b.get(originalIndicesB); + } + c.set(outputIndices, op(valA, valB)); + } + } + return c; + } + return void 0; + } + /** + * Determine if a shape is unidirectional broadcastable to another shape + * @param shape The input shape + * @param finalShape The desired shape after broadcasting + */ + static isValidBroadcast(shape2, finalShape) { + const inputRank = shape2.length; + const finalRank = finalShape.length; + if (inputRank > finalRank) { + return false; + } + for (let i = 1; i <= inputRank; i++) { + if (shape2[inputRank - i] !== 1 && shape2[inputRank - i] !== finalShape[finalRank - i]) { + return false; + } + } + return true; + } + /** + * Determine the broadcasted dims in input shape based on the given output shape. + * Note that this function only returns the broadcasted dims. + * @param inputShape The input shape + * @param outputShape The output shape + * @returns The broadcasted dims in input shape. + */ + static getBroadcastDims(inputShape, outputShape) { + const inRank = inputShape.length; + const dims = []; + for (let i = 0; i < inRank; i++) { + const dim = inRank - 1 - i; + const a = inputShape[dim] || 1; + const b = outputShape[outputShape.length - 1 - i] || 1; + if (b > 1 && a === 1) { + dims.unshift(dim); + } + } + return dims; + } + }; + GemmUtil = class { + // will make sure input shapes are compatible for this op + // and return back the shape of the output in the form of a tuple + // will throw exception if the input shapes are not compatible + static getShapeOfGemmResult(leftShape, transLeft, rightShape, transRight, biasShape) { + if (leftShape.length !== 2 || rightShape.length !== 2) { + throw new Error("shape need to be of size 2"); + } + let M; + let K; + let N; + if (transLeft) { + M = leftShape[1]; + K = leftShape[0]; + } else { + M = leftShape[0]; + K = leftShape[1]; + } + let kDim = -1; + if (transRight) { + N = rightShape[0]; + kDim = 1; + } else { + N = rightShape[1]; + kDim = 0; + } + if (rightShape[kDim] !== K) { + throw new Error("dimension mismatch"); + } + if (M <= 0 || N <= 0 || K <= 0) { + throw new Error("invalid shape specified"); + } + if (biasShape && !BroadcastUtil.isValidBroadcast(biasShape, [M, N])) { + throw new Error("gemm: invalid bias shape for broadcast"); + } + return [M, N, K]; + } + }; + ProtoUtil = class _ProtoUtil { + static tensorDataTypeFromProto(typeProto) { + switch (typeProto) { + case import_onnx.onnx.TensorProto.DataType.INT8: + return "int8"; + case import_onnx.onnx.TensorProto.DataType.UINT8: + return "uint8"; + case import_onnx.onnx.TensorProto.DataType.BOOL: + return "bool"; + case import_onnx.onnx.TensorProto.DataType.INT16: + return "int16"; + case import_onnx.onnx.TensorProto.DataType.UINT16: + return "uint16"; + case import_onnx.onnx.TensorProto.DataType.INT32: + return "int32"; + case import_onnx.onnx.TensorProto.DataType.UINT32: + return "uint32"; + case import_onnx.onnx.TensorProto.DataType.FLOAT: + return "float32"; + case import_onnx.onnx.TensorProto.DataType.DOUBLE: + return "float64"; + case import_onnx.onnx.TensorProto.DataType.STRING: + return "string"; + case import_onnx.onnx.TensorProto.DataType.INT64: + return "int32"; + case import_onnx.onnx.TensorProto.DataType.UINT64: + return "uint32"; + default: + throw new Error(`unsupported data type: ${import_onnx.onnx.TensorProto.DataType[typeProto]}`); + } + } + static tensorDataTypeStringToEnum(type) { + switch (type) { + case "int8": + return import_onnx.onnx.TensorProto.DataType.INT8; + case "uint8": + return import_onnx.onnx.TensorProto.DataType.UINT8; + case "bool": + return import_onnx.onnx.TensorProto.DataType.BOOL; + case "int16": + return import_onnx.onnx.TensorProto.DataType.INT16; + case "uint16": + return import_onnx.onnx.TensorProto.DataType.UINT16; + case "int32": + return import_onnx.onnx.TensorProto.DataType.INT32; + case "uint32": + return import_onnx.onnx.TensorProto.DataType.UINT32; + case "float32": + return import_onnx.onnx.TensorProto.DataType.FLOAT; + case "float64": + return import_onnx.onnx.TensorProto.DataType.DOUBLE; + case "string": + return import_onnx.onnx.TensorProto.DataType.STRING; + case "int64": + return import_onnx.onnx.TensorProto.DataType.INT64; + case "uint64": + return import_onnx.onnx.TensorProto.DataType.UINT64; + default: + throw new Error(`unsupported data type: ${type}`); + } + } + static tensorDimsFromProto(dims) { + return dims.map((d) => long_default.isLong(d) ? d.toNumber() : d); + } + static tensorValueTypeFromProto(valueType) { + return { + tensorType: _ProtoUtil.tensorDataTypeFromProto(valueType.elemType), + shape: { dims: _ProtoUtil.tensorDimsFromProto(valueType.shape.dim.map((d) => d.dimValue)) } + }; + } + static tensorDimsFromORTFormat(tensor) { + const dims = []; + for (let i = 0; i < tensor.dimsLength(); i++) { + dims.push(LongUtil.longToNumber(tensor.dims(i))); + } + return dims; + } + static tensorAttributesFromORTFormat(node) { + const attributes = []; + for (let i = 0; i < node.attributesLength(); i++) { + attributes.push(node.attributes(i)); + } + return attributes; + } + }; + LongUtil = class { + // This function is called to get a number from long type of data for attribute, dim, and ir version, + // which values are signed integers. + // To make it more generic, add an optional paramter to convert to a unsigned number. + static longToNumber(n, unsigned) { + if (long_default.isLong(n)) { + return n.toNumber(); + } else if (n instanceof flatbuffers.Long) { + return long_default.fromValue({ low: n.low, high: n.high, unsigned: unsigned ?? false }).toNumber(); + } + return n; + } + static isLong(n) { + return long_default.isLong(n) || n instanceof flatbuffers.Long; + } + }; + ShapeUtil = class _ShapeUtil { + static size(dims) { + return _ShapeUtil.getSizeFromDimensionRange(dims, 0, dims.length); + } + // `axis` inclusive + static sizeFromDimension(dims, axis) { + if (axis < 0 || axis > dims.length) { + throw new Error(`invalid dimension of ${axis} for sizeFromDimension as Tensor has ${dims.length} dimensions.`); + } + return _ShapeUtil.getSizeFromDimensionRange(dims, axis, dims.length); + } + // `axis` exclusive + static sizeToDimension(dims, axis) { + if (axis < 0 || axis > dims.length) { + throw new Error(`invalid dimension of ${axis} for sizeToDimension as Tensor has ${dims.length} dimensions.`); + } + return _ShapeUtil.getSizeFromDimensionRange(dims, 0, axis); + } + static getSizeFromDimensionRange(dims, start, end) { + let size = 1; + for (let i = start; i < end; i++) { + if (dims[i] <= 0) { + throw new Error( + // eslint-disable-next-line max-len + "cannot get valid size from specified dimension range. Most likely the range contains 0 or negative values in them." + ); + } + size *= dims[i]; + } + return size; + } + static computeStrides(dims) { + const rank = dims.length; + if (rank === 0) { + return []; + } else if (rank === 1) { + return [1]; + } + const strides = new Array(rank); + strides[rank - 1] = 1; + strides[rank - 2] = dims[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * dims[i + 1]; + } + return strides; + } + static transpose(dims) { + const copy = dims.slice(); + return copy.reverse(); + } + static indicesToOffset(indices, strides, axis) { + if (axis === void 0) { + axis = indices.length; + } + let offset = 0; + for (let i = 0; i < axis; ++i) { + offset += strides[i] * indices[i]; + } + return offset; + } + static offsetToIndices(offset, strides) { + const rank = strides.length; + if (rank === 0) { + return []; + } else if (rank === 1) { + return [offset * strides[0]]; + } + const indices = new Array(strides.length); + for (let i = 0; i < indices.length - 1; ++i) { + indices[i] = Math.floor(offset / strides[i]); + offset -= indices[i] * strides[i]; + } + indices[indices.length - 1] = offset; + return indices; + } + /** + * normailze axis of range [-r, r) into [0, r). + */ + static normalizeAxis(axis, tensorRank) { + if (axis < -tensorRank && axis >= tensorRank) { + throw new Error("unsupported axis for this operation."); + } + return axis < 0 ? axis + tensorRank : axis; + } + static normalizeAxes(axes, tensorRank) { + return axes.map((x) => this.normalizeAxis(x, tensorRank)); + } + // Increment an index into a tensor (in lexicographic + // ordering), wrapping around the specified upper_bound. + /** + * Increment an index into a tensor (in lexicographic ordering), wrapping around the specified upper_bound. + * @param index Given index to increment (Will be mutated) + * @param dims The dimensions of the tensor for which the given index corresponds to + * @param axisToIncrementOn The 1-indexed axis to increment on. If undefined, axisToIncrementOn == rank + */ + static incrementIndex(index, dims, axisToIncrementOn) { + if (dims.length === 0 || index.length === 0) { + throw new Error("Index incrementing unsupported for scalar Tensor"); + } + if (axisToIncrementOn === void 0) { + axisToIncrementOn = dims.length; + } else { + if (axisToIncrementOn <= 0 || axisToIncrementOn > dims.length) { + throw new Error("Incorrect axis to increment on"); + } + } + for (let k = axisToIncrementOn - 1; k >= 0; --k) { + index[k]++; + if (index[k] < dims[k]) { + break; + } + index[k] = 0; + } + } + /** + * Produces a new dimensions array based on the values in the 'originalDimensions' and 'shape' array + * Used in Reshape + * @param originalDims Original Shape array + * @param shapeHints array containing values to compute the new dimensions + * For example: + * originalDims = [2,2] and shapeHints = [0,-1] will return [2,2] + * originalDims = [2,2] and shapeHints = [4] will return [4] + * originalDims = [2,2] and shapeHints = [5] will throw an exception + * https://github.com/onnx/onnx/blob/main/docs/Operators.md#Reshape + */ + static calculateReshapedDims(originalDims, shapeHints) { + if (shapeHints.length === 0) { + if (originalDims.length === 0 || _ShapeUtil.size(originalDims) === 1) { + return []; + } else { + throw new Error("cannot reshape to a scalar Tensor"); + } + } + const nDims = shapeHints.length; + const reshapedDims = new Array(nDims); + let unknownDimension = -1; + let newTensorSize = 1; + for (let i = 0; i < nDims; i++) { + if (shapeHints[i] < -1) { + throw new Error("a dimension in shape hints cannot be less than -1"); + } + if (shapeHints[i] === -1) { + if (unknownDimension !== -1) { + throw new Error("at most one dimension in shape hints can be -1"); + } + unknownDimension = i; + } else { + if (shapeHints[i] === 0) { + if (i >= originalDims.length) { + throw new Error("the dimension with value zero exceeds the dimension size of the input tensor"); + } + reshapedDims[i] = originalDims[i]; + } else { + reshapedDims[i] = shapeHints[i]; + } + newTensorSize *= reshapedDims[i]; + } + } + const oldTensorSize = _ShapeUtil.size(originalDims); + if (unknownDimension !== -1) { + if (oldTensorSize % newTensorSize !== 0) { + throw new Error(`the input tensor cannot be reshaped to the requested shape. Input shape: [${originalDims}] Output shape: [${shapeHints}]`); + } + reshapedDims[unknownDimension] = oldTensorSize / newTensorSize; + } else { + if (newTensorSize !== oldTensorSize) { + throw new Error("reshapedDims and originalDims don't have matching sizes"); + } + } + return reshapedDims; + } + /** + * Sorts a given array based on the indices in the Perm array + * Used in Transpose + * @param a Array to be sorted such as dims or strides + * @param perm Perm given; if null a will be reversed + */ + static sortBasedOnPerm(a, perm) { + if (perm) { + return perm.map((v) => a[v]); + } else { + return a.slice().reverse(); + } + } + /** + * Pads a given shape according to the padding values + * @param dims shape of the Tensor to be padded + * @param pad pad values + */ + static padShape(dims, pad) { + const rank = dims.length; + return dims.map((v, i) => v + pad[i] + pad[i + rank]); + } + /** + * Determines if the two shapes are identical + * @param shape1 + * @param shape2 + */ + static areEqual(shape1, shape2) { + if (shape1.length !== shape2.length) { + return false; + } + return shape1.every((v, i) => v === shape2[i]); + } + /** + * Validates if the given `dims` or `shape` is valid in ONNX.js context and returns data size + * @param dims - input `dims` that needs to be checked + */ + static validateDimsAndCalcSize(dims) { + if (dims.length > 6) { + throw new TypeError("Only rank 0 to 6 is supported for tensor shape."); + } + let size = 1; + for (const n of dims) { + if (!Number.isInteger(n)) { + throw new TypeError(`Invalid shape: ${n} is not an integer`); + } + if (n < 0 || n > 2147483647) { + throw new TypeError(`Invalid shape: length ${n} is not allowed`); + } + size *= n; + } + return size; + } + /** + * Determines the shape of output tensor y = flatten(x, axis) + * @param dims - shape of input tensor + * @param axis - flatten axis, in the range [-r, r] + */ + static flattenShape(dims, axis) { + if (axis < 0) { + axis += dims.length; + } + const total = dims.reduce((x, y) => x * y, 1); + const right = dims.slice(axis).reduce((x, y) => x * y, 1); + const outputDims = [total / right, right]; + return outputDims; + } + /** + * Determines the shape of output tensor y = squeeze(x, axes) + * @param dims - shape of input tensor + * @param axes - squeeze axes + */ + static squeezeShape(dims, axes) { + const outputDims = new Array(); + axes = _ShapeUtil.normalizeAxes(axes, dims.length); + for (let i = 0; i < dims.length; i++) { + const inSqueezeList = axes.indexOf(i) >= 0; + if (inSqueezeList && dims[i] !== 1) { + throw new Error("squeeze an axis of size different than 1"); + } + if (axes.length === 0 && dims[i] > 1 || axes.length > 0 && !inSqueezeList) { + outputDims.push(dims[i]); + } + } + return outputDims; + } + /** + * Determines the shape of output tensor y = unsqueeze(x, axes) + * @param dims - shape of input tensor + * @param axes - unsqueeze axes + */ + static unsqueezeShape(dims, axes) { + const outputDims = new Array(dims.length + axes.length); + outputDims.fill(0); + for (let i = 0; i < axes.length; i++) { + const axis = _ShapeUtil.normalizeAxis(axes[i], outputDims.length); + if (axis >= outputDims.length) { + throw new Error("'axes' has an out of range axis"); + } + if (outputDims[axis] !== 0) { + throw new Error("'axes' has a duplicate axis"); + } + outputDims[axis] = 1; + } + let inputDimsIterator = 0; + for (let i = 0; i < outputDims.length; i++) { + if (outputDims[i] === 0) { + outputDims[i] = dims[inputDimsIterator++]; + } + } + if (inputDimsIterator !== dims.length) { + throw new Error("the unsqueezed dimension could not be established"); + } + return outputDims; + } + }; + SplitUtil = class _SplitUtil { + /** + * Calculates new Shapes from existing one and the splits given along the axis provides + * @param dims Shape of the Tensor to be splitted into two or more Shapes + * @param axis The dimension along which the Tensor will be split + * @param splits Offsets for the start of each split + */ + static splitShape(dims, axis, split2, numOutputs) { + if (split2.length === 0) { + if (!numOutputs) { + throw new Error("need to know number of outputs when the 'split' attribute is not specified"); + } + _SplitUtil.determineSplit(dims[axis], numOutputs, split2); + } + const shapes = []; + const offsets = [0]; + for (let i = 0; i < split2.length; ++i) { + if (i !== 0) { + offsets.push(offsets[i - 1] + split2[i - 1]); + } + const shape2 = dims.slice(); + shape2[axis] = split2[i]; + shapes.push(shape2); + } + return [shapes, offsets]; + } + static determineSplit(numElementsAlongAxis, numOutputs, split2) { + if (numElementsAlongAxis % numOutputs !== 0) { + throw new Error("cannot split tensor to equal sized parts"); + } + for (let i = 0; i < numOutputs; ++i) { + split2.push(numElementsAlongAxis / numOutputs); + } + } + }; + PoolConvUtil = class _PoolConvUtil { + /** + * Adjust the kernel, strides, pads to correct rank. Set to default value if not present + * @param isGlobalOperator If true, perform global pooling. + * @param inputDims The input tensor dimension. + * @param kernelShape The size of the kernel along each axis. + * @param strides Stride along each axis. + * @param dilations Dilation along each axis. + * @param pads Padding for the beginning and ending along each axis. + */ + static adjustPoolAttributes(isGlobalOperator, inputDims, kernelShape, strides, dilations, pads) { + if (!isGlobalOperator && kernelShape.length !== inputDims.length - 2) { + throw new Error("length of specified kernel shapes should be 2 less than length of input dimensions"); + } + if (isGlobalOperator) { + for (let dim = 0; dim < inputDims.length - 2; dim++) { + if (dim >= kernelShape.length) { + kernelShape.push(inputDims[dim + 2]); + } else { + kernelShape[dim] = inputDims[dim + 2]; + } + } + } + for (let dim = 0; dim < kernelShape.length; dim++) { + if (dim < strides.length) { + if (strides[dim] < 0) { + throw new Error("strides should be greater than or equal to 1"); + } + } else { + strides.push(1); + } + } + for (let dim = 0; dim < kernelShape.length; dim++) { + if (dim < dilations.length) { + if (dilations[dim] < 0) { + throw new Error("dilations should be greater than or equal to 1"); + } + } else { + dilations.push(1); + } + } + for (let dim = 0; dim < kernelShape.length * 2; dim++) { + if (dim < pads.length) { + if (pads[dim] < 0) { + throw new Error("pad should be greater than or equal to 1"); + } + } else { + pads.push(0); + } + } + for (let dim = 0; dim < kernelShape.length; dim++) { + if (kernelShape[dim] <= 0) { + throw new Error("kernel shapes need to be greater than 0"); + } + if (pads[dim] >= kernelShape[dim] || pads[dim + kernelShape.length] >= kernelShape[dim]) { + throw new Error("pads should be smaller than kernel"); + } + } + } + // adjust pad values based on 'autoPad' attribute + static adjustPadsBasedOnAutoPad(inputDims, strides, dilations, kernelShape, pads, autoPad) { + if (!autoPad) { + return; + } + if (pads.length !== 2 * (inputDims.length - 2)) { + throw new Error("length of pads should be twice the length of data dimensions"); + } + if (strides.length !== inputDims.length - 2) { + throw new Error("length of strides should be the length of data dimensions"); + } + if (kernelShape.length !== inputDims.length - 2) { + throw new Error("length of kernel shapes should be the length of data dimensions"); + } + for (let dim = 0; dim < inputDims.length - 2; dim++) { + _PoolConvUtil.adjustPadAndReturnShape( + inputDims[dim + 2], + strides[dim], + dilations[dim], + kernelShape[dim], + pads, + dim, + dim + inputDims.length - 2, + autoPad + ); + } + } + /** + * Calculate the output shape for Pool ops based on input attributes. (Should be used only for Pool ops) + * @param isGlobalOperator If true, perform global pooling. + * @param inputDims The input tensor dimension. (inputs[0].dims) + * @param strides Stride along each axis. + * @param dilations Dilation along each axis. + * @param kernelShape The size of the kernel along each axis. + * @param pads Padding for the beginning and ending along each axis. + * @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each + * dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID. + */ + static computePoolOutputShape(isGlobalOperator, inputDims, strides, dilations, kernelShape, pads, autoPad) { + if (inputDims.length <= 0) { + throw new Error("input shape must be of size greater than 0"); + } + const outputDims = [inputDims[0], inputDims[1]]; + _PoolConvUtil.computeShapeHelper( + isGlobalOperator, + inputDims, + outputDims, + strides, + dilations, + kernelShape, + pads, + autoPad + ); + return outputDims; + } + /** + * Calculate the output shape for Conv op based on input attributes. (Should be used only for Conv op) + * @param inputDims The input tensor dimension. (inputs[0].dims) + * @param filterDims The filter tensor dimension. (inputs[1].dims) + * @param strides Stride along each axis. + * @param kernelShape The size of the kernel along each axis. + * @param pads Padding for the beginning and ending along each axis. + * @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each + * dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID. + */ + static computeConvOutputShape(inputDims, filterDims, strides, dilations, kernelShape, pads, autoPad) { + if (inputDims.length <= 0 || filterDims.length <= 0) { + throw new Error("invalid input tensor dims or invalid filter tensor dims"); + } + const outputDims = [inputDims[0], filterDims[0]]; + _PoolConvUtil.computeShapeHelper(false, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad); + return outputDims; + } + // will compute output shapes for data dimensions ONLY (i.e.) no batch size and channels + // called by computePoolOutputShape() and computeConvOutputShape() + // adjust pads based on 'autoPad' attribute prior to shape computation + static computeShapeHelper(isGlobalOperator, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad) { + if (isGlobalOperator) { + for (let dim = 0; dim < inputDims.length - 2; dim++) { + outputDims.push(1); + } + } else { + for (let dim = 0; dim < inputDims.length - 2; dim++) { + outputDims.push(_PoolConvUtil.adjustPadAndReturnShape( + inputDims[dim + 2], + strides[dim], + dilations[dim], + kernelShape[dim], + pads, + dim, + dim + inputDims.length - 2, + autoPad + )); + } + } + } + // helper for computeShapeHelper() and adjustPadsBasedOnAutoPad() + // adjusts pad value for given 'autoPad' string and computes output shape along a particular dimension + static adjustPadAndReturnShape(inSize, stride, dilation, kernel, pads, padHeadIndex, padTailIndex, autoPad) { + const dkernel = dilation * (kernel - 1) + 1; + if (autoPad && autoPad !== "NOTSET") { + switch (autoPad) { + case "VALID": + pads[padHeadIndex] = 0; + pads[padTailIndex] = 0; + return Math.floor((inSize - dkernel) / stride + 1); + case "SAME_LOWER": + case "SAME_UPPER": + if (dilation !== 1) { + throw new Error("Dilation not supported for SAME_UPPER or SAME_LOWER"); + } else { + const legacyTargetSize = (inSize + stride - 1) / stride; + const padNeeded = (legacyTargetSize - 1) * stride + kernel - inSize; + pads[padHeadIndex] = autoPad === "SAME_LOWER" ? Math.floor((padNeeded + 1) / 2) : Math.floor(padNeeded / 2); + pads[padTailIndex] = padNeeded - pads[padHeadIndex]; + return Math.floor((inSize + padNeeded - kernel) / stride + 1); + } + default: + throw new Error("Unsupported AutoPad type"); + } + } else { + return Math.floor((inSize + pads[padHeadIndex] + pads[padTailIndex] - dkernel) / stride + 1); + } + } + }; + MIN_CLIP = -34028234663852886e22; + MAX_CLIP = 34028234663852886e22; + } +}); + +// web/lib/onnxjs/tensor.ts +function sizeof(type) { + switch (type) { + case "bool": + case "int8": + case "uint8": + return 1; + case "int16": + case "uint16": + return 2; + case "int32": + case "uint32": + case "float32": + return 4; + case "float64": + return 8; + default: + throw new Error(`cannot calculate sizeof() on type ${type}`); + } +} +function sizeofProto(type) { + switch (type) { + case import_onnx2.onnx.TensorProto.DataType.UINT8: + case import_onnx2.onnx.TensorProto.DataType.INT8: + case import_onnx2.onnx.TensorProto.DataType.BOOL: + return 1; + case import_onnx2.onnx.TensorProto.DataType.UINT16: + case import_onnx2.onnx.TensorProto.DataType.INT16: + return 2; + case import_onnx2.onnx.TensorProto.DataType.FLOAT: + case import_onnx2.onnx.TensorProto.DataType.INT32: + case import_onnx2.onnx.TensorProto.DataType.UINT32: + return 4; + case import_onnx2.onnx.TensorProto.DataType.INT64: + case import_onnx2.onnx.TensorProto.DataType.DOUBLE: + case import_onnx2.onnx.TensorProto.DataType.UINT64: + return 8; + default: + throw new Error(`cannot calculate sizeof() on type ${import_onnx2.onnx.TensorProto.DataType[type]}`); + } +} +function createView(dataBuffer, type) { + return new (dataviewConstructor(type))(dataBuffer); +} +function dataviewConstructor(type) { + switch (type) { + case "bool": + case "uint8": + return Uint8Array; + case "int8": + return Int8Array; + case "int16": + return Int16Array; + case "uint16": + return Uint16Array; + case "int32": + return Int32Array; + case "uint32": + return Uint32Array; + case "int64": + return BigInt64Array; + case "float32": + return Float32Array; + case "float64": + return Float64Array; + default: + throw new Error("unspecified error"); + } +} +function longToNumber(i, type) { + if (type === import_onnx2.onnx.TensorProto.DataType.INT64 || type === ortFbs.TensorDataType.INT64) { + if (i.greaterThanOrEqual(2147483648) || i.lessThan(-2147483648)) { + throw new TypeError("int64 is not supported"); + } + } else if (type === import_onnx2.onnx.TensorProto.DataType.UINT32 || type === ortFbs.TensorDataType.UINT32 || type === import_onnx2.onnx.TensorProto.DataType.UINT64 || type === ortFbs.TensorDataType.UINT64) { + if (i.greaterThanOrEqual(4294967296) || i.lessThan(0)) { + throw new TypeError("uint64 is not supported"); + } + } else { + throw new TypeError(`not a LONG type: ${import_onnx2.onnx.TensorProto.DataType[type]}`); + } + return i.toNumber(); +} +function readProto(view, type, byteOffset) { + switch (type) { + case import_onnx2.onnx.TensorProto.DataType.BOOL: + case import_onnx2.onnx.TensorProto.DataType.UINT8: + return view.getUint8(byteOffset); + case import_onnx2.onnx.TensorProto.DataType.INT8: + return view.getInt8(byteOffset); + case import_onnx2.onnx.TensorProto.DataType.UINT16: + return view.getUint16(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.INT16: + return view.getInt16(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.FLOAT: + return view.getFloat32(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.INT32: + return view.getInt32(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.UINT32: + return view.getUint32(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.INT64: + return longToNumber( + long_default.fromBits(view.getUint32(byteOffset, true), view.getUint32(byteOffset + 4, true), false), + type + ); + case import_onnx2.onnx.TensorProto.DataType.DOUBLE: + return view.getFloat64(byteOffset, true); + case import_onnx2.onnx.TensorProto.DataType.UINT64: + return longToNumber( + long_default.fromBits(view.getUint32(byteOffset, true), view.getUint32(byteOffset + 4, true), true), + type + ); + default: + throw new Error(`cannot read from DataView for type ${import_onnx2.onnx.TensorProto.DataType[type]}`); + } +} +var import_guid_typescript, import_onnx2, ortFbs, Tensor3; +var init_tensor2 = __esm({ + "web/lib/onnxjs/tensor.ts"() { + "use strict"; + import_guid_typescript = __toESM(require_guid()); + init_long(); + init_ort_generated(); + import_onnx2 = __toESM(require_onnx()); + init_util(); + ortFbs = onnxruntime.experimental.fbs; + Tensor3 = class _Tensor { + constructor(dims, type, dataProvider, asyncDataProvider, cache2, dataId = import_guid_typescript.Guid.create()) { + this.dims = dims; + this.type = type; + this.dataProvider = dataProvider; + this.asyncDataProvider = asyncDataProvider; + this.cache = cache2; + this.dataId = dataId; + this.size = ShapeUtil.validateDimsAndCalcSize(dims); + const size = this.size; + const empty = dataProvider === void 0 && asyncDataProvider === void 0 && cache2 === void 0; + if (cache2 !== void 0) { + if (cache2.length !== size) { + throw new RangeError("Input dims doesn't match data length."); + } + } + if (type === "string") { + if (cache2 !== void 0 && (!Array.isArray(cache2) || !cache2.every((i) => typeof i === "string"))) { + throw new TypeError("cache should be a string array"); + } + if (empty) { + this.cache = new Array(size); + } + } else { + if (cache2 !== void 0) { + const constructor = dataviewConstructor(type); + if (!(cache2 instanceof constructor)) { + throw new TypeError(`cache should be type ${constructor.name}`); + } + } + if (empty) { + const buf = new ArrayBuffer(size * sizeof(type)); + this.cache = createView(buf, type); + } + } + } + /** + * get the underlying tensor data + */ + get data() { + if (this.cache === void 0) { + const data = this.dataProvider(this.dataId); + if (data.length !== this.size) { + throw new Error("Length of data provided by the Data Provider is inconsistent with the dims of this Tensor."); + } + this.cache = data; + } + return this.cache; + } + /** + * get the underlying string tensor data. Should only use when type is STRING + */ + get stringData() { + if (this.type !== "string") { + throw new TypeError("data type is not string"); + } + return this.data; + } + /** + * get the underlying integer tensor data. Should only use when type is one of the following: (UINT8, INT8, UINT16, + * INT16, INT32, UINT32, BOOL) + */ + get integerData() { + switch (this.type) { + case "uint8": + case "int8": + case "uint16": + case "int16": + case "int32": + case "uint32": + case "bool": + return this.data; + default: + throw new TypeError("data type is not integer (uint8, int8, uint16, int16, int32, uint32, bool)"); + } + } + /** + * get the underlying float tensor data. Should only use when type is one of the following: (FLOAT, DOUBLE) + */ + get floatData() { + switch (this.type) { + case "float32": + case "float64": + return this.data; + default: + throw new TypeError("data type is not float (float32, float64)"); + } + } + /** + * get the underlying number tensor data. Should only use when type is one of the following: (UINT8, INT8, UINT16, + * INT16, INT32, UINT32, BOOL, FLOAT, DOUBLE) + */ + get numberData() { + if (this.type !== "string") { + return this.data; + } + throw new TypeError("type cannot be non-number (string)"); + } + /** + * get value of an element at the given indices + */ + get(indices) { + return this.data[ShapeUtil.indicesToOffset(indices, this.strides)]; + } + /** + * set value of an element at the given indices + */ + set(indices, value) { + this.data[ShapeUtil.indicesToOffset(indices, this.strides)] = value; + } + /** + * get the underlying tensor data asynchronously + */ + async getData() { + if (this.cache === void 0) { + this.cache = await this.asyncDataProvider(this.dataId); + } + return this.cache; + } + /** + * get the strides for each dimension + */ + get strides() { + if (!this._strides) { + this._strides = ShapeUtil.computeStrides(this.dims); + } + return this._strides; + } + /** + * Construct new Tensor from a ONNX Tensor object + * @param tensorProto the ONNX Tensor + */ + static fromProto(tensorProto) { + if (!tensorProto) { + throw new Error("cannot construct Value from an empty tensor"); + } + const type = ProtoUtil.tensorDataTypeFromProto(tensorProto.dataType); + const dims = ProtoUtil.tensorDimsFromProto(tensorProto.dims); + const value = new _Tensor(dims, type); + if (type === "string") { + tensorProto.stringData.forEach((str, i) => { + value.data[i] = decodeUtf8String(str); + }); + } else if (tensorProto.rawData && typeof tensorProto.rawData.byteLength === "number" && tensorProto.rawData.byteLength > 0) { + const dataDest = value.data; + const dataSource = new DataView(tensorProto.rawData.buffer, tensorProto.rawData.byteOffset, tensorProto.rawData.byteLength); + const elementSize = sizeofProto(tensorProto.dataType); + const length = tensorProto.rawData.byteLength / elementSize; + if (tensorProto.rawData.byteLength % elementSize !== 0) { + throw new Error("invalid buffer length"); + } + if (dataDest.length !== length) { + throw new Error("buffer length mismatch"); + } + for (let i = 0; i < length; i++) { + const n = readProto(dataSource, tensorProto.dataType, i * elementSize); + dataDest[i] = n; + } + } else { + let array; + switch (tensorProto.dataType) { + case import_onnx2.onnx.TensorProto.DataType.FLOAT: + array = tensorProto.floatData; + break; + case import_onnx2.onnx.TensorProto.DataType.INT32: + case import_onnx2.onnx.TensorProto.DataType.INT16: + case import_onnx2.onnx.TensorProto.DataType.UINT16: + case import_onnx2.onnx.TensorProto.DataType.INT8: + case import_onnx2.onnx.TensorProto.DataType.UINT8: + case import_onnx2.onnx.TensorProto.DataType.BOOL: + array = tensorProto.int32Data; + break; + case import_onnx2.onnx.TensorProto.DataType.INT64: + array = tensorProto.int64Data; + break; + case import_onnx2.onnx.TensorProto.DataType.DOUBLE: + array = tensorProto.doubleData; + break; + case import_onnx2.onnx.TensorProto.DataType.UINT32: + case import_onnx2.onnx.TensorProto.DataType.UINT64: + array = tensorProto.uint64Data; + break; + default: + throw new Error("unspecific error"); + } + if (array === null || array === void 0) { + throw new Error("failed to populate data from a tensorproto value"); + } + const data = value.data; + if (data.length !== array.length) { + throw new Error("array length mismatch"); + } + for (let i = 0; i < array.length; i++) { + const element = array[i]; + if (long_default.isLong(element)) { + data[i] = longToNumber(element, tensorProto.dataType); + } else { + data[i] = element; + } + } + } + return value; + } + /** + * Construct new Tensor from raw data + * @param data the raw data object. Should be a string array for 'string' tensor, and the corresponding typed array + * for other types of tensor. + * @param dims the dimensions of the tensor + * @param type the type of the tensor + */ + static fromData(data, dims, type) { + return new _Tensor(dims, type, void 0, void 0, data); + } + static fromOrtTensor(ortTensor) { + if (!ortTensor) { + throw new Error("cannot construct Value from an empty tensor"); + } + const dims = ProtoUtil.tensorDimsFromORTFormat(ortTensor); + const type = ProtoUtil.tensorDataTypeFromProto(ortTensor.dataType()); + const value = new _Tensor(dims, type); + if (type === "string") { + for (let i = 0; i < ortTensor.stringDataLength(); i++) { + value.data[i] = ortTensor.stringData(i); + } + } else if (ortTensor.rawDataArray() && typeof ortTensor.rawDataLength() === "number" && ortTensor.rawDataLength() > 0) { + const dataDest = value.data; + const dataSource = new DataView( + ortTensor.rawDataArray().buffer, + ortTensor.rawDataArray().byteOffset, + ortTensor.rawDataLength() + ); + const elementSize = sizeofProto(ortTensor.dataType()); + const length = ortTensor.rawDataLength() / elementSize; + if (ortTensor.rawDataLength() % elementSize !== 0) { + throw new Error("invalid buffer length"); + } + if (dataDest.length !== length) { + throw new Error("buffer length mismatch"); + } + for (let i = 0; i < length; i++) { + const n = readProto(dataSource, ortTensor.dataType(), i * elementSize); + dataDest[i] = n; + } + } + return value; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-source.ts +function getGlsl(version3) { + return version3 === 1 ? GLSL_ES_2_0 : GLSL_ES_3_0; +} +function getVertexShaderSource(version3) { + const glsl = getGlsl(version3); + return `${glsl.version} + precision highp float; + ${glsl.attribute} vec3 position; + ${glsl.attribute} vec2 textureCoord; + + ${glsl.varyingVertex} vec2 TexCoords; + + void main() + { + gl_Position = vec4(position, 1.0); + TexCoords = textureCoord; + }`; +} +function getFragShaderPreamble(version3) { + const glsl = getGlsl(version3); + return `${glsl.version} + precision highp float; + precision highp int; + precision highp sampler2D; + ${glsl.varyingFrag} vec2 TexCoords; + ${glsl.outputDeclaration} + const vec2 halfCR = vec2(0.5, 0.5); + + // Custom vector types to handle higher dimenalities. + struct ivec5 + { + int x; + int y; + int z; + int w; + int u; + }; + + struct ivec6 + { + int x; + int y; + int z; + int w; + int u; + int v; + }; + + int imod(int x, int y) { + return x - y * (x / y); + } + + `; +} +function getDefaultFragShaderMain(version3, outputShapeLength) { + const glsl = getGlsl(version3); + return ` + void main() { + int indices[${outputShapeLength}]; + toVec(TexCoords, indices); + vec4 result = vec4(process(indices)); + ${glsl.output} = result; + } + `; +} +var GLSL_ES_2_0, GLSL_ES_3_0; +var init_glsl_source = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-source.ts"() { + "use strict"; + GLSL_ES_2_0 = { + version: "", + attribute: "attribute", + varyingVertex: "varying", + varyingFrag: "varying", + texture2D: "texture2D", + output: "gl_FragColor", + outputDeclaration: "" + }; + GLSL_ES_3_0 = { + version: "#version 300 es", + attribute: "in", + varyingVertex: "out", + varyingFrag: "in", + texture2D: "texture", + output: "outputColor", + outputDeclaration: "out vec4 outputColor;" + }; + } +}); + +// web/lib/onnxjs/backends/webgl/types.ts +var init_types = __esm({ + "web/lib/onnxjs/backends/webgl/types.ts"() { + "use strict"; + } +}); + +// web/lib/onnxjs/backends/webgl/utils.ts +async function repeatedTry(checkFn, delayFn = (_counter) => 0, maxCounter) { + return new Promise((resolve, reject) => { + let tryCount = 0; + const tryFn = () => { + if (checkFn()) { + resolve(); + return; + } + tryCount++; + const nextBackoff = delayFn(tryCount); + if (maxCounter != null && tryCount >= maxCounter) { + reject(); + return; + } + setTimeout(tryFn, nextBackoff); + }; + tryFn(); + }); +} +function generateShaderFuncNameFromInputSamplerName(samplerName) { + assert(typeof samplerName !== "undefined" && samplerName.length !== 0, () => "empty string found for sampler name"); + return "get" + samplerName.charAt(0).toUpperCase() + samplerName.slice(1); +} +function generateShaderFuncNameFromInputSamplerNameAtOutCoords(samplerName) { + assert(typeof samplerName !== "undefined" && samplerName.length !== 0, () => "empty string found for sampler name"); + return "get" + samplerName.charAt(0).toUpperCase() + samplerName.slice(1) + "AtOutCoords"; +} +function squeezeInputShape(inputShape, squeezedShape) { + let newInputShape = JSON.parse(JSON.stringify(inputShape)); + newInputShape = squeezedShape; + return newInputShape; +} +function getSqueezedParams(params, keptDims) { + return keptDims.map((d) => params[d]).join(", "); +} +function getCoordsDataType(rank) { + if (rank <= 1) { + return "int"; + } else if (rank === 2) { + return "ivec2"; + } else if (rank === 3) { + return "ivec3"; + } else if (rank === 4) { + return "ivec4"; + } else if (rank === 5) { + return "ivec5"; + } else if (rank === 6) { + return "ivec6"; + } else { + throw Error(`GPU for rank ${rank} is not yet supported`); + } +} +function getGlChannels(rank = 6) { + return ["x", "y", "z", "w", "u", "v"].slice(0, rank); +} +var init_utils = __esm({ + "web/lib/onnxjs/backends/webgl/utils.ts"() { + "use strict"; + init_util(); + } +}); + +// web/lib/onnxjs/backends/webgl/ops/packing-utils.ts +function getVecChannels(name2, rank) { + return getGlChannels(rank).map((d) => `${name2}.${d}`); +} +function getChannels(name2, rank) { + if (rank === 1) { + return [name2]; + } + return getVecChannels(name2, rank); +} +function unpackFromChannel() { + return ` + float getChannel(vec4 frag, int dim) { + int modCoord = imod(dim, 2); + return modCoord == 0 ? frag.r : frag.g; + } + + float getChannel(vec4 frag, vec2 innerDims) { + vec2 modCoord = mod(innerDims, 2.); + return modCoord.x == 0. ? + (modCoord.y == 0. ? frag.r : frag.g) : + (modCoord.y == 0. ? frag.b : frag.a); + } + `; +} +var init_packing_utils = __esm({ + "web/lib/onnxjs/backends/webgl/ops/packing-utils.ts"() { + "use strict"; + init_utils(); + } +}); + +// web/lib/onnxjs/backends/webgl/ops/pack.ts +function getOutOfBoundsCondition(rank, shape2, dims) { + if (rank === 0) { + return "false"; + } + if (rank === 1) { + return `rc > ${shape2[0]}`; + } + let cond = ""; + for (let i = rank - 2; i < rank; i++) { + cond += `${dims[i]} >= ${shape2[i - rank + 2]}`; + if (i < rank - 1) { + cond += "||"; + } + } + return cond; +} +function getOutput(shape2, dims) { + const rank = shape2.length; + if (rank === 0) { + return "getA(), 0, 0, 0"; + } + if (rank === 1) { + return `getA(rc), + rc + 1 >= ${shape2[0]} ? 0. : getA(rc + 1), + 0, 0`; + } + const coord00 = "r, c"; + const coord01 = "r, cp1"; + const coord10 = "rp1, c"; + const coord11 = "rp1, cp1"; + let D = ""; + if (rank > 2) { + for (let i = 0; i < rank - 2; ++i) { + D = D + `${dims[i]},`; + } + } + return `getA(${D}${coord00}), + rEdge ? 0. : getA(${D}${coord10}), + cEdge ? 0. : getA(${D}${coord01}), + rEdge || cEdge ? 0. : getA(${D}${coord11})`; +} +function getSetup(rank, dims, rows, cols) { + if (rank === 0 || rank === 1) { + return ""; + } else { + const setup = ` + int r = ${dims[rank - 2]}; + int c = ${dims[rank - 1]}; + int rp1 = ${dims[rank - 2]} + 1; + int cp1 = ${dims[rank - 1]} + 1; + bool rEdge = rp1 >= ${cols}; + bool cEdge = cp1 >= ${rows}; + `; + return setup; + } +} +var packProgramMetadata, createPackProgramInfo, createPackProgramInfoLoader; +var init_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/pack.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + packProgramMetadata = { + name: "pack", + inputNames: ["A"], + inputTypes: [1 /* unpackedReversed */] + }; + createPackProgramInfo = (handler, input) => { + const glsl = getGlsl(handler.session.backend.glContext.version); + const inputShape = input.dims; + const inputRank = inputShape.length; + const outputRank = input.dims.length; + const coordsDataType = getCoordsDataType(outputRank); + const channels = getChannels("rc", outputRank); + const setup = getSetup(outputRank, channels, inputShape[inputShape.length - 2], inputShape[inputShape.length - 1]); + let reversedInputWH; + if (inputRank === 0) { + reversedInputWH = [1, 1]; + } else if (inputRank === 1) { + reversedInputWH = [inputShape[0], 1]; + } else { + reversedInputWH = [inputShape[outputRank - 1], inputShape[outputRank - 2]]; + } + const outOfBoundsCondition = getOutOfBoundsCondition(outputRank, reversedInputWH, channels); + const output = getOutput(inputShape, channels); + const shaderSource = ` + void main() { + ${coordsDataType} rc = getOutputCoords(); + + if(${outOfBoundsCondition}) { + ${glsl.output} = vec4(0); + } else { + ${setup} + + ${glsl.output} = vec4(${output}); + } + } + `; + return { + ...packProgramMetadata, + hasMain: true, + output: { dims: input.dims, type: input.type, textureType: 2 /* packed */ }, + shaderSource + }; + }; + createPackProgramInfoLoader = (handler, input) => ({ ...packProgramMetadata, get: () => createPackProgramInfo(handler, input) }); + } +}); + +// web/lib/onnxjs/backends/webgl/ops/reshape-packed.ts +function processDims3D(shape2) { + if (shape2.length === 0) { + return [1, 1, 1]; + } + let batch = 1; + for (let i = 0; i < shape2.length - 2; ++i) { + batch *= shape2[i]; + } + return [batch, shape2.length > 1 ? shape2[shape2.length - 2] : 1, shape2[shape2.length - 1]]; +} +function isReshapeCheap(dims, reshapedDims) { + let isCheapReshape = false; + if (dims.length === 0 || reshapedDims.length === 0) { + isCheapReshape = true; + } else if (dims.length < 2 || reshapedDims.length < 2) { + isCheapReshape = dims[dims.length - 1] === reshapedDims[reshapedDims.length - 1]; + } else { + isCheapReshape = dims[dims.length - 1] === reshapedDims[reshapedDims.length - 1] && dims[dims.length - 2] === reshapedDims[reshapedDims.length - 2]; + } + return isCheapReshape; +} +function getReshapedInputCoords(shape2) { + const strides = ShapeUtil.computeStrides(shape2); + const coords = ["b", "r", "c"]; + const index = "index"; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coords[i]} = ${index} / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coords[i + 1]} = ${index} - ${coords[i]} * ${stride}` : `index -= ${coords[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + return ` + ivec3 inputCoordsFromReshapedOutCoords(int index) { + ${coordsFromIndexSnippet} + return ivec3(b, r, c); + } + `; +} +function getFlattenedIndexFrom3D(shape2) { + const strides = ShapeUtil.computeStrides(shape2); + return ` + int getFlattenedIndex(ivec3 coords) { + // reverse y, z order + return coords.x * ${strides[0]} + coords.z * ${strides[1]} + coords.y; + } +`; +} +var createPackedReshape3DProgramMetadata, createPackedReshape3DProgramInfo, createPackedReshape3DProgramInfoLoader; +var init_reshape_packed = __esm({ + "web/lib/onnxjs/backends/webgl/ops/reshape-packed.ts"() { + "use strict"; + init_util(); + init_glsl_source(); + init_types(); + init_packing_utils(); + createPackedReshape3DProgramMetadata = (outputShape3D) => ({ name: "Reshape (packed)", inputTypes: [2 /* packed */], inputNames: ["A"], cacheHint: `${outputShape3D}` }); + createPackedReshape3DProgramInfo = (handler, input3D, metadata, outputShape3D) => { + const inputShape3D = input3D.dims; + const squeezedOutputShape = outputShape3D; + let mainLoop = ""; + for (let i = 0; i < 4; i++) { + let outputCoords = ""; + switch (i) { + case 0: + outputCoords = "outputCoords = rc;"; + break; + case 1: + outputCoords = "outputCoords = ivec3(rc.x, rc.y+1, rc.z);"; + break; + case 2: + outputCoords = "outputCoords = ivec3(rc.x, rc.y, rc.z+1);"; + break; + case 3: + outputCoords = "outputCoords = ivec3(rc.x, rc.y+1, rc.z+1);"; + break; + default: + throw new Error(); + } + mainLoop += ` + ${outputCoords} + ${i > 0 ? "if(outputCoords.y < rows && outputCoords.z < cols){" : ""} + int flattenedIndex = getFlattenedIndex(outputCoords); + + ivec3 inputRC = inputCoordsFromReshapedOutCoords(flattenedIndex); + vec2 innerDims = vec2(float(inputRC.y),float(inputRC.z)); + + result[${i}] = getChannel(getA(inputRC.x, inputRC.y, inputRC.z), innerDims); + + ${i > 0 ? "}" : ""} + `; + } + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${getReshapedInputCoords(inputShape3D)} + ${getFlattenedIndexFrom3D(squeezedOutputShape)} + ${unpackFromChannel()} + + void main() { + ivec3 rc = getOutputCoords(); + + vec4 result = vec4(0.0); + + ivec3 outputCoords; + int rows = ${squeezedOutputShape[2]}; + int cols = ${squeezedOutputShape[1]}; + + ${mainLoop} + ${glsl.output} = result; + } + `; + return { + ...metadata, + output: { dims: squeezedOutputShape, type: input3D.type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedReshape3DProgramInfoLoader = (handler, input3D, outputShape3D) => { + const metadata = createPackedReshape3DProgramMetadata(outputShape3D); + return { ...metadata, get: () => createPackedReshape3DProgramInfo(handler, input3D, metadata, outputShape3D) }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/uint8-encode.ts +var encodeAsUint8; +var init_uint8_encode = __esm({ + "web/lib/onnxjs/backends/webgl/ops/uint8-encode.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + encodeAsUint8 = (inferenceHandler, input) => { + const outputShape = input.shape; + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const shaderSource = ` + const float FLOAT_MAX = 1.70141184e38; + const float FLOAT_MIN = 1.17549435e-38; + + bool isNaN(float val) { + return (val < 1.0 || 0.0 < val || val == 0.0) ? false : true; + } + + highp vec4 encodeAsUint8(highp float v) { + if (isNaN(v)) { + return vec4(255, 255, 255, 255); + } + + highp float av = abs(v); + + if(av < FLOAT_MIN) { + return vec4(0.0, 0.0, 0.0, 0.0); + } else if(v > FLOAT_MAX) { + return vec4(0.0, 0.0, 128.0, 127.0) / 255.0; + } else if(v < -FLOAT_MAX) { + return vec4(0.0, 0.0, 128.0, 255.0) / 255.0; + } + + highp vec4 c = vec4(0,0,0,0); + + highp float e = floor(log2(av)); + highp float m = exp2(fract(log2(av))) - 1.0; + + c[2] = floor(128.0 * m); + m -= c[2] / 128.0; + c[1] = floor(32768.0 * m); + m -= c[1] / 32768.0; + c[0] = floor(8388608.0 * m); + + highp float ebias = e + 127.0; + c[3] = floor(ebias / 2.0); + ebias -= c[3] * 2.0; + c[2] += floor(ebias) * 128.0; + + c[3] += 128.0 * step(0.0, -v); + + return c / 255.0; + } + + void main() { + float value = ${glsl.texture2D}(X,TexCoords).r; + ${glsl.output} = encodeAsUint8(value); + }`; + const programInfo = { + name: "Uint8Encode", + inputTypes: [0 /* unpacked */], + inputNames: ["X"], + output: { dims: outputShape, type: input.tensor.type, textureType: 3 /* downloadUint8AsFloat */ }, + shaderSource, + hasMain: true + }; + return inferenceHandler.executeProgram(programInfo, [input.tensor]); + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/unpack.ts +function getSourceCoords(rank, dims) { + if (rank === 1) { + return "rc"; + } + let coords = ""; + for (let i = 0; i < rank; i++) { + coords += dims[i]; + if (i < rank - 1) { + coords += ","; + } + } + return coords; +} +var unpackProgramMetadata, createUnpackProgramInfo, createUnpackProgramInfoLoader; +var init_unpack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/unpack.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + unpackProgramMetadata = { + name: "unpack", + inputNames: ["A"], + inputTypes: [2 /* packed */] + }; + createUnpackProgramInfo = (handler, input) => { + const rank = input.dims.length; + const channels = getChannels("rc", rank); + const innerDims = channels.slice(-2); + const coordsDataType = getCoordsDataType(rank); + const unpackChannel = unpackFromChannel(); + const isScalar = input.dims.length === 0; + const sourceCoords = isScalar ? "" : getSourceCoords(rank, channels); + const coords = rank <= 1 ? "rc" : `vec2(${innerDims.join(",")})`; + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${unpackChannel} + void main() { + ${coordsDataType} rc = getOutputCoords(); + + // Sample the texture with the coords to get the rgba channel value. + vec4 packedInput = getA(${sourceCoords}); + + ${glsl.output} = vec4(getChannel(packedInput, ${coords}), 0, 0, 0); + } + `; + return { + ...unpackProgramMetadata, + hasMain: true, + output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createUnpackProgramInfoLoader = (handler, input) => ({ ...unpackProgramMetadata, get: () => createUnpackProgramInfo(handler, input) }); + } +}); + +// web/lib/onnxjs/backends/webgl/texture-data-encoder.ts +var RedFloat32DataEncoder, RGBAFloatDataEncoder, Uint8DataEncoder; +var init_texture_data_encoder = __esm({ + "web/lib/onnxjs/backends/webgl/texture-data-encoder.ts"() { + "use strict"; + init_instrument(); + RedFloat32DataEncoder = class { + constructor(gl, channels = 1) { + if (channels === 1) { + this.internalFormat = gl.R32F; + this.format = gl.RED; + this.textureType = gl.FLOAT; + this.channelSize = channels; + } else if (channels === 4) { + this.internalFormat = gl.RGBA32F; + this.format = gl.RGBA; + this.textureType = gl.FLOAT; + this.channelSize = channels; + } else { + throw new Error(`Invalid number of channels: ${channels}`); + } + } + encode(src, textureSize) { + let result; + let source; + if (src.constructor !== Float32Array) { + Logger.warning("Encoder", "data was not of type Float32; creating new Float32Array"); + source = new Float32Array(src); + } + if (textureSize * this.channelSize > src.length) { + Logger.warning("Encoder", "Source data too small. Allocating larger array"); + source = src; + result = this.allocate(textureSize * this.channelSize); + source.forEach((v, i) => result[i] = v); + } else { + source = src; + result = source; + } + return result; + } + allocate(size) { + return new Float32Array(size * 4); + } + decode(buffer, dataSize) { + if (this.channelSize === 1) { + const filteredData = buffer.filter((_value, index) => index % 4 === 0).subarray(0, dataSize); + return filteredData; + } + return buffer.subarray(0, dataSize); + } + }; + RGBAFloatDataEncoder = class { + constructor(gl, channels = 1, textureType) { + if (channels !== 1 && channels !== 4) { + throw new Error(`Invalid number of channels: ${channels}`); + } + this.internalFormat = gl.RGBA; + this.format = gl.RGBA; + this.channelSize = channels; + this.textureType = textureType || gl.FLOAT; + } + encode(src, textureSize) { + let dest = src; + if (this.channelSize === 1) { + Logger.verbose("Encoder", "Exploding into a larger array"); + dest = this.allocate(textureSize); + src.forEach((v, i) => dest[i * 4] = v); + } + return dest; + } + allocate(size) { + return new Float32Array(size * 4); + } + decode(buffer, dataSize) { + if (this.channelSize === 1) { + const filteredData = buffer.filter((_value, index) => index % 4 === 0).subarray(0, dataSize); + return filteredData; + } + return buffer.subarray(0, dataSize); + } + }; + Uint8DataEncoder = class { + constructor(gl, channels = 1) { + this.channelSize = 4; + if (channels === 1) { + this.internalFormat = gl.ALPHA; + this.format = gl.ALPHA; + this.textureType = gl.UNSIGNED_BYTE; + this.channelSize = channels; + } else if (channels === 4) { + this.internalFormat = gl.RGBA; + this.format = gl.RGBA; + this.textureType = gl.UNSIGNED_BYTE; + this.channelSize = channels; + } else { + throw new Error(`Invalid number of channels: ${channels}`); + } + } + encode(src, _textureSize) { + return new Uint8Array(src.buffer, src.byteOffset, src.byteLength); + } + allocate(size) { + return new Uint8Array(size * this.channelSize); + } + decode(buffer, dataSize) { + if (buffer instanceof Uint8Array) { + return buffer.subarray(0, dataSize); + } + throw new Error(`Invalid array type: ${buffer.constructor}`); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/texture-layout.ts +var createTextureLayoutFromTextureType, calculateTextureWidthAndHeight, createTextureLayoutFromShape; +var init_texture_layout = __esm({ + "web/lib/onnxjs/backends/webgl/texture-layout.ts"() { + "use strict"; + init_util(); + init_types(); + createTextureLayoutFromTextureType = (textureLayoutStrategy, shape2, textureType) => { + const channel = textureType === 0 /* unpacked */ || textureType === 1 /* unpackedReversed */ ? 1 : 4; + const isPacked = textureType === 2 /* packed */; + const reverseWH = textureType === 1 /* unpackedReversed */ || textureType === 2 /* packed */; + const breakAxis = textureType === 4 /* packedLastDimension */ ? shape2.length - 1 : void 0; + const unpackedShape = textureType === 4 /* packedLastDimension */ ? shape2.map((d, i) => i === shape2.length - 1 ? d * 4 : d) : void 0; + return createTextureLayoutFromShape( + textureLayoutStrategy, + shape2, + channel, + unpackedShape, + { isPacked, reverseWH, breakAxis } + ); + }; + calculateTextureWidthAndHeight = (textureLayoutStrategy, shape2, textureType) => { + const layout = createTextureLayoutFromTextureType(textureLayoutStrategy, shape2, textureType); + return [layout.width, layout.height]; + }; + createTextureLayoutFromShape = (textureLayoutStrategy, shape2, channels = 1, unpackedShape, prefs) => { + const isPacked = !!(prefs && prefs.isPacked); + const [width, height] = textureLayoutStrategy.computeTextureWH(isPacked ? unpackedShape || shape2 : shape2, prefs); + const rank = shape2.length; + let inferredDims = shape2.slice(0); + if (rank === 0) { + inferredDims = [1]; + } + if (channels === 1) { + unpackedShape = shape2; + } else if (isPacked) { + if (channels !== 4) { + throw new Error("a packed texture must be 4-channel"); + } + unpackedShape = shape2; + if (rank > 0) { + inferredDims[rank - 1] = Math.ceil(inferredDims[rank - 1] / 2); + } + if (rank > 1) { + inferredDims[rank - 2] = Math.ceil(inferredDims[rank - 2] / 2); + } + } else if (!unpackedShape) { + throw new Error("Unpacked shape is needed when using channels > 1"); + } + return { + width, + height, + channels, + isPacked, + shape: inferredDims, + strides: ShapeUtil.computeStrides(inferredDims), + unpackedShape, + reversedWH: prefs && prefs.reverseWH + }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/inference-handler.ts +var getProgramInfoUniqueKey, WebGLInferenceHandler; +var init_inference_handler = __esm({ + "web/lib/onnxjs/backends/webgl/inference-handler.ts"() { + "use strict"; + init_instrument(); + init_tensor2(); + init_util(); + init_pack(); + init_reshape_packed(); + init_uint8_encode(); + init_unpack(); + init_texture_data_encoder(); + init_texture_layout(); + init_types(); + getProgramInfoUniqueKey = (programInfo, inputTextureDatas) => { + const inputs = inputTextureDatas.map((texture) => `${texture.unpackedShape.join(",")};${texture.width}x${texture.height}`).join("_"); + let key = programInfo.name; + if (programInfo.cacheHint) { + key += "[" + programInfo.cacheHint + "]"; + } + key += ":" + inputs; + return key; + }; + WebGLInferenceHandler = class { + constructor(session) { + this.session = session; + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + } + /** + * @returns [width, height] + */ + calculateTextureWidthAndHeight(shape2, textureType) { + return calculateTextureWidthAndHeight(this.session.layoutStrategy, shape2, textureType); + } + executeProgram(program, inputs) { + if (inputs.length < program.inputNames.length) { + throw new Error(`Input size mustn't be less than ${program.inputNames.length}.`); + } + if (program.inputNames.length !== program.inputTypes.length) { + throw new Error("input names size does not match input types"); + } + const inputTextureDatas = []; + for (let i = 0; i < program.inputNames.length; ++i) { + inputTextureDatas[i] = this.getOrCreateTextureData(inputs[i], program.inputTypes[i]); + } + const key = getProgramInfoUniqueKey(program, inputTextureDatas); + let artifact = this.session.programManager.getArtifact(key); + const programInfo = artifact ? artifact.programInfo : typeof program.get === "function" ? program.get() : program; + const outputTextureLayout = createTextureLayoutFromTextureType( + this.session.layoutStrategy, + programInfo.output.dims, + programInfo.output.textureType + ); + const outputTextureData = this.createTextureData(outputTextureLayout, programInfo.output.type); + if (!artifact) { + artifact = this.session.programManager.build(programInfo, inputTextureDatas, outputTextureData); + this.session.programManager.setArtifact(key, artifact); + } + this.runProgram(artifact, inputTextureDatas, outputTextureData); + return outputTextureData; + } + run(program, inputs) { + const outputTextureData = this.executeProgram(program, inputs); + return outputTextureData.tensor; + } + runProgram(artifact, inputs, output) { + for (let i = 0; i < inputs.length; ++i) { + if (!!inputs[i].isPacked !== (artifact.programInfo.inputTypes[i] === 2 /* packed */)) { + throw new Error(`input[${i}] property packed inconsistent`); + } + } + if (!!output.isPacked !== (artifact.programInfo.output.textureType === 2 /* packed */)) { + throw new Error("output property packed inconsistent"); + } + this.session.programManager.run(artifact, inputs, output); + } + /** + * Create a TextureData object from a tensor. + * Usage = EncoderUsage.UploadOnly. + * If a related texture data is found in cache, returns it; + * Otherwise: + * Creates a new texture layout if not provided; + * Creates WebGLTexture with the layout; + * Upload tensor data to the texture; + * Creates a texture data object associated with the given tensor. + * @param tensor the tensor with data to upload + */ + getOrCreateTextureData(tensor, textureType) { + let td = this.getTextureData(tensor.dataId, textureType === 2 /* packed */); + if (!td) { + td = this.getTextureData(tensor.dataId, textureType !== 2 /* packed */); + if (td) { + if (textureType === 2 /* packed */) { + return this.pack(td); + } else { + return this.unpack(td); + } + } + } + if (!td) { + const layout = createTextureLayoutFromTextureType(this.session.layoutStrategy, tensor.dims, textureType); + if (textureType === 4 /* packedLastDimension */) { + const group = 1; + const channels = 4; + const shape2 = tensor.dims; + if (shape2.length === 4) { + const adjustedKernelShape = [shape2[0], Math.ceil(shape2[1] * shape2[2] * shape2[3] / channels)]; + const adjustedLayout = createTextureLayoutFromTextureType(this.session.layoutStrategy, adjustedKernelShape, textureType); + let buffer = tensor.numberData; + if (shape2[1] * shape2[2] * shape2[3] % channels !== 0) { + const numFeatureMaps = shape2[0]; + const oldRowSize = shape2[1] * shape2[2] * shape2[3]; + const newRowSize = Math.ceil(oldRowSize * group / channels) * channels; + const newSize = numFeatureMaps * newRowSize; + buffer = new Float32Array(newSize); + for (let f = 0; f < numFeatureMaps; ++f) { + const oldOffset = f * oldRowSize; + const newOffset = f * newRowSize + f % group * oldRowSize; + buffer.set(tensor.numberData.subarray(oldOffset, oldOffset + oldRowSize), newOffset); + } + } + return this.createTextureData(adjustedLayout, tensor.type, buffer, tensor, 1 /* UploadOnly */); + } + } + if (textureType === 2 /* packed */) { + const unpackedTextureLayout = createTextureLayoutFromShape(this.session.layoutStrategy, tensor.dims, 1, [], { reverseWH: true }); + const unpackedTextureData = this.createTextureData( + unpackedTextureLayout, + tensor.type, + tensor.numberData, + tensor, + 1 /* UploadOnly */ + ); + td = this.pack(unpackedTextureData); + } else { + td = this.createTextureData(layout, tensor.type, tensor.numberData, tensor, 1 /* UploadOnly */); + } + } + return td; + } + /** + * Create a TextureData object using the given data and bind to the given tensor. + * Usage = EncoderUsage.UploadOnly. + * NOTE: this function is a hack for Conv implementation. should remove this function, after rewriting Conv + * implementation by Graph.Transformer + * @param dataType the tensor data type + * @param data the actual data to upload + * @param tensor the tensor to bind. tensor's data is ignored. + */ + createTextureDataFromLayoutBindTensor(layout, dataType, data, tensor) { + return this.createTextureData(layout, dataType, data, tensor, 1 /* UploadOnly */); + } + createTextureData(layout, dataType, data, tensor, usage) { + Logger.verbose("InferenceHandler", `Creating TextureData: layout:[${JSON.stringify(layout)}]`); + const texture = this.session.textureManager.createTextureFromLayout(dataType, layout, data, usage); + return this.createTextureDataFromTexture(layout, dataType, texture, tensor); + } + reshapeUnpacked(input, reshapedDims) { + const inputTD = this.getOrCreateTextureData(input, 0 /* unpacked */); + const newTextureLayout = { + channels: inputTD.channels, + height: inputTD.height, + width: inputTD.width, + // handle reshaping into scalar Tensors + shape: reshapedDims.length !== 0 ? reshapedDims : [1], + strides: ShapeUtil.computeStrides(reshapedDims), + unpackedShape: reshapedDims + }; + const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture); + return newTextureData.tensor; + } + reshapePacked(input, reshapedDims) { + const inputTD = this.getOrCreateTextureData(input, 2 /* packed */); + if (isReshapeCheap(input.dims, reshapedDims)) { + const newTextureLayout = { + channels: inputTD.channels, + height: inputTD.height, + width: inputTD.width, + // handle reshaping into scalar Tensors + shape: reshapedDims.length !== 0 ? reshapedDims : [1], + strides: ShapeUtil.computeStrides(reshapedDims), + unpackedShape: reshapedDims, + isPacked: true + }; + const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture); + return newTextureData.tensor; + } + const squeezedInputShape = processDims3D(input.dims); + const squeezedOutputShape = processDims3D(reshapedDims); + const squeezedInputTensor = this.reshapePacked(input, squeezedInputShape); + const squeezedOutputTensor = this.run( + createPackedReshape3DProgramInfoLoader(this, squeezedInputTensor, squeezedOutputShape), + [squeezedInputTensor] + ); + const outputTensor = this.reshapePacked(squeezedOutputTensor, reshapedDims); + return outputTensor; + } + cast(input, type) { + const inputTD = this.getOrCreateTextureData(input, 0 /* unpacked */); + const newTextureData = this.createTextureDataFromTexture(inputTD, type, inputTD.texture); + return newTextureData.tensor; + } + createTextureDataFromTexture(layout, dataType, texture, tensor, tensorId) { + const textureData = { + ...layout, + tensor: tensor || new Tensor3( + layout.unpackedShape, + dataType, + (_id) => this.readTexture(textureData), + async (_id) => this.readTextureAsync(textureData), + void 0, + tensorId + ), + texture + }; + this.setTextureData(textureData.tensor.dataId, textureData, layout.isPacked); + return textureData; + } + getTextureData(tensorId, isPacked = false) { + return this.session.isInitializer(tensorId) ? this.session.getTextureData(tensorId, isPacked) : isPacked ? this.packedTextureDataCache.get(tensorId) : this.unpackedTextureDataCache.get(tensorId); + } + setTextureData(tensorId, td, isPacked = false) { + if (this.session.isInitializer(tensorId)) { + this.session.setTextureData(tensorId, td, isPacked); + } else { + (isPacked ? this.packedTextureDataCache : this.unpackedTextureDataCache).set(tensorId, td); + } + } + isTextureLayoutCached(tensor, isPacked = false) { + return !!this.getTextureData(tensor.dataId, isPacked); + } + dispose() { + this.session.textureManager.clearActiveTextures(); + this.packedTextureDataCache.forEach((td) => this.session.textureManager.releaseTexture(td)); + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache.forEach((td) => this.session.textureManager.releaseTexture(td)); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + } + readTexture(textureData) { + if (textureData.isPacked) { + return this.readTexture(this.unpack(textureData)); + } + if (!this.session.backend.glContext.isFloat32DownloadSupported) { + return this.session.textureManager.readUint8TextureAsFloat(encodeAsUint8(this, textureData)); + } + return this.session.textureManager.readTexture(textureData, textureData.tensor.type, textureData.channels); + } + async readTextureAsync(textureData) { + if (textureData.isPacked) { + return this.readTextureAsync(this.unpack(textureData)); + } + if (!this.session.backend.glContext.isFloat32DownloadSupported) { + return this.session.textureManager.readUint8TextureAsFloat(encodeAsUint8(this, textureData)); + } + return this.session.textureManager.readTextureAsync(textureData, textureData.tensor.type, textureData.channels); + } + pack(input) { + const outputTextureData = this.executeProgram(createPackProgramInfoLoader(this, input.tensor), [input.tensor]); + return outputTextureData; + } + unpack(input) { + const outputTextureData = this.executeProgram(createUnpackProgramInfoLoader(this, input.tensor), [input.tensor]); + return outputTextureData; + } + }; + } +}); + +// web/lib/onnxjs/attribute-with-cache-key.ts +var AttributeWithCacheKeyImpl, createAttributeWithCacheKey; +var init_attribute_with_cache_key = __esm({ + "web/lib/onnxjs/attribute-with-cache-key.ts"() { + "use strict"; + AttributeWithCacheKeyImpl = class { + constructor(attribute) { + Object.assign(this, attribute); + } + get cacheKey() { + if (!this.key) { + this.key = Object.getOwnPropertyNames(this).sort().map((name2) => `${this[name2]}`).join(";"); + } + return this.key; + } + }; + createAttributeWithCacheKey = (attribute) => new AttributeWithCacheKeyImpl(attribute); + } +}); + +// web/lib/onnxjs/backends/webgl/ops/batch-normalization.ts +var batchNormalizationProgramMetadata, batchNormalization, parseBatchNormalizationAttributes, createBatchNormalizationProgramInfo, validateInputs; +var init_batch_normalization = __esm({ + "web/lib/onnxjs/backends/webgl/ops/batch-normalization.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_glsl_source(); + init_types(); + batchNormalizationProgramMetadata = { + name: "BatchNormalization", + inputNames: ["A", "Scale", "B", "Mean", "Variance"], + inputTypes: [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] + }; + batchNormalization = (inferenceHandler, inputs, attributes) => { + validateInputs(inputs); + const output = inferenceHandler.run( + { + ...batchNormalizationProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createBatchNormalizationProgramInfo(inferenceHandler, inputs, attributes) + }, + inputs + ); + return [output]; + }; + parseBatchNormalizationAttributes = (node) => { + const epsilon = node.attributes.getFloat("epsilon", 1e-5); + const momentum = node.attributes.getFloat("momentum", 0.9); + const spatial = node.attributes.getInt("spatial", 1); + return createAttributeWithCacheKey({ epsilon, momentum, spatial }); + }; + createBatchNormalizationProgramInfo = (inferenceHandler, inputs, attributes) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const rank = inputs[0].dims.length; + const [scaleWidth, scaleHeight] = inferenceHandler.calculateTextureWidthAndHeight(inputs[1].dims, 0 /* unpacked */); + const shaderSource = ` + float process(int[${rank}] indices) { + vec2 position = offsetToCoords(indices[1], ${scaleWidth}, ${scaleHeight}); + float scale = getColorAsFloat(${glsl.texture2D}(Scale, position)); + float mean = getColorAsFloat(${glsl.texture2D}(Mean, position)); + float variance = getColorAsFloat(${glsl.texture2D}(Variance, position)); + float b = getColorAsFloat(${glsl.texture2D}(B, position)); + + return scale * ( (_A(indices) - mean) / sqrt(variance + float(${attributes.epsilon})) ) + b; + }`; + return { + ...batchNormalizationProgramMetadata, + output: { dims: inputs[0].dims, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs = (inputs) => { + if (!inputs || inputs.length !== 5) { + throw new Error("BatchNormalization requires 5 inputs."); + } + const X = inputs[0]; + const scale = inputs[1]; + const B = inputs[2]; + const mean = inputs[3]; + const var_ = inputs[4]; + if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1 || mean.dims.length !== 1 || var_.dims.length !== 1) { + throw new Error("invalid input shape."); + } + if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1] || mean.dims[0] !== X.dims[1] || var_.dims[0] !== X.dims[1]) { + throw new Error("invalid input shape."); + } + if (X.type !== "float32" && X.type !== "float64" || scale.type !== "float32" && scale.type !== "float64" || B.type !== "float32" && B.type !== "float64" || mean.type !== "float32" && mean.type !== "float64" || var_.type !== "float32" && var_.type !== "float64") { + throw new Error("invalid input tensor types."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-definitions.ts +var GlslContext, GlslLib, GlslLibRoutine, GlslLibRoutineNode, TopologicalSortGlslRoutines; +var init_glsl_definitions = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-definitions.ts"() { + "use strict"; + GlslContext = class { + constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) { + this.glContext = glContext; + this.programInfo = programInfo; + this.inputTextureLayouts = inputTextureLayouts; + this.outputTextureLayout = outputTextureLayout; + } + }; + GlslLib = class { + constructor(context) { + this.context = context; + } + }; + GlslLibRoutine = class { + constructor(routineBody, dependencies) { + this.routineBody = routineBody; + this.dependencies = dependencies; + } + }; + GlslLibRoutineNode = class { + constructor(name2, routineBody, dependencies) { + this.name = name2; + if (dependencies) { + this.dependencies = dependencies; + } else { + this.dependencies = []; + } + if (routineBody) { + this.routineBody = routineBody; + } + } + addDependency(node) { + if (node) { + this.dependencies.push(node); + } + } + }; + TopologicalSortGlslRoutines = class { + static returnOrderedNodes(nodes) { + if (!nodes || nodes.length === 0) { + return []; + } + if (nodes.length === 1) { + return nodes; + } + const cycleCheck = /* @__PURE__ */ new Set(); + const alreadyTraversed = /* @__PURE__ */ new Set(); + const result = new Array(); + this.createOrderedNodes(nodes, cycleCheck, alreadyTraversed, result); + return result; + } + static createOrderedNodes(graphNodes, cycleCheck, alreadyTraversed, result) { + for (let i = 0; i < graphNodes.length; ++i) { + this.dfsTraverse(graphNodes[i], cycleCheck, alreadyTraversed, result); + } + } + static dfsTraverse(root, cycleCheck, alreadyTraversed, result) { + if (!root || alreadyTraversed.has(root.name)) { + return; + } + if (cycleCheck.has(root.name)) { + throw new Error("Cyclic dependency detected. Can't topologically sort routines needed for shader."); + } + cycleCheck.add(root.name); + const dependencies = root.dependencies; + if (dependencies && dependencies.length > 0) { + for (let i = 0; i < dependencies.length; ++i) { + this.dfsTraverse(dependencies[i], cycleCheck, alreadyTraversed, result); + } + } + result.push(root); + alreadyTraversed.add(root.name); + cycleCheck.delete(root.name); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/binary-op.ts +function glslAdd() { + const name2 = "add_"; + const body = ` + float ${name2}(float a, float b) { + return a + b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 + v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslDiv() { + const name2 = "div_"; + const body = ` + float ${name2}(float a, float b) { + return a / b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 / v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslMul() { + const name2 = "mul_"; + const body = ` + float ${name2}(float a, float b) { + return a * b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 * v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslSub() { + const name2 = "sub_"; + const body = ` + float ${name2}(float a, float b) { + return a - b; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return v1 - v2; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslEqual() { + const name2 = "equal_"; + const body = ` + float ${name2}(float a, float b) { + return float(a == b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4(equal(v1, v2)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslGreater() { + const name2 = "greater_"; + const body = ` + float ${name2}(float a, float b) { + return float(a > b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4( v1.r > v2.r , + v1.g > v2.g, + v1.b > v2.b, + v1.a > v2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslLess() { + const name2 = "less_"; + const body = ` + float ${name2}(float a, float b) { + return float(a < b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4( v1.r < v2.r , + v1.g < v2.g, + v1.b < v2.b, + v1.a < v2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslAnd() { + const name2 = "and_"; + const body = ` + float ${name2}(float a, float b) { + return float( bool(a) && bool(b) ); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + bvec4 b1 = bvec4(v1); + bvec4 b2 = bvec4(v2); + return vec4( b1.r && b2.r , + b1.g && b2.g, + b1.b && b2.b, + b1.a && b2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslOr() { + const name2 = "or_"; + const body = ` + float ${name2}(float a, float b) { + return float( bool(a) || bool(b) ); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + bvec4 b1 = bvec4(v1); + bvec4 b2 = bvec4(v2); + return vec4( b1.r || b2.r , + b1.g || b2.g, + b1.b || b2.b, + b1.a || b2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslXor() { + const name2 = "xor_"; + const body = ` + float ${name2}(float a, float b) { + return float( bool(a) ^^ bool(b) ); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + bvec4 b1 = bvec4(v1); + bvec4 b2 = bvec4(v2); + return vec4( b1.r ^^ b2.r , + b1.g ^^ b2.g, + b1.b ^^ b2.b, + b1.a ^^ b2.a ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslPow() { + return glslBuiltinBinary("pow"); +} +function glslPRelu() { + const name2 = "prelu_"; + const body = ` + float ${name2}(float a, float b) { + return a < 0.0 ? a * b: a; + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return vec4( + v1.r < 0.0 ? v1.r * v2.r: v1.r, + v1.g < 0.0 ? v1.g * v2.g: v1.g, + v1.b < 0.0 ? v1.b * v2.b: v1.b, + v1.a < 0.0 ? v1.a * v2.a: v1.a + ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslBuiltinBinary(fname) { + const name2 = `${fname}_`; + const body = ` + float ${name2}(float a, float b) { + return ${fname}(a, b); + } + vec4 ${name2}(vec4 v1, vec4 v2) { + return ${fname}(v1, v2); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +var createBinaryProgramInfoLoader, createBinaryProgramInfo, add2, and2, div, equal, greater, less, mul, or2, pow, pRelu, sub, xor2; +var init_binary_op = __esm({ + "web/lib/onnxjs/backends/webgl/ops/binary-op.ts"() { + "use strict"; + init_util(); + init_glsl_definitions(); + init_glsl_source(); + init_types(); + createBinaryProgramInfoLoader = (handler, inputs, glslFunc, outputTensorType = inputs[0].type, cacheKey) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + return { + name: glslFunc.name, + inputNames: ["A", "B"], + inputTypes: [textureType, textureType], + cacheHint: cacheKey, + get: () => createBinaryProgramInfo(handler, inputs, glslFunc, outputTensorType) + }; + }; + createBinaryProgramInfo = (handler, inputs, glslFunc, outputTensorType = inputs[0].type) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims); + let outputShape = inputs[0].dims; + const usePackedTexture = handler.session.pack; + if (isBroadcast) { + const calculatedShape = BroadcastUtil.calcShape(inputs[0].dims, inputs[1].dims, false); + if (!calculatedShape) { + throw new Error("Can't perform binary op on the given tensors"); + } + outputShape = calculatedShape; + const outputRank = outputShape.length; + const aRank = inputs[0].dims.length !== 0 ? inputs[0].dims.length : 1; + const bRank = inputs[1].dims.length !== 0 ? inputs[1].dims.length : 1; + const aBcast = inputs[0].dims.length !== 0 ? "bcastIndices_A(indices, aindices);" : "aindices[0] = 0;"; + const bBcast = inputs[1].dims.length !== 0 ? "bcastIndices_B(indices, bindices);" : "bindices[0] = 0;"; + const glsl2 = getGlsl(handler.session.backend.glContext.version); + const shaderSource2 = usePackedTexture ? ` + ${glslFunc.body} + void main() { + vec4 a = getAAtOutCoords(); + vec4 b = getBAtOutCoords(); + vec4 result = ${glslFunc.name}(a, b); + ${glsl2.output} = result; + }` : ` + ${glslFunc.body} + float process(int indices[${outputRank}]) { + int aindices[${aRank}]; + int bindices[${bRank}]; + ${aBcast} + ${bBcast} + return ${glslFunc.name}(_A(aindices), _B(bindices)); + }`; + return { + name: glslFunc.name, + inputNames: ["A", "B"], + inputTypes: [textureType, textureType], + output: { dims: outputShape, type: outputTensorType, textureType }, + shaderSource: shaderSource2, + hasMain: usePackedTexture + }; + } + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${glslFunc.body} + void main() { + vec4 v1 = ${glsl.texture2D}(A, TexCoords); + vec4 v2 = ${glsl.texture2D}(B, TexCoords); + vec4 result = ${glslFunc.name}(v1, v2); + ${glsl.output} = result; + } + `; + return { + name: glslFunc.name, + inputNames: ["A", "B"], + inputTypes: [textureType, textureType], + output: { dims: inputs[0].dims, type: outputTensorType, textureType }, + shaderSource, + hasMain: true + }; + }; + add2 = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAdd()), inputs)]; + and2 = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAnd(), "bool"), inputs)]; + div = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslDiv()), inputs)]; + equal = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslEqual(), "bool"), inputs)]; + greater = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslGreater(), "bool"), inputs)]; + less = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslLess(), "bool"), inputs)]; + mul = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslMul()), inputs)]; + or2 = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslOr(), "bool"), inputs)]; + pow = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPow()), inputs)]; + pRelu = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPRelu()), inputs)]; + sub = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslSub()), inputs)]; + xor2 = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslXor(), "bool"), inputs)]; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/cast.ts +var cast, parseCastAttributes, validateInputs2; +var init_cast = __esm({ + "web/lib/onnxjs/backends/webgl/ops/cast.ts"() { + "use strict"; + init_util(); + cast = (handler, inputs, to) => { + validateInputs2(inputs); + return [handler.cast(inputs[0], to)]; + }; + parseCastAttributes = (node) => ProtoUtil.tensorDataTypeFromProto(node.attributes.getInt("to")); + validateInputs2 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Cast requires 1 input."); + } + if (inputs[0].type === "string") { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/concat-packed.ts +var createPackedConcatProgramMetadata, createPackedConcatProgramInfo, createPackedConcatProgramInfoLoader, getShiftedChannelsSnippet; +var init_concat_packed = __esm({ + "web/lib/onnxjs/backends/webgl/ops/concat-packed.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + createPackedConcatProgramMetadata = (inputCount, cacheHint) => ({ + name: "Concat (packed)", + inputNames: Array.from({ length: inputCount }, (_v, i) => `X${i}`), + inputTypes: Array(inputCount).fill(2 /* packed */), + cacheHint + }); + createPackedConcatProgramInfo = (handler, metadata, inputs, axis) => { + const inputShape = inputs[0].dims.slice(); + if (axis >= inputShape.length || axis < -1 * inputShape.length) { + throw new Error("axis specified for concat doesn't match input dimensionality"); + } + if (axis < 0) { + axis = inputShape.length + axis; + } + const outputShape = inputShape.slice(0); + for (let i = 1; i < inputs.length; i++) { + const dataNShape = inputs[i].dims.slice(); + for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) { + if (axisIndex === axis) { + outputShape[axis] += dataNShape[axisIndex]; + } else if (inputShape[axisIndex] !== dataNShape[axisIndex]) { + throw new Error("non concat dimensions must match"); + } + } + } + const rank = outputShape.length; + const coords = getChannels("coords", rank); + const dtype = getCoordsDataType(rank); + const unpackChannel = unpackFromChannel(); + const shapes = inputs.map((i) => i.dims); + const channels = getGlChannels(rank); + const offsets = new Array(shapes.length - 1); + offsets[0] = shapes[0][axis]; + for (let i = 1; i < offsets.length; i++) { + offsets[i] = offsets[i - 1] + shapes[i][axis]; + } + const channel = channels[axis]; + const lastChannels = channels.slice(-2); + const allChannels = channels.join(); + let getValueSnippet = `if (${channel} < ${offsets[0]}) { + return getChannel( + getX0(${allChannels}), vec2(${lastChannels.join()})); + }`; + for (let i = 1; i < offsets.length; i++) { + const shift2 = offsets[i - 1]; + getValueSnippet += ` + if (${channel} < ${offsets[i]} && ${channel} >= ${offsets[i - 1]}) { + return getChannel( + getX${i}(${getShiftedChannelsSnippet(channels, channel, shift2)}), + vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift2)})); + }`; + } + const lastIndex = offsets.length; + const shift = offsets[offsets.length - 1]; + getValueSnippet += ` + return getChannel( + getX${lastIndex}(${getShiftedChannelsSnippet(channels, channel, shift)}), + vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift)}));`; + const glsl = getGlsl(handler.session.backend.glContext.version); + const shaderSource = ` + ${unpackChannel} + float getValue(${channels.map((x) => "int " + x)}) { + ${getValueSnippet} + } + + void main() { + ${dtype} coords = getOutputCoords(); + int lastDim = coords.${channels[rank - 1]}; + coords.${channels[rank - 1]} = coords.${channels[rank - 2]}; + coords.${channels[rank - 2]} = lastDim; + + vec4 result = vec4(getValue(${coords}), 0., 0., 0.); + + ${coords[rank - 1]} = ${coords[rank - 1]} + 1; + if (${coords[rank - 1]} < ${outputShape[rank - 1]}) { + result.g = getValue(${coords}); + } + + ${coords[rank - 2]} = ${coords[rank - 2]} + 1; + if (${coords[rank - 2]} < ${outputShape[rank - 2]}) { + result.a = getValue(${coords}); + } + + ${coords[rank - 1]} = ${coords[rank - 1]} - 1; + if (${coords[rank - 2]} < ${outputShape[rank - 2]} && + ${coords[rank - 1]} < ${outputShape[rank - 1]}) { + result.b = getValue(${coords}); + } + ${glsl.output} = result; + } + `; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedConcatProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = createPackedConcatProgramMetadata(inputs.length, attributes.cacheKey); + return { ...metadata, get: () => createPackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) }; + }; + getShiftedChannelsSnippet = (channels, channel, shift) => { + const channelIdx = channels.indexOf(channel); + const res = channels.map((c, idx) => { + if (idx === channelIdx) { + return `${c} - ${shift}`; + } else { + return c; + } + }); + return res.join(); + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/concat.ts +var concat, createUnpackedConcatProgramMetadata, createUnpackedConcatProgramInfo, createUnpackedConcatProgramInfoLoader, getTextureIndexWhereDataResidesLinearSearch, getTextureIndexWhereDataResidesBinarySearch, getFetchDataFromCorrectTextureMethod, getGetSizeInConcatAxisValueFromIndexMethod, parseConcatAttributes, validateInputs3; +var init_concat = __esm({ + "web/lib/onnxjs/backends/webgl/ops/concat.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_types(); + init_concat_packed(); + concat = (inferenceHandler, inputs, attributes) => { + validateInputs3(inputs); + if (inferenceHandler.session.pack && inputs[0].dims.length > 1) { + const output = inferenceHandler.run(createPackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), inputs); + return [output]; + } else { + const output = inferenceHandler.run(createUnpackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), inputs); + return [output]; + } + }; + createUnpackedConcatProgramMetadata = (inputCount, cacheHint) => ({ + name: "Concat", + inputNames: Array.from({ length: inputCount }, (_v, i) => `X${i}`), + inputTypes: Array(inputCount).fill(0 /* unpacked */), + cacheHint + }); + createUnpackedConcatProgramInfo = (_handler, metadata, inputs, axis) => { + const inputShape = inputs[0].dims.slice(); + if (axis >= inputShape.length || axis < -1 * inputShape.length) { + throw new Error("axis specified for concat doesn't match input dimensionality"); + } + if (axis < 0) { + axis = inputShape.length + axis; + } + const outputShape = inputShape.slice(0); + for (let i = 1; i < inputs.length; i++) { + const dataNShape = inputs[i].dims.slice(); + for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) { + if (axisIndex === axis) { + outputShape[axis] += dataNShape[axisIndex]; + } else if (inputShape[axisIndex] !== dataNShape[axisIndex]) { + throw new Error("non concat dimensions must match"); + } + } + } + const rank = outputShape.length; + const sizeInConcatAxis = new Array(inputs.length); + let previousSum = 0; + for (let i = 0; i < sizeInConcatAxis.length; ++i) { + previousSum += inputs[i].dims[axis]; + sizeInConcatAxis[i] = previousSum; + } + let getTextureIndexWhereDataResidesMethod = ""; + if (inputs.length < 5) { + getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis); + } else { + getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesBinarySearch(sizeInConcatAxis); + } + const fetchDataFromCorrectTextureMethod = getFetchDataFromCorrectTextureMethod(inputs.length, rank); + const getSizeInConcatAxisValueFromIndexMethod = getGetSizeInConcatAxisValueFromIndexMethod(sizeInConcatAxis); + const shaderSource = ` + ${fetchDataFromCorrectTextureMethod} + ${getSizeInConcatAxisValueFromIndexMethod} + ${getTextureIndexWhereDataResidesMethod} + float process(int indices[${rank}]) { + int textureIndex = getTextureWhereDataResides (indices[${axis}]); + + if(textureIndex != 0) { + indices[${axis}] = indices[${axis}] - int(getSizeInConcatAxisValueFromIndex(textureIndex-int(1))); + } + + return fetchDataFromCorrectTexture(textureIndex, indices); + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createUnpackedConcatProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = createUnpackedConcatProgramMetadata(inputs.length, attributes.cacheKey); + return { ...metadata, get: () => createUnpackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) }; + }; + getTextureIndexWhereDataResidesLinearSearch = (sizeInConcatAxis) => { + const searchAxis = sizeInConcatAxis.map((size, i) => `if(index<${size}) {return ${i};} +`); + return `int getTextureWhereDataResides(int index) { + ${searchAxis.join("")} + }`; + }; + getTextureIndexWhereDataResidesBinarySearch = (sizeInConcatAxis) => getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis); + getFetchDataFromCorrectTextureMethod = (numberOfTensors, tensorRank) => { + const codeLines = [`float fetchDataFromCorrectTexture(int textureIndex, int indices[${tensorRank}]) {`]; + for (let i = 0; i < numberOfTensors; ++i) { + if (i === 0) { + codeLines.push( + ` if (textureIndex == ${i}) { return _X${i}(indices); }` + ); + } else if (i === numberOfTensors - 1) { + codeLines.push( + ` else { return _X${i}(indices); }` + ); + } else { + codeLines.push( + ` else if (textureIndex == ${i}) { return _X${i}(indices); }` + ); + } + } + codeLines.push( + " }" + ); + return codeLines.join("\n"); + }; + getGetSizeInConcatAxisValueFromIndexMethod = (sizeInConcatAxis) => { + const codeLines = ["int getSizeInConcatAxisValueFromIndex(int index) {"]; + for (let i = 0; i < sizeInConcatAxis.length; ++i) { + if (i === 0) { + codeLines.push( + ` if (index == ${i}) { return ${sizeInConcatAxis[i]}; }` + ); + } else if (i === sizeInConcatAxis.length - 1) { + codeLines.push( + ` else { return ${sizeInConcatAxis[i]}; }` + ); + } else { + codeLines.push( + ` else if (index == ${i}) { return ${sizeInConcatAxis[i]}; }` + ); + } + } + codeLines.push( + " }" + ); + return codeLines.join("\n"); + }; + parseConcatAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis") }); + validateInputs3 = (inputs) => { + if (!inputs || inputs.length < 1) { + throw new Error("too few inputs"); + } + const inputType = inputs[0].type; + const inputDimensionality = inputs[0].dims.length; + if (inputType === "string") { + throw new Error("string tensor is not supported yet"); + } + for (const input of inputs) { + if (input.type !== inputType) { + throw new Error("input tensors should be one type"); + } + if (input.dims.length !== inputDimensionality) { + throw new Error("input tensors should have the same shape"); + } + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/unary-op.ts +function glslAbs() { + return glslBuiltinUnary("abs"); +} +function glslAcos() { + return glslBuiltinUnary("acos"); +} +function glslAsin() { + return glslBuiltinUnary("asin"); +} +function glslAtan() { + return glslBuiltinUnary("atan"); +} +function glslCeil() { + return glslBuiltinUnary("ceil"); +} +function glslCos() { + return glslBuiltinUnary("cos"); +} +function glslElu(alpha) { + const name2 = "elu"; + const body = ` + const float alpha = float(${alpha}); + + float ${name2}_(float a) { + return a >= 0.0 ? a: (exp(a) - 1.0) * alpha; + } + vec4 ${name2}_(vec4 v) { + return vec4(${name2}_(v.x), ${name2}_(v.y), ${name2}_(v.z), ${name2}_(v.w)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslExp() { + return glslBuiltinUnary("exp"); +} +function glslFloor() { + return glslBuiltinUnary("floor"); +} +function glslClip(min, max) { + const name2 = "clip"; + const body = ` + const float min = float(${min}); + const float max = float(${max}); + + float ${name2}_(float a) { + return clamp(a, min, max); + } + vec4 ${name2}_(vec4 v) { + return clamp(v, min, max); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslIdentity() { + const name2 = "indentity"; + const body = ` + float ${name2}_(float a) { + return a; + } + vec4 ${name2}_(vec4 v) { + return v; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslLeakyRelu(alpha) { + const name2 = "leakyRelu"; + const body = ` + const float alpha = float(${alpha}); + + float ${name2}_(float a) { + return a < 0.0 ? a * alpha : a; + } + vec4 ${name2}_(vec4 v) { + return vec4(${name2}_(v.x), ${name2}_(v.y), ${name2}_(v.z), ${name2}_(v.w)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslLog() { + return glslBuiltinUnary("log"); +} +function glslNeg() { + const name2 = "neg"; + const body = ` + float ${name2}_(float a) { + return -a; + } + vec4 ${name2}_(vec4 v) { + return -v; + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslNot() { + const name2 = "not"; + const body = ` + float ${name2}_(float a) { + return float( ! bool(a) ); + } + bool ${name2}_(bool a) { + return !a; + } + vec4 ${name2}_(vec4 v) { + return vec4(!bool(v.x), !bool(v.y), !bool(v.z), !bool(v.w)); + } + bvec4 ${name2}_(bvec4 v) { + return bvec4(!v.x, !v.y, !v.z, !v.w); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslSin() { + return glslBuiltinUnary("sin"); +} +function glslRelu() { + const name2 = "relu"; + const body = ` + float ${name2}_(float a) { + return max( a, 0.0 ); + } + vec4 ${name2}_(vec4 v) { + return max( v, 0.0 ); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslSigmoid() { + const name2 = "sigmoid"; + const body = ` + float ${name2}_(float a) { + return 1.0 / (1.0 + exp(-a)); + } + vec4 ${name2}_(vec4 v) { + return 1.0 / (1.0 + exp(-v)); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslSqrt() { + return glslBuiltinUnary("sqrt"); +} +function glslTan() { + return glslBuiltinUnary("tan"); +} +function glslTanh() { + const name2 = "tanh"; + const body = ` + float ${name2}_(float a) { + a = clamp(a, -10., 10.); + a = exp(2.*a); + return (a - 1.) / (a + 1.); + } + vec4 ${name2}_(vec4 v) { + v = clamp(v, -10., 10.); + v = exp(2.*v); + return (v - 1.) / (v + 1.); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +function glslBuiltinUnary(name2) { + const body = ` + float ${name2}_(float a) { + return ${name2}(a); + } + vec4 ${name2}_(vec4 v) { + return ${name2}(v); + } + `; + return { body, name: name2, type: 0 /* ValueBased */ }; +} +var createElementwiseProgramInfo, createElementwiseProgramInfoLoader, abs, acos, asin, atan, clip, parseClipAttributes, clipV11, generateClipAttributesFromInputs, ceil, cos, elu, parseEluAttributes, exp, floor, identity, leakyRelu, parseLeakyReluAttributes, log2, neg, not2, relu, sigmoid, sin, sqrt, tan, tanh; +var init_unary_op = __esm({ + "web/lib/onnxjs/backends/webgl/ops/unary-op.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_glsl_definitions(); + init_glsl_source(); + init_types(); + createElementwiseProgramInfo = (handler, metadata, input, glslFunc) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + const glsl = getGlsl(handler.session.backend.glContext.version); + return { + ...metadata, + output: { dims: input.dims, type: input.type, textureType }, + shaderSource: ` + ${glslFunc.body} + void main() { + vec4 v = ${glsl.texture2D}(A, TexCoords); + v = ${glslFunc.name}_(v); + ${glsl.output} = v; + } + `, + hasMain: true + }; + }; + createElementwiseProgramInfoLoader = (handler, input, glslFunc, cacheKey) => { + const textureType = handler.session.pack ? 2 /* packed */ : 0 /* unpacked */; + const metadata = { name: glslFunc.name, inputTypes: [textureType], inputNames: ["A"], cacheHint: cacheKey }; + return { ...metadata, get: () => createElementwiseProgramInfo(handler, metadata, input, glslFunc) }; + }; + abs = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAbs()), inputs)]; + acos = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAcos()), inputs)]; + asin = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAsin()), inputs)]; + atan = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAtan()), inputs)]; + clip = (handler, inputs, attributes) => [handler.run( + createElementwiseProgramInfoLoader( + handler, + inputs[0], + glslClip(attributes.min, attributes.max), + attributes.cacheKey + ), + inputs + )]; + parseClipAttributes = (node) => createAttributeWithCacheKey( + { min: node.attributes.getFloat("min", MIN_CLIP), max: node.attributes.getFloat("max", MAX_CLIP) } + ); + clipV11 = (handler, inputs) => { + const attributes = generateClipAttributesFromInputs(handler, inputs); + return clip(handler, [inputs[0]], attributes); + }; + generateClipAttributesFromInputs = (handler, inputs) => { + if (inputs.length >= 3 && (!handler.session.isInitializer(inputs[1].dataId) || !handler.session.isInitializer(inputs[2].dataId))) { + throw new Error("dynamic clip attributes are not allowed"); + } + const min = inputs.length >= 3 ? inputs[1].numberData[0] : MIN_CLIP; + const max = inputs.length >= 3 ? inputs[2].numberData[0] : MAX_CLIP; + return createAttributeWithCacheKey({ min, max }); + }; + ceil = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslCeil()), inputs)]; + cos = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslCos()), inputs)]; + elu = (handler, inputs, attributes) => [handler.run( + createElementwiseProgramInfoLoader(handler, inputs[0], glslElu(attributes.alpha), attributes.cacheKey), + inputs + )]; + parseEluAttributes = (node) => createAttributeWithCacheKey({ alpha: node.attributes.getFloat("alpha", 1) }); + exp = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslExp()), inputs)]; + floor = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslFloor()), inputs)]; + identity = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslIdentity()), inputs)]; + leakyRelu = (handler, inputs, attributes) => [handler.run( + createElementwiseProgramInfoLoader(handler, inputs[0], glslLeakyRelu(attributes.alpha), attributes.cacheKey), + inputs + )]; + parseLeakyReluAttributes = (node) => createAttributeWithCacheKey({ alpha: node.attributes.getFloat("alpha", 0.01) }); + log2 = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslLog()), inputs)]; + neg = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslNeg()), inputs)]; + not2 = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslNot()), inputs)]; + relu = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslRelu()), inputs)]; + sigmoid = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSigmoid()), inputs)]; + sin = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSin()), inputs)]; + sqrt = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSqrt()), inputs)]; + tan = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslTan()), inputs)]; + tanh = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslTanh()), inputs)]; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/fuse-utils.ts +function getActivationSnippet(attributes) { + let func; + switch (attributes.activation) { + case "Relu": + func = glslRelu(); + break; + case "Sigmoid": + func = glslSigmoid(); + break; + case "Clip": + func = glslClip(attributes.clipMin, attributes.clipMax); + break; + default: + return { activationFunction: "", applyActivation: "" }; + } + const activationName = func.name; + const activationFunction = func.body; + const applyActivation = `value = ${activationName}_(value);`; + return { activationFunction, applyActivation }; +} +var parseInternalActivationAttributes; +var init_fuse_utils = __esm({ + "web/lib/onnxjs/backends/webgl/ops/fuse-utils.ts"() { + "use strict"; + init_util(); + init_unary_op(); + parseInternalActivationAttributes = (attributes) => { + const activation = attributes.getString("activation", ""); + if (activation === "Clip") { + const [clipMin, clipMax] = attributes.getFloats("activation_params", [MIN_CLIP, MAX_CLIP]); + return { activation, clipMax, clipMin, activationCacheKey: `${activation}:${clipMin},${clipMax}` }; + } + return { activation, activationCacheKey: activation }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/conv-grouped.ts +var createUnpackedGroupedConvProgramMetadata, createUnpackedGroupedConvProgramInfo, createUnpackedGroupedConvProgramInfoLoader; +var init_conv_grouped = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv-grouped.ts"() { + "use strict"; + init_instrument(); + init_glsl_source(); + init_types(); + init_conv(); + init_fuse_utils(); + createUnpackedGroupedConvProgramMetadata = (hasBias, cacheHint) => ({ + name: "GroupedConv", + inputNames: hasBias ? ["X", "W", "Bias"] : ["X", "W"], + inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + cacheHint + }); + createUnpackedGroupedConvProgramInfo = (inferenceHandler, inputs, metadata, attributes) => { + const hasBias = inputs.length > 2; + const processBias = hasBias ? "value += getBias(output_channel);" : ""; + const xShape = inputs[0].dims.slice(); + const wShape = inputs[1].dims.slice(); + const outputChannelsPerGroup = wShape[0] / attributes.group; + Logger.verbose( + "GroupedConv", + `autpPad:${attributes.autoPad}, dilations:${attributes.dilations}, group:${attributes.group}, kernelShape:${attributes.kernelShape}, pads:${attributes.pads}, strides:${attributes.strides}` + ); + const outputShape = calculateOutputShape(xShape, wShape, attributes.dilations, attributes.pads, attributes.strides); + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const { activationFunction, applyActivation } = getActivationSnippet(attributes); + const shaderSource = ` + const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]}); + const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]}); + ${activationFunction} + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords.x; + int output_channel = coords.y; + ivec2 xRCCorner = coords.zw * strides - pads; + int group_id = output_channel / ${outputChannelsPerGroup}; + + float value = 0.0; + for (int wInChannel = 0; wInChannel < ${wShape[1]}; wInChannel++) { + int input_channel = group_id * ${wShape[1]} + wInChannel; + for (int wHeight = 0; wHeight < ${wShape[2]}; wHeight++) { + int xHeight = xRCCorner.x + wHeight * ${attributes.dilations[0]}; + + if (xHeight < 0 || xHeight >= ${xShape[2]}) { + continue; + } + + for (int wWidth = 0; wWidth < ${wShape[3]}; wWidth++) { + int xWidth = xRCCorner.y + wWidth * ${attributes.dilations[1]}; + if (xWidth < 0 || xWidth >= ${xShape[3]}) { + continue; + } + + float xVal = getX(batch, input_channel, xWidth, xHeight); + float wVal = getW(output_channel, wInChannel, wWidth, wHeight); + value += xVal*wVal; + } + } + } + ${processBias} + ${applyActivation} + ${glsl.output} = vec4(value, .0, .0, .0); + } +`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource, + hasMain: true + }; + }; + createUnpackedGroupedConvProgramInfoLoader = (inferenceHandler, inputs, attributes) => { + const metadata = createUnpackedGroupedConvProgramMetadata(inputs.length > 2, attributes.cacheKey); + return { + ...metadata, + get: () => createUnpackedGroupedConvProgramInfo(inferenceHandler, inputs, metadata, attributes) + }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/im2col-pack.ts +var createPackedIm2ColProgramMetadata, createPackedIm2ColProgramInfo, createPackedIm2ColProgramInfoLoader; +var init_im2col_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/im2col-pack.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_packing_utils(); + createPackedIm2ColProgramMetadata = (cacheHint) => ({ + name: "Im2Col (packed)", + inputNames: ["A"], + inputTypes: [2 /* packed */], + cacheHint + }); + createPackedIm2ColProgramInfo = (inferenceHandler, metadata, x, w, outputShape, attributes) => { + const xshape = x.dims; + const wshape = w.dims; + const rowDim = 2; + const colDim = 3; + const rank = outputShape.length; + const im2colShape = [wshape[1] * wshape[2] * wshape[3], outputShape[2] * outputShape[3]]; + const kernelSize = wshape[2] * wshape[3]; + const unpackChannel = unpackFromChannel(); + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + let unrolled = ""; + for (let row = 0; row <= 1; row++) { + for (let col = 0; col <= 1; col++) { + unrolled += ` + blockIndex = rc.x + ${col}; + pos = rc.y + ${row}; + + if(blockIndex < ${im2colShape[1]} && pos < ${im2colShape[0]}) { + offsetY = int(blockIndex / (${outputShape[rank - 1]})) * ${attributes.strides[0]} - + ${attributes.pads[0]}; + d0 = offsetY + ${attributes.dilations[0]} * (imod(pos, ${kernelSize}) / ${wshape[2]}); + + if(d0 < ${xshape[rowDim]} && d0 >= 0) { + offsetX = imod(blockIndex, ${outputShape[rank - 1]}) * ${attributes.strides[1]} - + ${attributes.pads[1]}; + d1 = offsetX + ${attributes.dilations[1]} * imod(imod(pos, ${kernelSize}), ${wshape[2]}); + + if(d1 < ${xshape[colDim]} && d1 >= 0) { + + ch = int(float(pos)/ ${kernelSize}.); + innerDims = vec2(d0, d1); + result[${row * 2 + col}] = getChannel( + getA(0, ch, int(innerDims.x), + int(innerDims.y)), innerDims); + } + } + } + + `; + } + } + const shaderSource = ` + ${unpackChannel} + + void main() { + ivec2 rc = getOutputCoords(); + vec4 result = vec4(0.0); + int blockIndex, pos, offsetY, d0, offsetX, d1, ch; + vec2 innerDims; + ${unrolled} + ${glsl.output} = result; + } + `; + return { + ...metadata, + output: { dims: im2colShape, type: x.type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => { + const metadata = createPackedIm2ColProgramMetadata(attributes.cacheKey); + return { + ...metadata, + get: () => createPackedIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) + }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/matmul.ts +function createMatmulProgramInfo(metadata, inputs, activationAttributes) { + const aShape = inputs[0].dims; + const bShape = inputs[1].dims; + const outputShape = BroadcastUtil.calcShape(aShape, bShape, true); + if (!outputShape) { + throw new Error("Can't use matmul on the given tensors"); + } + const coordsDataType = getCoordsDataType(outputShape.length); + const allGlChannels = getGlChannels(); + const { activationFunction, applyActivation } = getActivationSnippet(activationAttributes); + const hasBias = inputs.length > 2; + const processBias = hasBias ? "value += getBiasForMatmul();" : ""; + const getBiasForMatmulSnippet = hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, false)}` : ""; + const rank = outputShape.length; + const arank = aShape.length; + const brank = bShape.length; + const sharedDim = aShape[aShape.length - 1]; + const shaderSource = ` + ${activationFunction} + ${getBiasForMatmulSnippet} + float process(int indices[${rank}]) { + int a[${arank}]; + int b[${brank}]; + bcastMatmulIndices_A(indices, a); + bcastMatmulIndices_B(indices, b); + + float value; + for (int k=0; k<${sharedDim}; ++k) { + a[${arank - 1}] = k; + b[${brank - 2}] = k; + value += _A(a) * _B(b); + } + ${processBias} + ${applyActivation} + return value; + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; +} +function createMatmulProgramInfoLoader(inputs, activationAttributes) { + const metadata = createMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey); + return { ...metadata, get: () => createMatmulProgramInfo(metadata, inputs, activationAttributes) }; +} +function getBiasForMatmul(coordsDataType, allGlChannels, inShape, outShape, isPacked) { + let unpackedCoordsSnippet = ""; + const inRank = inShape.length; + const outRank = outShape.length; + const rankDiff = outRank - inRank; + if (outRank < 2 && inRank > 0) { + unpackedCoordsSnippet = "coords"; + } else { + unpackedCoordsSnippet = inShape.map((_s, i) => `coords.${allGlChannels[i + rankDiff]}`).join(", "); + } + const broadcastDims = BroadcastUtil.getBroadcastDims(inShape, outShape); + const coordsSnippet = broadcastDims.map((d) => `coords.${allGlChannels[d + rankDiff]} = 0;`).join("\n"); + const inSize = ShapeUtil.size(inShape); + const isInputScalar = inSize === 1; + let output = "vec4(outputValue.xx, outputValue.yy)"; + if (isInputScalar) { + output = "vec4(outputValue.x)"; + } + const getBiasForMatmulSource = isPacked ? ` +vec4 getBiasForMatmul() { + ${coordsDataType} coords = getOutputCoords(); + ${coordsSnippet} + vec4 outputValue = getBias(${unpackedCoordsSnippet}); + return ${output}; +}` : ` +float getBiasForMatmul() { + ${coordsDataType} coords = getOutputCoords(); + ${coordsSnippet} + return getBias(coords.x); +}`; + return getBiasForMatmulSource; +} +var matMul, parseMatMulAttributes, createMatmulProgramMetadata, validateInputs4; +var init_matmul = __esm({ + "web/lib/onnxjs/backends/webgl/ops/matmul.ts"() { + "use strict"; + init_util(); + init_types(); + init_utils(); + init_fuse_utils(); + init_matmul_pack(); + matMul = (inferenceHandler, inputs, attributes) => { + validateInputs4(inputs); + if (inferenceHandler.session.pack) { + return [inferenceHandler.run( + createPackedMatmulProgramInfoLoader(inferenceHandler, inputs, attributes), + inputs + )]; + } else { + return [inferenceHandler.run(createMatmulProgramInfoLoader(inputs, attributes), inputs)]; + } + }; + parseMatMulAttributes = (node) => parseInternalActivationAttributes(node.attributes); + createMatmulProgramMetadata = (hasBias, cacheHint) => ({ + name: "MatMul", + inputNames: hasBias ? ["A", "B", "Bias"] : ["A", "B"], + inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + cacheHint + }); + validateInputs4 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("MatMul requires 2 inputs."); + } + if (inputs[0].dims[inputs[0].dims.length - 1] !== inputs[1].dims[inputs[1].dims.length - 2]) { + throw new Error("shared dimension does not match."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64" || inputs[1].type !== "float32" && inputs[1].type !== "float64") { + throw new Error("inputs should be float type"); + } + if (inputs[0].type !== inputs[1].type) { + throw new Error("inputs types should match"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/matmul-pack.ts +function getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outShape) { + let unpackedACoordsSnippet = []; + let unpackedBCoordsSnippet = []; + const inAShape = inputs[0].dims; + const inBShape = inputs[1].dims; + const inARank = inAShape.length; + const inBRank = inBShape.length; + const outRank = outShape.length; + const rankADiff = outRank - inARank; + const rankBDiff = outRank - inBRank; + unpackedACoordsSnippet = inAShape.map((_s, i) => `coords.${allGlChannels[i + rankADiff]}`); + unpackedACoordsSnippet[inARank - 1] = "i*2"; + unpackedACoordsSnippet.join(", "); + unpackedBCoordsSnippet = inBShape.map((_s, i) => `coords.${allGlChannels[i + rankBDiff]}`); + unpackedBCoordsSnippet[inBRank - 2] = "i*2"; + unpackedBCoordsSnippet.join(", "); + const broadcastADims = BroadcastUtil.getBroadcastDims(inAShape, outShape); + const broadcastBDims = BroadcastUtil.getBroadcastDims(inBShape, outShape); + const coordsASnippet = broadcastADims.map((d) => `coords.${allGlChannels[d + rankADiff]} = 0;`).join("\n"); + const coordsBSnippet = broadcastBDims.map((d) => `coords.${allGlChannels[d + rankBDiff]} = 0;`).join("\n"); + const swapDimSnippet = `int lastDim = coords.${allGlChannels[outRank - 1]}; + coords.${allGlChannels[outRank - 1]} = coords.${allGlChannels[outRank - 2]}; + coords.${allGlChannels[outRank - 2]} = lastDim;`; + const getBcastSamplerMatmulSource = ` +vec4 getAAtOutCoordsMatmul(int i) { + ${coordsDataType} coords = getOutputCoords(); + ${swapDimSnippet} + ${coordsASnippet} + vec4 outputValue = getA(${unpackedACoordsSnippet}); + return outputValue; +} + +vec4 getBAtOutCoordsMatmul(int i) { + ${coordsDataType} coords = getOutputCoords(); + ${swapDimSnippet} + ${coordsBSnippet} + vec4 outputValue = getB(${unpackedBCoordsSnippet}); + return outputValue; +}`; + return getBcastSamplerMatmulSource; +} +function getA(allGlChannels, rank) { + let res = ""; + for (let i = 0; i < rank - 2; i++) { + res += `rc.${allGlChannels[i]}, `; + } + res += `rc.${allGlChannels[rank - 2]}, i*2`; + return res; +} +function getB(allGlChannels, rank) { + let res = ""; + for (let i = 0; i < rank - 2; i++) { + res += `rc.${allGlChannels[i]}, `; + } + res += `i*2, rc.${allGlChannels[rank - 1]}`; + return res; +} +var createPackedMatmulProgramMetadata, createPackedMatmulProgramInfo, createPackedMatmulProgramInfoLoader; +var init_matmul_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/matmul-pack.ts"() { + "use strict"; + init_util(); + init_glsl_source(); + init_types(); + init_utils(); + init_fuse_utils(); + init_matmul(); + createPackedMatmulProgramMetadata = (hasBias, cacheHint) => ({ + name: "MatMul (packed)", + inputNames: hasBias ? ["A", "B", "Bias"] : ["A", "B"], + inputTypes: hasBias ? [2 /* packed */, 2 /* packed */, 2 /* packed */] : [2 /* packed */, 2 /* packed */], + cacheHint + }); + createPackedMatmulProgramInfo = (inferenceHandler, metadata, inputs, activationAttributes) => { + const hasBias = inputs.length > 2; + const processBias = hasBias ? "value += getBiasForMatmul();" : ""; + const aShape = inputs[0].dims; + const bShape = inputs[1].dims; + const outputShape = BroadcastUtil.calcShape(aShape, bShape, true); + const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims); + if (!outputShape) { + throw new Error("Can't use matmul on the given tensors"); + } + const sharedDim = aShape[aShape.length - 1]; + const sharedDimIndex = Math.ceil(sharedDim / 2); + const aRank = aShape.length; + const bRank = bShape.length; + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const coordsDataType = getCoordsDataType(outputShape.length); + const outRank = outputShape.length; + const allGlChannels = getGlChannels(); + const { activationFunction, applyActivation } = getActivationSnippet(activationAttributes); + const getBiasForMatmulSnippet = hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, true)}` : ""; + const getBcastedSamplerForMatmulSnippet = isBroadcast ? `${getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outputShape)}` : ""; + const getSamplerAInLoopSnippet = isBroadcast ? "getAAtOutCoordsMatmul(i)" : `getA(${getA(allGlChannels, aRank)})`; + const getSamplerBInLoopSnippet = isBroadcast ? "getBAtOutCoordsMatmul(i)" : `getB(${getB(allGlChannels, bRank)})`; + const getOutputCoordsSnippet = isBroadcast ? "" : `${coordsDataType} rc = + getOutputCoords(); int lastDim = rc.${allGlChannels[outRank - 1]}; rc.${allGlChannels[outRank - 1]} = + rc.${allGlChannels[outRank - 2]}; rc.${allGlChannels[outRank - 2]} = lastDim; + `; + const shaderSource = ` + ${getBcastedSamplerForMatmulSnippet} + ${getBiasForMatmulSnippet} + ${activationFunction} + void main() { + ${getOutputCoordsSnippet} + + vec4 value = vec4(0); + for (int i = 0; i < ${sharedDimIndex}; i++) { + vec4 a = ${getSamplerAInLoopSnippet}; + vec4 b = ${getSamplerBInLoopSnippet}; + + value += (a.rrbb * b.rgrg); + value += (a.ggaa * b.baba); + } + ${processBias} + ${applyActivation} + ${glsl.output} = value; + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, + shaderSource, + hasMain: true + }; + }; + createPackedMatmulProgramInfoLoader = (inferenceHandler, inputs, activationAttributes) => { + const metadata = createPackedMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey); + return { + ...metadata, + get: () => createPackedMatmulProgramInfo(inferenceHandler, metadata, inputs, activationAttributes) + }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/conv-pack.ts +var conv2DPacked; +var init_conv_pack = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv-pack.ts"() { + "use strict"; + init_conv(); + init_im2col_pack(); + init_matmul_pack(); + conv2DPacked = (inferenceHandler, inputs, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); + const im2colOutput = inferenceHandler.run( + createPackedIm2ColProgramInfoLoader(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), + [inputs[0]] + ); + const kernelReshaped = inferenceHandler.reshapePacked(inputs[1], [kshape[0], kshape[1] * kshape[2] * kshape[3]]); + const matmulInputs = inputs.length === 3 ? [kernelReshaped, im2colOutput, inputs[2]] : [kernelReshaped, im2colOutput]; + const matmulOutput = inferenceHandler.run( + createPackedMatmulProgramInfoLoader(inferenceHandler, matmulInputs, attributes), + matmulInputs + ); + const outputReshaped = inferenceHandler.reshapePacked(matmulOutput, outputShape); + return outputReshaped; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/im2col.ts +var createIm2ColProgramMetadata, createIm2ColProgramInfo, createIm2ColProgramInfoLoader, calculateIm2ColDims; +var init_im2col = __esm({ + "web/lib/onnxjs/backends/webgl/ops/im2col.ts"() { + "use strict"; + init_types(); + createIm2ColProgramMetadata = (cacheHint) => ({ + name: "Im2Col", + inputNames: ["X"], + inputTypes: [0 /* unpacked */], + cacheHint + }); + createIm2ColProgramInfo = (_inferenceHandler, metadata, x, w, outputShape, attributes) => { + const xshape = x.dims; + const wshape = w.dims; + const rank = outputShape.length; + const im2colDims = calculateIm2ColDims(xshape, wshape, outputShape, 4); + const shaderSource = ` + const int XC = ${xshape[1]}; + const int XH = ${xshape[2]}; + const int XW = ${xshape[3]}; + const int KH = ${attributes.kernelShape[0]}; + const int KW = ${attributes.kernelShape[1]}; + const int dilationH = ${attributes.dilations[0]}; + const int dilationW = ${attributes.dilations[1]}; + const int strideH = ${attributes.strides[0]}; + const int strideW = ${attributes.strides[1]}; + const int padH = ${attributes.pads[0]}; + const int padW = ${attributes.pads[1]}; + const int KHKW = KH*KW; + const int XCKHKW = XC * KHKW; + const int outputChannels = 4; + vec4 process(int indices[${rank}]) { + int b = indices[0]; // batch size + int oh = indices[1] * strideH - padH; //output height + int ow = indices[2] * strideW - padW; //output width + int p = indices[3] * outputChannels; //patch + vec4 value = vec4(0.0); + for(int i=0; i < outputChannels; ++i) { + if(p < XCKHKW) { + int patchC = p / KHKW; + int patchH = (p - patchC*KHKW) / KW; + int patchW = (p - patchC*KHKW) - patchH * KW; + int xh2 = oh + patchH * dilationH; + int xw2 = ow + patchW * dilationW; + int x[${xshape.length}]; + x[0] = b; + x[1] = patchC; + x[2] = xh2; + x[3] = xw2; + if(xh2 >= 0 && + xh2 < XH && + xw2 >= 0 && + xw2 < XW) { + value[i] = _X(x); + } + } + ++p; + } + return value; + } + `; + return { + ...metadata, + output: { dims: im2colDims, type: x.type, textureType: 4 /* packedLastDimension */ }, + shaderSource + }; + }; + createIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => { + const metadata = createIm2ColProgramMetadata(attributes.cacheKey); + return { + ...metadata, + get: () => createIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) + }; + }; + calculateIm2ColDims = (inputShape, kernelShape, outputShape, channels = 4) => [ + outputShape[0], + outputShape[2], + outputShape[3], + Math.ceil(inputShape[1] * kernelShape[2] * kernelShape[3] / channels) + ]; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/dot-product.ts +var createDotProductProgramMetadata, createDotProductProgramInfo, createDotProductProgramInfoLoader; +var init_dot_product = __esm({ + "web/lib/onnxjs/backends/webgl/ops/dot-product.ts"() { + "use strict"; + init_util(); + init_glsl_source(); + init_types(); + init_fuse_utils(); + init_im2col(); + createDotProductProgramMetadata = (hasBias, attributes) => ({ + name: "ConvDotProduct", + inputNames: hasBias ? ["Im2Col", "K", "B"] : ["Im2Col", "K"], + inputTypes: hasBias ? [0 /* unpacked */, 4 /* packedLastDimension */, 0 /* unpacked */] : [0 /* unpacked */, 4 /* packedLastDimension */], + cacheKey: attributes.activationCacheKey + }); + createDotProductProgramInfo = (inferenceHandler, metadata, inputs, outputShape, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const adjustedKernelShape = [kshape[0], Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4)]; + const im2colShape = calculateIm2ColDims(xshape, kshape, outputShape); + const [kWidth, kHeight] = inferenceHandler.calculateTextureWidthAndHeight(adjustedKernelShape, 4 /* packedLastDimension */); + const im2colStrides = ShapeUtil.computeStrides(im2colShape); + const [im2colWidth, im2colHeight] = inferenceHandler.calculateTextureWidthAndHeight(im2colShape, 4 /* packedLastDimension */); + const rank = outputShape.length; + const initValue = inputs.length < 3 ? "0.0" : "_B(b)"; + const sharedDim = Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4); + const { activationFunction, applyActivation } = getActivationSnippet(attributes); + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const shaderSource = ` +${activationFunction} +float process(int indices[${rank}]) { + int b[1]; + b[0] = indices[1]; + int im2col[4]; + im2col[0] = indices[0]; + im2col[1] = indices[2]; + im2col[2] = indices[3]; + int im2colOffset = im2col[0] * ${im2colStrides[0]} + im2col[1] * ${im2colStrides[1]} + im2col[2] * ${im2colStrides[2]}; + int kernelOffset = indices[1] * ${adjustedKernelShape[1]}; + float value = ${initValue}; + for (int i = 0; i < ${sharedDim}; ++i) { + vec2 im2colCoords = offsetToCoords(im2colOffset, ${im2colWidth}, ${im2colHeight}); + vec2 kernelCoords = offsetToCoords(kernelOffset, ${kWidth}, ${kHeight}); + value += dot(${glsl.texture2D}(Im2Col, im2colCoords), ${glsl.texture2D}(K, kernelCoords)); + ++im2colOffset; + ++kernelOffset; + } + ${applyActivation} + return value; +}`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createDotProductProgramInfoLoader = (inferenceHandler, inputs, outputShape, attributes) => { + const metadata = createDotProductProgramMetadata(inputs.length > 2, attributes); + return { + ...metadata, + get: () => createDotProductProgramInfo(inferenceHandler, metadata, inputs, outputShape, attributes) + }; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/conv.ts +var calculateOutputShape, conv, conv2d, conv2DUnpackedPointwise, conv2DUnpacked, getAdjustedConvAttributes, parseConvAttributes, validateInputs5; +var init_conv = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_conv_grouped(); + init_conv_pack(); + init_dot_product(); + init_fuse_utils(); + init_im2col(); + init_matmul(); + calculateOutputShape = (inputShape, kernelShape, dilations, adjustPads, strides) => { + const batchSize = inputShape[0]; + const inputSpatialShape = inputShape.slice(2); + const spatialRank = inputSpatialShape.length; + const outChannels = kernelShape[0]; + const kernelSpatialShape = kernelShape.slice(2); + const dilatedKernelShape = kernelSpatialShape.map((v, i) => v + (v - 1) * (dilations[i] - 1)); + const inputSpatialShapeWithPad = inputSpatialShape.map((v, i) => v + adjustPads[i] + adjustPads[i + spatialRank]); + const outputSpatialShape = inputSpatialShapeWithPad.map((v, i) => Math.floor((v - dilatedKernelShape[i] + strides[i]) / strides[i])); + const outputShape = [batchSize, outChannels].concat(...outputSpatialShape); + return outputShape; + }; + conv = (inferenceHandler, inputs, attributes) => { + validateInputs5(inputs, attributes); + return conv2d(inferenceHandler, inputs, attributes); + }; + conv2d = (inferenceHandler, inputs, attributes) => { + const adjustedAttributes = getAdjustedConvAttributes(attributes, inputs); + const packMode = inferenceHandler.session.pack; + const isPointwise = adjustedAttributes.kernelShape[0] === 1 && adjustedAttributes.kernelShape[1] === 1; + if (adjustedAttributes.group > 1) { + const result = inferenceHandler.run( + createUnpackedGroupedConvProgramInfoLoader(inferenceHandler, inputs, adjustedAttributes), + inputs + ); + return [result]; + } else if (isPointwise && packMode) { + return [conv2DUnpackedPointwise(inferenceHandler, inputs, adjustedAttributes)]; + } else if (packMode && inputs[0].dims.length === 4 && inputs[0].dims[0] === 1 && !isPointwise) { + return [conv2DPacked(inferenceHandler, inputs, adjustedAttributes)]; + } else { + return [conv2DUnpacked(inferenceHandler, inputs, adjustedAttributes)]; + } + }; + conv2DUnpackedPointwise = (inferenceHandler, inputs, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); + const reshapedX = inferenceHandler.reshapeUnpacked(inputs[0], [xshape[1], xshape[2] * xshape[3]]); + const reshapedK = inferenceHandler.reshapeUnpacked(inputs[1], [kshape[0], kshape[1]]); + const matmulInputs = inputs.length > 2 ? [reshapedK, reshapedX, inputs[2]] : [reshapedK, reshapedX]; + const matmulOutput = inferenceHandler.run(createMatmulProgramInfoLoader(matmulInputs, attributes), matmulInputs); + return inferenceHandler.reshapeUnpacked(matmulOutput, outputShape); + }; + conv2DUnpacked = (inferenceHandler, inputs, attributes) => { + const xshape = inputs[0].dims; + const kshape = inputs[1].dims; + const outputShape = calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides); + const xIm2Col = inferenceHandler.run( + createIm2ColProgramInfoLoader(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), + [inputs[0]] + ); + const dotProductInputs = inputs.length === 3 ? [xIm2Col, inputs[1], inputs[2]] : [xIm2Col, inputs[1]]; + const output = inferenceHandler.run( + createDotProductProgramInfoLoader(inferenceHandler, inputs, outputShape, attributes), + dotProductInputs + ); + return output; + }; + getAdjustedConvAttributes = (attributes, inputs) => { + const kernelShape = attributes.kernelShape.slice(); + if (attributes.kernelShape.length === 0) { + for (let i = 2; i < inputs[1].dims.length; ++i) { + kernelShape.push(inputs[1].dims[i]); + } + } + const pads = attributes.pads.slice(); + PoolConvUtil.adjustPadsBasedOnAutoPad( + inputs[0].dims, + attributes.strides, + attributes.dilations, + kernelShape, + pads, + attributes.autoPad + ); + const newAttributes = Object.assign({}, attributes); + Object.assign(newAttributes, { kernelShape, pads, cacheKey: attributes.cacheKey }); + return newAttributes; + }; + parseConvAttributes = (node) => { + const attributes = node.attributes; + const activationAttributes = parseInternalActivationAttributes(attributes); + const autoPad = attributes.getString("auto_pad", "NOTSET"); + const dilations = attributes.getInts("dilations", [1, 1]); + const group = attributes.getInt("group", 1); + const kernelShape = attributes.getInts("kernel_shape", []); + const pads = attributes.getInts("pads", [0, 0, 0, 0]); + const strides = attributes.getInts("strides", [1, 1]); + return createAttributeWithCacheKey({ autoPad, dilations, group, kernelShape, pads, strides, ...activationAttributes }); + }; + validateInputs5 = (inputs, attributes) => { + if (!inputs || inputs.length !== 2 && inputs.length !== 3) { + throw new Error("Conv requires 2 or 3 inputs"); + } + if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) { + throw new Error("currently only support 2-dimensional conv"); + } + const dataChannel = inputs[0].dims[1]; + const filterInChannel = inputs[1].dims[1] * attributes.group; + if (dataChannel !== filterInChannel) { + throw new Error("FILTER_IN_CHANNEL should be equal to DATA_CHANNEL"); + } + if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[1].dims[0] !== inputs[2].dims[0])) { + throw new Error("invalid bias"); + } + const spatialRank = inputs[0].dims.length - 2; + if (attributes.dilations.length !== spatialRank) { + throw new Error(`dilations should be ${spatialRank}D`); + } + if (attributes.strides.length !== spatialRank) { + throw new Error(`strides should be ${spatialRank}D`); + } + if (attributes.pads.length !== spatialRank * 2) { + throw new Error(`pads should be ${spatialRank * 2}D`); + } + if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) { + throw new Error("invalid kernel shape"); + } + if (inputs[0].type !== "float32" || inputs[1].type !== "float32") { + throw new Error("Conv input(X,W) should be float tensor"); + } + if (inputs.length === 3 && inputs[2].type !== "float32") { + throw new Error("Conv input(bias) should be float tensor"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/conv-transpose.ts +var computeTotalPad, distributePadding, calculateOutputShapeAndPads, convTranspose, convTranspose2d, createConvTransposeProgramMetadata, createUnpackedConvTransposeProgramInfo, createUnpackedConvTransposeProgramInfoLoader, convTranspose2DUnpacked, getAdjustedConvTransposeAttributes, parseConvTransposeAttributes, validateInputs6; +var init_conv_transpose = __esm({ + "web/lib/onnxjs/backends/webgl/ops/conv-transpose.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_glsl_source(); + init_types(); + init_fuse_utils(); + computeTotalPad = (inDim, stride, adj, kernel, dilation, outSize) => (inDim - 1) * stride + adj + (kernel - 1) * dilation + 1 - outSize; + distributePadding = (totalPad, autoPad, pads, head, tail) => { + const smallPad = Math.floor(totalPad / 2); + if (autoPad === "SAME_UPPER") { + pads[head] = smallPad; + pads[tail] = totalPad - smallPad; + } else if (autoPad === "SAME_LOWER") { + pads[head] = totalPad - smallPad; + pads[tail] = smallPad; + } + }; + calculateOutputShapeAndPads = (inputShape, kernelShape, dilations, autoPad, pads, strides, outputPadding, outputShape) => { + const spatialRank = inputShape.length - 2; + const updateShape = outputShape.length === 0; + for (let i = 0; i < spatialRank; ++i) { + const outSize = updateShape ? inputShape[i + 2] * strides[i] : outputShape[i]; + const totalPad = computeTotalPad(inputShape[i + 2], strides[i], pads[i], kernelShape[i], dilations[i], outSize); + distributePadding(totalPad, autoPad, pads, i, i + spatialRank); + if (updateShape) { + outputShape.push( + strides[i] * (inputShape[i + 2] - 1) + outputPadding[i] + (kernelShape[i] - 1) * dilations[i] + 1 - pads[i] - pads[i + spatialRank] + ); + } + } + }; + convTranspose = (inferenceHandler, inputs, attributes) => { + validateInputs6(inputs, attributes); + return convTranspose2d(inferenceHandler, inputs, attributes); + }; + convTranspose2d = (inferenceHandler, inputs, attributes) => { + const adjustedAttributes = getAdjustedConvTransposeAttributes(attributes, inputs); + return [convTranspose2DUnpacked(inferenceHandler, inputs, adjustedAttributes)]; + }; + createConvTransposeProgramMetadata = (hasBias, cacheHint) => ({ + name: "ConvTranspose", + inputNames: hasBias ? ["X", "W", "B"] : ["X", "W"], + inputTypes: hasBias ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + cacheHint + }); + createUnpackedConvTransposeProgramInfo = (inferenceHandler, inputs, metadata, attributes) => { + const hasBias = inputs.length > 2; + const valueInit = hasBias ? "getB(output_channel)" : "0.0"; + const xShape = inputs[0].dims; + const wShape = inputs[1].dims; + const outputChannelsPerGroup = wShape[1]; + const inputChannelsPerGroup = wShape[0] / attributes.group; + const outputShape = [inputs[0].dims[0], inputs[1].dims[1] * attributes.group, ...attributes.outputShape]; + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const { activationFunction, applyActivation } = getActivationSnippet(attributes); + const shaderSource = ` + const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]}); + const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]}); + ${activationFunction} + void main() { + ivec4 coords = getOutputCoords(); + int batch = coords.x; + int output_channel = coords.y; + + ivec2 loc = coords.zw + pads; + + int group_id = output_channel / ${outputChannelsPerGroup}; + int wOutChannel = output_channel - group_id * ${outputChannelsPerGroup}; + + float value = ${valueInit}; + for (int inChannelOffset = 0; inChannelOffset < ${inputChannelsPerGroup}; inChannelOffset++) { + int input_channel = group_id * ${inputChannelsPerGroup} + inChannelOffset; + for (int wWOff = 0; wWOff < ${wShape[2]}; wWOff++) { + for (int wHOff = 0; wHOff < ${wShape[3]}; wHOff++) { + ivec2 wOff = ivec2(wWOff * ${attributes.dilations[0]}, wHOff * ${attributes.dilations[1]}); + ivec2 wLoc = loc - wOff; + ivec2 wLocIn = wLoc / strides; + if ( + wLocIn * strides == wLoc && + wLocIn.x >= 0 && wLocIn.x < ${xShape[2]} && + wLocIn.y >= 0 && wLocIn.y < ${xShape[3]} + ) { + float xVal = getX(batch, input_channel, wLocIn.y, wLocIn.x); + float wVal = getW(input_channel, wOutChannel, wHOff, wWOff); + value += xVal * wVal; + } + } + } + } + ${applyActivation} + ${glsl.output} = vec4(value, .0, .0, .0); + } +`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource, + hasMain: true + }; + }; + createUnpackedConvTransposeProgramInfoLoader = (inferenceHandler, inputs, attributes) => { + const metadata = createConvTransposeProgramMetadata(inputs.length > 2, attributes.cacheKey); + return { + ...metadata, + get: () => createUnpackedConvTransposeProgramInfo(inferenceHandler, inputs, metadata, attributes) + }; + }; + convTranspose2DUnpacked = (inferenceHandler, inputs, attributes) => { + const result = inferenceHandler.run( + createUnpackedConvTransposeProgramInfoLoader(inferenceHandler, inputs, attributes), + inputs + ); + return result; + }; + getAdjustedConvTransposeAttributes = (attributes, inputs) => { + const kernelShape = attributes.kernelShape.slice(); + if (attributes.kernelShape.length === 0) { + for (let i = 2; i < inputs[1].dims.length; ++i) { + kernelShape.push(inputs[1].dims[i]); + } + } + const pads = attributes.pads.slice(); + const outputShape = attributes.outputShape.slice(); + const inputShape = inputs[0].dims; + calculateOutputShapeAndPads( + inputShape, + kernelShape, + attributes.dilations, + attributes.autoPad, + pads, + attributes.strides, + attributes.outputPadding, + outputShape + ); + const newAttributes = Object.assign({}, attributes); + Object.assign(newAttributes, { kernelShape, pads, outputShape, cacheKey: attributes.cacheKey }); + return newAttributes; + }; + parseConvTransposeAttributes = (node) => { + const attributes = node.attributes; + const activationAttributes = parseInternalActivationAttributes(attributes); + const autoPad = attributes.getString("auto_pad", "NOTSET"); + const dilations = attributes.getInts("dilations", [1, 1]); + const group = attributes.getInt("group", 1); + const kernelShape = attributes.getInts("kernel_shape", []); + const outputPadding = attributes.getInts("output_padding", [0, 0]); + const outputShape = attributes.getInts("output_shape", []); + const pads = attributes.getInts("pads", [0, 0, 0, 0]); + const strides = attributes.getInts("strides", [1, 1]); + return createAttributeWithCacheKey( + { autoPad, dilations, group, kernelShape, outputPadding, outputShape, pads, strides, ...activationAttributes } + ); + }; + validateInputs6 = (inputs, attributes) => { + if (!inputs || inputs.length !== 2 && inputs.length !== 3) { + throw new Error("Conv requires 2 or 3 inputs"); + } + if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) { + throw new Error("currently only support 2-dimensional conv"); + } + const dataChannel = inputs[0].dims[1]; + const filterInChannel = inputs[1].dims[0]; + if (dataChannel !== filterInChannel) { + throw new Error("FILTER_IN_CHANNEL should be equal to DATA_CHANNEL"); + } + const featureMaps = inputs[1].dims[1] * attributes.group; + if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[2].dims[0] !== featureMaps)) { + throw new Error("invalid bias"); + } + const spatialRank = inputs[0].dims.length - 2; + if (attributes.dilations.length !== spatialRank) { + throw new Error(`dilations should be ${spatialRank}D`); + } + if (attributes.strides.length !== spatialRank) { + throw new Error(`strides should be ${spatialRank}D`); + } + if (attributes.pads.length !== spatialRank * 2) { + throw new Error(`pads should be ${spatialRank * 2}D`); + } + if (attributes.outputPadding.length !== spatialRank) { + throw new Error(`output_padding should be ${spatialRank}D`); + } + if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) { + throw new Error("invalid kernel shape"); + } + if (attributes.outputShape.length !== 0 && attributes.outputShape.length !== inputs[0].dims.length - 2) { + throw new Error("invalid output shape"); + } + if (inputs[0].type !== "float32" || inputs[1].type !== "float32") { + throw new Error("ConvTranspose input(X,W) should be float tensor"); + } + if (inputs.length === 3 && inputs[2].type !== "float32") { + throw new Error("ConvTranspose input(bias) should be float tensor"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/transpose.ts +var transposeProgramMetadata, transpose, parseTransposeAttributes, createTransposeProgramInfo, getAdjustedPerm, getOutputShape, getPermFunctionBody, validateInputs7; +var init_transpose = __esm({ + "web/lib/onnxjs/backends/webgl/ops/transpose.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + transposeProgramMetadata = { + name: "Transpose", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + transpose = (inferenceHandler, inputs, attributes) => { + validateInputs7(inputs); + const output = inferenceHandler.run( + { + ...transposeProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createTransposeProgramInfo(inferenceHandler, inputs[0], attributes.perm) + }, + inputs + ); + return [output]; + }; + parseTransposeAttributes = (node) => createAttributeWithCacheKey({ perm: node.attributes.getInts("perm", []) }); + createTransposeProgramInfo = (_inferenceHandler, input, perm) => { + const inputShape = input.dims; + perm = getAdjustedPerm(inputShape, perm); + const unpackedOutputShape = getOutputShape(inputShape, perm); + const rank = inputShape.length; + const shaderSource = ` + ${getPermFunctionBody("perm", perm, rank)} + float process(int indices[${rank}]) { + int a[${rank}]; + perm(a, indices); + return _A(a); + }`; + return { + ...transposeProgramMetadata, + output: { dims: unpackedOutputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + getAdjustedPerm = (inputShape, perm) => { + if (perm && perm.length !== inputShape.length) { + perm = [...inputShape.keys()].reverse(); + } + return perm; + }; + getOutputShape = (inputShape, perm) => { + perm = getAdjustedPerm(inputShape, perm); + return ShapeUtil.sortBasedOnPerm(inputShape, perm); + }; + getPermFunctionBody = (name2, perm, rank) => { + const reverseFunc = []; + reverseFunc.push(`void ${name2}(out int a[${rank}], int src[${rank}]) {`); + for (let i = 0; i < rank; ++i) { + reverseFunc.push(` a[${perm[i]}]=src[${i}];`); + } + reverseFunc.push(" }"); + return reverseFunc.join("\n"); + }; + validateInputs7 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Transpose requires 1 input."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("input should be float tensor"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/depth-to-space.ts +var depthToSpace, parseDepthToSpaceAttributes, validateInputs8; +var init_depth_to_space = __esm({ + "web/lib/onnxjs/backends/webgl/ops/depth-to-space.ts"() { + "use strict"; + init_transpose(); + depthToSpace = (inferenceHandler, inputs, attributes) => { + validateInputs8(inputs); + const blocksize = attributes.blocksize; + const blocksizeSqr = blocksize * blocksize; + const transposePerm = attributes.mode === "DCR" ? [0, 3, 4, 1, 5, 2] : [0, 1, 4, 2, 5, 3]; + const firstReshapeShape = attributes.mode === "DCR" ? [ + inputs[0].dims[0], + blocksize, + blocksize, + inputs[0].dims[1] / blocksizeSqr, + inputs[0].dims[2], + inputs[0].dims[3] + ] : [ + inputs[0].dims[0], + inputs[0].dims[1] / blocksizeSqr, + blocksize, + blocksize, + inputs[0].dims[2], + inputs[0].dims[3] + ]; + const firstReshapedTensor = inferenceHandler.reshapeUnpacked(inputs[0], firstReshapeShape); + const transposeAttributes = { perm: transposePerm, cacheKey: `${transposePerm}` }; + const [transposeOutput] = transpose(inferenceHandler, [firstReshapedTensor], transposeAttributes); + const secondReshapeShape = [ + inputs[0].dims[0], + inputs[0].dims[1] / blocksizeSqr, + inputs[0].dims[2] * blocksize, + inputs[0].dims[3] * blocksize + ]; + const result = inferenceHandler.reshapeUnpacked(transposeOutput, secondReshapeShape); + return [result]; + }; + parseDepthToSpaceAttributes = (node) => { + const blocksize = node.attributes.getInt("blocksize"); + if (blocksize < 1) { + throw new Error(`blocksize must be >= 1, but got : ${blocksize} for DepthToSpace`); + } + const mode = node.attributes.getString("mode", "DCR"); + if (mode !== "DCR" && mode !== "CRD") { + throw new Error(`unrecognized mode: ${mode} for DepthToSpace`); + } + return { mode, blocksize }; + }; + validateInputs8 = (inputs) => { + if (inputs.length !== 1) { + throw new Error(`DepthToSpace expect 1 inputs, but got ${inputs.length}`); + } + if (inputs[0].type === "string" || inputs[0].dims.length !== 4) { + throw new TypeError("DepthToSpace input should be a 4-D numeric tensor"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/flatten.ts +var flatten, parseFlattenAttributes, validateInputs9; +var init_flatten = __esm({ + "web/lib/onnxjs/backends/webgl/ops/flatten.ts"() { + "use strict"; + init_util(); + flatten = (inferenceHandler, inputs, axis) => { + validateInputs9(inputs, axis); + const outputDims = ShapeUtil.flattenShape(inputs[0].dims, axis); + return [inferenceHandler.reshapeUnpacked(inputs[0], outputDims)]; + }; + parseFlattenAttributes = (node) => node.attributes.getInt("axis", 1); + validateInputs9 = (inputs, axis) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Flatten requires 1 input."); + } + const r = inputs[0].dims.length; + if (r === 0) { + throw new Error("scalar tensor is not supported."); + } + if (axis < -r || axis > r) { + throw new Error("Invalid axis"); + } + if (inputs[0].type === "string") { + throw new Error("string tensor is not supported."); + } + }; + } +}); + +// web/lib/onnxjs/operators.ts +var NUMBER_TYPES; +var init_operators = __esm({ + "web/lib/onnxjs/operators.ts"() { + "use strict"; + NUMBER_TYPES = ["float32", "float64", "int32", "int16", "int8", "uint16", "uint32", "uint8"]; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/gather.ts +var gather, parseGatherAttributes, gatherProgramMetadata, createGatherProgramInfo, createGatherProgramInfoLoader, validateInputs10; +var init_gather = __esm({ + "web/lib/onnxjs/backends/webgl/ops/gather.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_operators(); + init_util(); + init_types(); + gather = (inferenceHandler, inputs, attributes) => { + validateInputs10(inputs, attributes.axis); + const output = inferenceHandler.run(createGatherProgramInfoLoader(inferenceHandler, inputs, attributes), inputs); + return [output]; + }; + parseGatherAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis", 0) }); + gatherProgramMetadata = { + name: "Gather", + inputNames: ["A", "B"], + inputTypes: [0 /* unpacked */, 0 /* unpacked */] + }; + createGatherProgramInfo = (_handler, metadata, inputs, axis) => { + const inputShape = inputs[0].dims.slice(); + const indexDataShape = inputs[1].dims.slice(); + const outputShape = new Array(inputShape.length + indexDataShape.length - 1); + axis = ShapeUtil.normalizeAxis(axis, inputShape.length); + const indexCopyOps = []; + for (let i = 0; i < outputShape.length; i++) { + if (i < axis) { + outputShape[i] = inputShape[i]; + indexCopyOps.push(`inputIdx[${i}] = outputIdx[${i}];`); + } else { + if (i < axis + indexDataShape.length) { + outputShape[i] = indexDataShape[i - axis]; + indexCopyOps.push(`indexDataIdx[${i - axis}] = outputIdx[${i}];`); + } else { + outputShape[i] = inputShape[i - indexDataShape.length + 1]; + indexCopyOps.push(`inputIdx[${i - indexDataShape.length + 1}] = outputIdx[${i}];`); + } + } + } + const orank = outputShape.length || 1; + const irank = inputShape.length; + const iDrank = indexDataShape.length || 1; + const shaderSource = ` + float process(int outputIdx[${orank}]) { + int inputIdx[${irank}]; + int indexDataIdx[${iDrank}]; + indexDataIdx[0] = 0; + ${indexCopyOps.join("\n ")} + int idx = int(_B(indexDataIdx)); + inputIdx[${axis}] = idx < 0 ? idx + ${inputShape[axis]} : idx; + return _A(inputIdx); + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createGatherProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = { ...gatherProgramMetadata, cacheHint: attributes.cacheKey }; + return { ...metadata, get: () => createGatherProgramInfo(handler, metadata, inputs, attributes.axis) }; + }; + validateInputs10 = (inputs, axis) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Gather requires 2 inputs."); + } + const tensorRank = inputs[0].dims.length; + if (tensorRank < 1) { + throw new Error("Invalid input shape."); + } + if (axis < -tensorRank || axis > tensorRank - 1) { + throw new Error("Invalid axis."); + } + if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { + throw new Error("Invaid input type."); + } + if (inputs[1].type !== "int32" && inputs[1].type !== "int16") { + throw new Error("Invaid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/gemm.ts +var gemm, parseGemmAttributes, parseGemmAttributesV7, parseGemmAttributesV11, createGemmProgramInfoLoader, createGemmProgramInfo, validateInputs11; +var init_gemm = __esm({ + "web/lib/onnxjs/backends/webgl/ops/gemm.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + gemm = (inferenceHandler, inputs, attributes) => { + validateInputs11(inputs, attributes); + const output = inferenceHandler.run(createGemmProgramInfoLoader(inputs, attributes), inputs); + return [output]; + }; + parseGemmAttributes = (node, isOptionalC) => { + const transA = node.attributes.getInt("transA", 0) !== 0; + const transB = node.attributes.getInt("transB", 0) !== 0; + const alpha = node.attributes.getFloat("alpha", 1); + const beta = node.attributes.getFloat("beta", 1); + return createAttributeWithCacheKey({ transA, transB, alpha, beta, isOptionalC }); + }; + parseGemmAttributesV7 = (node) => parseGemmAttributes(node, false); + parseGemmAttributesV11 = (node) => parseGemmAttributes(node, true); + createGemmProgramInfoLoader = (inputs, attributes) => { + const metadata = { + name: "Gemm", + inputNames: inputs.length === 3 ? ["A", "B", "C"] : ["A", "B"], + inputTypes: inputs.length === 3 ? [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] : [0 /* unpacked */, 0 /* unpacked */], + key: attributes.cacheKey + }; + return { ...metadata, get: () => createGemmProgramInfo(metadata, inputs, attributes) }; + }; + createGemmProgramInfo = (metadata, inputs, attributes) => { + const aShape = inputs[0].dims.slice(); + const bShape = inputs[1].dims.slice(); + const [M, N] = GemmUtil.getShapeOfGemmResult( + aShape, + attributes.transA, + bShape, + attributes.transB, + inputs.length === 3 ? inputs[2].dims : void 0 + ); + const outputShape = [M, N]; + if (!outputShape) { + throw new Error("Can't use gemm on the given tensors"); + } + let sharedDim = aShape[aShape.length - 1]; + let line = ""; + if (attributes.transA) { + sharedDim = aShape[0]; + } + if (attributes.transA && attributes.transB) { + line = "value += _A_T(a) * _B_T(b);"; + } else if (attributes.transA && !attributes.transB) { + line = "value += _A_T(a) * _B(b);"; + } else if (!attributes.transA && attributes.transB) { + line = "value += _A(a) * _B_T(b);"; + } else if (!attributes.transA && !attributes.transB) { + line = "value += _A(a) * _B(b);"; + } + const rank = outputShape.length; + const declareC = inputs.length === 3 ? `int c[${inputs[2].dims.length}];` : ""; + const broadcastC = inputs.length === 3 ? "bcastIndices_C(indices, c);" : ""; + const calculateC = inputs.length === 3 ? "value += beta * _C(c);" : ""; + const shaderSource = ` + float process(int indices[${rank}]) { + int a[${rank}]; + int b[${rank}]; + ${declareC} + + copyVec(indices, a); + copyVec(indices, b); + ${broadcastC} + + float value = 0.0; + for (int k=0; k<${sharedDim}; ++k) { + a[${rank - 1}] = k; + b[${rank - 2}] = k; + ${line} + } + + value = value * alpha; + ${calculateC} + return value; + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + variables: [ + { name: "alpha", type: "float", data: attributes.alpha }, + { name: "beta", type: "float", data: attributes.beta } + ], + shaderSource + }; + }; + validateInputs11 = (inputs, attributes) => { + if (!inputs) { + throw new Error("Input is missing"); + } + if (attributes.isOptionalC && (inputs.length < 2 || inputs.length > 3)) { + throw new Error("Invaid input shape."); + } + if (!attributes.isOptionalC && inputs.length !== 3) { + throw new Error("Gemm requires 3 inputs"); + } + if (inputs.length === 3 && inputs[2].dims.length !== 1 && inputs[2].dims.length !== 2) { + throw new Error("Invalid input shape of C"); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64" || inputs[1].type !== "float32" && inputs[1].type !== "float64" || inputs.length === 3 && inputs[2].type !== "float32" && inputs[2].type !== "float64") { + throw new Error("Invalid input type."); + } + if (inputs[0].type !== inputs[1].type || inputs.length === 3 && inputs[0].type !== inputs[2].type) { + throw new Error("Input types are mismatched"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/image-scaler.ts +var imageScaler, parseImageScalerAttributes, imageScalerProgramMetadata, createImageScalerProgramInfo, createImageScalerProgramInfoLoader, createGetBiasMethod, validateInputs12; +var init_image_scaler = __esm({ + "web/lib/onnxjs/backends/webgl/ops/image-scaler.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_types(); + imageScaler = (inferenceHandler, inputs, attributes) => { + validateInputs12(inputs); + const output = inferenceHandler.run(createImageScalerProgramInfoLoader(inferenceHandler, inputs, attributes), inputs); + return [output]; + }; + parseImageScalerAttributes = (node) => { + const scale = node.attributes.getFloat("scale"); + const bias = node.attributes.getFloats("bias"); + return createAttributeWithCacheKey({ scale, bias }); + }; + imageScalerProgramMetadata = { + name: "ImageScaler", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + createImageScalerProgramInfo = (_handler, metadata, inputs, attributes) => { + const outputShape = inputs[0].dims.slice(); + const rank = outputShape.length; + const getBiasMethod = createGetBiasMethod(attributes.bias.length); + const shaderSource = ` + ${getBiasMethod} + float process(int indices[${rank}]) { + return _X(indices) * scale + getBias(bias, indices[1]); + }`; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + variables: [ + { name: "bias", type: "float", arrayLength: attributes.bias.length, data: attributes.bias }, + { name: "scale", type: "float", data: attributes.scale } + ], + shaderSource + }; + }; + createImageScalerProgramInfoLoader = (handler, inputs, attributes) => { + const metadata = { ...imageScalerProgramMetadata, cacheHint: attributes.cacheKey }; + return { ...metadata, get: () => createImageScalerProgramInfo(handler, metadata, inputs, attributes) }; + }; + createGetBiasMethod = (numChannels) => { + const codeLines = [`float getBias(float bias[${numChannels}], int channel) {`]; + for (let i = 0; i < numChannels; ++i) { + if (i === 0) { + codeLines.push( + ` if (channel == ${i}) { return bias[${i}]; }` + ); + } else if (i === numChannels - 1) { + codeLines.push( + ` else { return bias[${i}]; }` + ); + } else { + codeLines.push( + ` else if (channel == ${i}) { return bias[${i}]; }` + ); + } + } + codeLines.push( + " }" + ); + return codeLines.join("\n"); + }; + validateInputs12 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("ImageScaler requires 1 input."); + } + if (inputs[0].dims.length !== 4) { + throw new Error("Invalid input shape."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/instance-normalization.ts +var instanceNormalization, parseInstanceNormalizationAttributes, meanAndVarianceProgramMetadata, createMeanAndVarianceProgramInfo, createMeanAndVarianceProgramInfoLoader, computeOutputProgramMetadata, createComputeOutputProgramInfo, createComputeOutputProgramInfoLoader, validateInputs13; +var init_instance_normalization = __esm({ + "web/lib/onnxjs/backends/webgl/ops/instance-normalization.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + instanceNormalization = (inferenceHandler, inputs, epsilon) => { + validateInputs13(inputs); + const meanAndVariance = inferenceHandler.run(createMeanAndVarianceProgramInfoLoader(inputs[0]), inputs); + const output = inferenceHandler.run( + createComputeOutputProgramInfoLoader(inferenceHandler, inputs[0], epsilon, meanAndVariance.dims), + [inputs[0], meanAndVariance, inputs[1], inputs[2]] + ); + return [output]; + }; + parseInstanceNormalizationAttributes = (node) => node.attributes.getFloat("epsilon", 1e-5); + meanAndVarianceProgramMetadata = { + name: "InstanceNormalization_MeanAndVariance", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + createMeanAndVarianceProgramInfo = (metadata, input) => { + const xDims = input.dims.slice(); + const channel = xDims[1]; + const channelSize = xDims[2] * xDims[3]; + const outputShape = [xDims[0], channel]; + const shaderSource = ` + vec4 process(int[2] indices) { + vec4 v = vec4(0.0); + int a[4]; + a[0] = indices[0]; + a[1] = indices[1]; + float temp = 0.0; + for(int a2=0; a2<${xDims[2]}; a2++) { + a[2] = a2; + for(int a3=0; a3<${xDims[3]}; a3++) { + a[3] = a3; + float x = _X(a); + temp += x; + } + } + float mean = temp / float(${channelSize}); + temp = 0.0; + for(int a2=0; a2<${xDims[2]}; a2++) { + a[2] = a2; + for(int a3=0; a3<${xDims[3]}; a3++) { + a[3] = a3; + float x = _X(a); + temp += (x - mean) * (x - mean); + } + } + v.r = mean; + v.g = temp / float(${channelSize}); + + return v; + }`; + return { + ...metadata, + output: { dims: outputShape, type: input.type, textureType: 4 /* packedLastDimension */ }, + shaderSource + }; + }; + createMeanAndVarianceProgramInfoLoader = (input) => ({ + ...meanAndVarianceProgramMetadata, + get: () => createMeanAndVarianceProgramInfo(meanAndVarianceProgramMetadata, input) + }); + computeOutputProgramMetadata = { + name: "InstanceNormalization_ComputeOutput", + inputNames: ["X", "MeanAndVariance", "Scale", "B"], + inputTypes: [0 /* unpacked */, 4 /* packedLastDimension */, 0 /* unpacked */, 0 /* unpacked */] + }; + createComputeOutputProgramInfo = (inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight(meanAndVarianceShape, 4 /* packedLastDimension */); + const [meanAndVarianceWidth, meanAndVarianceHeight] = [textureWidth / 4, textureHeight]; + const shaderSource = ` + vec4 get_MeanAndVariance(int[2] mv) { + int offset = indicesToOffset_MeanAndVariance(mv); + vec2 coords = offsetToCoords(offset, ${meanAndVarianceWidth}, ${meanAndVarianceHeight}); + return ${glsl.texture2D}(MeanAndVariance, coords); + } + + float process(int[4] indices) { + int mv[2]; + mv[0] = indices[0]; + mv[1] = indices[1]; + vec4 mean_and_variance = get_MeanAndVariance(mv); + float mean = mean_and_variance.r; + float variance = mean_and_variance.g; + + int sb[1]; + sb[0] = indices[1]; + float scale = _Scale(sb); + float b = _B(sb); + + return scale * (_X(indices) - mean) / sqrt(variance + epsilon) + b; + }`; + return { + ...metadata, + output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, + variables: [{ name: "epsilon", type: "float", data: epsilon }], + shaderSource + }; + }; + createComputeOutputProgramInfoLoader = (inferenceHandler, input, epsilon, meanAndVarianceShape) => { + const metadata = { ...computeOutputProgramMetadata, cacheHint: `${epsilon}` }; + return { + ...metadata, + get: () => createComputeOutputProgramInfo(inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) + }; + }; + validateInputs13 = (inputs) => { + if (!inputs || inputs.length !== 3) { + throw new Error("InstanceNormalization requires 3 inputs."); + } + const X = inputs[0]; + const scale = inputs[1]; + const B = inputs[2]; + if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1) { + throw new Error("Invalid input shape."); + } + if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1]) { + throw new Error("Input shapes are mismatched."); + } + if (X.type !== "float32" && X.type !== "float64" || scale.type !== "float32" && scale.type !== "float64" || B.type !== "float32" && B.type !== "float64") { + throw new Error("Invalid input type."); + } + if (inputs[0].dims.length !== 4) { + throw new Error("Only support 4-D input shape."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/lrn.ts +function createLrnProgramInfo(inputs, attributes) { + const C = inputs[0].dims[1]; + const rank = inputs[0].dims.length; + const from = -Math.floor((attributes.size - 1) / 2); + const to = Math.ceil((attributes.size - 1) / 2); + const alpha = `float(${attributes.alpha}) / float(${attributes.size})`; + const bias = `float(${attributes.bias})`; + const beta = `float(${attributes.beta})`; + const shaderSource = ` + float process(int indices[${rank}]) { + int c = indices[1]; + float x = _X(indices); + float square_sum = 0.0; + + for (int i = ${from}; i <= ${to}; i++) { + int idx = c + i; + if (c >= 0 && c < ${C}) { + indices[1] = idx; + float j = _X(indices); + square_sum += j * j; + } + } + return x / pow(${bias} + ${alpha} * square_sum, ${beta}); + }`; + return { + ...lrnProgramMetadata, + cacheHint: attributes.cacheKey, + output: { dims: inputs[0].dims, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; +} +function createLrnProgramInfoLoader(inputs, attributes) { + return { ...lrnProgramMetadata, cacheHint: attributes.cacheKey, get: () => createLrnProgramInfo(inputs, attributes) }; +} +var lrn, parseLrnAttributes, lrnProgramMetadata, validateInputs14; +var init_lrn = __esm({ + "web/lib/onnxjs/backends/webgl/ops/lrn.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_types(); + lrn = (inferenceHandler, inputs, attributes) => { + validateInputs14(inputs); + return [inferenceHandler.run(createLrnProgramInfoLoader(inputs, attributes), inputs)]; + }; + parseLrnAttributes = (node) => { + const alpha = node.attributes.getFloat("alpha", 1e-4); + const beta = node.attributes.getFloat("beta", 0.75); + const bias = node.attributes.getFloat("bias", 1); + const size = node.attributes.getInt("size"); + return createAttributeWithCacheKey({ alpha, beta, bias, size }); + }; + lrnProgramMetadata = { + name: "LRN", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + validateInputs14 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("LRN requires 1 input."); + } + if (inputs[0].dims.length !== 4) { + throw new Error('currently only support LRN for input with "NCHW" format'); + } + if (inputs[0].type !== "float32") { + throw new Error("input should be float type"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/pad.ts +var padProgramMetadata, padV2, parsePadAttributesV2, padV11, parsePadAttributesV11, generatePadAttributesFromInputs, createPadProgramInfo, validateInputsV2, validateInputsV11, getPadFunction, getPadConstant, getPadReflect, getPadEdge; +var init_pad = __esm({ + "web/lib/onnxjs/backends/webgl/ops/pad.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_glsl_source(); + init_types(); + padProgramMetadata = { + name: "Pad", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + padV2 = (inferenceHandler, inputs, attributes) => { + validateInputsV2(inputs); + const output = inferenceHandler.run( + { + ...padProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createPadProgramInfo(inferenceHandler, inputs[0], attributes) + }, + inputs + ); + return [output]; + }; + parsePadAttributesV2 = (node) => { + const mode = node.attributes.getString("mode", "constant"); + const value = node.attributes.getFloat("value", 0); + const pads = node.attributes.getInts("pads"); + return createAttributeWithCacheKey({ mode, value, pads }); + }; + padV11 = (inferenceHandler, inputs, mode) => { + validateInputsV11(inputs); + const attrubutes = generatePadAttributesFromInputs(inferenceHandler, inputs, mode); + return padV2(inferenceHandler, [inputs[0]], attrubutes); + }; + parsePadAttributesV11 = (node) => node.attributes.getString("mode", "constant"); + generatePadAttributesFromInputs = (inferenceHandler, inputs, mode) => { + if (!inferenceHandler.session.isInitializer(inputs[1].dataId) || inputs.length >= 3 && !inferenceHandler.session.isInitializer(inputs[2].dataId)) { + throw new Error("dynamic pad attributes are not allowed"); + } + const pads = Array.from(inputs[1].integerData); + const value = inputs.length >= 3 ? inputs[2].floatData[0] : 0; + return createAttributeWithCacheKey({ mode, pads, value }); + }; + createPadProgramInfo = (inferenceHandler, input, attributes) => { + const outputShape = ShapeUtil.padShape(input.dims.slice(), attributes.pads); + const rank = outputShape.length; + const padFunction = getPadFunction(inferenceHandler, input, attributes); + const shaderSource = ` + ${padFunction} + float process(int[${rank}] indices) { + return padA(indices); + }`; + return { + name: "Pad", + inputNames: ["A"], + inputTypes: [0 /* unpacked */], + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputsV2 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Pad requires 1 input"); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + }; + validateInputsV11 = (inputs) => { + if (!inputs || inputs.length !== 2 && inputs.length !== 3) { + throw new Error("Pad requires 2 or 3 inputs"); + } + if (inputs[1].type !== "int32") { + throw new Error("Invalid input type."); + } + if (inputs.length >= 3 && inputs[2].type === "string") { + throw new Error("Invalid input type."); + } + }; + getPadFunction = (inferenceHandler, input, attributes) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const [width, height] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, 0 /* unpacked */); + const strides = ShapeUtil.computeStrides(input.dims); + switch (attributes.mode) { + case "constant": + return getPadConstant(glsl, input.dims, strides, width, height, attributes.pads, attributes.value); + case "reflect": + return getPadReflect(glsl, input.dims, strides, width, height, attributes.pads); + case "edge": + return getPadEdge(glsl, input.dims, strides, width, height, attributes.pads); + default: + throw new Error("Invalid mode"); + } + }; + getPadConstant = (glsl, shape2, strides, width, height, pads, value) => { + const rank = shape2.length; + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + k = m[${i}] - ${pads[i]}; + if (k < 0) return constant; + if (k >= ${shape2[i]}) return constant; + offset += k * ${strides[i]}; + `; + } + return ` + float padA(int m[${rank}]) { + const float constant = float(${value}); + int offset = 0; + int k = 0; + ${block} + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(A, coords)); + return value; + } + `; + }; + getPadReflect = (glsl, shape2, strides, width, height, pads) => { + const rank = shape2.length; + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + k = m[${i}] - ${pads[i]}; + if (k < 0) { k = -k; } + { + const int _2n_1 = ${2 * (shape2[i] - 1)}; + k = int( mod( float(k), float(_2n_1) ) ) ; + if(k >= ${shape2[i]}) { k = _2n_1 - k; } + } + offset += k * ${strides[i]}; + `; + } + return ` + float padA(int m[${rank}]) { + int offset = 0; + int k = 0; + ${block} + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(A, coords)); + return value; + } + `; + }; + getPadEdge = (glsl, shape2, strides, width, height, pads) => { + const rank = shape2.length; + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + k = m[${i}] - ${pads[i]}; + if (k < 0) k = 0; + if (k >= ${shape2[i]}) k = ${shape2[i] - 1}; + offset += k * ${strides[i]}; + `; + } + return ` + float padA(int m[${rank}]) { + int offset = 0; + int k = 0; + ${block} + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(A, coords)); + return value; + } + `; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/pool.ts +var averagePool, parseAveragePoolAttributes, createAveragePoolProgramInfo, globalAveragePool, parseGlobalAveragePoolAttributes, maxPool, parseMaxPoolAttributes, createMaxPoolProgramInfo, getAdjustedPoolAttributesAndOutputShape, globalMaxPoolAttributes, globalMaxPoolMetadata, globalMaxPool, validateInputs15, generatePoolingCode, copyArray, offsetToIndices; +var init_pool = __esm({ + "web/lib/onnxjs/backends/webgl/ops/pool.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + averagePool = (inferenceHandler, inputs, attributes) => { + validateInputs15(inputs); + const metadata = { name: "AveragePool", inputNames: ["X"], inputTypes: [0 /* unpacked */], cacheHint: attributes.cacheKey }; + const output = inferenceHandler.run( + { ...metadata, get: () => createAveragePoolProgramInfo(inputs, metadata, false, attributes) }, + inputs + ); + return [output]; + }; + parseAveragePoolAttributes = (node) => { + const autoPad = node.attributes.getString("auto_pad", "NOTSET"); + const ceilMode = node.attributes.getInt("ceil_mode", 0); + const countIncludePad = node.attributes.getInt("count_include_pad", 0) === 0 ? false : true; + const kernelShape = node.attributes.getInts("kernel_shape"); + const strides = node.attributes.getInts("strides", []); + const pads = node.attributes.getInts("pads", []); + if (ceilMode !== 0) { + throw new Error("using ceil() in shape computation is not yet supported for AveragePool"); + } + return createAttributeWithCacheKey({ autoPad, ceilMode, countIncludePad, kernelShape, strides, pads }); + }; + createAveragePoolProgramInfo = (inputs, metadata, isGlobalOperator, attributes) => { + const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape(inputs, attributes, isGlobalOperator); + const kernelSize = ShapeUtil.size(adjustedAttributes.kernelShape); + const op1 = "value += _X(x);"; + let op2 = ""; + if (adjustedAttributes.countIncludePad) { + op2 += `value /= float(${kernelSize});`; + } else { + op2 += `value /= float(${kernelSize} - pad);`; + } + const poolingCode = generatePoolingCode(inputs[0].dims, adjustedAttributes, op1, op2, "0.0"); + const shaderSource = ` + ${poolingCode} + `; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + globalAveragePool = (inferenceHandler, inputs, attributes) => { + validateInputs15(inputs); + const metadata = { + name: "GlobalAveragePool", + inputNames: ["X"], + inputTypes: [0 /* unpacked */], + cacheHint: `${attributes.countIncludePad}` + }; + const output = inferenceHandler.run( + { ...metadata, get: () => createAveragePoolProgramInfo(inputs, metadata, true, attributes) }, + inputs + ); + return [output]; + }; + parseGlobalAveragePoolAttributes = (node) => { + const countIncludePad = node.attributes.getInt("count_include_pad", 0) === 0 ? false : true; + return createAttributeWithCacheKey( + { autoPad: "", ceilMode: 0, countIncludePad, kernelShape: [], strides: [], pads: [] } + ); + }; + maxPool = (inferenceHandler, inputs, attributes) => { + validateInputs15(inputs); + const metadata = { name: "MaxPool", inputNames: ["X"], inputTypes: [0 /* unpacked */], cacheHint: attributes.cacheKey }; + const output = inferenceHandler.run( + { ...metadata, get: () => createMaxPoolProgramInfo(inputs, metadata, false, attributes) }, + inputs + ); + return [output]; + }; + parseMaxPoolAttributes = (node) => { + const autoPad = node.attributes.getString("auto_pad", "NOTSET"); + const ceilMode = node.attributes.getInt("ceil_mode", 0); + const kernelShape = node.attributes.getInts("kernel_shape"); + const strides = node.attributes.getInts("strides", []); + const pads = node.attributes.getInts("pads", []); + const storageOrder = node.attributes.getInt("storage_order", 0); + const dilations = node.attributes.getInts("dilations", []); + if (storageOrder !== 0) { + throw new Error("column major storage order is not yet supported for MaxPool"); + } + if (ceilMode !== 0) { + throw new Error("using ceil() in shape computation is not yet supported for MaxPool"); + } + return createAttributeWithCacheKey( + { autoPad, ceilMode, countIncludePad: false, kernelShape, strides, pads, storageOrder, dilations } + ); + }; + createMaxPoolProgramInfo = (inputs, metadata, isGlobalOperator, attributes) => { + const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape(inputs, attributes, isGlobalOperator); + const op1 = ` + value = max(_X(x), value); + `; + const op2 = ""; + const poolingCode = generatePoolingCode(inputs[0].dims, adjustedAttributes, op1, op2, "-1e5"); + const shaderSource = ` + ${poolingCode} + `; + return { + ...metadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + getAdjustedPoolAttributesAndOutputShape = (inputs, attributes, isGlobalOperator) => { + const inputShape = inputs[0].dims.slice(); + const hasDilations = Object.hasOwnProperty.call(attributes, "dilations"); + const kernelShape = attributes.kernelShape.slice(); + const strides = attributes.strides.slice(); + const dilations = hasDilations ? attributes.dilations.slice() : []; + const pads = attributes.pads.slice(); + PoolConvUtil.adjustPoolAttributes(isGlobalOperator, inputShape, kernelShape, strides, dilations, pads); + const outputShape = PoolConvUtil.computePoolOutputShape( + isGlobalOperator, + inputShape, + strides, + dilations, + kernelShape, + pads, + attributes.autoPad + ); + const newAttributes = Object.assign({}, attributes); + if (hasDilations) { + Object.assign(newAttributes, { kernelShape, strides, pads, dilations, cacheKey: attributes.cacheKey }); + } else { + Object.assign(newAttributes, { kernelShape, strides, pads, cacheKey: attributes.cacheKey }); + } + return [newAttributes, outputShape]; + }; + globalMaxPoolAttributes = { + autoPad: "", + ceilMode: 0, + countIncludePad: false, + kernelShape: [], + strides: [], + pads: [], + storageOrder: 0, + dilations: [], + cacheKey: "" + }; + globalMaxPoolMetadata = { + name: "GlobalMaxPool", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + globalMaxPool = (inferenceHandler, inputs) => { + validateInputs15(inputs); + const output = inferenceHandler.run( + { + ...globalMaxPoolMetadata, + get: () => createMaxPoolProgramInfo(inputs, globalMaxPoolMetadata, true, globalMaxPoolAttributes) + }, + inputs + ); + return [output]; + }; + validateInputs15 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Pool ops requires 1 input."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + }; + generatePoolingCode = (inputDims, attributes, op1, op2, start) => { + const rank = inputDims.length; + if (attributes.kernelShape.length <= 2) { + const kw = attributes.kernelShape[attributes.kernelShape.length - 1]; + const sw = attributes.strides[attributes.strides.length - 1]; + const pwStart = attributes.pads[attributes.pads.length / 2 - 1]; + const pwEnd = attributes.pads[attributes.pads.length - 1]; + const dimW = inputDims[rank - 1]; + let codeW = ""; + let codeH = ""; + let codeHEnd = ""; + if (pwStart + pwEnd !== 0) { + codeW = ` + for (int i = 0; i < ${kw}; i++) { + x[${rank} - 1] = indices[${rank} - 1] * ${sw} - ${pwStart} + i; + if (x[${rank} - 1] < 0 || x[${rank} - 1] >= ${dimW}) { + pad++; + continue; + } + ${op1} + }`; + } else { + codeW = ` + for (int i = 0; i < ${kw}; i++) { + x[${rank} - 1] = indices[${rank} - 1] * ${sw} - ${pwStart} + i; + ${op1} + }`; + } + if (attributes.kernelShape.length === 2) { + const kh = attributes.kernelShape[attributes.kernelShape.length - 2]; + const sh = attributes.strides[attributes.strides.length - 2]; + const phStart = attributes.pads[attributes.pads.length / 2 - 2]; + const phEnd = attributes.pads[attributes.pads.length - 2]; + const dimH = inputDims[rank - 2]; + if (phStart + phEnd !== 0) { + codeH = ` + for (int j = 0; j < ${kh}; j++) { + x[${rank} - 2] = indices[${rank} - 2] * ${sh} - ${phStart} + j; + if (x[${rank} - 2] < 0 || x[${rank} - 2] >= ${dimH}) { + pad+= ${kw}; + continue; + } + `; + } else { + codeH = ` + for (int j = 0; j < ${kh}; j++) { + x[${rank} - 2] = indices[${rank} - 2] * ${sh} - ${phStart} + j; + `; + } + codeHEnd = ` + } + `; + } + const poolingCode = ` + float process(int indices[${rank}]) { + int x[${rank}]; + copyVec(indices, x); + + float value = ${start}; + int pad = 0; + ${codeH} + ${codeW} + ${codeHEnd} + ${op2} + return value; + } + `; + return poolingCode; + } else { + const kernelSize = ShapeUtil.size(attributes.kernelShape); + const kernelStrides = ShapeUtil.computeStrides(attributes.kernelShape); + const stridesRank = kernelStrides.length; + const padsRank = attributes.pads.length; + const offsetToIndicesFunction = offsetToIndices(stridesRank); + const copyInputDims = copyArray(inputDims, "inputDims"); + const copyPads = copyArray(attributes.pads, "pads"); + const copyKernelStrides = copyArray(kernelStrides, "kernelStrides"); + const copyStrides = copyArray(attributes.strides, "strides"); + const hasPads = attributes.pads.reduce((sum2, cur) => sum2 + cur); + let padCode = ""; + if (hasPads) { + padCode = ` + if (x[j] >= inputDims[j] || x[j] < 0) { + pad++; + isPad = true; + break; + } + } + if (!isPad) { + ${op1} + }`; + } else { + padCode = ` + } + ${op1} + `; + } + const poolingCode = ` + ${offsetToIndicesFunction} + float process(int indices[${rank}]) { + int x[${rank}]; + copyVec(indices, x); + int offset[${stridesRank}]; + int pads[${padsRank}]; + int inputDims[${rank}]; + int kernelStrides[${stridesRank}]; + int strides[${stridesRank}]; + ${copyPads} + ${copyInputDims} + ${copyStrides} + ${copyKernelStrides} + + float value = ${start}; + int pad = 0; + bool isPad = false; + for (int i = 0; i < ${kernelSize}; i++) { + offsetToIndices(i, kernelStrides, offset); + isPad = false; + for (int j = ${rank} - ${stridesRank}; j < ${rank}; j++) { + x[j] = indices[j] * strides[j - ${rank} + ${stridesRank}] + + offset[j - ${rank} + ${stridesRank}] - pads[j - 2]; + ${padCode} + } + ${op2} + + return value; + } + `; + return poolingCode; + } + }; + copyArray = (array, arrayName) => { + let block = ""; + for (let i = 0; i < array.length; i++) { + block += ` + ${arrayName}[${i}] = ${array[i]}; + `; + } + return block; + }; + offsetToIndices = (rank) => ` + void offsetToIndices(int offset, int[${rank}] strides, out int[${rank}] indices) { + if (${rank} == 0) { + return; + } + for (int i = 0; i < ${rank} - 1; ++i) { + indices[i] = offset / strides[i]; + offset -= indices[i] * strides[i]; + } + indices[${rank} - 1] = offset; + }`; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/reduce.ts +var reduce, parseReduceAttributes, createReduceProgramInfo, validateInputs16, reduceSum, reduceMean, reduceMax, reduceMin, reduceProd, reduceLogSum, reduceLogSumSquare; +var init_reduce = __esm({ + "web/lib/onnxjs/backends/webgl/ops/reduce.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_operators(); + init_util(); + init_types(); + reduce = (inferenceHandler, inputs, attributes, name2, reduceOp) => { + validateInputs16(inputs); + const reduceProgramMetadata = { + name: name2, + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + const output = inferenceHandler.run( + { + ...reduceProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createReduceProgramInfo(inferenceHandler, inputs, attributes, name2, reduceOp, reduceProgramMetadata) + }, + inputs + ); + return [output]; + }; + parseReduceAttributes = (node) => { + const axes = node.attributes.getInts("axes", []); + const keepDims = node.attributes.getInt("keepdims", 1) === 1; + return createAttributeWithCacheKey({ axes, keepDims }); + }; + createReduceProgramInfo = (_handler, inputs, attributes, _name, reduceOp, reduceProgramMetadata) => { + const outputShape = []; + const iRank = inputs[0].dims.length || 1; + const idxCopy = []; + const axes = ShapeUtil.normalizeAxes(attributes.axes, inputs[0].dims.length); + const ops = reduceOp(inputs, axes); + let reduceOps = ops[1]; + for (let k = 0; k < inputs[0].dims.length; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + if (attributes.keepDims) { + outputShape.push(1); + } + reduceOps = ` + for(int j${k} = 0; j${k} < ${inputs[0].dims[k]}; j${k}++) { + inputIdx[${k}] = j${k}; + ${reduceOps} + }`; + } else { + idxCopy.push(`inputIdx[${k}] = outputIdx[${outputShape.length}];`); + outputShape.push(inputs[0].dims[k]); + } + } + const oRank = outputShape.length || 1; + const shaderSource = ` + float process(int outputIdx[${oRank}]) { + float value; // final result + int inputIdx[${iRank}]; // addressing input data + ${idxCopy.join("\n")} + ${ops[0]} // init ops for reduce max/min + ${reduceOps} + ${ops[2]} // final computation for reduce mean + return value; + }`; + return { + ...reduceProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs16 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Reduce op requires 1 input."); + } + if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { + throw new Error("Invalid input type."); + } + }; + reduceSum = (inferenceHandler, inputs, attributes) => { + const reduceOp = () => ["value = 0.0;", "value += _A(inputIdx);", ""]; + return reduce(inferenceHandler, inputs, attributes, "ReduceSum", reduceOp); + }; + reduceMean = (inferenceHandler, inputs, attributes) => { + const reduceOp = (inputs2, axes) => { + let size = 1; + for (let k = 0; k < inputs2[0].dims.length; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + size *= inputs2[0].dims[k]; + } + } + return ["value = 0.0;", "value += _A(inputIdx);", `value /= ${size}.;`]; + }; + return reduce(inferenceHandler, inputs, attributes, "ReduceMean", reduceOp); + }; + reduceMax = (inferenceHandler, inputs, attributes) => { + const reduceOp = (inputs2, axes) => { + const idxZero = []; + for (let k = 0; k < inputs2[0].dims.length; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + idxZero.push(`inputIdx[${k}] = 0;`); + } + } + return [`${idxZero.join("\n")} +value = _A(inputIdx);`, "value = max(value, _A(inputIdx));", ""]; + }; + return reduce(inferenceHandler, inputs, attributes, "ReduceMax", reduceOp); + }; + reduceMin = (inferenceHandler, inputs, attributes) => { + const reduceOp = (inputs2, axes) => { + const idxZero = []; + for (let k = 0; k < inputs2[0].dims.length; k++) { + if (axes.indexOf(k) >= 0 || axes.length === 0) { + idxZero.push(`inputIdx[${k}] = 0;`); + } + } + return [`${idxZero.join("\n")} +value = _A(inputIdx);`, "value = min(value, _A(inputIdx));", ""]; + }; + return reduce(inferenceHandler, inputs, attributes, "ReduceMin", reduceOp); + }; + reduceProd = (inferenceHandler, inputs, attributes) => { + const reduceOp = () => ["value = 1.0;", "value *= _A(inputIdx);", ""]; + return reduce(inferenceHandler, inputs, attributes, "ReduceProd", reduceOp); + }; + reduceLogSum = (inferenceHandler, inputs, attributes) => { + const reduceOp = () => ["value = 0.0;", "value += _A(inputIdx);", "value = log(value);"]; + return reduce(inferenceHandler, inputs, attributes, "ReduceLogSum", reduceOp); + }; + reduceLogSumSquare = (inferenceHandler, inputs, attributes) => { + const reduceOp = () => ["float t; value = 0.0;", "t = _A(inputIdx); value += t * t;", ""]; + return reduce(inferenceHandler, inputs, attributes, "ReduceLogSumSquare", reduceOp); + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/reshape.ts +var reshape; +var init_reshape = __esm({ + "web/lib/onnxjs/backends/webgl/ops/reshape.ts"() { + "use strict"; + init_util(); + reshape = (handler, inputs) => { + const reshapedDims = ShapeUtil.calculateReshapedDims(inputs[0].dims, inputs[1].integerData); + if (handler.session.pack) { + return [handler.reshapePacked(inputs[0], reshapedDims)]; + } else { + return [handler.reshapeUnpacked(inputs[0], reshapedDims)]; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/upsample.ts +var upsampleProgramMetadata, upsample, parseUpsampleAttributesV7, parseUpsampleAttributesV9, parseUpsampleAttributes, createUpsampleProgramInfo, validateInputs17, scalesValidation; +var init_upsample = __esm({ + "web/lib/onnxjs/backends/webgl/ops/upsample.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_glsl_source(); + init_types(); + upsampleProgramMetadata = { + name: "Upsample", + inputNames: ["X"], + inputTypes: [0 /* unpacked */] + }; + upsample = (inferenceHandler, inputs, attributes) => { + validateInputs17(inputs, attributes); + const output = inferenceHandler.run( + { + ...upsampleProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createUpsampleProgramInfo(inferenceHandler, inputs, attributes) + }, + inputs + ); + return [output]; + }; + parseUpsampleAttributesV7 = (node) => parseUpsampleAttributes(node, 7); + parseUpsampleAttributesV9 = (node) => parseUpsampleAttributes(node, 9); + parseUpsampleAttributes = (node, opset) => { + const isResize = opset >= 10; + const mode = node.attributes.getString("mode", "nearest"); + if (mode !== "nearest" && mode !== "linear" && (opset < 11 || mode !== "cubic")) { + throw new Error(`unrecognized mode: ${mode}`); + } + let scales = []; + if (opset < 9) { + scales = node.attributes.getFloats("scales"); + scalesValidation(scales, mode, isResize); + } + const extrapolationValue = node.attributes.getFloat("extrapolation_value", 0); + const coordinateTransformMode = opset > 10 ? node.attributes.getString("coordinate_transformation_mode", "half_pixel") : "asymmetric"; + if ([ + "asymmetric", + "pytorch_half_pixel", + "tf_half_pixel_for_nn", + "align_corners", + "tf_crop_and_resize", + "half_pixel" + ].indexOf(coordinateTransformMode) === -1) { + throw new Error(`coordinate_transform_mode '${coordinateTransformMode}' is not supported`); + } + const needRoiInput = coordinateTransformMode === "tf_crop_and_resize"; + const useExtrapolation = needRoiInput; + const nearestMode = mode === "nearest" && opset >= 11 ? node.attributes.getString("nearest_mode", "round_prefer_floor") : ""; + if (["round_prefer_floor", "round_prefer_ceil", "floor", "ceil", ""].indexOf(nearestMode) === -1) { + throw new Error(`nearest_mode '${nearestMode}' is not supported`); + } + const cubicCoefficientA = node.attributes.getFloat("cubic_coeff_a", -0.75); + const excludeOutside = node.attributes.getInt("exclude_outside", 0) !== 0; + if (excludeOutside && mode !== "cubic") { + throw new Error("exclude_outside can be set to 1 only when mode is CUBIC."); + } + const useNearest2xOptimization = opset < 11 ? true : mode === "nearest" && coordinateTransformMode === "asymmetric" && nearestMode === "floor"; + let roiInputIdx = 0; + let scalesInputIdx = 0; + let sizesInputIdx = 0; + if (opset > 10) { + if (node.inputs.length > 2) { + roiInputIdx = 1; + scalesInputIdx = 2; + sizesInputIdx = 3; + } else { + scalesInputIdx = 1; + sizesInputIdx = 2; + } + } else if (opset === 9) { + scalesInputIdx = 1; + } + return createAttributeWithCacheKey({ + opset, + isResize, + mode, + scales, + extrapolationValue, + coordinateTransformMode, + useExtrapolation, + needRoiInput, + nearestMode, + cubicCoefficientA, + excludeOutside, + useNearest2xOptimization, + roiInputIdx, + scalesInputIdx, + sizesInputIdx + }); + }; + createUpsampleProgramInfo = (inferenceHandler, inputs, attributes) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const [inputWidth, inputHeight] = inferenceHandler.calculateTextureWidthAndHeight(inputs[0].dims, 0 /* unpacked */); + const outputShape = inputs[0].dims.map((dim2, i) => Math.floor(dim2 * attributes.scales[i])); + const [outputWidth, outputHeight] = inferenceHandler.calculateTextureWidthAndHeight(outputShape, 0 /* unpacked */); + const dim = outputShape.length; + const outputPitches = new Array(dim); + const inputPitches = new Array(dim); + let precalculatedPitches = ` + int output_pitches[${dim}]; + int input_pitches[${dim}]; + `; + for (let d = dim - 1; d >= 0; d--) { + outputPitches[d] = d === dim - 1 ? 1 : outputPitches[d + 1] * outputShape[d + 1]; + inputPitches[d] = d === dim - 1 ? 1 : inputPitches[d + 1] * inputs[0].dims[d + 1]; + precalculatedPitches += ` + output_pitches[${d}] = ${outputPitches[d]}; + input_pitches[${d}] = ${inputPitches[d]}; + `; + } + const getInputFloatFunction = ` + float getInputFloat(int index) { + vec2 coords = offsetToCoords(index, ${inputWidth}, ${inputHeight}); + float value = getColorAsFloat(${glsl.texture2D}(X, coords)); + return value; + } + `; + const shaderSource = attributes.mode === "nearest" ? ( + // nearest + ` + ${getInputFloatFunction} + float process(int indices[${dim}]) { + int input_index = 0; + int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight}); + + ${precalculatedPitches} + + int d, m; + for (int dim = 0; dim < ${dim}; ++dim) { + d = output_index / output_pitches[dim]; + m = output_index - d * output_pitches[dim]; + output_index = m; + + if (scales[dim] != 1 && d > 0) { + int d2 = d / scales[dim]; + m = d - d2 * scales[dim]; + d = d2; + } + input_index += input_pitches[dim] * d; + } + + return getInputFloat(input_index); + }` + ) : dim === 4 ? ( + // bilinear 4D + ` + ${getInputFloatFunction} + float process(int indices[4]) { + int input_index = 0; + int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight}); + + ${precalculatedPitches} + + int m; + int index_of_dim0, index_of_dim1, index_of_dim2, index_of_dim3; + index_of_dim0 = output_index / output_pitches[0]; + m = output_index - index_of_dim0 * output_pitches[0]; + index_of_dim1 = m / output_pitches[1]; + m = m - index_of_dim1 * output_pitches[1]; + index_of_dim2 = m / output_pitches[2]; + m = m - index_of_dim2 * output_pitches[2]; + index_of_dim3 = m; + + int index_of_input_dim2, index_of_input_dim3, x_offset, y_offset; + index_of_input_dim2 = index_of_dim2 / scales[2]; + y_offset = index_of_dim2 - index_of_input_dim2 * scales[2]; + index_of_input_dim3 = index_of_dim3 / scales[3]; + x_offset = index_of_dim3 - index_of_input_dim3 * scales[3]; + + input_index = index_of_dim0 * input_pitches[0] + + index_of_dim1 * input_pitches[1] + + index_of_input_dim2 * input_pitches[2] + + index_of_input_dim3; + + float x00 = getInputFloat(input_index); + float x10, x01, x11; + + bool end_of_dim2 = false; + if (index_of_input_dim2 == (${inputs[0].dims[2]} - 1)) { + // It's the end in dimension 2 + x01 = x00; + end_of_dim2 = true; + } else { + x01 = getInputFloat(input_index + input_pitches[2]); + } + + if (index_of_input_dim3 == (input_pitches[2] - 1)) { + // It's the end in dimension 3 + x10 = x00; + x11 = x01; + } + else { + x10 = getInputFloat(input_index + 1); + x11 = end_of_dim2 ? x10 : getInputFloat(input_index + input_pitches[2] + 1); + } + + float y0 = x00 + float(y_offset) * (x01 - x00) / float(scales[2]); + float y1 = x10 + float(y_offset) * (x11 - x10) / float(scales[2]); + return y0 + float(x_offset) * (y1 - y0) / float(scales[3]); + }` + ) : ( + // bilinear 2D + ` + ${getInputFloatFunction} + float process(int indices[2]) { + int input_index = 0; + int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight}); + + ${precalculatedPitches} + + int m; + int index_of_dim0, index_of_dim1; + index_of_dim0 = output_index / output_pitches[0]; + m = output_index - index_of_dim0 * output_pitches[0]; + index_of_dim1 = m; + + int index_of_input_dim0, index_of_input_dim1, x_offset, y_offset; + index_of_input_dim0 = index_of_dim0 / scales[0]; + y_offset = index_of_dim0 - index_of_input_dim0 * scales[0]; + index_of_input_dim1 = index_of_dim1 / scales[1]; + x_offset = index_of_dim1 - index_of_input_dim1 * scales[1]; + + input_index = index_of_input_dim0 * input_pitches[0] + index_of_input_dim1; + + float x00 = getInputFloat(input_index); + float x10, x01, x11; + + bool end_of_dim0 = false; + if (index_of_input_dim0 == (${inputs[0].dims[0]} - 1)) { + // It's the end in dimension 0 + x01 = x00; + end_of_dim0 = true; + } else { + x01 = getInputFloat(input_index + input_pitches[0]); + } + + if (index_of_input_dim1 == (input_pitches[0] - 1)) { + // It's the end in dimension 1 + x10 = x00; + x11 = x01; + } + else { + x10 = getInputFloat(input_index + 1); + x11 = end_of_dim0 ? x10 : getInputFloat(input_index + input_pitches[0] + 1); + } + + float y0 = x00 + float(y_offset) * (x01 - x00) / float(scales[0]); + float y1 = x10 + float(y_offset) * (x11 - x10) / float(scales[0]); + return y0 + float(x_offset) * (y1 - y0) / float(scales[1]); + }` + ); + return { + ...upsampleProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource, + variables: [{ + name: "scales", + type: "int", + arrayLength: attributes.scales.length, + data: attributes.scales.map((x) => Math.ceil(x)) + }] + }; + }; + validateInputs17 = (inputs, attribute) => { + if (!inputs || attribute.opset < 9 && inputs.length !== 1 || attribute.opset >= 9 && attribute.opset < 11 && inputs.length !== 2 || attribute.opset >= 11 && inputs.length < 2) { + throw new Error("invalid inputs."); + } + if (attribute.scales.length > 0 && inputs[0].dims.length !== attribute.scales.length) { + throw new Error("Invalid input shape."); + } + if (inputs[0].type === "string") { + throw new Error("Invalid input tensor types."); + } + }; + scalesValidation = (scales, mode, isResize) => { + if (!isResize) { + for (const scale of scales) { + if (scale < 1) { + throw new Error("Scale value should be greater than or equal to 1."); + } + } + } else { + for (const scale of scales) { + if (scale <= 0) { + throw new Error("Scale value should be greater than 0."); + } + } + } + if (mode === "linear" || mode === "cubic") { + if (scales.length !== 2 && (scales.length !== 4 || scales[0] !== 1 || scales[1] !== 1)) { + throw new Error(`'Linear' mode and 'Cubic' mode only support 2-D inputs ('Bilinear', 'Bicubic') or 4-D inputs with the corresponding outermost 2 scale values being 1 in the ${isResize ? "Resize" : "Upsample"} opeartor.`); + } + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/resize-packed.ts +var resizeProgramMetadata, resize, parseResizeAttributesV10, parseResizeAttributesV11, createPackedResizeProgramInfo, prepareInputs, parseScalesData, parseScalesDataFromOutputSize; +var init_resize_packed = __esm({ + "web/lib/onnxjs/backends/webgl/ops/resize-packed.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + init_utils(); + init_packing_utils(); + init_upsample(); + resizeProgramMetadata = { + name: "Resize", + inputNames: ["A"], + inputTypes: [2 /* packed */] + }; + resize = (inferenceHandler, inputs, attributes) => { + validateInputs17(inputs, attributes); + const output = inferenceHandler.run( + { + ...resizeProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createPackedResizeProgramInfo(inferenceHandler, inputs, attributes) + }, + inputs + ); + return [output]; + }; + parseResizeAttributesV10 = (node) => parseUpsampleAttributes(node, 10); + parseResizeAttributesV11 = (node) => parseUpsampleAttributes(node, 11); + createPackedResizeProgramInfo = (inferenceHandler, inputs, attributes) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const [scales, outputShape] = prepareInputs(inputs, attributes); + const isSame = scales.every((s) => s === 1) && attributes.coordinateTransformMode !== "tf_crop_and_resize"; + if (isSame) { + return { + ...resizeProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, + hasMain: true, + shaderSource: `void main() { + vec4 v = ${glsl.texture2D}(X, TexCoords); + ${glsl.output} = v; + }` + }; + } + const dim = outputShape.length; + if (dim < 2) { + throw new Error(`output dimension should be at least 2, but got ${dim}`); + } + const outputHeight = outputShape[dim - 2]; + const outputWidth = outputShape[dim - 1]; + const inputShape = inputs[0].dims; + if (dim !== inputShape.length) { + throw new Error(`output dimension should match input ${inputShape.length}, but got ${dim}`); + } + const inputHeight = inputShape[dim - 2]; + const inputWidth = inputShape[dim - 1]; + const scalesHeight = scales[dim - 2]; + const scalesWidth = scales[dim - 1]; + let getSourceFracIndex = ""; + if (attributes.mode !== "linear") { + throw new Error(`resize (packed) does not support mode: '${attributes.mode}'`); + } + switch (attributes.coordinateTransformMode) { + case "asymmetric": + getSourceFracIndex = ` + vec4 getSourceFracIndex(ivec4 coords) { + return vec4(coords) / scaleWHWH; + } + `; + break; + case "half_pixel": + getSourceFracIndex = ` + vec4 getSourceFracIndex(ivec4 coords) { + return (vec4(coords) + 0.5) / scaleWHWH - 0.5; + } + `; + break; + case "pytorch_half_pixel": + getSourceFracIndex = ` + vec4 getSourceFracIndex(ivec4 coords) { + vec4 fcoords = vec4(coords); + return vec4( + ${outputWidth}.0 > 1.0 ? (fcoords.x + 0.5) / scaleWHWH.x - 0.5 : 0.0, + ${outputHeight}.0 > 1.0 ? (fcoords.y + 0.5) / scaleWHWH.y - 0.5 : 0.0, + ${outputWidth}.0 > 1.0 ? (fcoords.z + 0.5) / scaleWHWH.z - 0.5 : 0.0, + ${outputHeight}.0 > 1.0 ? (fcoords.w + 0.5) / scaleWHWH.w - 0.5 : 0.0 + ); + } + `; + break; + case "align_corners": + getSourceFracIndex = ` + vec4 getSourceFracIndex(ivec4 coords) { + vec4 resized = vec4(${outputWidth}.0 - 1.0, ${outputHeight}.0 - 1.0, ${outputWidth}.0 - 1.0, + ${outputHeight}.0 - 1.0); + vec4 original = vec4(${inputWidth}.0 - 1.0, ${inputHeight}.0 - 1.0, ${inputWidth}.0 - 1.0, + ${inputHeight}.0 - 1.0); + vec4 new_scale = original / resized; + return vec4(coords) * new_scale; + } + `; + break; + default: + throw new Error(`resize (packed) does not support coordinateTransformMode: '${attributes.coordinateTransformMode}'`); + } + const coordsDataType = getCoordsDataType(dim); + const unpackChannel = unpackFromChannel(); + const shaderSource = ` + const vec2 inputWH = vec2(${inputHeight}.0, ${inputWidth}.0); + const vec4 scaleWHWH = vec4(float(${scalesHeight}), float(${scalesWidth}), float(${scalesHeight}), float(${scalesWidth})); + ${unpackChannel} + ${getSourceFracIndex} + float getAValue(int x10, int r, int c, int d) { + return getChannel(getA(x10, r, c, d), vec2(c, d)); + } + void main() { + ${coordsDataType} rc = getOutputCoords(); + + int batch = rc[0]; + int depth = rc[1]; + + // retrieve the 4 coordinates that is used in the 4 packed output values. + ivec4 coords = ivec4(rc.wz, rc.w + 1, rc.z + 1); + + // calculate the source index in fraction + vec4 sourceFrac = getSourceFracIndex(coords); + + // get the lower and upper bound of the 4 values that will be packed into one texel. + ivec4 x00 = ivec4(max(sourceFrac.xy, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.xy))); + ivec4 x01 = ivec4(max(sourceFrac.xw, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.xw))); + ivec4 x10 = ivec4(max(sourceFrac.zy, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.zy))); + ivec4 x11 = ivec4(max(sourceFrac.zw, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.zw))); + + bool hasNextRow = rc.w < ${outputHeight - 1}; + bool hasNextCol = rc.z < ${outputWidth - 1}; + + // pack x00, x01, x10, x11's top-left corner into one vec4 structure + vec4 topLeft = vec4( + getAValue(batch, depth, x00.x, x00.y), + hasNextCol ? getAValue(batch, depth, x01.x, x01.y) : 0.0, + hasNextRow ? getAValue(batch, depth, x10.x, x10.y) : 0.0, + (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.x, x11.y) : 0.0); + + // pack x00, x01, x10, x11's top-right corner into one vec4 structure + vec4 topRight = vec4( + getAValue(batch, depth, x00.x, x00.w), + hasNextCol ? getAValue(batch, depth, x01.x, x01.w) : 0.0, + hasNextRow ? getAValue(batch, depth, x10.x, x10.w) : 0.0, + (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.x, x11.w) : 0.0); + + // pack x00, x01, x10, x11's bottom-left corner into one vec4 structure + vec4 bottomLeft = vec4( + getAValue(batch, depth, x00.z, x00.y), + hasNextCol ? getAValue(batch, depth, x01.z, x01.y) : 0.0, + hasNextRow ? getAValue(batch, depth, x10.z, x10.y) : 0.0, + (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.z, x11.y) : 0.0); + + // pack x00, x01, x10, x11's bottom-right corner into one vec4 structure + vec4 bottomRight = vec4( + getAValue(batch, depth, x00.z, x00.w), + hasNextCol ? getAValue(batch, depth, x01.z, x01.w) : 0.0, + hasNextRow ? getAValue(batch, depth, x10.z, x10.w) : 0.0, + (hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.z, x11.w) : 0.0); + + // calculate the interpolation fraction on u and v direction + vec4 frac = vec4(sourceFrac) - floor(sourceFrac); + vec4 clampFrac = clamp(frac, vec4(0.0), vec4(1.0)); + + vec4 top = mix(topLeft, topRight, clampFrac.ywyw); + vec4 bottom = mix(bottomLeft, bottomRight, clampFrac.ywyw); + vec4 newValue = mix(top, bottom, clampFrac.xxzz); + + ${glsl.output} = vec4(newValue); + } + `; + return { + ...resizeProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 2 /* packed */ }, + hasMain: true, + shaderSource + }; + }; + prepareInputs = (inputs, attributes) => { + const x = inputs[0]; + const xDims = x.dims; + let scales = attributes.scales; + let outputSizes; + if (scales.length === 0) { + const scalesTensor = inputs[attributes.scalesInputIdx]; + if (scalesTensor && scalesTensor.size !== 0) { + if (inputs[attributes.sizesInputIdx]) { + throw new Error("Only one of scales or sizes must be provided as input."); + } + scales = parseScalesData(scalesTensor, attributes.mode, attributes.isResize); + } else { + const sizesTensor = inputs[attributes.sizesInputIdx]; + if (!sizesTensor || sizesTensor.size === 0) { + throw new Error("Either scales or sizes MUST be provided as input."); + } + outputSizes = Array.from(sizesTensor.integerData); + scales = parseScalesDataFromOutputSize(outputSizes, xDims, attributes.mode, attributes.isResize); + } + } else { + if (inputs[attributes.sizesInputIdx]) { + throw new Error("Only one of scales or sizes must be provided as input."); + } + } + const yDims = outputSizes || xDims.map((dim, i) => Math.floor(dim * scales[i])); + return [scales, yDims]; + }; + parseScalesData = (scale, mode, isResize) => { + const scales = Array.from(scale.floatData); + scalesValidation(scales, mode, isResize); + return scales; + }; + parseScalesDataFromOutputSize = (yDims, xDims, mode, isResize) => { + const length = xDims.length; + const scales = new Array(length); + for (let i = 0, end = length; i < end; i++) { + if (xDims[i] === 0) { + if (yDims[i] !== 0) { + throw new Error("Input dim is zero but required output dim is non-zero."); + } + scales[i] = 1; + } else { + scales[i] = yDims[i] / xDims[i]; + } + } + scalesValidation(scales, mode, isResize); + return scales; + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/shape.ts +var shape, validateInputs18; +var init_shape = __esm({ + "web/lib/onnxjs/backends/webgl/ops/shape.ts"() { + "use strict"; + init_tensor2(); + shape = (_inferenceHandler, inputs) => { + validateInputs18(inputs); + return [new Tensor3([inputs[0].dims.length], "int32", void 0, void 0, new Int32Array(inputs[0].dims))]; + }; + validateInputs18 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Shape requires 1 input."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/slice.ts +var sliceProgramMetadata, slice, parseSliceAttributes, createSliceProgramInfo, validateInputs19, sliceV10, generateSliceAttributesFromInputs, validateInputsV10; +var init_slice = __esm({ + "web/lib/onnxjs/backends/webgl/ops/slice.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_operators(); + init_util(); + init_types(); + sliceProgramMetadata = { + name: "Slice", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + slice = (inferenceHandler, inputs, attributes) => { + validateInputs19(inputs); + const output = inferenceHandler.run( + { + ...sliceProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createSliceProgramInfo(inferenceHandler, inputs[0], attributes) + }, + inputs + ); + return [output]; + }; + parseSliceAttributes = (node) => { + const starts = node.attributes.getInts("starts"); + const ends = node.attributes.getInts("ends"); + const axes = node.attributes.getInts("axes", []); + return createAttributeWithCacheKey({ starts, ends, axes }); + }; + createSliceProgramInfo = (_inferenceHandler, input, attributes) => { + const axes = attributes.axes.length === 0 ? input.dims.slice(0).map((_val, i) => i) : attributes.axes; + const normalizedAxes = ShapeUtil.normalizeAxes(axes, input.dims.length); + const starts = attributes.starts.map((start, i) => { + if (start > input.dims[normalizedAxes[i]] - 1) { + return input.dims[normalizedAxes[i]]; + } + return ShapeUtil.normalizeAxis(start, input.dims[normalizedAxes[i]]); + }); + const ends = attributes.ends.map((end, i) => { + if (end > input.dims[normalizedAxes[i]] - 1) { + return input.dims[normalizedAxes[i]]; + } + return ShapeUtil.normalizeAxis(end, input.dims[normalizedAxes[i]]); + }); + const outputShape = input.dims.slice(); + const sliceOps = []; + for (let i = 0; i < normalizedAxes.length; i++) { + outputShape[normalizedAxes[i]] = ends[i] - starts[i]; + if (starts[i] > 0) { + sliceOps.push(`outputIdx[${normalizedAxes[i]}] += ${starts[i]};`); + } + } + const rank = outputShape.length; + const shaderSource = ` + float process(int outputIdx[${rank}]) { + ${sliceOps.join("\n ")} + return _A(outputIdx); + }`; + return { + ...sliceProgramMetadata, + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs19 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Slice requires 1 input."); + } + if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { + throw new Error("Invalid input type."); + } + }; + sliceV10 = (inferenceHandler, inputs) => { + validateInputsV10(inputs); + const attributes = generateSliceAttributesFromInputs(inferenceHandler, inputs); + const output = inferenceHandler.run( + { + ...sliceProgramMetadata, + cacheHint: attributes.cacheKey, + get: () => createSliceProgramInfo(inferenceHandler, inputs[0], attributes) + }, + [inputs[0]] + ); + return [output]; + }; + generateSliceAttributesFromInputs = (inferenceHandler, inputs) => { + if (!inferenceHandler.session.isInitializer(inputs[1].dataId) || !inferenceHandler.session.isInitializer(inputs[2].dataId) || inputs.length >= 4 && !inferenceHandler.session.isInitializer(inputs[3].dataId) || inputs.length >= 5 && !inferenceHandler.session.isInitializer(inputs[4].dataId)) { + throw new Error("dynamic slice attributes are not allowed"); + } + if (inputs.length >= 5 && inputs[4].integerData.some((i) => i !== 1)) { + throw new Error("currently non-1 steps is not supported for Slice"); + } + const starts = Array.from(inputs[1].integerData); + const ends = Array.from(inputs[2].integerData); + const axes = inputs.length >= 4 ? Array.from(inputs[3].integerData) : []; + const cacheKey = `${axes};${starts};${ends}`; + return { starts, ends, axes, cacheKey }; + }; + validateInputsV10 = (inputs) => { + if (!inputs || inputs.length < 3 || inputs.length > 5) { + throw new Error("Invalid input number."); + } + if (inputs[1].type !== "int32" || inputs[1].dims.length !== 1) { + throw new Error("Invalid input type."); + } + if (inputs[2].type !== "int32" || inputs[2].dims.length !== 1) { + throw new Error("Invalid input type."); + } + if (inputs.length >= 4 && (inputs[3].type !== "int32" || inputs[3].dims.length !== 1)) { + throw new Error("Invalid input type."); + } + if (inputs.length >= 5 && (inputs[4].type !== "int32" || inputs[4].dims.length !== 1)) { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/softmax.ts +var softmaxComputeMaxProgramMetadata, softmaxComputeScaleProgramMetadata, softmaxProgramMetadata, softmax, parseSoftmaxAttributes, parseSoftmaxAttributesV13, softmaxV13, computeSoftmax, createComputeMaxProgramInfo, createComputScaleProgramInfo, createSoftMaxProgramInfo, validateInputs20; +var init_softmax = __esm({ + "web/lib/onnxjs/backends/webgl/ops/softmax.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_glsl_source(); + init_types(); + init_transpose(); + softmaxComputeMaxProgramMetadata = { + name: "SoftmaxComputeMax", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + softmaxComputeScaleProgramMetadata = { + name: "SoftmaxComputeScale", + inputNames: ["A", "Max"], + inputTypes: [0 /* unpacked */, 0 /* unpacked */] + }; + softmaxProgramMetadata = { + name: "SoftMax", + inputNames: ["A", "Max", "Norm"], + inputTypes: [0 /* unpacked */, 0 /* unpacked */, 0 /* unpacked */] + }; + softmax = (inferenceHandler, inputs, attributes) => { + validateInputs20(inputs); + const inputShape = inputs[0].dims.slice(); + const axis = ShapeUtil.normalizeAxis(attributes.axis, inputShape.length); + const logicalRowCount = ShapeUtil.sizeToDimension(inputShape, axis); + const featureCount = ShapeUtil.sizeFromDimension(inputShape, axis); + const output = computeSoftmax(inferenceHandler, inputs, attributes, logicalRowCount, featureCount); + return output; + }; + parseSoftmaxAttributes = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis", 1) }); + parseSoftmaxAttributesV13 = (node) => createAttributeWithCacheKey({ axis: node.attributes.getInt("axis", -1) }); + softmaxV13 = (inferenceHandler, inputs, attributes) => { + validateInputs20(inputs); + const inputShape = inputs[0].dims.slice(); + const axis = ShapeUtil.normalizeAxis(attributes.axis, inputShape.length); + const rank = inputShape.length; + const isTransposeRequired = axis !== rank - 1 ? true : false; + const transposedInputShape = []; + let perm = []; + let transposedInputs = []; + let transposeAttribute; + if (isTransposeRequired) { + perm = Array.from({ length: rank }).map((_, i) => i); + perm[axis] = rank - 1; + perm[rank - 1] = axis; + perm.map((p) => transposedInputShape.push(inputShape[p])); + transposeAttribute = createAttributeWithCacheKey({ perm }); + transposedInputs = transpose(inferenceHandler, inputs, transposeAttribute); + } + const logicalRowCount = isTransposeRequired ? ShapeUtil.sizeToDimension(transposedInputShape, rank - 1) : ShapeUtil.sizeToDimension(inputShape, rank - 1); + const featureCount = isTransposeRequired ? ShapeUtil.sizeFromDimension(transposedInputShape, rank - 1) : ShapeUtil.sizeFromDimension(inputShape, rank - 1); + const output = computeSoftmax( + inferenceHandler, + isTransposeRequired ? transposedInputs : inputs, + attributes, + logicalRowCount, + featureCount + ); + if (isTransposeRequired) { + const reversedOutput = transpose(inferenceHandler, output, transposeAttribute); + return reversedOutput; + } else { + return output; + } + }; + computeSoftmax = (inferenceHandler, inputs, attributes, logicalRowCount, featureCount) => { + const computeMaxProgramInfo = createComputeMaxProgramInfo(inferenceHandler, inputs[0], logicalRowCount, featureCount, [logicalRowCount]); + const max = inferenceHandler.run( + { ...softmaxComputeMaxProgramMetadata, cacheHint: attributes.cacheKey, get: () => computeMaxProgramInfo }, + inputs + ); + const computeScaleProgramInfo = createComputScaleProgramInfo( + inferenceHandler, + inputs[0], + logicalRowCount, + featureCount, + computeMaxProgramInfo.output.dims, + [logicalRowCount] + ); + const scale = inferenceHandler.run( + { ...softmaxComputeScaleProgramMetadata, cacheHint: attributes.cacheKey, get: () => computeScaleProgramInfo }, + [inputs[0], max] + ); + const softMaxProgramInfo = createSoftMaxProgramInfo( + inferenceHandler, + inputs[0], + logicalRowCount, + featureCount, + computeMaxProgramInfo.output.dims, + computeScaleProgramInfo.output.dims + ); + const output = inferenceHandler.run( + { ...softmaxProgramMetadata, cacheHint: attributes.cacheKey, get: () => softMaxProgramInfo }, + [inputs[0], max, scale] + ); + return [output]; + }; + createComputeMaxProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, outputShape) => { + const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, 0 /* unpacked */); + const rank = outputShape.length; + if (logicalRowCount < 1 || featureCount < 1) { + throw new Error("Logical row count N and feature count D must be greater than or equal to 1"); + } + if (outputShape.length !== 1) { + throw new Error("Dimensionality of the output should be 1"); + } + if (outputShape[0] !== logicalRowCount) { + throw new Error("Shape of the output should be equal to logical row count"); + } + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const shaderSource = ` + float process(int[${rank}] indices) { + int logical_row_start_offset = indices[0] * ${featureCount}; + + float max = getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset, ${textureWidth}, + ${textureHeight} ))); + for(int i=1; i<${featureCount}; ++i) + { + float current = getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset + i, + ${textureWidth}, ${textureHeight}))); + if(current > max) + max = current; + } + + return max; + }`; + return { + ...softmaxComputeMaxProgramMetadata, + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createComputScaleProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, maxElementPerLogicalRow, outputShape) => { + const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, 0 /* unpacked */); + const rank = outputShape.length; + if (logicalRowCount < 1 || featureCount < 1) { + throw new Error("Logical row count N and feature count D must be greater than or equal to 1"); + } + if (outputShape.length !== 1) { + throw new Error("Dimensionality of the output should be 1"); + } + if (outputShape[0] !== logicalRowCount) { + throw new Error("Shape of the output should be equal to logical row count"); + } + if (maxElementPerLogicalRow.length !== 1) { + throw new Error("Dimensionality of the intermediate results should be 1"); + } + if (maxElementPerLogicalRow[0] !== logicalRowCount) { + throw new Error("Shape of the intermediate results should be equal to logical row count"); + } + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const shaderSource = ` + float process(int[${rank}] indices) { + int logical_row_start_offset = indices[0] * ${featureCount}; + + float norm_factor = 0.0; + float max = _Max(indices); + for(int i=0; i<${featureCount}; ++i) + { + norm_factor += exp(getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset + i, + ${textureWidth}, ${textureHeight}))) - max); + } + + return norm_factor; + }`; + return { + ...softmaxComputeScaleProgramMetadata, + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + createSoftMaxProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, maxElementPerLogicalRow, normalizationPerLogicalRow) => { + const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, 0 /* unpacked */); + const rank = input.dims.length; + if (logicalRowCount < 1 || featureCount < 1) { + throw new Error("Logical row count N and feature count D must be greater than or equal to 1"); + } + if (maxElementPerLogicalRow.length !== 1 || normalizationPerLogicalRow.length !== 1) { + throw new Error("Dimensionality of the intermediate results should be 1"); + } + if (maxElementPerLogicalRow[0] !== logicalRowCount || normalizationPerLogicalRow[0] !== logicalRowCount) { + throw new Error("Shape of the intermediate results should be equal to logical row count"); + } + const shaderSource = ` + float process(int[${rank}] indices) { + + // get offset of current logical tensor index from the 2-D texture coordinates (TexCoords) + int offset = coordsToOffset(TexCoords, ${textureWidth}, ${textureHeight}); + + //determine the logical row for this index + int logical_row_index[1]; + logical_row_index[0] = offset / ${featureCount}; + + float norm_factor = _Norm(logical_row_index); + + // avoid possible division by 0 + // if norm_facor is 0, all elements are zero + // if so, return 0 + if(norm_factor == 0.0) + return 0.0; + + return exp(_A(indices) - _Max(logical_row_index)) / norm_factor; + }`; + return { + ...softmaxProgramMetadata, + output: { dims: input.dims, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs20 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Softmax requires 1 input."); + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/split.ts +var splitProgramMetadata, split, parseSplitAttributes, getProgramCount, createSplitProgramInfo, validateInputs21; +var init_split = __esm({ + "web/lib/onnxjs/backends/webgl/ops/split.ts"() { + "use strict"; + init_attribute_with_cache_key(); + init_util(); + init_types(); + splitProgramMetadata = { + name: "Split", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + split = (inferenceHandler, inputs, attributes) => { + validateInputs21(inputs); + const axis = ShapeUtil.normalizeAxis(attributes.axis, inputs[0].dims.length); + const count = getProgramCount(inferenceHandler, inputs, axis, attributes); + const output = []; + for (let i = 0; i < count; ++i) { + output.push(inferenceHandler.run( + { + ...splitProgramMetadata, + cacheHint: `${attributes.cacheKey};${i}`, + get: () => createSplitProgramInfo(inferenceHandler, inputs[0], attributes, axis, i) + }, + inputs + )); + } + return output; + }; + parseSplitAttributes = (node) => { + const axis = node.attributes.getInt("axis", 0); + const split2 = node.attributes.getInts("split", []); + const numOutputs = node.outputs.length; + return createAttributeWithCacheKey({ axis, split: split2, numOutputs }); + }; + getProgramCount = (_inferenceHandler, inputs, axis, attributes) => { + const [, offsets] = SplitUtil.splitShape(inputs[0].dims, axis, attributes.split, attributes.numOutputs); + return offsets.length; + }; + createSplitProgramInfo = (_inferenceHandler, input, attributes, axis, index) => { + const [shapes, offsets] = SplitUtil.splitShape(input.dims, axis, attributes.split, attributes.numOutputs); + const offset = offsets[index]; + const outputShape = shapes[index]; + const rank = outputShape.length; + const shaderSource = ` + float process(int indices[${rank}]) { + indices[${axis}] += ${offset}; + return _A(indices); + } + `; + return { + ...splitProgramMetadata, + cacheHint: `${attributes.cacheKey}:${index}`, + output: { dims: outputShape, type: input.type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs21 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Split requires one input."); + } + if (inputs[0].type !== "int8" && inputs[0].type !== "uint8" && inputs[0].type !== "int16" && inputs[0].type !== "uint16" && inputs[0].type !== "int32" && inputs[0].type !== "uint32" && inputs[0].type !== "float32" && inputs[0].type !== "float64" && inputs[0].type !== "bool") { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/squeeze.ts +var squeeze, squeezeV13, parseSqueezeAttributes, validateInputs22, validateInputsV13; +var init_squeeze = __esm({ + "web/lib/onnxjs/backends/webgl/ops/squeeze.ts"() { + "use strict"; + init_util(); + squeeze = (inferenceHandler, inputs, axes) => { + validateInputs22(inputs); + const outputShape = ShapeUtil.squeezeShape(inputs[0].dims, axes); + const output = inferenceHandler.reshapeUnpacked(inputs[0], outputShape); + return [output]; + }; + squeezeV13 = (inferenceHandler, inputs) => { + validateInputsV13(inputs); + return squeeze(inferenceHandler, [inputs[0]], Array.from(inputs[1].integerData)); + }; + parseSqueezeAttributes = (node) => node.attributes.getInts("axes"); + validateInputs22 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Squeeze requires 1 input."); + } + if (inputs[0].type === "string") { + throw new Error("invalid input tensor types."); + } + }; + validateInputsV13 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Squeeze requires 2 inputs."); + } + if (inputs[1].type !== "int32") { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/sum.ts +var sum, createSumProgramInfo, validateInputs23; +var init_sum = __esm({ + "web/lib/onnxjs/backends/webgl/ops/sum.ts"() { + "use strict"; + init_glsl_source(); + init_types(); + sum = (inferenceHandler, inputs) => { + validateInputs23(inputs); + const sumProgramMetadata = { + name: "Sum", + inputNames: inputs.map((_v, i) => `X${i}`), + inputTypes: new Array(inputs.length).fill(0 /* unpacked */) + }; + const output = inferenceHandler.run( + { ...sumProgramMetadata, get: () => createSumProgramInfo(inferenceHandler, inputs, sumProgramMetadata) }, + inputs + ); + return [output]; + }; + createSumProgramInfo = (inferenceHandler, inputs, sumProgramMetadata) => { + const glsl = getGlsl(inferenceHandler.session.backend.glContext.version); + const outputShape = inputs[0].dims.slice(); + const sumLine = inputs.map((_v, i) => `${glsl.texture2D}(X${i},TexCoords)`).join(" + "); + const shaderSource = ` + void main() { + vec4 result = ${sumLine}; + ${glsl.output} = result; + } + `; + return { + ...sumProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + hasMain: true, + shaderSource + }; + }; + validateInputs23 = (inputs) => { + if (!inputs || inputs.length === 0) { + throw new Error("Sum requires inputs."); + } + const length = inputs[0].dims.length; + for (let i = 1; i < inputs.length; i++) { + if (length !== inputs[i].dims.length) { + throw new Error("Input shapes are mismatched."); + } + for (let j = 0; j < length; j++) { + if (inputs[0].dims[j] !== inputs[i].dims[j]) { + throw new Error("Input shapes are not matched."); + } + } + } + if (inputs[0].type !== "float32" && inputs[0].type !== "float64") { + throw new Error("Invalid input type."); + } + for (let i = 1; i < inputs.length; i++) { + if (inputs[0].type !== inputs[i].type) { + throw new Error("Input types are not matched."); + } + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/tile.ts +var tile, createTileProgramInfo, validateInputs24; +var init_tile = __esm({ + "web/lib/onnxjs/backends/webgl/ops/tile.ts"() { + "use strict"; + init_operators(); + init_types(); + tile = (inferenceHandler, inputs) => { + validateInputs24(inputs); + const tileProgramMetadata = { + name: "Tile", + inputNames: ["A"], + inputTypes: [0 /* unpacked */] + }; + const output = inferenceHandler.run( + { ...tileProgramMetadata, get: () => createTileProgramInfo(inferenceHandler, inputs, tileProgramMetadata) }, + inputs + ); + return [output]; + }; + createTileProgramInfo = (_handler, inputs, tileProgramMetadata) => { + const inputShape = inputs[0].dims.slice(); + const outputShape = new Array(inputShape.length); + const tileOps = []; + for (let i = 0; i < inputShape.length; i++) { + outputShape[i] = inputShape[i] * inputs[1].numberData[i]; + tileOps.push(`inputIdx[${i}] = int(mod(float(outputIdx[${i}]), ${inputShape[i]}.));`); + } + const rank = outputShape.length; + const shaderSource = ` + float process(int outputIdx[${rank}]) { + int inputIdx[${rank}]; + ${tileOps.join("\n")} + return _A(inputIdx); + } + `; + return { + ...tileProgramMetadata, + output: { dims: outputShape, type: inputs[0].type, textureType: 0 /* unpacked */ }, + shaderSource + }; + }; + validateInputs24 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Tile requires 2 input."); + } + if (inputs[1].dims.length !== 1) { + throw new Error("The second input shape must 1 dimension."); + } + if (inputs[1].dims[0] !== inputs[0].dims.length) { + throw new Error("Invalid input shape."); + } + if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) { + throw new Error("Invalid input type."); + } + if (inputs[1].type !== "int32" && inputs[1].type !== "int16") { + throw new Error("Invalid repeat type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/ops/unsqueeze.ts +var unsqueeze, unsqueezeV13, parseUnsqueezeAttributes, validateInputs25, validateInputsV132; +var init_unsqueeze = __esm({ + "web/lib/onnxjs/backends/webgl/ops/unsqueeze.ts"() { + "use strict"; + init_util(); + unsqueeze = (inferenceHandler, inputs, axes) => { + validateInputs25(inputs); + const outputShape = ShapeUtil.unsqueezeShape(inputs[0].dims, axes); + const output = inferenceHandler.reshapeUnpacked(inputs[0], outputShape); + return [output]; + }; + unsqueezeV13 = (inferenceHandler, inputs) => { + validateInputsV132(inputs); + return unsqueeze(inferenceHandler, [inputs[0]], Array.from(inputs[1].integerData)); + }; + parseUnsqueezeAttributes = (node) => node.attributes.getInts("axes"); + validateInputs25 = (inputs) => { + if (!inputs || inputs.length !== 1) { + throw new Error("Unsqueeze requires 1 input."); + } + if (inputs[0].type === "string") { + throw new Error("invalid input tensor types."); + } + }; + validateInputsV132 = (inputs) => { + if (!inputs || inputs.length !== 2) { + throw new Error("Unsqueeze requires 2 inputs."); + } + if (inputs[1].type !== "int32") { + throw new Error("Invalid input type."); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/op-resolve-rules.ts +var WEBGL_OP_RESOLVE_RULES; +var init_op_resolve_rules = __esm({ + "web/lib/onnxjs/backends/webgl/op-resolve-rules.ts"() { + "use strict"; + init_batch_normalization(); + init_binary_op(); + init_cast(); + init_concat(); + init_conv(); + init_conv_transpose(); + init_depth_to_space(); + init_flatten(); + init_gather(); + init_gemm(); + init_image_scaler(); + init_instance_normalization(); + init_lrn(); + init_matmul(); + init_pad(); + init_pool(); + init_reduce(); + init_reshape(); + init_resize_packed(); + init_shape(); + init_slice(); + init_softmax(); + init_split(); + init_squeeze(); + init_sum(); + init_tile(); + init_transpose(); + init_unary_op(); + init_unsqueeze(); + init_upsample(); + WEBGL_OP_RESOLVE_RULES = [ + ["Abs", "", "6+", abs], + ["Acos", "", "7+", acos], + ["Add", "", "7+", add2], + ["And", "", "7+", and2], + ["Asin", "", "7+", asin], + ["Atan", "", "7+", atan], + // TODO: support new attributes for AveragePool-10 + ["AveragePool", "", "7+", averagePool, parseAveragePoolAttributes], + ["BatchNormalization", "", "7+", batchNormalization, parseBatchNormalizationAttributes], + ["Cast", "", "6+", cast, parseCastAttributes], + ["Ceil", "", "6+", ceil], + ["Clip", "", "6-10", clip, parseClipAttributes], + ["Clip", "", "11+", clipV11], + ["Concat", "", "4+", concat, parseConcatAttributes], + ["Conv", "", "1+", conv, parseConvAttributes], + ["ConvTranspose", "", "1+", convTranspose, parseConvTransposeAttributes], + ["Cos", "", "7+", cos], + ["Div", "", "7+", div], + ["Dropout", "", "7+", identity], + ["DepthToSpace", "", "1+", depthToSpace, parseDepthToSpaceAttributes], + ["Equal", "", "7+", equal], + ["Elu", "", "6+", elu, parseEluAttributes], + ["Exp", "", "6+", exp], + ["Flatten", "", "1+", flatten, parseFlattenAttributes], + ["Floor", "", "6+", floor], + ["FusedConv", "com.microsoft", "1+", conv, parseConvAttributes], + ["Gather", "", "1+", gather, parseGatherAttributes], + ["Gemm", "", "7-10", gemm, parseGemmAttributesV7], + ["Gemm", "", "11+", gemm, parseGemmAttributesV11], + ["GlobalAveragePool", "", "1+", globalAveragePool, parseGlobalAveragePoolAttributes], + ["GlobalMaxPool", "", "1+", globalMaxPool], + ["Greater", "", "7+", greater], + ["Identity", "", "1+", identity], + ["ImageScaler", "", "1+", imageScaler, parseImageScalerAttributes], + ["InstanceNormalization", "", "6+", instanceNormalization, parseInstanceNormalizationAttributes], + ["LeakyRelu", "", "6+", leakyRelu, parseLeakyReluAttributes], + ["Less", "", "7+", less], + ["LRN", "", "1+", lrn, parseLrnAttributes], + ["Log", "", "6+", log2], + ["MatMul", "", "1+", matMul, parseMatMulAttributes], + // TODO: support new attributes for MaxPool-8 and MaxPool-10 + ["MaxPool", "", "1+", maxPool, parseMaxPoolAttributes], + ["Mul", "", "7+", mul], + ["Neg", "", "6+", neg], + ["Not", "", "1+", not2], + ["Or", "", "7+", or2], + ["Pad", "", "2-10", padV2, parsePadAttributesV2], + ["Pad", "", "11+", padV11, parsePadAttributesV11], + ["Pow", "", "7+", pow], + ["PRelu", "", "7+", pRelu], + ["ReduceLogSum", "", "1+", reduceLogSum, parseReduceAttributes], + ["ReduceMax", "", "1+", reduceMax, parseReduceAttributes], + ["ReduceMean", "", "1+", reduceMean, parseReduceAttributes], + ["ReduceMin", "", "1+", reduceMin, parseReduceAttributes], + ["ReduceProd", "", "1+", reduceProd, parseReduceAttributes], + ["ReduceSum", "", "1-12", reduceSum, parseReduceAttributes], + ["ReduceSumSquare", "", "1+", reduceLogSumSquare, parseReduceAttributes], + ["Relu", "", "6+", relu], + ["Reshape", "", "5+", reshape], + ["Resize", "", "10", resize, parseResizeAttributesV10], + ["Resize", "", "11+", resize, parseResizeAttributesV11], + ["Shape", "", "1+", shape], + ["Sigmoid", "", "6+", sigmoid], + ["Sin", "", "7+", sin], + ["Slice", "", "10+", sliceV10], + // TODO: support 'steps' for Slice-10 + ["Slice", "", "1-9", slice, parseSliceAttributes], + // The "semantic" meaning of axis has changed in opset-13. + ["Softmax", "", "1-12", softmax, parseSoftmaxAttributes], + ["Softmax", "", "13+", softmaxV13, parseSoftmaxAttributesV13], + // 'Split' operator has an optional attribute 'split' + // this attribute determines how the specified axis of input data is split. + // When the attribute is missing, we need the count of number of outputs + // so that we can determine the 'split' attribute from the runtime input to the Operator + ["Split", "", "2-12", split, parseSplitAttributes], + ["Sqrt", "", "6+", sqrt], + ["Squeeze", "", "1-12", squeeze, parseSqueezeAttributes], + ["Squeeze", "", "13+", squeezeV13], + ["Sub", "", "7+", sub], + ["Sum", "", "6+", sum], + ["Tan", "", "7+", tan], + ["Tanh", "", "6+", tanh], + ["Tile", "", "6+", tile], + ["Transpose", "", "1+", transpose, parseTransposeAttributes], + ["Upsample", "", "7-8", upsample, parseUpsampleAttributesV7], + ["Upsample", "", "9", upsample, parseUpsampleAttributesV9], + ["Unsqueeze", "", "1-12", unsqueeze, parseUnsqueezeAttributes], + ["Unsqueeze", "", "13+", unsqueezeV13], + ["Xor", "", "7+", xor2] + ]; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-function-inliner.ts +function replaceInlines(script) { + const inlineDefs = {}; + let match; + while ((match = INLINE_FUNC_DEF_REGEX.exec(script)) !== null) { + const params = match[3].split(",").map((s) => { + const tokens = s.trim().split(" "); + if (tokens && tokens.length === 2) { + return { type: tokens[0], name: tokens[1] }; + } + return null; + }).filter((v) => v !== null); + inlineDefs[match[2]] = { params, body: match[4] }; + } + for (const name2 in inlineDefs) { + const regexString = FUNC_CALL_REGEX.replace("__FUNC__", name2); + const regex = new RegExp(regexString, "gm"); + while ((match = regex.exec(script)) !== null) { + const type = match[1]; + const variable = match[2]; + const params = match[3].split(","); + const declLine = type ? `${type} ${variable};` : ""; + let newBody = inlineDefs[name2].body; + let paramRedecLine = ""; + inlineDefs[name2].params.forEach((v, i) => { + if (v) { + paramRedecLine += `${v.type} ${v.name} = ${params[i]}; +`; + } + }); + newBody = `${paramRedecLine} + ${newBody}`; + newBody = newBody.replace("return", `${variable} = `); + const replacement = ` + ${declLine} + { + ${newBody} + } + `; + script = script.replace(match[0], replacement); + } + } + script = script.replace(INLINE_FUNC_DEF_REGEX, ""); + return script; +} +var INLINE_FUNC_DEF_REGEX, FUNC_CALL_REGEX; +var init_glsl_function_inliner = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-function-inliner.ts"() { + "use strict"; + INLINE_FUNC_DEF_REGEX = /@inline[\s\n\r]+(\w+)[\s\n\r]+([0-9a-zA-Z_]+)\s*\(([^)]*)\)\s*{(([^}]|[\n\r])*)}/gm; + FUNC_CALL_REGEX = "(\\w+)?\\s+([_0-9a-zA-Z]+)\\s+=\\s+__FUNC__\\((.*)\\)\\s*;"; + } +}); + +// web/lib/onnxjs/backends/webgl/texture-layout-strategy.ts +function squeezeShape(shape2, axis) { + const newShape = []; + const keptDims = []; + const isEmptyArray = axis != null && Array.isArray(axis) && axis.length === 0; + const axes = axis == null || isEmptyArray ? null : parseAxisParam(axis, shape2).sort(); + let j = 0; + for (let i = 0; i < shape2.length; ++i) { + if (axes != null) { + if (axes[j] === i && shape2[i] !== 1) { + throw new Error(`Can't squeeze axis ${i} since its dim '${shape2[i]}' is not 1`); + } + if ((axes[j] == null || axes[j] > i) && shape2[i] === 1) { + newShape.push(shape2[i]); + keptDims.push(i); + } + if (axes[j] <= i) { + j++; + } + } + if (shape2[i] !== 1) { + newShape.push(shape2[i]); + keptDims.push(i); + } + } + return { newShape, keptDims }; +} +function parseAxisParam(axis, shape2) { + const rank = shape2.length; + axis = axis == null ? shape2.map((_s, i) => i) : [].concat(axis); + assert( + axis.every((ax) => ax >= -rank && ax < rank), + () => `All values in axis param must be in range [-${rank}, ${rank}) but got axis ${axis}` + ); + assert( + axis.every(isInt), + () => `All values in axis param must be integers but got axis ${axis}` + ); + return axis.map((a) => a < 0 ? rank + a : a); +} +function isInt(a) { + return a % 1 === 0; +} +function sizeFromShape(shape2) { + if (shape2.length === 0) { + return 1; + } + let size = shape2[0]; + for (let i = 1; i < shape2.length; i++) { + size *= shape2[i]; + } + return size; +} +function sizeToSquarishShape(size) { + const width = Math.ceil(Math.sqrt(size)); + return [width, Math.ceil(size / width)]; +} +var PreferLogicalStrategy; +var init_texture_layout_strategy = __esm({ + "web/lib/onnxjs/backends/webgl/texture-layout-strategy.ts"() { + "use strict"; + init_instrument(); + init_util(); + PreferLogicalStrategy = class { + constructor(maxTextureSize) { + this.maxTextureSize = maxTextureSize; + } + computeTextureWH(shape2, prefs) { + const wh = this.computeTexture(shape2, prefs); + if (prefs && prefs.isPacked) { + wh[0] /= 2; + wh[1] /= 2; + } + if (prefs && prefs.reverseWH) { + return [wh[1], wh[0]]; + } + return wh; + } + computeTexture(shape2, prefs) { + const isPacked = prefs && prefs.isPacked; + if (shape2.length === 0) { + return isPacked ? [2, 2] : [1, 1]; + } + let maxTextureSize = this.maxTextureSize; + if (prefs && prefs.breakAxis !== void 0) { + const wsize = prefs.breakAxis >= shape2.length ? 1 : shape2.slice(prefs.breakAxis).reduce((a, b) => a * b); + const hsize = prefs.breakAxis <= 0 ? 1 : shape2.slice(0, prefs.breakAxis).reduce((a, b) => a * b); + if (wsize > maxTextureSize || hsize > maxTextureSize) { + Logger.verbose( + "TextureLayout", + `Given width/height preferences were unattainable: shape:${shape2}, breakAxis:${prefs.breakAxis}` + ); + } else { + return [wsize, hsize]; + } + } + let logShape = shape2.slice(0); + if (isPacked) { + maxTextureSize = maxTextureSize * 2; + logShape = logShape.map( + (_d, i) => i >= logShape.length - 2 ? logShape[i] % 2 === 0 ? logShape[i] : logShape[i] + 1 : logShape[i] + ); + if (logShape.length === 1) { + logShape = [2, logShape[0]]; + } + } + if (logShape.length !== 2) { + const squeezeResult = squeezeShape(logShape); + logShape = squeezeResult.newShape; + } + const size = sizeFromShape(logShape); + if (logShape.length <= 1 && size <= maxTextureSize) { + return [1, size]; + } else if (logShape.length === 2 && logShape[0] <= maxTextureSize && logShape[1] <= maxTextureSize) { + return logShape; + } else if (logShape.length === 3 && logShape[0] * logShape[1] <= maxTextureSize && logShape[2] <= maxTextureSize) { + return [logShape[0] * logShape[1], logShape[2]]; + } else if (logShape.length === 3 && logShape[0] <= maxTextureSize && logShape[1] * logShape[2] <= maxTextureSize) { + return [logShape[0], logShape[1] * logShape[2]]; + } else if (logShape.length === 4 && logShape[0] * logShape[1] * logShape[2] <= maxTextureSize && logShape[3] <= maxTextureSize) { + return [logShape[0] * logShape[1] * logShape[2], logShape[3]]; + } else if (logShape.length === 4 && logShape[0] <= maxTextureSize && logShape[1] * logShape[2] * logShape[3] <= maxTextureSize) { + return [logShape[0], logShape[1] * logShape[2] * logShape[3]]; + } else { + if (isPacked) { + return sizeToSquarishShape(size / 4).map((d) => d * 2); + } + return sizeToSquarishShape(size); + } + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts +var CoordsGlslLib; +var init_glsl_coordinate_lib = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts"() { + "use strict"; + init_util(); + init_glsl_definitions(); + init_glsl_source(); + init_texture_layout_strategy(); + init_utils(); + CoordsGlslLib = class extends GlslLib { + constructor(context) { + super(context); + } + getFunctions() { + return { + ...this.offsetToCoords(), + ...this.coordsToOffset(), + ...this.toVec(), + ...this.valueFrom(), + // TODO return these only when packing is enabled. + ...this.getCommonUtilFuncs(), + ...this.getInputsSamplingSnippets(), + ...this.getOutputSamplingSnippet() + }; + } + getCustomTypes() { + return {}; + } + /** + * Produces a function that can map from + * 2D normalzied coordinates (s,t) to a flat offset + */ + offsetToCoords() { + const funcName = "offsetToCoords"; + return { + offsetToCoords: new GlslLibRoutine(` + vec2 ${funcName}(int offset, int width, int height) { + int t = offset / width; + int s = offset - t*width; + vec2 coords = (vec2(s,t) + vec2(0.5,0.5)) / vec2(width, height); + return coords; + } + `) + }; + } + /** + * Produces a function that can map from + * 2D normalzied coordinates (s,t) to a flat offset + */ + coordsToOffset() { + const funcName = "coordsToOffset"; + return { + coordsToOffset: new GlslLibRoutine(` + int ${funcName}(vec2 coords, int width, int height) { + float s = coords.s * float(width); + float t = coords.t * float(height); + int offset = int(t) * width + int(s); + return offset; + } + `) + }; + } + /** + * Generates code for output sampler. + */ + getOutputSamplingSnippet() { + const outputLayout = this.context.outputTextureLayout; + if (outputLayout.isPacked) { + return this.getPackedOutputSamplingSnippet(outputLayout); + } else { + return this.getUnpackedOutputSamplingSnippet(outputLayout); + } + } + /** + * Generates code for packed output sampler. + */ + getPackedOutputSamplingSnippet(outputLayout) { + const outShape = outputLayout.unpackedShape; + const outTexShape = [outputLayout.width, outputLayout.height]; + const result = {}; + const funcName = "getOutputCoords"; + switch (outShape.length) { + case 0: + result[funcName] = this.getOutputScalarCoords(); + break; + case 1: + result[funcName] = this.getOutputPacked1DCoords(outShape, outTexShape); + break; + case 2: + result[funcName] = this.getOutputPacked2DCoords(outShape, outTexShape); + break; + case 3: + result[funcName] = this.getOutputPacked3DCoords(outShape, outTexShape); + break; + default: + result[funcName] = this.getOutputPackedNDCoords(outShape, outTexShape); + } + const glsl = getGlsl(this.context.glContext.version); + const floatTextureSetRGBASource = ` + void setOutput(vec4 val) { + ${glsl.output} = val; + } + `; + const floatTextureSetRGBAFuncName = "floatTextureSetRGBA"; + result[floatTextureSetRGBAFuncName] = new GlslLibRoutine(floatTextureSetRGBASource); + return result; + } + /** + * Generates code for unpacked output sampler. + */ + getUnpackedOutputSamplingSnippet(outputLayout) { + const outShape = outputLayout.unpackedShape; + const outTexShape = [outputLayout.width, outputLayout.height]; + const result = {}; + const funcName = "getOutputCoords"; + switch (outShape.length) { + case 0: + result[funcName] = this.getOutputScalarCoords(); + break; + case 1: + result[funcName] = this.getOutputUnpacked1DCoords(outShape, outTexShape); + break; + case 2: + result[funcName] = this.getOutputUnpacked2DCoords(outShape, outTexShape); + break; + case 3: + result[funcName] = this.getOutputUnpacked3DCoords(outShape, outTexShape); + break; + case 4: + result[funcName] = this.getOutputUnpacked4DCoords( + outShape, + outTexShape + ); + break; + case 5: + result[funcName] = this.getOutputUnpacked5DCoords( + outShape, + outTexShape + ); + break; + case 6: + result[funcName] = this.getOutputUnpacked6DCoords( + outShape, + outTexShape + ); + break; + default: + throw new Error(`Unsupported output dimensionality: ${outShape.length}`); + } + const glsl = getGlsl(this.context.glContext.version); + const floatTextureSetRSource = ` + void setOutput(float val) { + ${glsl.output} = vec4(val, 0, 0, 0); + } + `; + const floatTextureSetRFuncName = "floatTextureSetR"; + result[floatTextureSetRFuncName] = new GlslLibRoutine(floatTextureSetRSource); + return result; + } + /** + * Scalar output coordinates. + */ + getOutputScalarCoords() { + return new GlslLibRoutine(` + int getOutputCoords() { + return 0; + } + `); + } + /** + * 1D packed output coordinates. + */ + getOutputPacked1DCoords(_shape, texShape) { + const packedTexShape = texShape; + let source = ""; + if (packedTexShape[0] === 1) { + source = ` + int getOutputCoords() { + return 2 * int(TexCoords.y * ${packedTexShape[1]}.0); + } + `; + return new GlslLibRoutine(source); + } + if (packedTexShape[1] === 1) { + source = ` + int getOutputCoords() { + return 2 * int(TexCoords.x * ${packedTexShape[0]}.0); + } + `; + return new GlslLibRoutine(source); + } + source = ` + int getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + return 2 * (resTexRC.y * ${packedTexShape[0]} + resTexRC.x); + } + `; + return new GlslLibRoutine(source); + } + /** + * 2D packed output coordinates. + */ + getOutputPacked2DCoords(shape2, texShape) { + let source = ""; + if (ArrayUtil.arraysEqual(shape2, texShape)) { + source = ` + ivec2 getOutputCoords() { + return 2 * ivec2(TexCoords.xy * vec2(${texShape[0]}, ${texShape[1]})); + } + `; + return new GlslLibRoutine(source); + } + const packedTexShape = texShape; + const texelsInLogicalRow = Math.ceil(shape2[1] / 2); + source = ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + + int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x; + + // reverse r and c order for packed texture + int r = imod(index, ${texelsInLogicalRow}) * 2; + int c = 2 * (index / ${texelsInLogicalRow}); + + return ivec2(r, c); + } + `; + return new GlslLibRoutine(source); + } + /** + * 3D packed output coordinates. + */ + getOutputPacked3DCoords(shape2, texShape) { + const packedTexShape = [texShape[0], texShape[1]]; + const texelsInLogicalRow = Math.ceil(shape2[2] / 2); + const texelsInBatch = texelsInLogicalRow * Math.ceil(shape2[1] / 2); + const source = ` + ivec3 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x; + + int b = index / ${texelsInBatch}; + index -= b * ${texelsInBatch}; + + // reverse r and c order for packed texture + int r = imod(index, ${texelsInLogicalRow}) * 2; + int c = 2 * (index / ${texelsInLogicalRow}); + + return ivec3(b, r, c); + } + `; + return new GlslLibRoutine(source); + } + /** + * ND packed output coordinates. + */ + getOutputPackedNDCoords(shape2, texShape) { + const packedTexShape = [texShape[0], texShape[1]]; + const texelsInLogicalRow = Math.ceil(shape2[shape2.length - 1] / 2); + const texelsInBatch = texelsInLogicalRow * Math.ceil(shape2[shape2.length - 2] / 2); + let texelsInBatchN = texelsInBatch; + let batches = ""; + let coords = "b, r, c"; + for (let b = 2; b < shape2.length - 1; b++) { + texelsInBatchN *= shape2[shape2.length - b - 1]; + batches = ` + int b${b} = index / ${texelsInBatchN}; + index -= b${b} * ${texelsInBatchN}; + ` + batches; + coords = `b${b}, ` + coords; + } + const source = ` + ivec${shape2.length} getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${packedTexShape[0]}, ${packedTexShape[1]})); + int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x; + + ${batches} + + int b = index / ${texelsInBatch}; + index -= b * ${texelsInBatch}; + + // reverse r and c order for packed texture + int r = imod(index, ${texelsInLogicalRow}) * 2; + int c = 2 * (index / ${texelsInLogicalRow}); + + return ivec${shape2.length}(${coords}); + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 1D output coordinates. + */ + getOutputUnpacked1DCoords(_shape, texShape) { + const source = ` + int getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + return resTexRC.y * ${texShape[0]} + resTexRC.x; + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 2D output coordinates. + */ + getOutputUnpacked2DCoords(shape2, texShape) { + const source = ` + ivec2 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.y * ${texShape[0]} + resTexRC.x; + int r = index / ${shape2[1]}; + int c = index - r * ${shape2[1]}; + return ivec2(r, c); + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 3D output coordinates. + */ + getOutputUnpacked3DCoords(shape2, texShape) { + let source = ""; + const rank = shape2.length; + let strides = null; + if (rank < 2) { + strides = []; + } + strides = new Array(rank - 1); + strides[rank - 2] = shape2[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * shape2[i + 1]; + } + const coordsToCompute = ["r", "c", "d"]; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + source = ` + ivec3 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.y * ${texShape[0]} + resTexRC.x; + ${coordsFromIndexSnippet} + return ivec3(r, c, d); + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 4D output coordinates. + */ + getOutputUnpacked4DCoords(shape2, texShape) { + let source = ""; + const rank = shape2.length; + let strides = null; + if (rank < 2) { + strides = []; + } + strides = new Array(rank - 1); + strides[rank - 2] = shape2[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * shape2[i + 1]; + } + const coordsToCompute = ["r", "c", "d", "d2"]; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + source = ` + ivec4 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.y * ${texShape[0]} + resTexRC.x; + ${coordsFromIndexSnippet} + return ivec4(r, c, d, d2); + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 5D output coordinates. + */ + getOutputUnpacked5DCoords(shape2, texShape) { + let source = ""; + const rank = shape2.length; + let strides = null; + if (rank < 2) { + strides = []; + } + strides = new Array(rank - 1); + strides[rank - 2] = shape2[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * shape2[i + 1]; + } + const coordsToCompute = ["r", "c", "d", "d2", "d3"]; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + source = ` + ivec5 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.y * ${texShape[0]} + resTexRC.x; + ${coordsFromIndexSnippet} + return ivec5(r, c, d, d2, d3); + } + `; + return new GlslLibRoutine(source); + } + /** + * Unpacked 6D output coordinates. + */ + getOutputUnpacked6DCoords(shape2, texShape) { + let source = ""; + const rank = shape2.length; + let strides = null; + if (rank < 2) { + strides = []; + } + strides = new Array(rank - 1); + strides[rank - 2] = shape2[rank - 1]; + for (let i = rank - 3; i >= 0; --i) { + strides[i] = strides[i + 1] * shape2[i + 1]; + } + const coordsToCompute = ["r", "c", "d", "d2", "d3", "d4"]; + const coordsFromIndexSnippet = strides.map((stride, i) => { + const line1 = `int ${coordsToCompute[i]} = index / ${stride}`; + const line2 = i === strides.length - 1 ? `int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` : `index -= ${coordsToCompute[i]} * ${stride}`; + return `${line1}; ${line2};`; + }).join(""); + source = ` + ivec6 getOutputCoords() { + ivec2 resTexRC = ivec2(TexCoords.xy * + vec2(${texShape[0]}, ${texShape[1]})); + int index = resTexRC.y * ${texShape[0]} + resTexRC.x; + ${coordsFromIndexSnippet} + return ivec6(r, c, d, d2, d3, d4); + } + `; + return new GlslLibRoutine(source); + } + /** + * Generates code for common UV coords computation utility functions. + */ + getCommonUtilFuncs() { + const result = {}; + let funcName = "uvFromFlat"; + result[funcName] = new GlslLibRoutine(` + vec2 uvFromFlat(int texNumR, int texNumC, int index) { + int texC = index / texNumR; + int texR = index - texC * texNumR; + // TODO: swap texR, texC order in following function so row is corresponding to u and column is corresponding to + // v. + return (vec2(texR, texC) + halfCR) / vec2(texNumR, texNumC); + } + `); + funcName = "packedUVfrom1D"; + result[funcName] = new GlslLibRoutine(` + vec2 packedUVfrom1D(int texNumR, int texNumC, int index) { + int texelIndex = index / 2; + int texR = texelIndex / texNumC; + int texC = texelIndex - texR * texNumC; + return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); + } + `); + funcName = "packedUVfrom2D"; + result[funcName] = new GlslLibRoutine(` + vec2 packedUVfrom2D(int texNumR, int texNumC, int texelsInLogicalRow, int row, int col) { + int texelIndex = (row / 2) * texelsInLogicalRow + (col / 2); + int texR = texelIndex / texNumC; + int texC = texelIndex - texR * texNumC; + return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); + } + `); + funcName = "packedUVfrom3D"; + result[funcName] = new GlslLibRoutine(` + vec2 packedUVfrom3D(int texNumR, int texNumC, + int texelsInBatch, int texelsInLogicalRow, int b, + int row, int col) { + int index = b * texelsInBatch + (row / 2) * texelsInLogicalRow + (col / 2); + int texR = index / texNumC; + int texC = index - texR * texNumC; + return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR); + } + `); + funcName = "sampleTexture"; + const glsl = getGlsl(this.context.glContext.version); + result[funcName] = new GlslLibRoutine(` + float sampleTexture(sampler2D textureSampler, vec2 uv) { + return ${glsl.texture2D}(textureSampler, uv).r; + }`); + return result; + } + /** + * Constructing snippets for inputs + */ + getInputsSamplingSnippets() { + const result = {}; + const outputLayout = this.context.outputTextureLayout; + this.context.programInfo.inputNames.forEach((samplerName, i) => { + const inputLayout = this.context.inputTextureLayouts[i]; + const funcName = generateShaderFuncNameFromInputSamplerName(samplerName); + if (inputLayout.isPacked) { + result[funcName] = this.getPackedSamplerFromInput(funcName, samplerName, inputLayout); + } else { + result[funcName] = this.getUnpackedSamplerFromInput(funcName, samplerName, inputLayout); + } + const outCoordFuncName = generateShaderFuncNameFromInputSamplerNameAtOutCoords(samplerName); + if (inputLayout.unpackedShape.length <= outputLayout.unpackedShape.length) { + if (inputLayout.isPacked) { + result[outCoordFuncName] = this.getPackedSamplerAtOutputCoords(outCoordFuncName, inputLayout, outputLayout, samplerName); + } else { + result[outCoordFuncName] = this.getUnpackedSamplerAtOutputCoords(outCoordFuncName, inputLayout, outputLayout, samplerName); + } + } + }); + return result; + } + /** + * Constructing snippets for output coordinates of samplers + */ + getPackedSamplerAtOutputCoords(funcName, inputLayout, outputLayout, name2) { + const inShape = inputLayout.unpackedShape; + const outShape = outputLayout.unpackedShape; + const texName = name2; + const texFuncSnippet = generateShaderFuncNameFromInputSamplerName(texName); + const inRank = inShape.length; + const outRank = outShape.length; + const broadcastDims = BroadcastUtil.getBroadcastDims(inShape, outShape); + const type = getCoordsDataType(outRank); + const rankDiff = outRank - inRank; + let coordsSnippet; + const fields = getGlChannels(); + if (inRank === 0) { + coordsSnippet = ""; + } else if (outRank < 2 && broadcastDims.length >= 1) { + coordsSnippet = "coords = 0;"; + } else { + coordsSnippet = broadcastDims.map((d) => `coords.${fields[d + rankDiff]} = 0;`).join("\n"); + } + let unpackedCoordsSnippet = ""; + if (outRank < 2 && inRank > 0) { + unpackedCoordsSnippet = "coords"; + } else { + unpackedCoordsSnippet = inShape.map((_s, i) => `coords.${fields[i + rankDiff]}`).join(", "); + } + let output = "return outputValue;"; + const inSize = ShapeUtil.size(inShape); + const isInputScalar = inSize === 1; + const outSize = ShapeUtil.size(outShape); + const isOutputScalar = outSize === 1; + if (inRank === 1 && !isInputScalar && !isOutputScalar) { + output = ` + return vec4(outputValue.xy, outputValue.xy); + `; + } else if (isInputScalar && !isOutputScalar) { + if (outRank === 1) { + output = ` + return vec4(outputValue.x, outputValue.x, 0., 0.); + `; + } else { + output = ` + return vec4(outputValue.x); + `; + } + } else if (broadcastDims.length) { + const rows = inRank - 2; + const cols = inRank - 1; + if (broadcastDims.indexOf(rows) > -1 && broadcastDims.indexOf(cols) > -1) { + output = "return vec4(outputValue.x);"; + } else if (broadcastDims.indexOf(rows) > -1) { + output = "return vec4(outputValue.x, outputValue.y, outputValue.x, outputValue.y);"; + } else if (broadcastDims.indexOf(cols) > -1) { + output = "return vec4(outputValue.xx, outputValue.zz);"; + } + } + const swapLastDimsSnippet = ` + int lastDim = coords.${fields[outRank - 1]}; + coords.${fields[outRank - 1]} = coords.${fields[outRank - 2]}; + coords.${fields[outRank - 2]} = lastDim; + `; + const source = ` + vec4 ${funcName}() { + ${type} coords = getOutputCoords(); + ${swapLastDimsSnippet} + ${coordsSnippet} + vec4 outputValue = ${texFuncSnippet}(${unpackedCoordsSnippet}); + ${output} + } + `; + return new GlslLibRoutine(source, ["coordinates.getOutputCoords"]); + } + /** + * Constructing snippets for unpacked output coordinates of samplers + */ + getUnpackedSamplerAtOutputCoords(funcName, inputLayout, outputLayout, name2) { + const outTexShape = [outputLayout.width, outputLayout.height]; + const inTexShape = [inputLayout.width, inputLayout.height]; + const inRank = inputLayout.unpackedShape.length; + const outRank = outputLayout.unpackedShape.length; + const inShape = inputLayout.unpackedShape; + const outShape = outputLayout.unpackedShape; + const texFuncSnippet = generateShaderFuncNameFromInputSamplerName(name2); + if (inRank === outRank && ArrayUtil.arraysEqual(inTexShape, outTexShape)) { + const source2 = ` + float ${funcName}() { + return sampleTexture(${name2}, TexCoords); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + const type = getCoordsDataType(outRank); + const broadcastDims = BroadcastUtil.getBroadcastDims(inShape, outShape); + const rankDiff = outRank - inRank; + let coordsSnippet; + const fields = getGlChannels(); + if (inRank === 0) { + coordsSnippet = ""; + } else if (outRank < 2 && broadcastDims.length >= 1) { + coordsSnippet = "coords = 0;"; + } else { + coordsSnippet = broadcastDims.map((d) => `coords.${fields[d + rankDiff]} = 0;`).join("\n"); + } + let unpackedCoordsSnippet = ""; + if (outRank < 2 && inRank > 0) { + unpackedCoordsSnippet = "coords"; + } else { + unpackedCoordsSnippet = inputLayout.unpackedShape.map((_s, i) => `coords.${fields[i + rankDiff]}`).join(", "); + } + const source = ` + float ${funcName}() { + ${type} coords = getOutputCoords(); + ${coordsSnippet} + return ${texFuncSnippet}(${unpackedCoordsSnippet}); + } + `; + return new GlslLibRoutine(source, ["coordinates.getOutputCoords"]); + } + /** + * Constructing snippets for packed operations. + */ + getPackedSamplerFromInput(funcName, name2, inputLayout) { + switch (inputLayout.unpackedShape.length) { + case 0: + return this.getPackedSamplerScalar(funcName, name2); + case 1: + return this.getPackedSampler1D(funcName, name2, inputLayout); + case 2: + return this.getPackedSampler2D(funcName, name2, inputLayout); + case 3: + return this.getPackedSampler3D(funcName, name2, inputLayout); + default: + return this.getPackedSamplerND(funcName, name2, inputLayout); + } + } + /** + * Constructing snippets for unpacked operations. + */ + getUnpackedSamplerFromInput(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + switch (shape2.length) { + case 0: + return this.getUnpackedSamplerScalar(funcName, name2, inputLayout); + case 1: + return this.getUnpackedSampler1D(funcName, name2, inputLayout); + case 2: + return this.getUnpackedSampler2D(funcName, name2, inputLayout); + case 3: + return this.getUnpackedSampler3D(funcName, name2, inputLayout); + case 4: + return this.getUnpackedSampler4D(funcName, name2, inputLayout); + case 5: + return this.getUnpackedSampler5D(funcName, name2, inputLayout); + case 6: + return this.getUnpackedSampler6D(funcName, name2, inputLayout); + default: + throw new Error(`Unsupported dimension ${shape2.length}-D`); + } + } + /** + * Packed scalar snippet. + */ + getPackedSamplerScalar(funcName, name2) { + const glsl = getGlsl(this.context.glContext.version); + const source = ` + vec4 ${funcName}() { + return ${glsl.texture2D}(${name2}, halfCR); + } + `; + return new GlslLibRoutine(source); + } + /** + * Packed 1D snippet. + */ + getPackedSampler1D(funcName, name2, inputLayout) { + const texShape = [inputLayout.width, inputLayout.height]; + const packedTexShape = [texShape[1], texShape[0]]; + const glsl = getGlsl(this.context.glContext.version); + const packedSampler = `vec4 ${funcName}(int index) { + vec2 uv = packedUVfrom1D( + ${packedTexShape[0]}, ${packedTexShape[1]}, index); + return ${glsl.texture2D}(${name2}, uv); + }`; + const source = packedSampler; + return new GlslLibRoutine(source, ["coordinates.packedUVfrom1D"]); + } + /** + * Packed 2D snippet. + */ + getPackedSampler2D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const texShape = [inputLayout.width, inputLayout.height]; + const glsl = getGlsl(this.context.glContext.version); + const texNumR = texShape[0]; + const texNumC = texShape[1]; + if (texShape != null && ArrayUtil.arraysEqual(shape2, texShape)) { + const packedSampler2 = `vec4 ${funcName}(int row, int col) { + vec2 uv = (vec2(col, row) + halfCR) / vec2(${texNumC}.0, ${texNumR}.0); + return ${glsl.texture2D}(${name2}, uv); + }`; + return new GlslLibRoutine(packedSampler2); + } + const packedTexShape = texShape; + const valuesPerRow = Math.ceil(shape2[1] / 2); + const packedSampler = `vec4 ${funcName}(int row, int col) { + vec2 uv = packedUVfrom2D(${packedTexShape[1]}, ${packedTexShape[0]}, ${valuesPerRow}, row, col); + return ${glsl.texture2D}(${name2}, uv); + }`; + const source = packedSampler; + return new GlslLibRoutine(source, ["coordinates.packedUVfrom2D"]); + } + /** + * Packed 3D snippet. + */ + getPackedSampler3D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const texShape = [inputLayout.width, inputLayout.height]; + const packedTexShape = [texShape[0], texShape[1]]; + const glsl = getGlsl(this.context.glContext.version); + if (shape2[0] === 1) { + const squeezedShape = shape2.slice(1); + const keptDims = [1, 2]; + const newInputShape = squeezeInputShape(shape2, squeezedShape); + const params = ["b", "row", "col"]; + const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); + newInputLayout.unpackedShape = newInputShape; + const samplerRoutine = this.getPackedSamplerFromInput(funcName, name2, newInputLayout); + const packedSampler2 = `${samplerRoutine.routineBody} + vec4 ${funcName}(int b, int row, int col) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } `; + const source2 = packedSampler2; + return new GlslLibRoutine(source2, samplerRoutine.dependencies); + } + const texNumR = packedTexShape[0]; + const texNumC = packedTexShape[1]; + const valuesPerRow = Math.ceil(shape2[2] / 2); + const texelsInBatch = valuesPerRow * Math.ceil(shape2[1] / 2); + const packedSampler = `vec4 ${funcName}(int b, int row, int col) { + vec2 uv = packedUVfrom3D( + ${texNumC}, ${texNumR}, ${texelsInBatch}, ${valuesPerRow}, b, row, col); + return ${glsl.texture2D}(${name2}, uv);}`; + const source = packedSampler; + return new GlslLibRoutine(source, ["coordinates.packedUVfrom3D"]); + } + /* + * Packed ND snippet. + */ + getPackedSamplerND(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const rank = shape2.length; + const texShape = [inputLayout.width, inputLayout.height]; + const glsl = getGlsl(this.context.glContext.version); + const packedTexShape = [texShape[0], texShape[1]]; + const texNumR = packedTexShape[1]; + const texNumC = packedTexShape[0]; + const valuesPerRow = Math.ceil(shape2[rank - 1] / 2); + let texelsInBatch = valuesPerRow * Math.ceil(shape2[rank - 2] / 2); + let params = "int b, int row, int col"; + let index = `b * ${texelsInBatch} + (row / 2) * ${valuesPerRow} + (col / 2)`; + for (let b = 2; b < rank - 1; b++) { + params = `int b${b}, ` + params; + texelsInBatch *= shape2[rank - b - 1]; + index = `b${b} * ${texelsInBatch} + ` + index; + } + const packedSampler = `vec4 ${funcName}(${params}) { + int index = ${index}; + int texR = index / ${texNumC}; + int texC = index - texR * ${texNumC}; + vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${texNumC}, ${texNumR}); + return ${glsl.texture2D}(${name2}, uv); + }`; + const source = packedSampler; + return new GlslLibRoutine(source); + } + /** + * Unpacked scalar snippet. + */ + getUnpackedSamplerScalar(funcName, name2, inputLayout) { + const [texNumR, texNumC] = [inputLayout.width, inputLayout.height]; + if (texNumR === 1 && texNumC === 1) { + const source2 = ` + float ${funcName}() { + return sampleTexture(${name2}, halfCR); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + const source = ` + float ${funcName}() { + int offset_${name2} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC}); + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, offset_${name2}); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine( + source, + ["coordinates.uvFromFlat", "coordinates.sampleTexture", "coordinates.coordsToOffset"] + ); + } + /** + * Unpacked 1D snippet. + */ + getUnpackedSampler1D(funcName, name2, inputLayout) { + const tNumR = inputLayout.width; + const tNumC = inputLayout.height; + if (tNumC === 1 && tNumR === 1) { + const source2 = ` + float ${funcName}(int index) { + return sampleTexture(${name2}, halfCR); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + if (tNumC === 1) { + const source2 = ` + float ${funcName}(int index) { + vec2 uv = vec2((float(index) + 0.5) / ${tNumR}.0, 0.5); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + if (tNumR === 1) { + const source2 = ` + float ${funcName}(int index) { + vec2 uv = vec2(0.5, (float(index) + 0.5) / ${tNumC}.0); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + const source = ` + float ${funcName}(int index) { + vec2 uv = uvFromFlat(${tNumR}, ${tNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source, ["coordinates.uvFromFlat", "coordinates.sampleTexture"]); + } + /** + * Unpacked 2D snippet. + */ + getUnpackedSampler2D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const texShape = [inputLayout.height, inputLayout.width]; + if (texShape != null && ArrayUtil.arraysEqual(shape2, texShape)) { + const texNumR2 = texShape[1]; + const texNumC2 = texShape[0]; + const source2 = ` + float ${funcName}(int row, int col) { + vec2 uv = (vec2(row, col) + halfCR) / vec2(${texNumR2}.0, ${texNumC2}.0); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + const { newShape, keptDims } = squeezeShape(shape2); + const squeezedShape = newShape; + if (squeezedShape.length < shape2.length) { + const newInputShape = squeezeInputShape(shape2, squeezedShape); + const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); + newInputLayout.unpackedShape = newInputShape; + const params = ["col", "row"]; + const source2 = ` + ${this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout).routineBody} + float ${funcName}(int row, int col) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture"]); + } + const texNumR = texShape[1]; + const texNumC = texShape[0]; + if (texNumC === 1) { + const source2 = ` + float ${funcName}(int row, int col) { + int offset_${name2} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC}); + float index = dot(vec3(row, col, offset_${name2}), vec3(${shape2[1]}, 1, 1)); + vec2 uv = vec2(0.5, (index + 0.5) / ${texNumR}.0); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.coordsToOffset"]); + } + if (texNumR === 1) { + const source2 = ` + float ${funcName}(int row, int col) { + int offset_${name2} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC}); + float index = dot(vec3(row, col, offset_${name2}), vec3(${shape2[1]}, 1, 1)); + vec2 uv = vec2((index + 0.5) / ${texNumC}.0, 0.5); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.coordsToOffset"]); + } + const source = ` + float ${funcName}(int row, int col) { + int index = col * ${shape2[1]} + row; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine( + source, + ["coordinates.uvFromFlat", "coordinates.sampleTexture", "coordinates.coordsToOffset"] + ); + } + /** + * Unpacked 3D snippet. + */ + getUnpackedSampler3D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const stride0 = shape2[1] * shape2[2]; + const stride1 = shape2[2]; + const { newShape, keptDims } = squeezeShape(shape2); + const squeezedShape = newShape; + if (squeezedShape.length < shape2.length) { + const newInputShape = squeezeInputShape(shape2, squeezedShape); + const params = ["batch", "col", "row"]; + const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); + newInputLayout.unpackedShape = newInputShape; + const routine = this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout); + const revDims = keptDims.reverse(); + const source2 = ` + ${routine.routineBody} + float ${funcName}(int batch, int row, int col) { + return ${funcName}(${getSqueezedParams(params, revDims)}); + } + `; + return new GlslLibRoutine(source2, routine.dependencies); + } + const texNumR = inputLayout.width; + const texNumC = inputLayout.height; + const source = ` + float ${funcName}(int depth, int row, int col) { + // Explicitly use integer operations as dot() only works on floats. + int index = depth * ${stride0} + col * ${stride1} + row; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine( + source, + ["coordinates.uvFromFlat", "coordinates.sampleTexture", "coordinates.coordsToOffset"] + ); + } + /** + * Unpacked 4D snippet. + */ + getUnpackedSampler4D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const stride2 = shape2[3]; + const stride1 = shape2[2] * stride2; + const stride0 = shape2[1] * stride1; + const texNumR = inputLayout.width; + const texNumC = inputLayout.height; + const source = ` + float ${funcName}(int row, int col, int depth, int depth2) { + int index = row * ${stride0} + col * ${stride1} + + depth2 * ${stride2} + depth; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source, ["coordinates.uvFromFlat", "coordinates.sampleTexture"]); + } + /** + * Unpacked 5D snippet. + */ + getUnpackedSampler5D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const stride3 = shape2[4]; + const stride2 = shape2[3] * stride3; + const stride1 = shape2[2] * stride2; + const stride0 = shape2[1] * stride1; + const { newShape, keptDims } = squeezeShape(shape2); + if (newShape.length < shape2.length) { + const newInputShape = squeezeInputShape(shape2, newShape); + const params = ["row", "col", "depth", "depth2", "depth3"]; + const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); + newInputLayout.unpackedShape = newInputShape; + const source2 = ` + ${this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout).routineBody} + float ${funcName}(int row, int col, int depth, int depth2, int depth3) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.uvFromFlat"]); + } + const texNumR = inputLayout.width; + const texNumC = inputLayout.height; + const source = ` + float ${funcName}(int row, int col, int depth, int depth2, int depth3) { + int index = row * ${stride0} + col * ${stride1} + depth * ${stride2} + + depth3 * ${stride3} + depth2; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine(source, ["coordinates.sampleTexture", "coordinates.uvFromFlat"]); + } + /** + * Unpacked 6D snippet. + */ + getUnpackedSampler6D(funcName, name2, inputLayout) { + const shape2 = inputLayout.unpackedShape; + const stride4 = shape2[5]; + const stride3 = shape2[4] * stride4; + const stride2 = shape2[3] * stride3; + const stride1 = shape2[2] * stride2; + const stride0 = shape2[1] * stride1; + const { newShape, keptDims } = squeezeShape(shape2); + if (newShape.length < shape2.length) { + const newInputShape = squeezeInputShape(shape2, newShape); + const params = ["row", "col", "depth", "depth2", "depth3", "depth4"]; + const newInputLayout = JSON.parse(JSON.stringify(inputLayout)); + newInputLayout.unpackedShape = newInputShape; + const source2 = ` + ${this.getUnpackedSamplerFromInput(funcName, name2, newInputLayout).routineBody} + float ${funcName}(int row, int col, int depth, + int depth2, int depth3, int depth4) { + return ${funcName}(${getSqueezedParams(params, keptDims)}); + } + `; + return new GlslLibRoutine(source2, ["coordinates.sampleTexture", "coordinates.uvFromFlat"]); + } + const texNumR = inputLayout.width; + const texNumC = inputLayout.height; + const source = ` + float ${funcName}(int row, int col, int depth, + int depth2, int depth3, int depth4) { + int index = row * ${stride0} + col * ${stride1} + depth * ${stride2} + + depth2 * ${stride3} + depth3 * ${stride4} + depth4; + vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index); + return sampleTexture(${name2}, uv); + } + `; + return new GlslLibRoutine( + source, + ["coordinates.uvFromFlat", "coordinates.sampleTexture", "coordinates.coordsToOffset"] + ); + } + /** + * This is the main function to map from the given texture coordiantes (s,t) + * to logical indices for the output + * There will only be one single variation of this + * Also see coordsToOffset and offsetToIndices for input-specific versions + */ + toVec() { + const output = this.context.outputTextureLayout; + const rank = output.shape.length; + const strides = output.strides; + const xScale = output.width; + const yScale = output.height; + const stridesBlock = []; + for (let i = 0; i < rank - 1; ++i) { + stridesBlock.push(` + c[${i}] = offset / ${strides[i]};`); + stridesBlock.push(` + offset -= c[${i}] * ${strides[i]};`); + } + stridesBlock.push(` + c[${rank - 1}] = offset;`); + const body = ` + void toVec(vec2 texCoords, out int c[${rank}]) { + int offset = coordsToOffset(texCoords, ${xScale}, ${yScale}); + ${stridesBlock.join("")} + } + void toVec(int offset, out int c[${rank}]) { + ${stridesBlock.join("")} + } + `; + return { toVec: new GlslLibRoutine(body, ["coordinates.coordsToOffset"]) }; + } + /** + * These are value getter functions generated for each input + * Each function is hardwired to the name and dimensions of the input + * An '_T' variation is also produced which accesses values as if the + * input was transposed + */ + valueFrom() { + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const layout = this.context.inputTextureLayouts[i]; + const shape2 = layout.unpackedShape.length > 0 ? layout.unpackedShape : layout.shape; + const rank = shape2.length; + let funcName = `_${name2}`; + result[funcName] = new GlslLibRoutine( + this.getValueFromSingle(name2, rank, layout.width, layout.height, false), + [`shapeUtils.indicesToOffset${funcName}`, "coordinates.offsetToCoords", "fragcolor.getColorAsFloat"] + ); + funcName = funcName + "_T"; + result[funcName] = new GlslLibRoutine( + this.getValueFromSingle(name2, rank, layout.width, layout.height, true), + [`shapeUtils.indicesToOffset${funcName}`, "coordinates.offsetToCoords", "fragcolor.getColorAsFloat"] + ); + }); + return result; + } + /** + * Produces one value getter function for the name and rank given + * If a transpose is set proper offsetToCoords mapping will be used + * @param name name of the function + * @param rank rank of the input + * @param transpose whether or not should generate a transpose variation + */ + getValueFromSingle(varName, rank, width, height, transpose2) { + let name2 = `_${varName}`; + if (transpose2) { + name2 = name2 + "_T"; + } + const glsl = getGlsl(this.context.glContext.version); + return ` + float ${name2}(int m[${rank}]) { + int offset = indicesToOffset${name2}(m); + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + float value = getColorAsFloat(${glsl.texture2D}(${varName}, coords)); + return value; + } + `; + } + /** + * Produces a packed value getter function for the name and rank given + * If a transpose is set proper offsetToCoords mapping will be used + * @param name name of the function + * @param rank rank of the input + * @param transpose whether or not should generate a transpose variation + */ + getPackedValueFrom(varName, rank, width, height, transpose2) { + let name2 = `_${varName}_Pack`; + if (transpose2) { + name2 = name2 + "_T"; + } + const glsl = getGlsl(this.context.glContext.version); + return ` + vec4 ${name2}(int m[${rank}]) { + int offset = indicesToOffset_${varName}(m); + vec2 coords = offsetToCoords(offset, ${width}, ${height}); + return ${glsl.texture2D}(${varName}, coords); + } + `; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-encoding-lib.ts +var EncodingGlslLib; +var init_glsl_encoding_lib = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-encoding-lib.ts"() { + "use strict"; + init_glsl_definitions(); + EncodingGlslLib = class _EncodingGlslLib extends GlslLib { + constructor(context) { + super(context); + } + getFunctions() { + return { ...this.encodeFloat32(), ...this.decodeFloat32() }; + } + getCustomTypes() { + return {}; + } + encodeFloat32() { + return { + encode: new GlslLibRoutine(`highp vec4 encode(highp float f) { + return vec4(f, 0.0, 0.0, 0.0); + } + `) + }; + } + decodeFloat32() { + return { + decode: new GlslLibRoutine(`highp float decode(highp vec4 rgba) { + return rgba.r; + } + `) + }; + } + /** + * returns the routine to encode encode a 32bit float to a vec4 (of unsigned bytes) + * @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float + */ + encodeUint8() { + const endianness = _EncodingGlslLib.isLittleEndian() ? "rgba.rgba=rgba.abgr;" : ""; + return { + encode: new GlslLibRoutine(` + highp vec4 encode(highp float f) { + highp float F = abs(f); + highp float Sign = step(0.0,-f); + highp float Exponent = floor(log2(F)); + highp float Mantissa = (exp2(- Exponent) * F); + Exponent = floor(log2(F) + 127.0) + floor(log2(Mantissa)); + highp vec4 rgba; + rgba[0] = 128.0 * Sign + floor(Exponent*exp2(-1.0)); + rgba[1] = 128.0 * mod(Exponent,2.0) + mod(floor(Mantissa*128.0),128.0); + rgba[2] = floor(mod(floor(Mantissa*exp2(23.0 -8.0)),exp2(8.0))); + rgba[3] = floor(exp2(23.0)*mod(Mantissa,exp2(-15.0))); + ${endianness} + rgba = rgba / 255.0; // values need to be normalized to [0,1] + return rgba; + } + `) + }; + } + /** + * returns the routine to encode a vec4 of unsigned bytes to float32 + * @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float + */ + decodeUint8() { + const endianness = _EncodingGlslLib.isLittleEndian() ? "rgba.rgba=rgba.abgr;" : ""; + return { + decode: new GlslLibRoutine(` + highp float decode(highp vec4 rgba) { + rgba = rgba * 255.0; // values need to be de-normalized from [0,1] to [0,255] + ${endianness} + highp float Sign = 1.0 - step(128.0,rgba[0])*2.0; + highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0; + highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000); + highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 )); + return Result; + } + `) + }; + } + /** + * Determines if the machine is little endian or not + * @credit: https://gist.github.com/TooTallNate/4750953 + */ + static isLittleEndian() { + const b = new ArrayBuffer(4); + const a = new Uint32Array(b); + const c = new Uint8Array(b); + a[0] = 3735928559; + if (c[0] === 239) { + return true; + } + if (c[0] === 222) { + return false; + } + throw new Error("unknown endianness"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts +var FragColorGlslLib; +var init_glsl_fragcolor_lib = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts"() { + "use strict"; + init_glsl_definitions(); + init_glsl_source(); + FragColorGlslLib = class extends GlslLib { + constructor(context) { + super(context); + } + getFunctions() { + return { ...this.setFragColor(), ...this.getColorAsFloat() }; + } + getCustomTypes() { + return {}; + } + setFragColor() { + const glsl = getGlsl(this.context.glContext.version); + return { + setFragColor: new GlslLibRoutine( + ` + void setFragColor(float value) { + ${glsl.output} = encode(value); + } + `, + ["encoding.encode"] + ) + }; + } + getColorAsFloat() { + return { + getColorAsFloat: new GlslLibRoutine( + ` + float getColorAsFloat(vec4 color) { + return decode(color); + } + `, + ["encoding.decode"] + ) + }; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts +var ShapeUtilsGlslLib; +var init_glsl_shape_utils_lib = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts"() { + "use strict"; + init_glsl_definitions(); + ShapeUtilsGlslLib = class _ShapeUtilsGlslLib extends GlslLib { + constructor(context) { + super(context); + } + getFunctions() { + return { + ...this.bcastIndex(), + ...this.bcastMatmulIndex(), + ...this.offsetToIndices(), + ...this.indicesToOffset(), + ...this.incrementIndices() + }; + } + getCustomTypes() { + return {}; + } + bcastIndex() { + const outputRank = this.context.outputTextureLayout.shape.length; + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const shape2 = this.context.inputTextureLayouts[i].unpackedShape; + if (shape2.length <= outputRank) { + const rank = shape2.length; + const dimOffset = outputRank - rank; + const funcName = `bcastIndices_${name2}`; + let block = ""; + for (let i2 = 0; i2 < rank; ++i2) { + block += ` + realIndices[${i2}] = int( mod(float(bcastedIndices[${dimOffset + i2}]), ${shape2[i2]}.0) ); + `; + } + const body = ` + void ${funcName} (int bcastedIndices[${outputRank}], out int realIndices[${rank}]) { + ${block} + } + `; + result[funcName] = new GlslLibRoutine(body); + } + }); + return result; + } + bcastMatmulIndex() { + const outputRank = this.context.outputTextureLayout.shape.length; + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const shape2 = this.context.inputTextureLayouts[i].shape; + if (!(shape2.length < 2 || shape2.length > outputRank)) { + const rank = shape2.length; + const dimOffset = outputRank - rank; + const funcName = `bcastMatmulIndices_${name2}`; + let block = ""; + for (let i2 = 0; i2 < rank - 2; ++i2) { + block += ` + realIndices[${i2}] = int( mod(float(bcastedIndices[${dimOffset + i2}]), ${shape2[i2]}.0) ); + `; + } + const body = ` + void ${funcName}(int bcastedIndices[${outputRank}], out int realIndices[${rank}]) { + ${block} + realIndices[${rank - 1}] = bcastedIndices[${outputRank - 1}]; + realIndices[${rank - 2}] = bcastedIndices[${outputRank - 2}]; + } + `; + result[funcName] = new GlslLibRoutine(body); + } + }); + return result; + } + indicesToOffset() { + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const shape2 = this.context.inputTextureLayouts[i].shape; + const strides = this.context.inputTextureLayouts[i].strides; + const rank = shape2.length; + let funcName = `indicesToOffset_${name2}`; + result[funcName] = new GlslLibRoutine(_ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides)); + funcName = `indicesToOffset_${name2}_T`; + result[funcName] = new GlslLibRoutine(_ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides.slice().reverse())); + }); + return result; + } + static indexToOffsetSingle(name2, rank, strides) { + let block = ""; + for (let i = rank - 1; i >= 0; --i) { + block += ` + offset += indices[${i}] * ${strides[i]}; + `; + } + return ` + int ${name2}(int indices[${rank}]) { + int offset = 0; + ${block} + return offset; + } + `; + } + offsetToIndices() { + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const shape2 = this.context.inputTextureLayouts[i].shape; + const strides = this.context.inputTextureLayouts[i].strides; + const rank = shape2.length; + let funcName = `offsetToIndices_${name2}`; + result[funcName] = new GlslLibRoutine(_ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides)); + funcName = `offsetToIndices_${name2}_T`; + result[funcName] = new GlslLibRoutine(_ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides.slice().reverse())); + }); + return result; + } + static offsetToIndicesSingle(name2, rank, strides) { + const stridesBlock = []; + for (let i = 0; i < rank - 1; ++i) { + stridesBlock.push(` + indices[${i}] = offset / ${strides[i]};`); + stridesBlock.push(` + offset -= indices[${i}] * ${strides[i]};`); + } + stridesBlock.push(` + indices[${rank - 1}] = offset;`); + return ` + void ${name2}(int offset, out int indices[${rank}]) { + ${stridesBlock.join("")} + } + `; + } + incrementIndices() { + const result = {}; + this.context.programInfo.inputNames.forEach((name2, i) => { + const shape2 = this.context.inputTextureLayouts[i].shape; + const rank = shape2.length; + const funcName = `incrementIndices_${name2}`; + let shapeInit = ""; + for (let i2 = 0; i2 < rank; ++i2) { + shapeInit += ` + shape[${i2}] = ${shape2[i2]};`; + } + const body = ` + void ${funcName}(int axis, out int indices[${rank}]) { + int shape[${rank}]; + ${shapeInit}; + for(int i = ${rank} -1 ; i >= 0; --i) { + if(i > axis) continue; + indices[i] += 1; + if(indices[i] < shape[i]) { + break; + } + indices[i] = 0; + } + } + `; + result[funcName] = new GlslLibRoutine(body); + }); + return result; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-vec-lib.ts +var VecGlslLib; +var init_glsl_vec_lib = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-vec-lib.ts"() { + "use strict"; + init_glsl_definitions(); + VecGlslLib = class extends GlslLib { + constructor(context) { + super(context); + } + getCustomTypes() { + return {}; + } + getFunctions() { + return { ...this.binaryVecFunctions(), ...this.copyVec(), ...this.setVecItem(), ...this.getVecItem() }; + } + binaryVecFunctions() { + const outputLayout = this.context.outputTextureLayout; + const rank = outputLayout.shape.length; + const nameOp = { add: "+=", sub: "-=", mul: "*=", div: "/=" }; + const result = {}; + for (const name2 in nameOp) { + const fname = `${name2}Vec`; + let assignmentBlock = ""; + for (let i = 0; i < rank; ++i) { + assignmentBlock += ` + dest[${i}] ${nameOp[name2]} src[${i}]; + `; + } + const body = ` + void ${fname}(int src[${rank}], out int dest[${rank}]) { + ${assignmentBlock} + } + `; + result[fname] = new GlslLibRoutine(body); + } + return result; + } + copyVec() { + const outputLayout = this.context.outputTextureLayout; + const rank = outputLayout.shape.length; + let assignmentBlock = ""; + for (let i = 0; i < rank; ++i) { + assignmentBlock += ` + dest[${i}] = src[${i}]; + `; + } + const body = ` + void copyVec(int src[${rank}], out int dest[${rank}]) { + ${assignmentBlock} + } + `; + return { copyVec: new GlslLibRoutine(body) }; + } + setVecItem() { + const outputLayout = this.context.outputTextureLayout; + const rank = outputLayout.shape.length; + let block = ` + if(index < 0) + index =${rank} + index; + if (index == 0) + m[0] = value; + `; + for (let i = 1; i < rank - 1; ++i) { + block += ` + else if (index == ${i}) + m[${i}] = value; + `; + } + block += ` + else + m[${rank - 1}] = value; + `; + const body = ` + void setVecItem(out int m[${rank}], int index, int value) { + ${block} + } + `; + return { setVecItem: new GlslLibRoutine(body) }; + } + getVecItem() { + const outputLayout = this.context.outputTextureLayout; + const rank = outputLayout.shape.length; + let block = ` + if(index < 0) + index = ${rank} + index; + if (index == 0) + return m[0]; + `; + for (let i = 1; i < rank - 1; ++i) { + block += ` + else if (index == ${i}) + return m[${i}]; + `; + } + block += ` + else + return m[${rank - 1}]; + `; + const body = ` + int getVecItem(int m[${rank}], int index) { + ${block} + } + `; + return { getVecItem: new GlslLibRoutine(body) }; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-registered-libs.ts +var glslRegistry; +var init_glsl_registered_libs = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-registered-libs.ts"() { + "use strict"; + init_glsl_coordinate_lib(); + init_glsl_encoding_lib(); + init_glsl_fragcolor_lib(); + init_glsl_shape_utils_lib(); + init_glsl_vec_lib(); + glslRegistry = { + "encoding": EncodingGlslLib, + "fragcolor": FragColorGlslLib, + "vec": VecGlslLib, + "shapeUtils": ShapeUtilsGlslLib, + "coordinates": CoordsGlslLib + // 'arrays': ArrayGlslSLib + }; + } +}); + +// web/lib/onnxjs/backends/webgl/glsl-preprocessor.ts +var GlslPreprocessor; +var init_glsl_preprocessor = __esm({ + "web/lib/onnxjs/backends/webgl/glsl-preprocessor.ts"() { + "use strict"; + init_glsl_definitions(); + init_glsl_function_inliner(); + init_glsl_registered_libs(); + init_glsl_source(); + GlslPreprocessor = class { + constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) { + this.libs = {}; + this.glslLibRoutineDependencyGraph = {}; + this.context = new GlslContext(glContext, programInfo, inputTextureLayouts, outputTextureLayout); + Object.keys(glslRegistry).forEach((name2) => { + const lib = new glslRegistry[name2](this.context); + this.libs[name2] = lib; + }); + const map = this.glslLibRoutineDependencyGraph; + for (const libName in this.libs) { + const lib = this.libs[libName]; + const routinesInLib = lib.getFunctions(); + for (const routine in routinesInLib) { + const key = libName + "." + routine; + let currentNode; + if (map[key]) { + currentNode = map[key]; + currentNode.routineBody = routinesInLib[routine].routineBody; + } else { + currentNode = new GlslLibRoutineNode(key, routinesInLib[routine].routineBody); + map[key] = currentNode; + } + const dependencies = routinesInLib[routine].dependencies; + if (dependencies) { + for (let i = 0; i < dependencies.length; ++i) { + if (!map[dependencies[i]]) { + const node = new GlslLibRoutineNode(dependencies[i]); + map[dependencies[i]] = node; + currentNode.addDependency(node); + } else { + currentNode.addDependency(map[dependencies[i]]); + } + } + } + } + } + } + preprocess() { + const programInfo = this.context.programInfo; + let source = programInfo.shaderSource; + if (!this.context.programInfo.hasMain) { + source = `${source} + ${getDefaultFragShaderMain(this.context.glContext.version, this.context.outputTextureLayout.shape.length)}`; + } + source = replaceInlines(source); + return `${getFragShaderPreamble(this.context.glContext.version)} + ${this.getUniforms(programInfo.inputNames, programInfo.variables)} + ${this.getImports(source)} + ${source}`; + } + getImports(script) { + const routinesIncluded = this.selectGlslLibRoutinesToBeIncluded(script); + if (routinesIncluded.length === 0) { + return ""; + } + let routines = ""; + for (let i = 0; i < routinesIncluded.length; ++i) { + if (routinesIncluded[i].routineBody) { + routines += routinesIncluded[i].routineBody + "\n"; + } else { + throw new Error(`Missing body for the Glsl Library routine: ${routinesIncluded[i].name}`); + } + } + return routines; + } + selectGlslLibRoutinesToBeIncluded(script) { + const nodes = []; + Object.keys(this.glslLibRoutineDependencyGraph).forEach((classAndRoutine) => { + const routine = classAndRoutine.split(".")[1]; + if (script.indexOf(routine) !== -1) { + nodes.push(this.glslLibRoutineDependencyGraph[classAndRoutine]); + } + }); + return TopologicalSortGlslRoutines.returnOrderedNodes(nodes); + } + getUniforms(samplers, variables) { + const uniformLines = []; + if (samplers) { + for (const sampler of samplers) { + uniformLines.push(`uniform sampler2D ${sampler};`); + } + } + if (variables) { + for (const variable of variables) { + uniformLines.push( + `uniform ${variable.type} ${variable.name}${variable.arrayLength ? `[${variable.arrayLength}]` : ""};` + ); + } + } + return uniformLines.join("\n"); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/program-manager.ts +var ProgramManager; +var init_program_manager = __esm({ + "web/lib/onnxjs/backends/webgl/program-manager.ts"() { + "use strict"; + init_esm(); + init_instrument(); + init_glsl_preprocessor(); + init_glsl_source(); + ProgramManager = class { + constructor(profiler, glContext, textureLayoutStrategy) { + this.profiler = profiler; + this.glContext = glContext; + this.textureLayoutStrategy = textureLayoutStrategy; + this.repo = /* @__PURE__ */ new Map(); + this.attributesBound = false; + } + getArtifact(key) { + return this.repo.get(key); + } + setArtifact(key, artifact) { + this.repo.set(key, artifact); + } + run(buildArtifact, inputs, output) { + this.profiler.event("op", `ProgramManager.run ${buildArtifact.programInfo.name ?? "unknown kernel"}`, () => { + const gl = this.glContext.gl; + const program = buildArtifact.program; + gl.useProgram(program); + try { + this.bindOutput(output); + if (!this.attributesBound) { + this.bindAttributes(buildArtifact.attribLocations); + } + this.bindUniforms(buildArtifact.uniformLocations, buildArtifact.programInfo.variables ?? [], inputs); + } catch (err) { + Logger.error("ProgramManager", buildArtifact.programInfo.shaderSource); + throw err; + } + this.profiler.event("backend", "GlContext.draw()", () => { + this.glContext.draw(); + }); + }, this.glContext); + } + dispose() { + if (this.vertexShader) { + this.glContext.deleteShader(this.vertexShader); + } + this.repo.forEach((a) => this.glContext.deleteProgram(a.program)); + } + build(programInfo, inputTextureLayouts, outputTextureLayout) { + return this.profiler.event("backend", "ProgramManager.build", () => { + const preprocessor = new GlslPreprocessor(this.glContext, programInfo, inputTextureLayouts, outputTextureLayout); + const fragScript = preprocessor.preprocess(); + const program = this.compile(fragScript); + const artifact = { + programInfo, + program, + uniformLocations: this.getUniformLocations( + program, + preprocessor.context.programInfo.inputNames, + preprocessor.context.programInfo.variables + ), + attribLocations: this.getAttribLocations(program) + }; + return artifact; + }); + } + compile(fragShaderScript) { + if (!this.vertexShader) { + Logger.verbose("ProrgramManager", "Compiling and caching Vertex shader for the first time"); + const vertexShaderScript = getVertexShaderSource(this.glContext.version); + this.vertexShader = this.glContext.compileShader(vertexShaderScript, this.glContext.gl.VERTEX_SHADER); + } + if (env2.debug) { + Logger.verbose("ProrgramManager", `FragShader: +${fragShaderScript} +`); + } + const fragShader = this.glContext.compileShader(fragShaderScript, this.glContext.gl.FRAGMENT_SHADER); + const program = this.glContext.createProgram(this.vertexShader, fragShader); + this.glContext.deleteShader(fragShader); + return program; + } + bindOutput(td) { + const width = td.width; + const height = td.height; + Logger.verbose( + "ProrgramManager", + `Binding output texture to Framebuffer: w/h=${width}/${height}, shape=${td.shape}, type=${td.tensor.type}` + ); + this.glContext.attachFramebuffer(td.texture, width, height); + } + bindAttributes(attribLocations) { + const positionHandle = attribLocations.position; + const textureCoordHandle = attribLocations.textureCoord; + this.glContext.setVertexAttributes(positionHandle, textureCoordHandle); + this.attributesBound = true; + } + bindUniforms(uniformLocations, variables, textures) { + const gl = this.glContext.gl; + let texturePosition = 0; + for (const { name: name2, type, location, arrayLength } of uniformLocations) { + const value = variables.find((v) => v.name === name2)?.data; + if (type !== "sampler2D" && !value) { + throw new Error(`variable '${name2}' does not have data defined in program info`); + } + switch (type) { + case "sampler2D": + this.bindTexture(textures[texturePosition], location, texturePosition); + texturePosition++; + break; + case "float": + if (arrayLength) { + gl.uniform1fv(location, value); + } else { + gl.uniform1f(location, value); + } + break; + case "int": + if (arrayLength) { + gl.uniform1iv(location, value); + } else { + gl.uniform1i(location, value); + } + break; + default: + throw new Error(`Uniform not implemented: ${type}`); + } + } + } + bindTexture(td, uniformHandle, position) { + this.glContext.bindTextureToUniform(td.texture, position, uniformHandle); + } + getAttribLocations(program) { + return { + position: this.getAttribLocation(program, "position"), + textureCoord: this.getAttribLocation(program, "textureCoord") + }; + } + getUniformLocations(program, samplers, variables) { + const uniformLocations = []; + if (samplers) { + for (const sampler of samplers) { + uniformLocations.push({ name: sampler, type: "sampler2D", location: this.getUniformLocation(program, sampler) }); + } + } + if (variables) { + for (const variable of variables) { + uniformLocations.push({ ...variable, location: this.getUniformLocation(program, variable.name) }); + } + } + return uniformLocations; + } + getUniformLocation(program, name2) { + const gl = this.glContext.gl; + const reference = gl.getUniformLocation(program, name2); + if (reference === null) { + throw new Error(`Uniform ${name2} not found.`); + } + return reference; + } + getAttribLocation(program, name2) { + const gl = this.glContext.gl; + const attributeLocation = gl.getAttribLocation(program, name2); + return attributeLocation; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/texture-manager.ts +var TextureManager; +var init_texture_manager = __esm({ + "web/lib/onnxjs/backends/webgl/texture-manager.ts"() { + "use strict"; + init_instrument(); + init_texture_data_encoder(); + TextureManager = class { + constructor(glContext, layoutStrategy, profiler, config) { + this.glContext = glContext; + this.layoutStrategy = layoutStrategy; + this.profiler = profiler; + this.config = config; + this.pendingRead = /* @__PURE__ */ new Map(); + if (config.reuseTextures) { + this.inUseTextures = /* @__PURE__ */ new Map(); + this.idleTextures = /* @__PURE__ */ new Map(); + this.textureLookup = /* @__PURE__ */ new Map(); + } + } + createTextureFromLayout(dataType, layout, data, usage) { + const textureDataType = this.toEncoderType(dataType); + const encoder = this.glContext.getEncoder(textureDataType, layout.channels || 1, usage); + if (layout.isPacked && usage === 1 /* UploadOnly */) { + throw new Error("not implemented"); + } + const width = layout.width; + const height = layout.height; + let key; + let inUseTextures; + if (this.config.reuseTextures) { + key = `${width}x${height}_${encoder.format}_${encoder.internalFormat}_${encoder.textureType}`; + inUseTextures = this.inUseTextures.get(key); + if (!inUseTextures) { + inUseTextures = []; + this.inUseTextures.set(key, inUseTextures); + } + const idleTextures = this.idleTextures.get(key); + if (idleTextures && idleTextures.length > 0) { + const texture2 = idleTextures.pop(); + inUseTextures.push(texture2); + if (usage === 1 /* UploadOnly */) { + this.glContext.updateTexture(texture2, width, height, encoder, this.toTextureData(dataType, data)); + } + return texture2; + } + } + Logger.verbose("TextureManager", `Creating new texture of size ${layout.width}x${layout.height}`); + const texture = this.glContext.allocateTexture(width, height, encoder, this.toTextureData(dataType, data)); + if (this.config.reuseTextures) { + inUseTextures.push(texture); + this.textureLookup.set(texture, key); + } + return texture; + } + readTexture(td, dataType, channels) { + if (!channels) { + channels = 1; + } + return this.profiler.event("backend", "TextureManager.readTexture", () => { + const dataSize = td.shape.reduce((a, b) => a * b) * channels; + const data = this.glContext.readTexture( + td.texture, + td.width, + td.height, + dataSize, + this.toEncoderType(dataType), + channels + ); + return this.toTensorData(dataType, data); + }); + } + async readTextureAsync(td, dataType, channels) { + const dataId = td.tensor.dataId; + if (!channels) { + channels = 1; + } + if (this.pendingRead.has(dataId)) { + const subscribers = this.pendingRead.get(dataId); + return new Promise((resolve) => subscribers?.push(resolve)); + } + return this.profiler.event("backend", "TextureManager.readTextureAsync", async () => { + this.pendingRead.set(dataId, []); + const dataSize = td.shape.reduce((a, b) => a * b) * channels; + await this.glContext.createAndWaitForFence(); + const data = this.glContext.readTexture( + td.texture, + td.width, + td.height, + dataSize, + this.toEncoderType(dataType), + channels + ); + const tensorData = this.toTensorData(dataType, data); + const subscribers = this.pendingRead.get(dataId); + this.pendingRead.delete(dataId); + subscribers?.forEach((resolve) => resolve(tensorData)); + return tensorData; + }); + } + readUint8TextureAsFloat(td) { + return this.profiler.event("backend", "TextureManager.readUint8TextureAsFloat", () => { + const dataSize = td.shape.reduce((a, b) => a * b); + const data = this.glContext.readTexture(td.texture, td.width, td.height, dataSize * 4, "byte", 4); + return new Float32Array(data.buffer, data.byteOffset, dataSize); + }); + } + releaseTexture(textureData, deleteTexture) { + let key; + if (this.config.reuseTextures) { + key = this.textureLookup.get(textureData.texture); + if (key) { + if (deleteTexture) { + this.textureLookup.delete(key); + } + const inUseTextures = this.inUseTextures.get(key); + if (inUseTextures) { + const index = inUseTextures.indexOf(textureData.texture); + if (index !== -1) { + inUseTextures.splice(index, 1); + let idleTextures = this.idleTextures.get(key); + if (!idleTextures) { + idleTextures = []; + this.idleTextures.set(key, idleTextures); + } + idleTextures.push(textureData.texture); + } + } + } + } + if (!key || deleteTexture) { + Logger.verbose("TextureManager", `Deleting texture of size ${textureData.width}x${textureData.height}`); + this.glContext.deleteTexture(textureData.texture); + } + } + toTensorData(dataType, data) { + switch (dataType) { + case "int16": + return data instanceof Int16Array ? data : Int16Array.from(data); + case "int32": + return data instanceof Int32Array ? data : Int32Array.from(data); + case "int8": + return data instanceof Int8Array ? data : Int8Array.from(data); + case "uint16": + return data instanceof Uint16Array ? data : Uint16Array.from(data); + case "uint32": + return data instanceof Uint32Array ? data : Uint32Array.from(data); + case "uint8": + case "bool": + return data instanceof Uint8Array ? data : Uint8Array.from(data); + case "float32": + return data instanceof Float32Array ? data : Float32Array.from(data); + case "float64": + return data instanceof Float64Array ? data : Float64Array.from(data); + default: + throw new Error(`TensorData type ${dataType} is not supported`); + } + } + toTextureData(_dataType, data) { + if (!data) { + return void 0; + } + return data instanceof Float32Array ? data : new Float32Array(data); + } + toEncoderType(_dataType) { + return "float"; + } + clearActiveTextures() { + this.glContext.clearActiveTextures(); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/session-handler.ts +var WebGLSessionHandler; +var init_session_handler = __esm({ + "web/lib/onnxjs/backends/webgl/session-handler.ts"() { + "use strict"; + init_instrument(); + init_opset(); + init_inference_handler(); + init_op_resolve_rules(); + init_program_manager(); + init_texture_layout_strategy(); + init_texture_manager(); + WebGLSessionHandler = class { + constructor(backend2, context) { + this.backend = backend2; + this.context = context; + this.layoutStrategy = new PreferLogicalStrategy(backend2.glContext.maxTextureSize); + this.programManager = new ProgramManager(this.context.profiler, backend2.glContext, this.layoutStrategy); + this.textureManager = new TextureManager( + backend2.glContext, + this.layoutStrategy, + this.context.profiler, + { reuseTextures: backend2.textureCacheMode === "full" } + ); + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + this.pack = backend2.pack; + this.pack2unpackMap = /* @__PURE__ */ new Map(); + this.unpack2packMap = /* @__PURE__ */ new Map(); + } + createInferenceHandler() { + return new WebGLInferenceHandler(this); + } + onGraphInitialized(graph) { + const initializers = graph.getValues().filter((v) => v.from === -1 && v.tensor).map((v) => v.tensor.dataId); + this.initializers = new Set(initializers); + } + isInitializer(tensorId) { + return this.initializers ? this.initializers.has(tensorId) : false; + } + addInitializer(tensorId) { + this.initializers.add(tensorId); + } + getTextureData(tensorId, isPacked) { + if (isPacked) { + return this.packedTextureDataCache.get(tensorId); + } else { + return this.unpackedTextureDataCache.get(tensorId); + } + } + setTextureData(tensorId, textureData, isPacked = false) { + Logger.verbose("WebGLSessionHandler", "Storing Texture data in cache"); + if (isPacked) { + this.packedTextureDataCache.set(tensorId, textureData); + } else { + this.unpackedTextureDataCache.set(tensorId, textureData); + } + } + dispose() { + this.programManager.dispose(); + this.textureManager.clearActiveTextures(); + this.packedTextureDataCache.forEach((td) => this.textureManager.releaseTexture(td, true)); + this.packedTextureDataCache = /* @__PURE__ */ new Map(); + this.unpackedTextureDataCache.forEach((td) => this.textureManager.releaseTexture(td, true)); + this.unpackedTextureDataCache = /* @__PURE__ */ new Map(); + } + resolve(node, opsets, graph) { + const op = resolveOperator(node, opsets, WEBGL_OP_RESOLVE_RULES); + return { impl: op.opImpl, context: op.opInit ? op.opInit(node, graph) : node }; + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/webgl-context.ts +function linearSearchLastTrue(arr) { + let i = 0; + for (; i < arr.length; ++i) { + const isDone = arr[i](); + if (!isDone) { + break; + } + } + return i - 1; +} +var WebGLContext; +var init_webgl_context = __esm({ + "web/lib/onnxjs/backends/webgl/webgl-context.ts"() { + "use strict"; + init_esm(); + init_texture_data_encoder(); + init_texture_data_encoder(); + init_utils(); + WebGLContext = class { + constructor(gl, version3) { + this.frameBufferBound = false; + this.itemsToPoll = []; + this.gl = gl; + this.version = version3; + this.getExtensions(); + this.vertexbuffer = this.createVertexbuffer(); + this.framebuffer = this.createFramebuffer(); + this.queryVitalParameters(); + } + allocateTexture(width, height, encoder, data) { + const gl = this.gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + const buffer = data ? encoder.encode(data, width * height) : null; + gl.texImage2D( + gl.TEXTURE_2D, + 0, + // Level of detail. + encoder.internalFormat, + width, + height, + 0, + // Always 0 in OpenGL ES. + encoder.format, + encoder.textureType, + buffer + ); + this.checkError(); + return texture; + } + updateTexture(texture, width, height, encoder, data) { + const gl = this.gl; + gl.bindTexture(gl.TEXTURE_2D, texture); + const buffer = encoder.encode(data, width * height); + gl.texSubImage2D( + gl.TEXTURE_2D, + 0, + // level + 0, + // xoffset + 0, + // yoffset + width, + height, + encoder.format, + encoder.textureType, + buffer + ); + this.checkError(); + } + attachFramebuffer(texture, width, height) { + const gl = this.gl; + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + texture, + 0 + ); + this.checkError(); + gl.viewport(0, 0, width, height); + gl.scissor(0, 0, width, height); + } + readTexture(texture, width, height, dataSize, dataType, channels) { + const gl = this.gl; + if (!channels) { + channels = 1; + } + if (!this.frameBufferBound) { + this.attachFramebuffer(texture, width, height); + } + const encoder = this.getEncoder(dataType, channels); + const buffer = encoder.allocate(width * height); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + texture, + 0 + ); + gl.readPixels(0, 0, width, height, gl.RGBA, encoder.textureType, buffer); + this.checkError(); + return encoder.decode(buffer, dataSize); + } + isFramebufferReady() { + return true; + } + getActiveTexture() { + const gl = this.gl; + const n = gl.getParameter(this.gl.ACTIVE_TEXTURE); + return `TEXTURE${n - gl.TEXTURE0}`; + } + getTextureBinding() { + return this.gl.getParameter(this.gl.TEXTURE_BINDING_2D); + } + getFramebufferBinding() { + return this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING); + } + setVertexAttributes(positionHandle, textureCoordHandle) { + const gl = this.gl; + gl.vertexAttribPointer(positionHandle, 3, gl.FLOAT, false, 20, 0); + gl.enableVertexAttribArray(positionHandle); + if (textureCoordHandle !== -1) { + gl.vertexAttribPointer(textureCoordHandle, 2, gl.FLOAT, false, 20, 12); + gl.enableVertexAttribArray(textureCoordHandle); + } + this.checkError(); + } + createProgram(vertexShader, fragShader) { + const gl = this.gl; + const program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragShader); + gl.linkProgram(program); + return program; + } + compileShader(shaderSource, shaderType) { + const gl = this.gl; + const shader = gl.createShader(shaderType); + if (!shader) { + throw new Error(`createShader() returned null with type ${shaderType}`); + } + gl.shaderSource(shader, shaderSource); + gl.compileShader(shader); + if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) === false) { + throw new Error(`Failed to compile shader: ${gl.getShaderInfoLog(shader)} +Shader source: +${shaderSource}`); + } + return shader; + } + deleteShader(shader) { + this.gl.deleteShader(shader); + } + bindTextureToUniform(texture, position, uniformHandle) { + const gl = this.gl; + gl.activeTexture(gl.TEXTURE0 + position); + this.checkError(); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.checkError(); + gl.uniform1i(uniformHandle, position); + this.checkError(); + } + draw() { + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4); + this.checkError(); + } + checkError() { + if (env2.debug) { + const gl = this.gl; + const error = gl.getError(); + let label = ""; + switch (error) { + case gl.NO_ERROR: + return; + case gl.INVALID_ENUM: + label = "INVALID_ENUM"; + break; + case gl.INVALID_VALUE: + label = "INVALID_VALUE"; + break; + case gl.INVALID_OPERATION: + label = "INVALID_OPERATION"; + break; + case gl.INVALID_FRAMEBUFFER_OPERATION: + label = "INVALID_FRAMEBUFFER_OPERATION"; + break; + case gl.OUT_OF_MEMORY: + label = "OUT_OF_MEMORY"; + break; + case gl.CONTEXT_LOST_WEBGL: + label = "CONTEXT_LOST_WEBGL"; + break; + default: + label = `Unknown WebGL Error: ${error.toString(16)}`; + } + throw new Error(label); + } + } + deleteTexture(texture) { + this.gl.deleteTexture(texture); + } + deleteProgram(program) { + this.gl.deleteProgram(program); + } + getEncoder(dataType, channels, usage = 0 /* Default */) { + if (this.version === 2) { + return new RedFloat32DataEncoder(this.gl, channels); + } + switch (dataType) { + case "float": + if (usage === 1 /* UploadOnly */ || this.isRenderFloat32Supported) { + return new RGBAFloatDataEncoder(this.gl, channels); + } else { + return new RGBAFloatDataEncoder( + this.gl, + channels, + this.textureHalfFloatExtension.HALF_FLOAT_OES + ); + } + case "int": + throw new Error("not implemented"); + case "byte": + return new Uint8DataEncoder(this.gl, channels); + default: + throw new Error(`Invalid dataType: ${dataType}`); + } + } + clearActiveTextures() { + const gl = this.gl; + for (let unit = 0; unit < this.maxTextureImageUnits; ++unit) { + gl.activeTexture(gl.TEXTURE0 + unit); + gl.bindTexture(gl.TEXTURE_2D, null); + } + } + dispose() { + if (this.disposed) { + return; + } + const gl = this.gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(this.framebuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.deleteBuffer(this.vertexbuffer); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + gl.finish(); + this.disposed = true; + } + createDefaultGeometry() { + return new Float32Array([ + -1, + 1, + 0, + 0, + 1, + // upper left + -1, + -1, + 0, + 0, + 0, + // lower left + 1, + 1, + 0, + 1, + 1, + // upper right + 1, + -1, + 0, + 1, + 0 + // lower right + ]); + } + createVertexbuffer() { + const gl = this.gl; + const buffer = gl.createBuffer(); + if (!buffer) { + throw new Error("createBuffer() returned null"); + } + const geometry = this.createDefaultGeometry(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, geometry, gl.STATIC_DRAW); + this.checkError(); + return buffer; + } + createFramebuffer() { + const fb = this.gl.createFramebuffer(); + if (!fb) { + throw new Error("createFramebuffer returned null"); + } + return fb; + } + queryVitalParameters() { + const gl = this.gl; + this.isFloatTextureAttachableToFrameBuffer = this.checkFloatTextureAttachableToFrameBuffer(); + this.isRenderFloat32Supported = this.checkRenderFloat32(); + this.isFloat32DownloadSupported = this.checkFloat32Download(); + if (this.version === 1 && !this.textureHalfFloatExtension && !this.isRenderFloat32Supported) { + throw new Error("both float32 and float16 TextureType are not supported"); + } + this.isBlendSupported = !this.isRenderFloat32Supported || this.checkFloat32Blend(); + this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this.maxTextureImageUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); + if (this.version === 2) { + } + } + getExtensions() { + if (this.version === 2) { + this.colorBufferFloatExtension = this.gl.getExtension("EXT_color_buffer_float"); + this.disjointTimerQueryWebgl2Extension = this.gl.getExtension("EXT_disjoint_timer_query_webgl2"); + } else { + this.textureFloatExtension = this.gl.getExtension("OES_texture_float"); + this.textureHalfFloatExtension = this.gl.getExtension("OES_texture_half_float"); + } + } + checkFloatTextureAttachableToFrameBuffer() { + const gl = this.gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + const internalFormat = this.version === 2 ? gl.RGBA32F : gl.RGBA; + gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); + const frameBuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + const isComplete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE; + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteTexture(texture); + gl.deleteFramebuffer(frameBuffer); + return isComplete; + } + checkRenderFloat32() { + if (this.version === 2) { + if (!this.colorBufferFloatExtension) { + return false; + } + } else { + if (!this.textureFloatExtension) { + return false; + } + } + return this.isFloatTextureAttachableToFrameBuffer; + } + checkFloat32Download() { + if (this.version === 2) { + if (!this.colorBufferFloatExtension) { + return false; + } + } else { + if (!this.textureFloatExtension) { + return false; + } + if (!this.gl.getExtension("WEBGL_color_buffer_float")) { + return false; + } + } + return this.isFloatTextureAttachableToFrameBuffer; + } + /** + * Check whether GL_BLEND is supported + */ + checkFloat32Blend() { + const gl = this.gl; + let texture; + let frameBuffer; + let vertexShader; + let fragmentShader; + let program; + try { + texture = gl.createTexture(); + frameBuffer = gl.createFramebuffer(); + gl.bindTexture(gl.TEXTURE_2D, texture); + const internalFormat = this.version === 2 ? gl.RGBA32F : gl.RGBA; + gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + gl.enable(gl.BLEND); + vertexShader = gl.createShader(gl.VERTEX_SHADER); + if (!vertexShader) { + return false; + } + gl.shaderSource(vertexShader, "void main(){}"); + gl.compileShader(vertexShader); + fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + if (!fragmentShader) { + return false; + } + gl.shaderSource(fragmentShader, "precision highp float;void main(){gl_FragColor=vec4(0.5);}"); + gl.compileShader(fragmentShader); + program = gl.createProgram(); + if (!program) { + return false; + } + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + gl.useProgram(program); + gl.drawArrays(gl.POINTS, 0, 1); + return gl.getError() === gl.NO_ERROR; + } finally { + gl.disable(gl.BLEND); + if (program) { + gl.deleteProgram(program); + } + if (vertexShader) { + gl.deleteShader(vertexShader); + } + if (fragmentShader) { + gl.deleteShader(fragmentShader); + } + if (frameBuffer) { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(frameBuffer); + } + if (texture) { + gl.bindTexture(gl.TEXTURE_2D, null); + gl.deleteTexture(texture); + } + } + } + beginTimer() { + if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { + const gl2 = this.gl; + const ext = this.disjointTimerQueryWebgl2Extension; + const query = gl2.createQuery(); + gl2.beginQuery(ext.TIME_ELAPSED_EXT, query); + return query; + } else { + throw new Error("WebGL1 profiling currently not supported."); + } + } + endTimer() { + if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { + const gl2 = this.gl; + const ext = this.disjointTimerQueryWebgl2Extension; + gl2.endQuery(ext.TIME_ELAPSED_EXT); + return; + } else { + throw new Error("WebGL1 profiling currently not supported"); + } + } + isTimerResultAvailable(query) { + let available = false, disjoint = false; + if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) { + const gl2 = this.gl; + const ext = this.disjointTimerQueryWebgl2Extension; + available = gl2.getQueryParameter(query, gl2.QUERY_RESULT_AVAILABLE); + disjoint = gl2.getParameter(ext.GPU_DISJOINT_EXT); + } else { + throw new Error("WebGL1 profiling currently not supported"); + } + return available && !disjoint; + } + getTimerResult(query) { + let timeElapsed = 0; + if (this.version === 2) { + const gl2 = this.gl; + timeElapsed = gl2.getQueryParameter(query, gl2.QUERY_RESULT); + gl2.deleteQuery(query); + } else { + throw new Error("WebGL1 profiling currently not supported"); + } + return timeElapsed / 1e6; + } + async waitForQueryAndGetTime(query) { + await repeatedTry(() => this.isTimerResultAvailable(query)); + return this.getTimerResult(query); + } + async createAndWaitForFence() { + const fenceContext = this.createFence(this.gl); + return this.pollFence(fenceContext); + } + createFence(gl) { + let isFencePassed; + const gl2 = gl; + const query = gl2.fenceSync(gl2.SYNC_GPU_COMMANDS_COMPLETE, 0); + gl.flush(); + if (query === null) { + isFencePassed = () => true; + } else { + isFencePassed = () => { + const status = gl2.clientWaitSync(query, 0, 0); + return status === gl2.ALREADY_SIGNALED || status === gl2.CONDITION_SATISFIED; + }; + } + return { query, isFencePassed }; + } + async pollFence(fenceContext) { + return new Promise((resolve) => { + void this.addItemToPoll(() => fenceContext.isFencePassed(), () => resolve()); + }); + } + pollItems() { + const index = linearSearchLastTrue(this.itemsToPoll.map((x) => x.isDoneFn)); + for (let i = 0; i <= index; ++i) { + const { resolveFn } = this.itemsToPoll[i]; + resolveFn(); + } + this.itemsToPoll = this.itemsToPoll.slice(index + 1); + } + async addItemToPoll(isDoneFn, resolveFn) { + this.itemsToPoll.push({ isDoneFn, resolveFn }); + if (this.itemsToPoll.length > 1) { + return; + } + await repeatedTry(() => { + this.pollItems(); + return this.itemsToPoll.length === 0; + }); + } + }; + } +}); + +// web/lib/onnxjs/backends/webgl/webgl-context-factory.ts +function createWebGLContext(contextId) { + let context; + if ((!contextId || contextId === "webgl2") && "webgl2" in cache) { + context = cache.webgl2; + } else if ((!contextId || contextId === "webgl") && "webgl" in cache) { + context = cache.webgl; + } + if (!context) { + try { + const offscreenCanvas = createOffscreenCanvas(); + context = createNewWebGLContext(offscreenCanvas, contextId); + } catch (e) { + const canvas = createCanvas(); + context = createNewWebGLContext(canvas, contextId); + } + } + contextId = contextId || context.version === 1 ? "webgl" : "webgl2"; + const gl = context.gl; + cache[contextId] = context; + if (gl.isContextLost()) { + delete cache[contextId]; + return createWebGLContext(contextId); + } + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.STENCIL_TEST); + gl.disable(gl.BLEND); + gl.disable(gl.DITHER); + gl.disable(gl.POLYGON_OFFSET_FILL); + gl.disable(gl.SAMPLE_COVERAGE); + gl.enable(gl.SCISSOR_TEST); + gl.enable(gl.CULL_FACE); + gl.cullFace(gl.BACK); + return context; +} +function createNewWebGLContext(canvas, contextId) { + const contextAttributes = { + alpha: false, + depth: false, + antialias: false, + stencil: false, + preserveDrawingBuffer: false, + premultipliedAlpha: false, + failIfMajorPerformanceCaveat: false + }; + let gl; + const ca = contextAttributes; + if (!contextId || contextId === "webgl2") { + gl = canvas.getContext("webgl2", ca); + if (gl) { + try { + return new WebGLContext(gl, 2); + } catch (err) { + Logger.warning("GlContextFactory", `failed to create WebGLContext using contextId 'webgl2'. Error: ${err}`); + } + } + } + if (!contextId || contextId === "webgl") { + gl = canvas.getContext("webgl", ca) || canvas.getContext("experimental-webgl", ca); + if (gl) { + try { + return new WebGLContext(gl, 1); + } catch (err) { + Logger.warning( + "GlContextFactory", + `failed to create WebGLContext using contextId 'webgl' or 'experimental-webgl'. Error: ${err}` + ); + } + } + } + throw new Error("WebGL is not supported"); +} +function createCanvas() { + if (typeof document === "undefined") { + throw new TypeError("failed to create canvas: document is not supported"); + } + const canvas = document.createElement("canvas"); + canvas.width = 1; + canvas.height = 1; + return canvas; +} +function createOffscreenCanvas() { + if (typeof OffscreenCanvas === "undefined") { + throw new TypeError("failed to create offscreen canvas: OffscreenCanvas is not supported"); + } + return new OffscreenCanvas(1, 1); +} +var cache; +var init_webgl_context_factory = __esm({ + "web/lib/onnxjs/backends/webgl/webgl-context-factory.ts"() { + "use strict"; + init_instrument(); + init_webgl_context(); + cache = {}; + } +}); + +// web/lib/onnxjs/backends/backend-webgl.ts +var WebGLBackend; +var init_backend_webgl = __esm({ + "web/lib/onnxjs/backends/backend-webgl.ts"() { + "use strict"; + init_esm(); + init_instrument(); + init_session_handler(); + init_webgl_context_factory(); + WebGLBackend = class { + get contextId() { + return env2.webgl.contextId; + } + set contextId(value) { + env2.webgl.contextId = value; + } + get matmulMaxBatchSize() { + return env2.webgl.matmulMaxBatchSize; + } + set matmulMaxBatchSize(value) { + env2.webgl.matmulMaxBatchSize = value; + } + get textureCacheMode() { + return env2.webgl.textureCacheMode; + } + set textureCacheMode(value) { + env2.webgl.textureCacheMode = value; + } + get pack() { + return env2.webgl.pack; + } + set pack(value) { + env2.webgl.pack = value; + } + get async() { + return env2.webgl.async; + } + set async(value) { + env2.webgl.async = value; + } + initialize() { + try { + this.glContext = createWebGLContext(this.contextId); + if (typeof this.matmulMaxBatchSize !== "number") { + this.matmulMaxBatchSize = 16; + } + if (typeof this.textureCacheMode !== "string") { + this.textureCacheMode = "full"; + } + if (typeof this.pack !== "boolean") { + this.pack = false; + } + if (typeof this.async !== "boolean") { + this.async = false; + } + Logger.setWithEnv(env2); + if (!env2.webgl.context) { + Object.defineProperty(env2.webgl, "context", { value: this.glContext.gl }); + } + Logger.verbose( + "WebGLBackend", + `Created WebGLContext: ${typeof this.glContext} with matmulMaxBatchSize: ${this.matmulMaxBatchSize}; textureCacheMode: ${this.textureCacheMode}; pack: ${this.pack}; async: ${this.async}.` + ); + return true; + } catch (e) { + Logger.warning("WebGLBackend", `Unable to initialize WebGLBackend. ${e}`); + return false; + } + } + createSessionHandler(context) { + return new WebGLSessionHandler(this, context); + } + dispose() { + this.glContext.dispose(); + } + }; + } +}); + +// web/lib/onnxjs/backend.ts +async function resolveBackend(hint) { + if (!hint) { + return resolveBackend(["webgl"]); + } else { + const hints = typeof hint === "string" ? [hint] : hint; + for (const backendHint of hints) { + const cache2 = backendsCache.get(backendHint); + if (cache2) { + return cache2; + } + const backend2 = await tryLoadBackend(backendHint); + if (backend2) { + return backend2; + } + } + } + throw new Error("no available backend to use"); +} +async function tryLoadBackend(backendHint) { + const backendObj = backend; + if (typeof backendObj[backendHint] !== "undefined" && isBackend(backendObj[backendHint])) { + const backend2 = backendObj[backendHint]; + let init = backend2.initialize(); + if (typeof init === "object" && "then" in init) { + init = await init; + } + if (init) { + backendsCache.set(backendHint, backend2); + return backend2; + } + } + return void 0; +} +function isBackend(obj) { + const o = obj; + if ("initialize" in o && typeof o.initialize === "function" && // initialize() + "createSessionHandler" in o && typeof o.createSessionHandler === "function" && // createSessionHandler() + "dispose" in o && typeof o.dispose === "function") { + return true; + } + return false; +} +var backendsCache, backend; +var init_backend2 = __esm({ + "web/lib/onnxjs/backend.ts"() { + "use strict"; + init_backend_webgl(); + backendsCache = /* @__PURE__ */ new Map(); + backend = { + webgl: new WebGLBackend() + }; + } +}); + +// web/lib/onnxjs/execution-plan.ts +var KernelOp, ExecutionPlan; +var init_execution_plan = __esm({ + "web/lib/onnxjs/execution-plan.ts"() { + "use strict"; + init_instrument(); + KernelOp = class { + constructor(op, node) { + this.op = op; + this.node = node; + } + }; + ExecutionPlan = class { + constructor(graph, ops, profiler) { + this.graph = graph; + this.profiler = profiler; + this.initialize(ops); + } + initialize(ops) { + this.profiler.event("session", "ExecutionPlan.initialize", () => { + const graphNodes = this.graph.getNodes(); + if (graphNodes.length !== ops.length) { + throw new Error("The size of nodes and OPs do not match."); + } + this._ops = ops.map((op, i) => new KernelOp(op, graphNodes[i])); + this.reset(); + this._starter = []; + this._ops.forEach((op, i) => { + let resolved = true; + for (const input of op.node.inputs) { + if (!this._values[input] && this.graph.getInputIndices().indexOf(input) === -1) { + resolved = false; + break; + } + } + if (resolved) { + this._starter.push(i); + } + }); + }); + } + reset() { + this._values = this.graph.getValues().map((i) => i.tensor); + } + async execute(sessionHandler, modelInputs) { + return this.profiler.event("session", "ExecutionPlan.execute", async () => { + this.reset(); + const inferenceHandler = sessionHandler.createInferenceHandler(); + const graphInputs = this.graph.getInputIndices(); + if (modelInputs.length !== graphInputs.length) { + throw new Error(`number of input tensors don't match the number of inputs to the model: actual: ${modelInputs.length} expected: ${graphInputs.length}`); + } + modelInputs.forEach((input, i) => { + const index = graphInputs[i]; + this._values[index] = input; + }); + const sequence = this._starter.slice(0); + const graphValues = this.graph.getValues(); + const graphNodes = this.graph.getNodes(); + let rear = 0; + while (rear < sequence.length) { + const thisOpIndex = sequence[rear++]; + const thisOp = this._ops[thisOpIndex]; + const inputList = thisOp.node.inputs.map((i) => this._values[i]); + if (inputList.indexOf(void 0) !== -1) { + throw new Error(`unresolved input detected: op: ${thisOp.node}`); + } + const inputTensors = inputList; + Logger.verbose( + "ExecPlan", + `Runing op:${thisOp.node.name} (${inputTensors.map((t, i) => `'${thisOp.node.inputs[i]}': ${t.type}[${t.dims.join(",")}]`).join(", ")})` + ); + const outputList = await this.profiler.event( + "node", + thisOp.node.name, + async () => thisOp.op.impl(inferenceHandler, inputTensors, thisOp.op.context) + ); + if (outputList.length !== thisOp.node.outputs.length) { + throw new Error("the size of output does not match model definition."); + } + outputList.forEach((output2, i) => { + const j = thisOp.node.outputs[i]; + if (this._values[j]) { + throw new Error(`output [${j}] already has value: op:${thisOp.node.name}`); + } + this._values[j] = output2; + }); + const downstreamNodes = /* @__PURE__ */ new Set(); + outputList.forEach((_output, i) => { + const j = thisOp.node.outputs[i]; + for (const currentDownstreamNodeIndex of graphValues[j].to) { + const currentDownstreamNode = graphNodes[currentDownstreamNodeIndex]; + let resolved = true; + for (const k of currentDownstreamNode.inputs) { + if (!this._values[k]) { + resolved = false; + break; + } + } + if (resolved) { + downstreamNodes.add(currentDownstreamNodeIndex); + } + } + }); + sequence.push(...downstreamNodes); + } + const output = []; + for (let i = 0; i < this.graph.getOutputIndices().length; i++) { + const outputIndex = this.graph.getOutputIndices()[i]; + const outputTensor = this._values[outputIndex]; + if (outputTensor === void 0) { + throw new Error(`required output [${outputIndex}] does not have value`); + } + if (outputIndex === 0) { + await outputTensor.getData(); + } else { + outputTensor.data; + } + output.push(outputTensor); + } + Logger.verbose("ExecPlan", "disposing of inferenceHandler"); + inferenceHandler.dispose(); + return output; + }); + } + }; + } +}); + +// web/lib/onnxjs/attribute.ts +var import_onnx3, ortFbs2, Attribute; +var init_attribute = __esm({ + "web/lib/onnxjs/attribute.ts"() { + "use strict"; + init_ort_generated(); + import_onnx3 = __toESM(require_onnx()); + init_tensor2(); + init_util(); + ortFbs2 = onnxruntime.experimental.fbs; + Attribute = class _Attribute { + constructor(attributes) { + this._attributes = /* @__PURE__ */ new Map(); + if (attributes !== null && attributes !== void 0) { + for (const attr of attributes) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + this._attributes.set(attr.name, [_Attribute.getValue(attr), _Attribute.getType(attr)]); + } else if (attr instanceof ortFbs2.Attribute) { + this._attributes.set(attr.name(), [_Attribute.getValue(attr), _Attribute.getType(attr)]); + } + } + if (this._attributes.size < attributes.length) { + throw new Error("duplicated attribute names"); + } + } + } + set(key, type, value) { + this._attributes.set(key, [value, type]); + } + delete(key) { + this._attributes.delete(key); + } + getFloat(key, defaultValue) { + return this.get(key, "float", defaultValue); + } + getInt(key, defaultValue) { + return this.get(key, "int", defaultValue); + } + getString(key, defaultValue) { + return this.get(key, "string", defaultValue); + } + getTensor(key, defaultValue) { + return this.get(key, "tensor", defaultValue); + } + getFloats(key, defaultValue) { + return this.get(key, "floats", defaultValue); + } + getInts(key, defaultValue) { + return this.get(key, "ints", defaultValue); + } + getStrings(key, defaultValue) { + return this.get(key, "strings", defaultValue); + } + getTensors(key, defaultValue) { + return this.get(key, "tensors", defaultValue); + } + get(key, type, defaultValue) { + const valueAndType = this._attributes.get(key); + if (valueAndType === void 0) { + if (defaultValue !== void 0) { + return defaultValue; + } + throw new Error(`required attribute not found: ${key}`); + } + if (valueAndType[1] !== type) { + throw new Error(`type mismatch: expected ${type} but got ${valueAndType[1]}`); + } + return valueAndType[0]; + } + static getType(attr) { + const type = attr instanceof import_onnx3.onnx.AttributeProto ? attr.type : attr.type(); + switch (type) { + case import_onnx3.onnx.AttributeProto.AttributeType.FLOAT: + return "float"; + case import_onnx3.onnx.AttributeProto.AttributeType.INT: + return "int"; + case import_onnx3.onnx.AttributeProto.AttributeType.STRING: + return "string"; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSOR: + return "tensor"; + case import_onnx3.onnx.AttributeProto.AttributeType.FLOATS: + return "floats"; + case import_onnx3.onnx.AttributeProto.AttributeType.INTS: + return "ints"; + case import_onnx3.onnx.AttributeProto.AttributeType.STRINGS: + return "strings"; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSORS: + return "tensors"; + default: + throw new Error(`attribute type is not supported yet: ${import_onnx3.onnx.AttributeProto.AttributeType[type]}`); + } + } + static getValue(attr) { + const attrType = attr instanceof import_onnx3.onnx.AttributeProto ? attr.type : attr.type(); + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.GRAPH || attrType === import_onnx3.onnx.AttributeProto.AttributeType.GRAPHS) { + throw new Error("graph attribute is not supported yet"); + } + const value = this.getValueNoCheck(attr); + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.INT && LongUtil.isLong(value)) { + return LongUtil.longToNumber(value); + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.INTS) { + const arr = value; + const numberValue = new Array(arr.length); + for (let i = 0; i < arr.length; i++) { + const maybeLong = arr[i]; + numberValue[i] = LongUtil.longToNumber(maybeLong); + } + return numberValue; + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.TENSOR) { + return attr instanceof import_onnx3.onnx.AttributeProto ? Tensor3.fromProto(value) : Tensor3.fromOrtTensor(value); + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.TENSORS) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + const tensorProtos = value; + return tensorProtos.map((value2) => Tensor3.fromProto(value2)); + } else if (attr instanceof ortFbs2.Attribute) { + const tensorProtos = value; + return tensorProtos.map((value2) => Tensor3.fromOrtTensor(value2)); + } + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.STRING) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + const utf8String = value; + return decodeUtf8String(utf8String); + } + } + if (attrType === import_onnx3.onnx.AttributeProto.AttributeType.STRINGS) { + if (attr instanceof import_onnx3.onnx.AttributeProto) { + const utf8Strings = value; + return utf8Strings.map(decodeUtf8String); + } + } + return value; + } + static getValueNoCheck(attr) { + return attr instanceof import_onnx3.onnx.AttributeProto ? this.getValueNoCheckFromOnnxFormat(attr) : this.getValueNoCheckFromOrtFormat(attr); + } + static getValueNoCheckFromOnnxFormat(attr) { + switch (attr.type) { + case import_onnx3.onnx.AttributeProto.AttributeType.FLOAT: + return attr.f; + case import_onnx3.onnx.AttributeProto.AttributeType.INT: + return attr.i; + case import_onnx3.onnx.AttributeProto.AttributeType.STRING: + return attr.s; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSOR: + return attr.t; + case import_onnx3.onnx.AttributeProto.AttributeType.GRAPH: + return attr.g; + case import_onnx3.onnx.AttributeProto.AttributeType.FLOATS: + return attr.floats; + case import_onnx3.onnx.AttributeProto.AttributeType.INTS: + return attr.ints; + case import_onnx3.onnx.AttributeProto.AttributeType.STRINGS: + return attr.strings; + case import_onnx3.onnx.AttributeProto.AttributeType.TENSORS: + return attr.tensors; + case import_onnx3.onnx.AttributeProto.AttributeType.GRAPHS: + return attr.graphs; + default: + throw new Error(`unsupported attribute type: ${import_onnx3.onnx.AttributeProto.AttributeType[attr.type]}`); + } + } + static getValueNoCheckFromOrtFormat(attr) { + switch (attr.type()) { + case ortFbs2.AttributeType.FLOAT: + return attr.f(); + case ortFbs2.AttributeType.INT: + return attr.i(); + case ortFbs2.AttributeType.STRING: + return attr.s(); + case ortFbs2.AttributeType.TENSOR: + return attr.t(); + case ortFbs2.AttributeType.GRAPH: + return attr.g(); + case ortFbs2.AttributeType.FLOATS: + return attr.floatsArray(); + case ortFbs2.AttributeType.INTS: { + const ints = []; + for (let i = 0; i < attr.intsLength(); i++) { + ints.push(attr.ints(i)); + } + return ints; + } + case ortFbs2.AttributeType.STRINGS: { + const strings = []; + for (let i = 0; i < attr.stringsLength(); i++) { + strings.push(attr.strings(i)); + } + return strings; + } + case ortFbs2.AttributeType.TENSORS: { + const tensors = []; + for (let i = 0; i < attr.tensorsLength(); i++) { + tensors.push(attr.tensors(i)); + } + return tensors; + } + default: + throw new Error(`unsupported attribute type: ${ortFbs2.AttributeType[attr.type()]}`); + } + } + }; + } +}); + +// web/lib/onnxjs/graph.ts +var import_onnx4, ortFbs3, Graph, Value, Node, GraphImpl; +var init_graph = __esm({ + "web/lib/onnxjs/graph.ts"() { + "use strict"; + init_attribute(); + init_ort_generated(); + import_onnx4 = __toESM(require_onnx()); + init_tensor2(); + init_util(); + ortFbs3 = onnxruntime.experimental.fbs; + Graph = { + /** + * construct a graph from a graph protobuf type + */ + from: (graphProto, initializer) => new GraphImpl(graphProto, initializer) + }; + Value = class { + constructor(valueInfo) { + this._from = void 0; + this._to = []; + this.tensor = void 0; + this.type = void 0; + if (valueInfo) { + this.type = ProtoUtil.tensorValueTypeFromProto(valueInfo.type.tensorType); + } + } + // -1 represent from initializer + get from() { + return this._from; + } + get to() { + return this._to; + } + }; + Node = class { + constructor(_nodeProto, name2) { + if (_nodeProto instanceof import_onnx4.onnx.NodeProto) { + this.name = _nodeProto.name; + this.opType = _nodeProto.opType; + this.attributes = new Attribute(_nodeProto.attribute); + } else if (_nodeProto instanceof ortFbs3.Node) { + this.name = name2 ?? _nodeProto.name(); + this.opType = _nodeProto.opType(); + this.attributes = new Attribute(ProtoUtil.tensorAttributesFromORTFormat(_nodeProto)); + } + this.inputs = []; + this.outputs = []; + this.executeNode = true; + } + }; + GraphImpl = class { + constructor(graph, graphInitializer) { + if (!graph) { + throw new TypeError("graph is empty"); + } + this.buildGraph(graph); + this.transformGraph(graphInitializer); + this.checkIsAcyclic(); + } + getInputIndices() { + return this._allInputIndices; + } + getInputNames() { + return this._allInputNames; + } + getOutputIndices() { + return this._allOutputIndices; + } + getOutputNames() { + return this._allOutputNames; + } + getValues() { + return this._allData; + } + getNodes() { + return this._nodes; + } + buildGraph(graph) { + if (graph instanceof import_onnx4.onnx.GraphProto) { + this.buildGraphFromOnnxFormat(graph); + } else if (graph instanceof ortFbs3.Graph) { + this.buildGraphFromOrtFormat(graph); + } else { + throw new TypeError("Graph type is not supported."); + } + } + buildGraphFromOnnxFormat(graph) { + const dataIndices = /* @__PURE__ */ new Map(); + this._allData = []; + this._allInputIndices = []; + this._allInputNames = []; + this._allOutputIndices = []; + this._allOutputNames = []; + this._nodes = []; + const nodesIndices = /* @__PURE__ */ new Map(); + if (!graph.input) { + throw new Error("missing information in graph: input"); + } + const inputValueNames = []; + for (const i of graph.input) { + if (dataIndices.has(i.name)) { + throw new Error(`duplicated input name: ${i.name}`); + } + const currentIndex = this._allData.push(new Value(i)) - 1; + dataIndices.set(i.name, currentIndex); + inputValueNames.push(i.name); + } + if (!graph.initializer) { + throw new Error("missing information in graph: initializer"); + } + for (const i of graph.initializer) { + let index = dataIndices.get(i.name); + if (index === void 0) { + const value = new Value(); + value.type = { + shape: { dims: ProtoUtil.tensorDimsFromProto(i.dims) }, + tensorType: ProtoUtil.tensorDataTypeFromProto(i.dataType) + }; + index = this._allData.push(value) - 1; + dataIndices.set(i.name, index); + } + this._allData[index]._from = -1; + this._allData[index].tensor = Tensor3.fromProto(i); + } + for (let i = 0; i < this._allData.length; i++) { + if (!this._allData[i].tensor) { + this._allInputIndices.push(i); + this._allInputNames.push(inputValueNames[i]); + } + } + if (!graph.output) { + throw new Error("missing information in graph: output"); + } + for (const i of graph.output) { + if (dataIndices.has(i.name)) { + throw new Error(`duplicated output name: ${i.name}`); + } + const currentIndex = this._allData.push(new Value(i)) - 1; + dataIndices.set(i.name, currentIndex); + this._allOutputIndices.push(currentIndex); + this._allOutputNames.push(i.name); + } + if (!graph.node) { + throw new Error("missing information in graph: node"); + } + for (const nodeProto of graph.node) { + if (!nodeProto.name) { + for (let pick = 0; ; pick++) { + const name2 = `unnamed_${nodeProto.opType}_${pick}`; + if (!nodesIndices.has(name2)) { + nodeProto.name = name2; + break; + } + } + } + if (nodesIndices.has(nodeProto.name)) { + throw new Error(`duplicated node name: ${nodeProto.name}`); + } + const currentIndex = this._nodes.push(new Node(nodeProto)) - 1; + nodesIndices.set(nodeProto.name, currentIndex); + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.node[i]; + if (!nodeProto.output) { + throw new Error(`missing output for node: ${nodeProto.name}`); + } + for (const output of nodeProto.output) { + let dataIndex = dataIndices.get(output); + if (typeof dataIndex === "undefined") { + dataIndex = this._allData.push(new Value()) - 1; + dataIndices.set(output, dataIndex); + } + node.outputs.push(dataIndex); + if (this._allData[dataIndex]._from !== void 0) { + throw new Error(`multiple nodes output to one data value: ${dataIndex}`); + } + this._allData[dataIndex]._from = i; + if (nodeProto.opType === "Constant") { + if (!nodeProto.attribute || nodeProto.attribute.length !== 1 || !nodeProto.attribute[0].t) { + throw new Error("missing attributes or missing tensor value in attributes for this Constant operator"); + } + if (!nodeProto.output || nodeProto.output.length !== 1) { + throw new Error("missing output or incorrect number of outputs for this Constant operator"); + } + node.outputs.pop(); + node.executeNode = false; + this._allData[dataIndex]._from = -1; + this._allData[dataIndex].tensor = Tensor3.fromProto(nodeProto.attribute[0].t); + } + } + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.node[i]; + if (!nodeProto.input) { + throw new Error(`missing input for node: ${nodeProto.name}`); + } + for (const input of nodeProto.input) { + const dataIndex = dataIndices.get(input); + if (typeof dataIndex === "undefined") { + if (input === "" && (nodeProto.input.length === 3 || nodeProto.input.length === 4) && nodeProto.opType === "Resize") { + continue; + } + throw new Error(`unrecognized input '${input}' for node: ${nodeProto.name}`); + } + node.inputs.push(dataIndex); + this._allData[dataIndex]._to.push(i); + } + } + return true; + } + buildGraphFromOrtFormat(graph) { + const dataIndices = /* @__PURE__ */ new Map(); + this._allData = []; + this._allInputIndices = []; + this._allInputNames = []; + this._allOutputIndices = []; + this._allOutputNames = []; + this._nodes = []; + const nodesIndices = /* @__PURE__ */ new Map(); + const inputValueNames = []; + for (let i = 0; i < graph.inputsLength(); i++) { + const inputName = graph.inputs(i); + if (dataIndices.has(inputName)) { + throw new Error(`duplicated input name: ${inputName}`); + } + for (let j = 0; j < graph.nodeArgsLength(); j++) { + if (graph.nodeArgs(j)?.name() === inputName) { + const value = new Value(); + const valueType = graph.nodeArgs(j)?.type()?.valueType(); + if (valueType !== ortFbs3.TypeInfoValue.tensor_type) { + throw new Error("Unexpected value type for the nodeArg."); + } + const valueInfo = graph.nodeArgs(j).type().value(new ortFbs3.TensorTypeAndShape()); + const type = ProtoUtil.tensorDataTypeFromProto(valueInfo.elemType()); + const shape2 = valueInfo.shape(); + const dims = []; + for (let k = 0; k < shape2.dimLength(); k++) { + dims.push(LongUtil.longToNumber(shape2.dim(k).value().dimValue())); + } + value.type = { shape: { dims }, tensorType: type }; + const currentIndex = this._allData.push(value) - 1; + dataIndices.set(inputName, currentIndex); + inputValueNames.push(inputName); + } + } + } + for (let i = 0; i < graph.initializersLength(); i++) { + const initializer = graph.initializers(i); + let index = dataIndices.get(initializer.name()); + if (index === void 0) { + const value = new Value(); + const dims = ProtoUtil.tensorDimsFromORTFormat(initializer); + const type = ProtoUtil.tensorDataTypeFromProto(initializer.dataType()); + value.type = { shape: { dims }, tensorType: type }; + index = this._allData.push(value) - 1; + dataIndices.set(initializer.name(), index); + } + this._allData[index]._from = -1; + this._allData[index].tensor = Tensor3.fromOrtTensor(initializer); + } + for (let i = 0; i < this._allData.length; i++) { + if (!this._allData[i].tensor) { + this._allInputIndices.push(i); + this._allInputNames.push(inputValueNames[i]); + } + } + for (let i = 0; i < graph.outputsLength(); i++) { + const outputName = graph.outputs(i); + if (dataIndices.has(outputName)) { + throw new Error(`duplicated output name: ${outputName}`); + } + const currentIndex = this._allData.push(new Value()) - 1; + dataIndices.set(outputName, currentIndex); + this._allOutputIndices.push(currentIndex); + this._allOutputNames.push(outputName); + } + if (!graph.nodes) { + throw new Error("missing information in graph: node"); + } + for (let i = 0; i < graph.nodesLength(); i++) { + const nodeProto = graph.nodes(i); + let name2 = nodeProto.name(); + if (!name2) { + for (let pick = 0; ; pick++) { + name2 = `unnamed_${nodeProto.opType()}_${pick}`; + if (!nodesIndices.has(name2)) { + break; + } + } + } + if (nodesIndices.has(name2)) { + throw new Error(`duplicated node name: ${name2}`); + } + const currentIndex = this._nodes.push(new Node(nodeProto, name2)) - 1; + nodesIndices.set(name2, currentIndex); + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.nodes(i); + if (nodeProto == null) { + throw new Error(`No node exists at index ${i}`); + } + if (nodeProto?.outputsLength() === 0) { + throw new Error(`missing output for node: ${nodeProto.name}`); + } + for (let j = 0; j < nodeProto?.outputsLength(); j++) { + const output = nodeProto?.outputs(j); + let dataIndex = dataIndices.get(output); + if (typeof dataIndex === "undefined") { + dataIndex = this._allData.push(new Value()) - 1; + dataIndices.set(output, dataIndex); + } + node.outputs.push(dataIndex); + if (this._allData[dataIndex]._from !== void 0) { + throw new Error(`multiple nodes output to one data value: ${dataIndex}`); + } + this._allData[dataIndex]._from = i; + if (nodeProto.opType() === "Constant") { + if (nodeProto.attributesLength() !== 1 || !nodeProto.attributes(0).t()) { + throw new Error("missing attributes or missing tensor value in attributes for this Constant operator"); + } + if (nodeProto.outputsLength() !== 1) { + throw new Error("missing output or incorrect number of outputs for this Constant operator"); + } + node.outputs.pop(); + node.executeNode = false; + this._allData[dataIndex]._from = -1; + this._allData[dataIndex].tensor = Tensor3.fromOrtTensor(nodeProto.attributes(0).t()); + } + } + } + for (let i = 0; i < this._nodes.length; i++) { + const node = this._nodes[i]; + const nodeProto = graph.nodes(i); + if (nodeProto.inputsLength() === 0) { + throw new Error(`missing input for node: ${nodeProto.name}`); + } + for (let j = 0; j < nodeProto.inputsLength(); j++) { + const input = nodeProto.inputs(j); + const dataIndex = dataIndices.get(input); + if (typeof dataIndex === "undefined") { + throw new Error(`unrecognized input '${input}' for node: ${nodeProto.name()}`); + } + node.inputs.push(dataIndex); + this._allData[dataIndex]._to.push(i); + } + } + } + checkIsAcyclic() { + const starters = /* @__PURE__ */ new Set(); + this._allInputIndices.forEach((i) => { + const data = this._allData[i]; + data._to.forEach((j) => { + starters.add(j); + }); + }); + const nodesStack = Array.from(starters); + const nodesState = new Array(this._nodes.length).fill("white"); + while (nodesStack.length > 0) { + const nodeIndex = nodesStack.pop(); + if (nodesState[nodeIndex] === "gray") { + nodesState[nodeIndex] = "black"; + } else { + nodesStack.push(nodeIndex); + nodesState[nodeIndex] = "gray"; + this._nodes[nodeIndex].outputs.forEach((outgoingEdgeIndex) => { + const data = this._allData[outgoingEdgeIndex]; + if (typeof data.tensor !== "undefined") { + throw new Error("node outputs should not be initialized"); + } + if (data._from !== nodeIndex) { + throw new Error("from property of the Value object doesn't match index of Node being processed"); + } + data._to.forEach((downstreamNodeIndex) => { + if (nodesState[downstreamNodeIndex] === "gray") { + throw new Error("model graph is cyclic"); + } else if (nodesState[downstreamNodeIndex] === "white") { + nodesStack.push(downstreamNodeIndex); + } + }); + }); + } + } + } + transformGraph(graphInitializer) { + this.removeAllIdentityNodes(); + this.removeAllDropoutNodes(); + this.fuseConvActivationNodes(); + if (graphInitializer) { + graphInitializer.transformGraph(this); + } + this.finalizeGraph(); + } + /** + * finalize the graph. + * + * this function should be called after all the transformation completed. + * this function removes all unnecessary nodes and values from the graph + */ + finalizeGraph() { + let offset = 0; + const newIndices = new Array(this._nodes.length, 0); + let nodePossition = 0; + for (let i = 0; i < this._nodes.length; i++) { + newIndices[i] = nodePossition; + if (this._nodes[i].executeNode) { + if (nodePossition !== i) { + this._nodes[nodePossition] = this._nodes[i]; + } + nodePossition++; + } else { + this._nodes[i].outputs.forEach((ind) => { + this._allData[ind]._from = -2; + }); + } + } + this._nodes.splice(nodePossition, this._nodes.length - nodePossition); + for (let i = 0; i < this._allData.length; i++) { + const currentData = this._allData[i]; + if (currentData._from !== void 0 && currentData._from !== -1 && currentData._from !== -2) { + currentData._from = newIndices[currentData._from]; + } + for (let j = 0; j < currentData._to.length; j++) { + if (currentData._to[j] >= 0) { + currentData._to[j] = newIndices[currentData._to[j]]; + } else { + throw new Error("Trying to update a removed node"); + } + } + } + offset = 0; + for (let i = 0; i < this._allData.length; i++) { + if (this._allData[i].from === -2 && this._allOutputIndices.indexOf(i + offset) === -1) { + offset++; + this._allData.splice(i, 1); + i--; + continue; + } + if (offset > 0) { + let ind = -1; + if (this._allData[i].from !== void 0 && this._allData[i].from !== -1) { + ind = this._nodes[this._allData[i].from].outputs.indexOf(i + offset); + if (ind !== -1) { + this._nodes[this._allData[i].from].outputs[ind] = i; + } + } else { + ind = this._allInputIndices.indexOf(i + offset); + if (ind !== -1) { + this._allInputIndices[ind] = i; + } + } + this._allData[i].to.forEach((node) => { + ind = this._nodes[node].inputs.indexOf(i + offset); + if (ind !== -1) { + this._nodes[node].inputs[ind] = i; + } + }); + if (this._allData[i].to.length === 0) { + ind = this._allOutputIndices.indexOf(i + offset); + if (ind !== -1) { + this._allOutputIndices[ind] = i; + } + } + } + } + } + /** + * Delete the specifed node. Assume the node has one incoming input and the first output connected to other nodes. + * An input validation must be done before calling this function. + * @param nodeIndex The index of node to be deleted + */ + deleteNode(nodeIndex) { + const node = this._nodes[nodeIndex]; + if (node.outputs.length > 1) { + for (let i = 1; i < node.outputs.length; i++) { + if (this._allData[node.outputs[i]].to.length > 0) { + throw new Error("Node deletion with more than one output connected to other nodes is not supported. "); + } + } + } + node.executeNode = false; + const inputValueIndex = node.inputs[0]; + const outputValueIndex = node.outputs[0]; + const nodesConsumingOutput = this._allData[outputValueIndex].to; + for (let i = 0; i < node.inputs.length; i++) { + const delIndex = this._allData[node.inputs[i]].to.indexOf(nodeIndex); + if (delIndex === -1) { + throw new Error("The Value object doesn't have the current Node in it's 'to' property "); + } + this._allData[node.inputs[i]].to.splice(delIndex, 1); + } + this._allData[outputValueIndex]._to = []; + const index = this._allOutputIndices.indexOf(outputValueIndex); + if (index !== -1) { + this._allOutputIndices[index] = inputValueIndex; + } + if (nodesConsumingOutput && nodesConsumingOutput.length > 0) { + for (const nodeIndex2 of nodesConsumingOutput) { + const replaceIndex = this._nodes[nodeIndex2].inputs.indexOf(outputValueIndex); + if (replaceIndex === -1) { + throw new Error("The Node object doesn't have the output Value in it's 'inputs' property "); + } + this._nodes[nodeIndex2].inputs[replaceIndex] = inputValueIndex; + this._allData[inputValueIndex].to.push(nodeIndex2); + } + } + } + removeAllDropoutNodes() { + let nodeIndex = 0; + for (const node of this._nodes) { + if (node.opType === "Dropout") { + if (node.inputs.length !== 1) { + throw new Error("Dropout nodes should only contain one input. "); + } + if (node.outputs.length !== 1 && node.outputs.length !== 2) { + throw new Error("Dropout nodes should contain either 1 or 2 output(s)"); + } + if (node.outputs.length === 2 && this._allData[node.outputs[1]]._to.length !== 0) { + throw new Error("Dropout nodes's second output should not be referenced by other nodes"); + } + this.deleteNode(nodeIndex); + } + nodeIndex++; + } + } + removeAllIdentityNodes() { + let nodeIndex = 0; + for (const node of this._nodes) { + if (node.opType === "Identity") { + this.deleteNode(nodeIndex); + } + nodeIndex++; + } + } + isActivation(n) { + switch (n.opType) { + case "Relu": + case "Sigmoid": + case "Clip": + return true; + default: + return false; + } + } + fuseConvActivationNodes() { + for (const node of this._nodes) { + if (node.opType === "Conv") { + const next = this._allData[node.outputs[0]]._to; + if (next.length === 1 && this.isActivation(this._nodes[next[0]])) { + const child = this._nodes[next[0]]; + if (child.opType === "Clip") { + if (child.inputs.length === 1) { + try { + node.attributes.set( + "activation_params", + "floats", + [child.attributes.getFloat("min"), child.attributes.getFloat("max")] + ); + } catch (e) { + node.attributes.set("activation_params", "floats", [MIN_CLIP, MAX_CLIP]); + } + } else if (child.inputs.length >= 3 && this._allData[child.inputs[1]].tensor !== void 0 && this._allData[child.inputs[2]].tensor !== void 0) { + node.attributes.set("activation_params", "floats", [ + this._allData[child.inputs[1]].tensor.floatData[0], + this._allData[child.inputs[2]].tensor.floatData[0] + ]); + } else { + continue; + } + } + node.attributes.set("activation", "string", child.opType); + this.deleteNode(next[0]); + } + } + } + } + }; + } +}); + +// web/lib/onnxjs/model.ts +var import_onnx5, ortFbs4, Model; +var init_model = __esm({ + "web/lib/onnxjs/model.ts"() { + "use strict"; + init_flatbuffers(); + init_graph(); + init_ort_generated(); + import_onnx5 = __toESM(require_onnx()); + init_util(); + ortFbs4 = onnxruntime.experimental.fbs; + Model = class { + // empty model + constructor() { + } + load(buf, graphInitializer, isOrtFormat) { + let onnxError; + if (!isOrtFormat) { + try { + this.loadFromOnnxFormat(buf, graphInitializer); + return; + } catch (e) { + if (isOrtFormat !== void 0) { + throw e; + } + onnxError = e; + } + } + try { + this.loadFromOrtFormat(buf, graphInitializer); + } catch (e) { + if (isOrtFormat !== void 0) { + throw e; + } + throw new Error(`Failed to load model as ONNX format: ${onnxError} +as ORT format: ${e}`); + } + } + loadFromOnnxFormat(buf, graphInitializer) { + const modelProto = import_onnx5.onnx.ModelProto.decode(buf); + const irVersion = LongUtil.longToNumber(modelProto.irVersion); + if (irVersion < 3) { + throw new Error("only support ONNX model with IR_VERSION>=3"); + } + this._opsets = modelProto.opsetImport.map((i) => ({ domain: i.domain, version: LongUtil.longToNumber(i.version) })); + this._graph = Graph.from(modelProto.graph, graphInitializer); + } + loadFromOrtFormat(buf, graphInitializer) { + const fb = new flatbuffers.ByteBuffer(buf); + const ortModel = ortFbs4.InferenceSession.getRootAsInferenceSession(fb).model(); + const irVersion = LongUtil.longToNumber(ortModel.irVersion()); + if (irVersion < 3) { + throw new Error("only support ONNX model with IR_VERSION>=3"); + } + this._opsets = []; + for (let i = 0; i < ortModel.opsetImportLength(); i++) { + const opsetId = ortModel.opsetImport(i); + this._opsets.push({ domain: opsetId?.domain(), version: LongUtil.longToNumber(opsetId.version()) }); + } + this._graph = Graph.from(ortModel.graph(), graphInitializer); + } + get graph() { + return this._graph; + } + get opsets() { + return this._opsets; + } + }; + } +}); + +// web/lib/onnxjs/session.ts +var Session; +var init_session = __esm({ + "web/lib/onnxjs/session.ts"() { + "use strict"; + init_promises(); + init_backend2(); + init_execution_plan(); + init_instrument(); + init_model(); + Session = class { + constructor(config = {}) { + this._initialized = false; + this.backendHint = config.backendHint; + this.profiler = Profiler.create(config.profiler); + this.context = { profiler: this.profiler, graphInputTypes: [], graphInputDims: [] }; + } + get inputNames() { + return this._model.graph.getInputNames(); + } + get outputNames() { + return this._model.graph.getOutputNames(); + } + startProfiling() { + this.profiler.start(); + } + endProfiling() { + this.profiler.stop(); + } + async loadModel(arg, byteOffset, length) { + await this.profiler.event("session", "Session.loadModel", async () => { + const backend2 = await resolveBackend(this.backendHint); + this.sessionHandler = backend2.createSessionHandler(this.context); + this._model = new Model(); + if (typeof arg === "string") { + const isOrtFormat = arg.endsWith(".ort"); + if (typeof process !== "undefined" && process.versions && process.versions.node) { + const buf = await readFile(arg); + this.initialize(buf, isOrtFormat); + } else { + const response = await fetch(arg); + const buf = await response.arrayBuffer(); + this.initialize(new Uint8Array(buf), isOrtFormat); + } + } else if (!ArrayBuffer.isView(arg)) { + const arr = new Uint8Array(arg, byteOffset || 0, length || arg.byteLength); + this.initialize(arr); + } else { + this.initialize(arg); + } + }); + } + initialize(modelProtoBlob, isOrtFormat) { + if (this._initialized) { + throw new Error("already initialized"); + } + this.profiler.event("session", "Session.initialize", () => { + const graphInitializer = this.sessionHandler.transformGraph ? this.sessionHandler : void 0; + this._model.load(modelProtoBlob, graphInitializer, isOrtFormat); + if (this.sessionHandler.onGraphInitialized) { + this.sessionHandler.onGraphInitialized(this._model.graph); + } + this.initializeOps(this._model.graph); + this._executionPlan = new ExecutionPlan(this._model.graph, this._ops, this.profiler); + }); + this._initialized = true; + } + async run(inputs) { + if (!this._initialized) { + throw new Error("session not initialized yet"); + } + return this.profiler.event("session", "Session.run", async () => { + const inputTensors = this.normalizeAndValidateInputs(inputs); + const outputTensors = await this._executionPlan.execute(this.sessionHandler, inputTensors); + return this.createOutput(outputTensors); + }); + } + normalizeAndValidateInputs(inputs) { + const modelInputNames = this._model.graph.getInputNames(); + if (Array.isArray(inputs)) { + if (inputs.length !== modelInputNames.length) { + throw new Error(`incorrect input array length: expected ${modelInputNames.length} but got ${inputs.length}`); + } + } else { + if (inputs.size !== modelInputNames.length) { + throw new Error(`incorrect input map size: expected ${modelInputNames.length} but got ${inputs.size}`); + } + const sortedInputs = new Array(inputs.size); + let sortedInputsIndex = 0; + for (let i = 0; i < modelInputNames.length; ++i) { + const tensor = inputs.get(modelInputNames[i]); + if (!tensor) { + throw new Error(`missing input tensor for: '${name}'`); + } + sortedInputs[sortedInputsIndex++] = tensor; + } + inputs = sortedInputs; + } + if (!this.context.graphInputTypes || this.context.graphInputTypes.length === 0 || !this.context.graphInputDims || this.context.graphInputDims.length === 0) { + const modelInputIndices = this._model.graph.getInputIndices(); + const modelValues = this._model.graph.getValues(); + const graphInputDims = new Array(modelInputIndices.length); + for (let i = 0; i < modelInputIndices.length; ++i) { + const graphInput = modelValues[modelInputIndices[i]]; + graphInputDims[i] = graphInput.type.shape.dims; + this.context.graphInputTypes.push(graphInput.type.tensorType); + this.context.graphInputDims.push(inputs[i].dims); + } + this.validateInputTensorDims(graphInputDims, inputs, true); + } else { + this.validateInputTensorDims(this.context.graphInputDims, inputs, false); + } + this.validateInputTensorTypes(this.context.graphInputTypes, inputs); + return inputs; + } + validateInputTensorTypes(graphInputTypes, givenInputs) { + for (let i = 0; i < givenInputs.length; i++) { + const expectedType = graphInputTypes[i]; + const actualType = givenInputs[i].type; + if (expectedType !== actualType) { + throw new Error(`input tensor[${i}] check failed: expected type '${expectedType}' but got ${actualType}`); + } + } + } + validateInputTensorDims(graphInputDims, givenInputs, noneDimSupported) { + for (let i = 0; i < givenInputs.length; i++) { + const expectedDims = graphInputDims[i]; + const actualDims = givenInputs[i].dims; + if (!this.compareTensorDims(expectedDims, actualDims, noneDimSupported)) { + throw new Error(`input tensor[${i}] check failed: expected shape '[${expectedDims.join(",")}]' but got [${actualDims.join(",")}]`); + } + } + } + compareTensorDims(expectedDims, actualDims, noneDimSupported) { + if (expectedDims.length !== actualDims.length) { + return false; + } + for (let i = 0; i < expectedDims.length; ++i) { + if (expectedDims[i] !== actualDims[i] && (!noneDimSupported || expectedDims[i] !== 0)) { + return false; + } + } + return true; + } + createOutput(outputTensors) { + const modelOutputNames = this._model.graph.getOutputNames(); + if (outputTensors.length !== modelOutputNames.length) { + throw new Error("expected number of outputs do not match number of generated outputs"); + } + const output = /* @__PURE__ */ new Map(); + for (let i = 0; i < modelOutputNames.length; ++i) { + output.set(modelOutputNames[i], outputTensors[i]); + } + return output; + } + initializeOps(graph) { + const nodes = graph.getNodes(); + this._ops = new Array(nodes.length); + for (let i = 0; i < nodes.length; i++) { + this._ops[i] = this.sessionHandler.resolve(nodes[i], this._model.opsets, graph); + } + } + }; + } +}); + +// web/lib/onnxjs/session-handler-inference.ts +var OnnxjsSessionHandler; +var init_session_handler_inference = __esm({ + "web/lib/onnxjs/session-handler-inference.ts"() { + "use strict"; + init_esm(); + init_tensor2(); + OnnxjsSessionHandler = class { + constructor(session) { + this.session = session; + this.inputNames = this.session.inputNames; + this.outputNames = this.session.outputNames; + } + async dispose() { + } + async run(feeds, _fetches, _options) { + const inputMap = /* @__PURE__ */ new Map(); + for (const name2 in feeds) { + if (Object.hasOwnProperty.call(feeds, name2)) { + const feed = feeds[name2]; + inputMap.set( + name2, + new Tensor3( + feed.dims, + feed.type, + void 0, + void 0, + feed.data + ) + ); + } + } + const outputMap = await this.session.run(inputMap); + const output = {}; + outputMap.forEach((tensor, name2) => { + output[name2] = new Tensor2(tensor.type, tensor.data, tensor.dims); + }); + return output; + } + startProfiling() { + this.session.startProfiling(); + } + endProfiling() { + this.session.endProfiling(); + } + }; + } +}); + +// web/lib/backend-onnxjs.ts +var backend_onnxjs_exports = {}; +__export(backend_onnxjs_exports, { + onnxjsBackend: () => onnxjsBackend +}); +var OnnxjsBackend, onnxjsBackend; +var init_backend_onnxjs = __esm({ + "web/lib/backend-onnxjs.ts"() { + "use strict"; + init_session(); + init_session_handler_inference(); + OnnxjsBackend = class { + // eslint-disable-next-line @typescript-eslint/no-empty-function + async init() { + } + async createInferenceSessionHandler(pathOrBuffer, options) { + const session = new Session(options); + if (typeof pathOrBuffer === "string") { + await session.loadModel(pathOrBuffer); + } else { + await session.loadModel(pathOrBuffer); + } + return new OnnxjsSessionHandler(session); + } + }; + onnxjsBackend = new OnnxjsBackend(); + } +}); + +// web/lib/index.ts +init_esm(); +init_esm(); +init_esm(); + +// web/lib/version.ts +var version2 = "1.18.0"; + +// web/lib/index.ts +var lib_default = esm_exports; +if (true) { + const onnxjsBackend2 = (init_backend_onnxjs(), __toCommonJS(backend_onnxjs_exports)).onnxjsBackend; + registerBackend("webgl", onnxjsBackend2, -10); +} +if (false) { + const wasmBackend = true ? null.wasmBackend : null.wasmBackend; + if (false) { + registerBackend("webgpu", wasmBackend, 5); + registerBackend("webnn", wasmBackend, 5); + } + registerBackend("cpu", wasmBackend, 10); + registerBackend("wasm", wasmBackend, 10); +} +Object.defineProperty(env2.versions, "web", { value: version2, enumerable: true }); +export { + InferenceSession2 as InferenceSession, + TRACE, + TRACE_FUNC_BEGIN, + TRACE_FUNC_END, + Tensor2 as Tensor, + TrainingSession2 as TrainingSession, + lib_default as default, + env2 as env, + registerBackend +}; +/*! Bundled license information: + +long/index.js: + (** + * @license + * Copyright 2009 The Closure Library Authors + * Copyright 2020 Daniel Wirtz / The long.js Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + *) +*/ +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vY29tbW9uL2xpYi9iYWNrZW5kLWltcGwudHMiLCAiLi4vLi4vLi4vY29tbW9uL2xpYi9iYWNrZW5kLnRzIiwgIi4uLy4uLy4uL2NvbW1vbi9saWIvdmVyc2lvbi50cyIsICIuLi8uLi8uLi9jb21tb24vbGliL2Vudi1pbXBsLnRzIiwgIi4uLy4uLy4uL2NvbW1vbi9saWIvZW52LnRzIiwgIi4uLy4uLy4uL2NvbW1vbi9saWIvdGVuc29yLWNvbnZlcnNpb24taW1wbC50cyIsICIuLi8uLi8uLi9jb21tb24vbGliL3RlbnNvci1mYWN0b3J5LWltcGwudHMiLCAiLi4vLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItaW1wbC10eXBlLW1hcHBpbmcudHMiLCAiLi4vLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItdXRpbHMtaW1wbC50cyIsICIuLi8uLi8uLi9jb21tb24vbGliL3RlbnNvci1pbXBsLnRzIiwgIi4uLy4uLy4uL2NvbW1vbi9saWIvdGVuc29yLnRzIiwgIi4uLy4uLy4uL2NvbW1vbi9saWIvdHJhY2UudHMiLCAiLi4vLi4vLi4vY29tbW9uL2xpYi9pbmZlcmVuY2Utc2Vzc2lvbi1pbXBsLnRzIiwgIi4uLy4uLy4uL2NvbW1vbi9saWIvaW5mZXJlbmNlLXNlc3Npb24udHMiLCAiLi4vLi4vLi4vY29tbW9uL2xpYi90ZW5zb3ItY29udmVyc2lvbi50cyIsICIuLi8uLi8uLi9jb21tb24vbGliL3RlbnNvci1mYWN0b3J5LnRzIiwgIi4uLy4uLy4uL2NvbW1vbi9saWIvb25ueC1tb2RlbC50cyIsICIuLi8uLi8uLi9jb21tb24vbGliL29ubngtdmFsdWUudHMiLCAiLi4vLi4vLi4vY29tbW9uL2xpYi90cmFpbmluZy1zZXNzaW9uLWltcGwudHMiLCAiLi4vLi4vLi4vY29tbW9uL2xpYi90cmFpbmluZy1zZXNzaW9uLnRzIiwgIi4uLy4uLy4uL2NvbW1vbi9saWIvaW5kZXgudHMiLCAibm9kZWpzLWlnbm9yZTpub2RlOmZzL3Byb21pc2VzIiwgIi4uLy4uL2xpYi9vbm54anMvaW5zdHJ1bWVudC50cyIsICIuLi8uLi9saWIvb25ueGpzL29wc2V0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9ndWlkLXR5cGVzY3JpcHQvZGlzdC9ndWlkLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9sb25nL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9mbGF0YnVmZmVycy9qcy9mbGF0YnVmZmVycy5tanMiLCAiLi4vLi4vbGliL29ubnhqcy9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ydC1nZW5lcmF0ZWQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2FzcHJvbWlzZS9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvYmFzZTY0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9ldmVudGVtaXR0ZXIvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2Zsb2F0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9pbnF1aXJlL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy91dGY4L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9wb29sL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy91dGlsL2xvbmdiaXRzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy91dGlsL21pbmltYWwuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3dyaXRlci5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvd3JpdGVyX2J1ZmZlci5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcmVhZGVyLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9yZWFkZXJfYnVmZmVyLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9ycGMvc2VydmljZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcnBjLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy9yb290cy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvaW5kZXgtbWluaW1hbC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9taW5pbWFsLmpzIiwgIi4uLy4uL2xpYi9vbm54anMvb3J0LXNjaGVtYS9wcm90b2J1Zi9vbm54LmpzIiwgIi4uLy4uL2xpYi9vbm54anMvdXRpbC50cyIsICIuLi8uLi9saWIvb25ueGpzL3RlbnNvci50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtc291cmNlLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdHlwZXMudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC91dGlscy50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9wYWNraW5nLXV0aWxzLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3BhY2sudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcmVzaGFwZS1wYWNrZWQudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdWludDgtZW5jb2RlLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3VucGFjay50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3RleHR1cmUtZGF0YS1lbmNvZGVyLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdGV4dHVyZS1sYXlvdXQudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9pbmZlcmVuY2UtaGFuZGxlci50cyIsICIuLi8uLi9saWIvb25ueGpzL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleS50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9iYXRjaC1ub3JtYWxpemF0aW9uLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1kZWZpbml0aW9ucy50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9iaW5hcnktb3AudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY2FzdC50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb25jYXQtcGFja2VkLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbmNhdC50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy91bmFyeS1vcC50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9mdXNlLXV0aWxzLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbnYtZ3JvdXBlZC50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9pbTJjb2wtcGFjay50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9tYXRtdWwudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvbWF0bXVsLXBhY2sudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29udi1wYWNrLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2ltMmNvbC50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9kb3QtcHJvZHVjdC50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb252LnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbnYtdHJhbnNwb3NlLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3RyYW5zcG9zZS50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9kZXB0aC10by1zcGFjZS50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9mbGF0dGVuLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvb3BlcmF0b3JzLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2dhdGhlci50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9nZW1tLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2ltYWdlLXNjYWxlci50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9pbnN0YW5jZS1ub3JtYWxpemF0aW9uLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2xybi50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9wYWQudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcG9vbC50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9yZWR1Y2UudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcmVzaGFwZS50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy91cHNhbXBsZS50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9yZXNpemUtcGFja2VkLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3NoYXBlLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3NsaWNlLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3NvZnRtYXgudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc3BsaXQudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc3F1ZWV6ZS50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zdW0udHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdGlsZS50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy91bnNxdWVlemUudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcC1yZXNvbHZlLXJ1bGVzLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1mdW5jdGlvbi1pbmxpbmVyLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3kudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWNvb3JkaW5hdGUtbGliLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1lbmNvZGluZy1saWIudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWZyYWdjb2xvci1saWIudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXNoYXBlLXV0aWxzLWxpYi50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtdmVjLWxpYi50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtcmVnaXN0ZXJlZC1saWJzLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1wcmVwcm9jZXNzb3IudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9wcm9ncmFtLW1hbmFnZXIudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLW1hbmFnZXIudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9zZXNzaW9uLWhhbmRsZXIudHMiLCAiLi4vLi4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC93ZWJnbC1jb250ZXh0LnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvd2ViZ2wtY29udGV4dC1mYWN0b3J5LnRzIiwgIi4uLy4uL2xpYi9vbm54anMvYmFja2VuZHMvYmFja2VuZC13ZWJnbC50cyIsICIuLi8uLi9saWIvb25ueGpzL2JhY2tlbmQudHMiLCAiLi4vLi4vbGliL29ubnhqcy9leGVjdXRpb24tcGxhbi50cyIsICIuLi8uLi9saWIvb25ueGpzL2F0dHJpYnV0ZS50cyIsICIuLi8uLi9saWIvb25ueGpzL2dyYXBoLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvbW9kZWwudHMiLCAiLi4vLi4vbGliL29ubnhqcy9zZXNzaW9uLnRzIiwgIi4uLy4uL2xpYi9vbm54anMvc2Vzc2lvbi1oYW5kbGVyLWluZmVyZW5jZS50cyIsICIuLi8uLi9saWIvYmFja2VuZC1vbm54anMudHMiLCAiLi4vLi4vbGliL2luZGV4LnRzIiwgIi4uLy4uL2xpYi92ZXJzaW9uLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtCYWNrZW5kfSBmcm9tICcuL2JhY2tlbmQuanMnO1xuaW1wb3J0IHtJbmZlcmVuY2VTZXNzaW9ufSBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcblxuaW50ZXJmYWNlIEJhY2tlbmRJbmZvIHtcbiAgYmFja2VuZDogQmFja2VuZDtcbiAgcHJpb3JpdHk6IG51bWJlcjtcblxuICBpbml0UHJvbWlzZT86IFByb21pc2U8dm9pZD47XG4gIGluaXRpYWxpemVkPzogYm9vbGVhbjtcbiAgYWJvcnRlZD86IGJvb2xlYW47XG4gIGVycm9yPzogc3RyaW5nO1xufVxuXG5jb25zdCBiYWNrZW5kczogTWFwPHN0cmluZywgQmFja2VuZEluZm8+ID0gbmV3IE1hcCgpO1xuY29uc3QgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5OiBzdHJpbmdbXSA9IFtdO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGEgYmFja2VuZC5cbiAqXG4gKiBAcGFyYW0gbmFtZSAtIHRoZSBuYW1lIGFzIGEga2V5IHRvIGxvb2t1cCBhcyBhbiBleGVjdXRpb24gcHJvdmlkZXIuXG4gKiBAcGFyYW0gYmFja2VuZCAtIHRoZSBiYWNrZW5kIG9iamVjdC5cbiAqIEBwYXJhbSBwcmlvcml0eSAtIGFuIGludGVnZXIgaW5kaWNhdGluZyB0aGUgcHJpb3JpdHkgb2YgdGhlIGJhY2tlbmQuIEhpZ2hlciBudW1iZXIgbWVhbnMgaGlnaGVyIHByaW9yaXR5LiBpZiBwcmlvcml0eVxuICogPCAwLCBpdCB3aWxsIGJlIGNvbnNpZGVyZWQgYXMgYSAnYmV0YScgdmVyc2lvbiBhbmQgd2lsbCBub3QgYmUgdXNlZCBhcyBhIGZhbGxiYWNrIGJhY2tlbmQgYnkgZGVmYXVsdC5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCByZWdpc3RlckJhY2tlbmQgPSAobmFtZTogc3RyaW5nLCBiYWNrZW5kOiBCYWNrZW5kLCBwcmlvcml0eTogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmIChiYWNrZW5kICYmIHR5cGVvZiBiYWNrZW5kLmluaXQgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGJhY2tlbmQuY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCBjdXJyZW50QmFja2VuZCA9IGJhY2tlbmRzLmdldChuYW1lKTtcbiAgICBpZiAoY3VycmVudEJhY2tlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgYmFja2VuZHMuc2V0KG5hbWUsIHtiYWNrZW5kLCBwcmlvcml0eX0pO1xuICAgIH0gZWxzZSBpZiAoY3VycmVudEJhY2tlbmQucHJpb3JpdHkgPiBwcmlvcml0eSkge1xuICAgICAgLy8gc2FtZSBuYW1lIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCB3aXRoIGEgaGlnaGVyIHByaW9yaXR5LiBza2lwIHJlZ2lzdGVyYXRpb24uXG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChjdXJyZW50QmFja2VuZC5wcmlvcml0eSA9PT0gcHJpb3JpdHkpIHtcbiAgICAgIGlmIChjdXJyZW50QmFja2VuZC5iYWNrZW5kICE9PSBiYWNrZW5kKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgY2Fubm90IHJlZ2lzdGVyIGJhY2tlbmQgXCIke25hbWV9XCIgdXNpbmcgcHJpb3JpdHkgJHtwcmlvcml0eX1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJpb3JpdHkgPj0gMCkge1xuICAgICAgY29uc3QgaSA9IGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eS5pbmRleE9mKG5hbWUpO1xuICAgICAgaWYgKGkgIT09IC0xKSB7XG4gICAgICAgIGJhY2tlbmRzU29ydGVkQnlQcmlvcml0eS5zcGxpY2UoaSwgMSk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChiYWNrZW5kcy5nZXQoYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5W2ldKSEucHJpb3JpdHkgPD0gcHJpb3JpdHkpIHtcbiAgICAgICAgICBiYWNrZW5kc1NvcnRlZEJ5UHJpb3JpdHkuc3BsaWNlKGksIDAsIG5hbWUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5LnB1c2gobmFtZSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ25vdCBhIHZhbGlkIGJhY2tlbmQnKTtcbn07XG5cbi8qKlxuICogVHJ5IHRvIHJlc29sdmUgYW5kIGluaXRpYWxpemUgYSBiYWNrZW5kLlxuICpcbiAqIEBwYXJhbSBiYWNrZW5kTmFtZSAtIHRoZSBuYW1lIG9mIHRoZSBiYWNrZW5kLlxuICogQHJldHVybnMgdGhlIGJhY2tlbmQgaW5zdGFuY2UgaWYgcmVzb2x2ZWQgYW5kIGluaXRpYWxpemVkIHN1Y2Nlc3NmdWxseSwgb3IgYW4gZXJyb3IgbWVzc2FnZSBpZiBmYWlsZWQuXG4gKi9cbmNvbnN0IHRyeVJlc29sdmVBbmRJbml0aWFsaXplQmFja2VuZCA9IGFzeW5jKGJhY2tlbmROYW1lOiBzdHJpbmcpOiBQcm9taXNlPEJhY2tlbmR8c3RyaW5nPiA9PiB7XG4gIGNvbnN0IGJhY2tlbmRJbmZvID0gYmFja2VuZHMuZ2V0KGJhY2tlbmROYW1lKTtcbiAgaWYgKCFiYWNrZW5kSW5mbykge1xuICAgIHJldHVybiAnYmFja2VuZCBub3QgZm91bmQuJztcbiAgfVxuXG4gIGlmIChiYWNrZW5kSW5mby5pbml0aWFsaXplZCkge1xuICAgIHJldHVybiBiYWNrZW5kSW5mby5iYWNrZW5kO1xuICB9IGVsc2UgaWYgKGJhY2tlbmRJbmZvLmFib3J0ZWQpIHtcbiAgICByZXR1cm4gYmFja2VuZEluZm8uZXJyb3IhO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGlzSW5pdGlhbGl6aW5nID0gISFiYWNrZW5kSW5mby5pbml0UHJvbWlzZTtcbiAgICB0cnkge1xuICAgICAgaWYgKCFpc0luaXRpYWxpemluZykge1xuICAgICAgICBiYWNrZW5kSW5mby5pbml0UHJvbWlzZSA9IGJhY2tlbmRJbmZvLmJhY2tlbmQuaW5pdChiYWNrZW5kTmFtZSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBiYWNrZW5kSW5mby5pbml0UHJvbWlzZTtcbiAgICAgIGJhY2tlbmRJbmZvLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBiYWNrZW5kSW5mby5iYWNrZW5kO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmICghaXNJbml0aWFsaXppbmcpIHtcbiAgICAgICAgYmFja2VuZEluZm8uZXJyb3IgPSBgJHtlfWA7XG4gICAgICAgIGJhY2tlbmRJbmZvLmFib3J0ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhY2tlbmRJbmZvLmVycm9yITtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZGVsZXRlIGJhY2tlbmRJbmZvLmluaXRQcm9taXNlO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBSZXNvbHZlIGV4ZWN1dGlvbiBwcm92aWRlcnMgZnJvbSB0aGUgc3BlY2lmaWMgc2Vzc2lvbiBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gdGhlIHNlc3Npb24gb3B0aW9ucyBvYmplY3QuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHR1cGxlIG9mIGFuIGluaXRpYWxpemVkIGJhY2tlbmQgaW5zdGFuY2UgYW5kIGEgc2Vzc2lvbiBvcHRpb25zIG9iamVjdCB3aXRoXG4gKiBmaWx0ZXJlZCBFUCBsaXN0LlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGNvbnN0IHJlc29sdmVCYWNrZW5kQW5kRXhlY3V0aW9uUHJvdmlkZXJzID0gYXN5bmMob3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6XG4gICAgUHJvbWlzZTxbYmFja2VuZDogQmFja2VuZCwgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9uc10+ID0+IHtcbiAgICAgIC8vIGV4dHJhY3QgYmFja2VuZCBoaW50cyBmcm9tIHNlc3Npb24gb3B0aW9uc1xuICAgICAgY29uc3QgZXBzID0gb3B0aW9ucy5leGVjdXRpb25Qcm92aWRlcnMgfHwgW107XG4gICAgICBjb25zdCBiYWNrZW5kSGludHMgPSBlcHMubWFwKGkgPT4gdHlwZW9mIGkgPT09ICdzdHJpbmcnID8gaSA6IGkubmFtZSk7XG4gICAgICBjb25zdCBiYWNrZW5kTmFtZXMgPSBiYWNrZW5kSGludHMubGVuZ3RoID09PSAwID8gYmFja2VuZHNTb3J0ZWRCeVByaW9yaXR5IDogYmFja2VuZEhpbnRzO1xuXG4gICAgICAvLyB0cnkgdG8gcmVzb2x2ZSBhbmQgaW5pdGlhbGl6ZSBhbGwgcmVxdWVzdGVkIGJhY2tlbmRzXG4gICAgICBsZXQgYmFja2VuZDogQmFja2VuZHx1bmRlZmluZWQ7XG4gICAgICBjb25zdCBlcnJvcnMgPSBbXTtcbiAgICAgIGNvbnN0IGF2YWlsYWJsZUJhY2tlbmROYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgZm9yIChjb25zdCBiYWNrZW5kTmFtZSBvZiBiYWNrZW5kTmFtZXMpIHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZVJlc3VsdCA9IGF3YWl0IHRyeVJlc29sdmVBbmRJbml0aWFsaXplQmFja2VuZChiYWNrZW5kTmFtZSk7XG4gICAgICAgIGlmICh0eXBlb2YgcmVzb2x2ZVJlc3VsdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBlcnJvcnMucHVzaCh7bmFtZTogYmFja2VuZE5hbWUsIGVycjogcmVzb2x2ZVJlc3VsdH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICghYmFja2VuZCkge1xuICAgICAgICAgICAgYmFja2VuZCA9IHJlc29sdmVSZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChiYWNrZW5kID09PSByZXNvbHZlUmVzdWx0KSB7XG4gICAgICAgICAgICBhdmFpbGFibGVCYWNrZW5kTmFtZXMuYWRkKGJhY2tlbmROYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gaWYgbm8gYmFja2VuZCBpcyBhdmFpbGFibGUsIHRocm93IGVycm9yLlxuICAgICAgaWYgKCFiYWNrZW5kKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbm8gYXZhaWxhYmxlIGJhY2tlbmQgZm91bmQuIEVSUjogJHtlcnJvcnMubWFwKGUgPT4gYFske2UubmFtZX1dICR7ZS5lcnJ9YCkuam9pbignLCAnKX1gKTtcbiAgICAgIH1cblxuICAgICAgLy8gZm9yIGVhY2ggZXhwbGljaXRseSByZXF1ZXN0ZWQgYmFja2VuZCwgaWYgaXQncyBub3QgYXZhaWxhYmxlLCBvdXRwdXQgd2FybmluZyBtZXNzYWdlLlxuICAgICAgZm9yIChjb25zdCB7bmFtZSwgZXJyfSBvZiBlcnJvcnMpIHtcbiAgICAgICAgaWYgKGJhY2tlbmRIaW50cy5pbmNsdWRlcyhuYW1lKSkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgY29uc29sZS53YXJuKGByZW1vdmluZyByZXF1ZXN0ZWQgZXhlY3V0aW9uIHByb3ZpZGVyIFwiJHtcbiAgICAgICAgICAgICAgbmFtZX1cIiBmcm9tIHNlc3Npb24gb3B0aW9ucyBiZWNhdXNlIGl0IGlzIG5vdCBhdmFpbGFibGU6ICR7ZXJyfWApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbHRlcmVkRXBzID0gZXBzLmZpbHRlcihpID0+IGF2YWlsYWJsZUJhY2tlbmROYW1lcy5oYXModHlwZW9mIGkgPT09ICdzdHJpbmcnID8gaSA6IGkubmFtZSkpO1xuXG4gICAgICByZXR1cm4gW1xuICAgICAgICBiYWNrZW5kLCBuZXcgUHJveHkob3B0aW9ucywge1xuICAgICAgICAgIGdldDogKHRhcmdldCwgcHJvcCkgPT4ge1xuICAgICAgICAgICAgaWYgKHByb3AgPT09ICdleGVjdXRpb25Qcm92aWRlcnMnKSB7XG4gICAgICAgICAgICAgIHJldHVybiBmaWx0ZXJlZEVwcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3ApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIF07XG4gICAgfTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtJbmZlcmVuY2VTZXNzaW9ufSBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcbmltcG9ydCB7T25ueFZhbHVlfSBmcm9tICcuL29ubngtdmFsdWUuanMnO1xuaW1wb3J0IHtUcmFpbmluZ1Nlc3Npb259IGZyb20gJy4vdHJhaW5pbmctc2Vzc2lvbi5qcyc7XG5cbi8qKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgU2Vzc2lvbkhhbmRsZXIge1xuICB0eXBlIEZlZWRzVHlwZSA9IHtbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlfTtcbiAgdHlwZSBGZXRjaGVzVHlwZSA9IHtbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlIHwgbnVsbH07XG4gIHR5cGUgUmV0dXJuVHlwZSA9IHtbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlfTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIHNoYXJlZCBTZXNzaW9uSGFuZGxlciBmdW5jdGlvbmFsaXR5XG4gKlxuICogQGlnbm9yZVxuICovXG5pbnRlcmZhY2UgU2Vzc2lvbkhhbmRsZXIge1xuICBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD47XG5cbiAgcmVhZG9ubHkgaW5wdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG4gIHJlYWRvbmx5IG91dHB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBoYW5kbGVyIGluc3RhbmNlIG9mIGFuIGluZmVyZW5jZSBzZXNzaW9uLlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciBleHRlbmRzIFNlc3Npb25IYW5kbGVyIHtcbiAgc3RhcnRQcm9maWxpbmcoKTogdm9pZDtcbiAgZW5kUHJvZmlsaW5nKCk6IHZvaWQ7XG5cbiAgcnVuKGZlZWRzOiBTZXNzaW9uSGFuZGxlci5GZWVkc1R5cGUsIGZldGNoZXM6IFNlc3Npb25IYW5kbGVyLkZldGNoZXNUeXBlLFxuICAgICAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlPjtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBoYW5kbGVyIGluc3RhbmNlIG9mIGEgdHJhaW5pbmcgaW5mZXJlbmNlIHNlc3Npb24uXG4gKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRyYWluaW5nU2Vzc2lvbkhhbmRsZXIgZXh0ZW5kcyBTZXNzaW9uSGFuZGxlciB7XG4gIHJlYWRvbmx5IGV2YWxJbnB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgZXZhbE91dHB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICBsYXp5UmVzZXRHcmFkKCk6IFByb21pc2U8dm9pZD47XG4gIHJ1blRyYWluU3RlcChcbiAgICAgIGZlZWRzOiBTZXNzaW9uSGFuZGxlci5GZWVkc1R5cGUsIGZldGNoZXM6IFNlc3Npb25IYW5kbGVyLkZldGNoZXNUeXBlLFxuICAgICAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlPjtcbiAgcnVuT3B0aW1pemVyU3RlcChvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+O1xuICBydW5FdmFsU3RlcChcbiAgICAgIGZlZWRzOiBTZXNzaW9uSGFuZGxlci5GZWVkc1R5cGUsIGZldGNoZXM6IFNlc3Npb25IYW5kbGVyLkZldGNoZXNUeXBlLFxuICAgICAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlPjtcblxuICBnZXRQYXJhbWV0ZXJzU2l6ZSh0cmFpbmFibGVPbmx5OiBib29sZWFuKTogUHJvbWlzZTxudW1iZXI+O1xuICBsb2FkUGFyYW1ldGVyc0J1ZmZlcihidWZmZXI6IFVpbnQ4QXJyYXksIHRyYWluYWJsZU9ubHk6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+O1xuICBnZXRDb250aWd1b3VzUGFyYW1ldGVycyh0cmFpbmFibGVPbmx5OiBib29sZWFuKTogUHJvbWlzZTxPbm54VmFsdWU+O1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBhIGJhY2tlbmQgdGhhdCBwcm92aWRlcyBpbXBsZW1lbnRhdGlvbiBvZiBtb2RlbCBpbmZlcmVuY2luZy5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFja2VuZCB7XG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHRoZSBiYWNrZW5kIGFzeW5jaHJvbm91c2x5LiBTaG91bGQgdGhyb3cgd2hlbiBmYWlsZWQuXG4gICAqL1xuICBpbml0KGJhY2tlbmROYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIGNyZWF0ZUluZmVyZW5jZVNlc3Npb25IYW5kbGVyKHVyaU9yQnVmZmVyOiBzdHJpbmd8VWludDhBcnJheSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOlxuICAgICAgUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcj47XG5cbiAgY3JlYXRlVHJhaW5pbmdTZXNzaW9uSGFuZGxlcj9cbiAgICAgIChjaGVja3BvaW50U3RhdGVVcmlPckJ1ZmZlcjogVHJhaW5pbmdTZXNzaW9uLlVyaU9yQnVmZmVyLCB0cmFpbk1vZGVsVXJpT3JCdWZmZXI6IFRyYWluaW5nU2Vzc2lvbi5VcmlPckJ1ZmZlcixcbiAgICAgICBldmFsTW9kZWxVcmlPckJ1ZmZlcjogVHJhaW5pbmdTZXNzaW9uLlVyaU9yQnVmZmVyLCBvcHRpbWl6ZXJNb2RlbFVyaU9yQnVmZmVyOiBUcmFpbmluZ1Nlc3Npb24uVXJpT3JCdWZmZXIsXG4gICAgICAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8VHJhaW5pbmdTZXNzaW9uSGFuZGxlcj47XG59XG5cbmV4cG9ydCB7cmVnaXN0ZXJCYWNrZW5kfSBmcm9tICcuL2JhY2tlbmQtaW1wbC5qcyc7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8vIFRoaXMgZmlsZSBpcyBnZW5lcmF0ZWQgYnkgL2pzL3NjcmlwdHMvdXBkYXRlLXZlcnNpb24udHNcbi8vIERvIG5vdCBtb2RpZnkgZmlsZSBjb250ZW50IG1hbnVhbGx5LlxuXG5leHBvcnQgY29uc3QgdmVyc2lvbiA9ICcxLjE4LjAnO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0Vudn0gZnJvbSAnLi9lbnYuanMnO1xuaW1wb3J0IHt2ZXJzaW9ufSBmcm9tICcuL3ZlcnNpb24uanMnO1xuXG50eXBlIExvZ0xldmVsVHlwZSA9IEVudlsnbG9nTGV2ZWwnXTtcblxubGV0IGxvZ0xldmVsVmFsdWU6IFJlcXVpcmVkPExvZ0xldmVsVHlwZT4gPSAnd2FybmluZyc7XG5cbmV4cG9ydCBjb25zdCBlbnY6IEVudiA9IHtcbiAgd2FzbToge30gYXMgRW52LldlYkFzc2VtYmx5RmxhZ3MsXG4gIHdlYmdsOiB7fSBhcyBFbnYuV2ViR0xGbGFncyxcbiAgd2ViZ3B1OiB7fSBhcyBFbnYuV2ViR3B1RmxhZ3MsXG4gIHZlcnNpb25zOiB7Y29tbW9uOiB2ZXJzaW9ufSxcblxuICBzZXQgbG9nTGV2ZWwodmFsdWU6IExvZ0xldmVsVHlwZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnIHx8IFsndmVyYm9zZScsICdpbmZvJywgJ3dhcm5pbmcnLCAnZXJyb3InLCAnZmF0YWwnXS5pbmRleE9mKHZhbHVlKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgbG9nZ2luZyBsZXZlbDogJHt2YWx1ZX1gKTtcbiAgICB9XG4gICAgbG9nTGV2ZWxWYWx1ZSA9IHZhbHVlO1xuICB9LFxuICBnZXQgbG9nTGV2ZWwoKTogUmVxdWlyZWQ8TG9nTGV2ZWxUeXBlPiB7XG4gICAgcmV0dXJuIGxvZ0xldmVsVmFsdWU7XG4gIH0sXG59O1xuXG4vLyBzZXQgcHJvcGVydHkgJ2xvZ0xldmVsJyBzbyB0aGF0IHRoZXkgY2FuIGJlIGNvcnJlY3RseSB0cmFuc2ZlcnJlZCB0byB3b3JrZXIgYnkgYHBvc3RNZXNzYWdlKClgLlxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGVudiwgJ2xvZ0xldmVsJywge2VudW1lcmFibGU6IHRydWV9KTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtlbnYgYXMgZW52SW1wbH0gZnJvbSAnLi9lbnYtaW1wbC5qcyc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBFbnYge1xuICBleHBvcnQgdHlwZSBXYXNtUHJlZml4T3JGaWxlUGF0aHMgPSBzdHJpbmd8e1xuICAgIC8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xuICAgICdvcnQtd2FzbS53YXNtJz86IHN0cmluZztcbiAgICAnb3J0LXdhc20tdGhyZWFkZWQud2FzbSc/OiBzdHJpbmc7XG4gICAgJ29ydC13YXNtLXNpbWQud2FzbSc/OiBzdHJpbmc7XG4gICAgJ29ydC10cmFpbmluZy13YXNtLXNpbWQud2FzbSc/OiBzdHJpbmc7XG4gICAgJ29ydC13YXNtLXNpbWQtdGhyZWFkZWQud2FzbSc/OiBzdHJpbmc7XG4gICAgLyogZXNsaW50LWVuYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cbiAgfTtcbiAgZXhwb3J0IGludGVyZmFjZSBXZWJBc3NlbWJseUZsYWdzIHtcbiAgICAvKipcbiAgICAgKiBzZXQgb3IgZ2V0IG51bWJlciBvZiB0aHJlYWQocykuIElmIG9taXR0ZWQgb3Igc2V0IHRvIDAsIG51bWJlciBvZiB0aHJlYWQocykgd2lsbCBiZSBkZXRlcm1pbmVkIGJ5IHN5c3RlbS4gSWYgc2V0XG4gICAgICogdG8gMSwgbm8gd29ya2VyIHRocmVhZCB3aWxsIGJlIHNwYXduZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgd2hlbiBXZWJBc3NlbWJseSBtdWx0aXRocmVhZCBmZWF0dXJlIGlzIGF2YWlsYWJsZSBpbiBjdXJyZW50IGNvbnRleHQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGAwYFxuICAgICAqL1xuICAgIG51bVRocmVhZHM/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBzZXQgb3IgZ2V0IGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gZW5hYmxlIFNJTUQuIElmIHNldCB0byBmYWxzZSwgU0lNRCB3aWxsIGJlIGZvcmNlbHkgZGlzYWJsZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgd2hlbiBXZWJBc3NlbWJseSBTSU1EIGZlYXR1cmUgaXMgYXZhaWxhYmxlIGluIGN1cnJlbnQgY29udGV4dC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYHRydWVgXG4gICAgICovXG4gICAgc2ltZD86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBzZXQgb3IgZ2V0IGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gZW5hYmxlIHRyYWNlLlxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWQgVXNlIGBlbnYudHJhY2VgIGluc3RlYWQuIElmIGBlbnYudHJhY2VgIGlzIHNldCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlIGlnbm9yZWQuXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICovXG4gICAgdHJhY2U/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCBhIG51bWJlciBzcGVjaWZ5aW5nIHRoZSB0aW1lb3V0IGZvciBpbml0aWFsaXphdGlvbiBvZiBXZWJBc3NlbWJseSBiYWNrZW5kLCBpbiBtaWxsaXNlY29uZHMuIEEgemVyb1xuICAgICAqIHZhbHVlIGluZGljYXRlcyBubyB0aW1lb3V0IGlzIHNldC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYDBgXG4gICAgICovXG4gICAgaW5pdFRpbWVvdXQ/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYSBjdXN0b20gVVJMIHByZWZpeCB0byB0aGUgLndhc20gZmlsZXMgb3IgYSBzZXQgb2Ygb3ZlcnJpZGVzIGZvciBlYWNoIC53YXNtIGZpbGUuIFRoZSBvdmVycmlkZSBwYXRoIHNob3VsZCBiZVxuICAgICAqIGFuIGFic29sdXRlIHBhdGguXG4gICAgICovXG4gICAgd2FzbVBhdGhzPzogV2FzbVByZWZpeE9yRmlsZVBhdGhzO1xuXG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHByb3h5IHRoZSBleGVjdXRpb24gb2YgbWFpbiB0aHJlYWQgdG8gYSB3b3JrZXIgdGhyZWFkLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICovXG4gICAgcHJveHk/OiBib29sZWFuO1xuICB9XG5cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHTEZsYWdzIHtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBXZWJHTCBDb250ZXh0IElEICh3ZWJnbCBvciB3ZWJnbDIpLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgJ3dlYmdsMidgXG4gICAgICovXG4gICAgY29udGV4dElkPzogJ3dlYmdsJ3wnd2ViZ2wyJztcbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIFdlYkdMIHJlbmRlcmluZyBjb250ZXh0LlxuICAgICAqL1xuICAgIHJlYWRvbmx5IGNvbnRleHQ6IFdlYkdMUmVuZGVyaW5nQ29udGV4dDtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBtYXhpbXVtIGJhdGNoIHNpemUgZm9yIG1hdG11bC4gMCBtZWFucyB0byBkaXNhYmxlIGJhdGNoaW5nLlxuICAgICAqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBtYXRtdWxNYXhCYXRjaFNpemU/OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgdGV4dHVyZSBjYWNoZSBtb2RlLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgJ2Z1bGwnYFxuICAgICAqL1xuICAgIHRleHR1cmVDYWNoZU1vZGU/OiAnaW5pdGlhbGl6ZXJPbmx5J3wnZnVsbCc7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcGFja2VkIHRleHR1cmUgbW9kZVxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgZmFsc2VgXG4gICAgICovXG4gICAgcGFjaz86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB3aGV0aGVyIGVuYWJsZSBhc3luYyBkb3dubG9hZC5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgICAqL1xuICAgIGFzeW5jPzogYm9vbGVhbjtcbiAgfVxuXG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR3B1UHJvZmlsaW5nRGF0YVYxVGVuc29yTWV0YWRhdGEge1xuICAgIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICAgIGRhdGFUeXBlOiBzdHJpbmc7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHcHVQcm9maWxpbmdEYXRhVjEge1xuICAgIHZlcnNpb246IDE7XG4gICAgaW5wdXRzTWV0YWRhdGE6IHJlYWRvbmx5IFdlYkdwdVByb2ZpbGluZ0RhdGFWMVRlbnNvck1ldGFkYXRhW107XG4gICAgb3V0cHV0c01ldGFkYXRhOiByZWFkb25seSBXZWJHcHVQcm9maWxpbmdEYXRhVjFUZW5zb3JNZXRhZGF0YVtdO1xuICAgIGtlcm5lbElkOiBudW1iZXI7XG4gICAga2VybmVsVHlwZTogc3RyaW5nO1xuICAgIGtlcm5lbE5hbWU6IHN0cmluZztcbiAgICBwcm9ncmFtTmFtZTogc3RyaW5nO1xuICAgIHN0YXJ0VGltZTogbnVtYmVyO1xuICAgIGVuZFRpbWU6IG51bWJlcjtcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIFdlYkdwdVByb2ZpbGluZ0RhdGEgPSBXZWJHcHVQcm9maWxpbmdEYXRhVjE7XG5cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHcHVGbGFncyB7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcHJvZmlsaW5nIG1vZGUuXG4gICAgICpcbiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgYGVudi53ZWJncHUucHJvZmlsaW5nLm1vZGVgIGluc3RlYWQuIElmIGBlbnYud2ViZ3B1LnByb2ZpbGluZy5tb2RlYCBpcyBzZXQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZVxuICAgICAqIGlnbm9yZWQuXG4gICAgICovXG4gICAgcHJvZmlsaW5nTW9kZT86ICdvZmYnfCdkZWZhdWx0JztcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBwcm9maWxpbmcgY29uZmlndXJhdGlvbi5cbiAgICAgKi9cbiAgICBwcm9maWxpbmc/OiB7XG4gICAgICAvKipcbiAgICAgICAqIFNldCBvciBnZXQgdGhlIHByb2ZpbGluZyBtb2RlLlxuICAgICAgICpcbiAgICAgICAqIEBkZWZhdWx0VmFsdWUgYCdvZmYnYFxuICAgICAgICovXG4gICAgICBtb2RlPzogJ29mZid8J2RlZmF1bHQnO1xuXG4gICAgICAvKipcbiAgICAgICAqIFNldCBvciBnZXQgYSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIGEgcHJvZmlsaW5nIGRhdGEgaXMgcmVjZWl2ZWQuIElmIG5vdCBzZXQsIHRoZSBwcm9maWxpbmcgZGF0YSB3aWxsIGJlXG4gICAgICAgKiBwcmludGVkIHRvIGNvbnNvbGUuXG4gICAgICAgKi9cbiAgICAgIG9uZGF0YT86IChkYXRhOiBXZWJHcHVQcm9maWxpbmdEYXRhKSA9PiB2b2lkO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgcG93ZXIgcHJlZmVyZW5jZS5cbiAgICAgKlxuICAgICAqIFNldHRpbmcgdGhpcyBwcm9wZXJ0eSBvbmx5IGhhcyBlZmZlY3QgYmVmb3JlIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC4gVGhlIHZhbHVlIHdpbGwgYmVcbiAgICAgKiB1c2VkIGFzIG9wdGlvbnMgZm9yIGBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKClgLlxuICAgICAqXG4gICAgICogU2VlIHtAbGluayBodHRwczovL2dwdXdlYi5naXRodWIuaW8vZ3B1d2ViLyNkaWN0ZGVmLWdwdXJlcXVlc3RhZGFwdGVyb3B0aW9uc30gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0VmFsdWUgYHVuZGVmaW5lZGBcbiAgICAgKi9cbiAgICBwb3dlclByZWZlcmVuY2U/OiAnbG93LXBvd2VyJ3wnaGlnaC1wZXJmb3JtYW5jZSc7XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB0aGUgZm9yY2UgZmFsbGJhY2sgYWRhcHRlciBmbGFnLlxuICAgICAqXG4gICAgICogU2V0dGluZyB0aGlzIHByb3BlcnR5IG9ubHkgaGFzIGVmZmVjdCBiZWZvcmUgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGUgdmFsdWUgd2lsbCBiZVxuICAgICAqIHVzZWQgYXMgb3B0aW9ucyBmb3IgYG5hdmlnYXRvci5ncHUucmVxdWVzdEFkYXB0ZXIoKWAuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIGh0dHBzOi8vZ3B1d2ViLmdpdGh1Yi5pby9ncHV3ZWIvI2RpY3RkZWYtZ3B1cmVxdWVzdGFkYXB0ZXJvcHRpb25zfSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQGRlZmF1bHRWYWx1ZSBgdW5kZWZpbmVkYFxuICAgICAqL1xuICAgIGZvcmNlRmFsbGJhY2tBZGFwdGVyPzogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBTZXQgb3IgZ2V0IHRoZSBhZGFwdGVyIGZvciBXZWJHUFUuXG4gICAgICpcbiAgICAgKiBTZXR0aW5nIHRoaXMgcHJvcGVydHkgb25seSBoYXMgZWZmZWN0IGJlZm9yZSB0aGUgZmlyc3QgV2ViR1BVIGluZmVyZW5jZSBzZXNzaW9uIGlzIGNyZWF0ZWQuIFRoZSB2YWx1ZSB3aWxsIGJlXG4gICAgICogdXNlZCBhcyB0aGUgR1BVIGFkYXB0ZXIgZm9yIHRoZSB1bmRlcmx5aW5nIFdlYkdQVSBiYWNrZW5kIHRvIGNyZWF0ZSBHUFUgZGV2aWNlLlxuICAgICAqXG4gICAgICogSWYgdGhpcyBwcm9wZXJ0eSBpcyBub3Qgc2V0LCBpdCB3aWxsIGJlIGF2YWlsYWJsZSB0byBnZXQgYWZ0ZXIgdGhlIGZpcnN0IFdlYkdQVSBpbmZlcmVuY2Ugc2Vzc2lvbiBpcyBjcmVhdGVkLiBUaGVcbiAgICAgKiB2YWx1ZSB3aWxsIGJlIHRoZSBHUFUgYWRhcHRlciB0aGF0IGNyZWF0ZWQgYnkgdGhlIHVuZGVybHlpbmcgV2ViR1BVIGJhY2tlbmQuXG4gICAgICpcbiAgICAgKiBXaGVuIHVzZSB3aXRoIFR5cGVTY3JpcHQsIHRoZSB0eXBlIG9mIHRoaXMgcHJvcGVydHkgaXMgYEdQVUFkYXB0ZXJgIGRlZmluZWQgaW4gXCJAd2ViZ3B1L3R5cGVzXCIuXG4gICAgICogVXNlIGBjb25zdCBhZGFwdGVyID0gZW52LndlYmdwdS5hZGFwdGVyIGFzIEdQVUFkYXB0ZXI7YCBpbiBUeXBlU2NyaXB0IHRvIGFjY2VzcyB0aGlzIHByb3BlcnR5IHdpdGggY29ycmVjdCB0eXBlLlxuICAgICAqXG4gICAgICogc2VlIGNvbW1lbnRzIG9uIHtAbGluayBUZW5zb3IuR3B1QnVmZmVyVHlwZX1cbiAgICAgKi9cbiAgICBhZGFwdGVyOiB1bmtub3duO1xuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZGV2aWNlIGZvciBXZWJHUFUuXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgYXZhaWxhYmxlIGFmdGVyIHRoZSBmaXJzdCBXZWJHUFUgaW5mZXJlbmNlIHNlc3Npb24gaXMgY3JlYXRlZC5cbiAgICAgKlxuICAgICAqIFdoZW4gdXNlIHdpdGggVHlwZVNjcmlwdCwgdGhlIHR5cGUgb2YgdGhpcyBwcm9wZXJ0eSBpcyBgR1BVRGV2aWNlYCBkZWZpbmVkIGluIFwiQHdlYmdwdS90eXBlc1wiLlxuICAgICAqIFVzZSBgY29uc3QgZGV2aWNlID0gZW52LndlYmdwdS5kZXZpY2UgYXMgR1BVRGV2aWNlO2AgaW4gVHlwZVNjcmlwdCB0byBhY2Nlc3MgdGhpcyBwcm9wZXJ0eSB3aXRoIGNvcnJlY3QgdHlwZS5cbiAgICAgKlxuICAgICAqIHNlZSBjb21tZW50cyBvbiB7QGxpbmsgVGVuc29yLkdwdUJ1ZmZlclR5cGV9IGZvciBtb3JlIGRldGFpbHMgYWJvdXQgd2h5IG5vdCB1c2UgdHlwZXMgZGVmaW5lZCBpbiBcIkB3ZWJncHUvdHlwZXNcIi5cbiAgICAgKi9cbiAgICByZWFkb25seSBkZXZpY2U6IHVua25vd247XG4gICAgLyoqXG4gICAgICogU2V0IG9yIGdldCB3aGV0aGVyIHZhbGlkYXRlIGlucHV0IGNvbnRlbnQuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICAgKi9cbiAgICB2YWxpZGF0ZUlucHV0Q29udGVudD86IGJvb2xlYW47XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBFbnYge1xuICAvKipcbiAgICogc2V0IHRoZSBzZXZlcml0eSBsZXZlbCBmb3IgbG9nZ2luZy5cbiAgICpcbiAgICogQGRlZmF1bHRWYWx1ZSBgJ3dhcm5pbmcnYFxuICAgKi9cbiAgbG9nTGV2ZWw/OiAndmVyYm9zZSd8J2luZm8nfCd3YXJuaW5nJ3wnZXJyb3InfCdmYXRhbCc7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlIHdoZXRoZXIgcnVuIGluIGRlYnVnIG1vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0VmFsdWUgYGZhbHNlYFxuICAgKi9cbiAgZGVidWc/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBzZXQgb3IgZ2V0IGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gZW5hYmxlIHRyYWNlLlxuICAgKlxuICAgKiBAZGVmYXVsdFZhbHVlIGBmYWxzZWBcbiAgICovXG4gIHRyYWNlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogR2V0IHZlcnNpb24gb2YgdGhlIGN1cnJlbnQgcGFja2FnZS5cbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb25zOiB7XG4gICAgcmVhZG9ubHkgY29tbW9uOiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgd2ViPzogc3RyaW5nO1xuICAgIHJlYWRvbmx5IG5vZGU/OiBzdHJpbmc7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICAgIHJlYWRvbmx5ICdyZWFjdC1uYXRpdmUnPzogc3RyaW5nO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZXByZXNlbnQgYSBzZXQgb2YgZmxhZ3MgZm9yIFdlYkFzc2VtYmx5XG4gICAqL1xuICByZWFkb25seSB3YXNtOiBFbnYuV2ViQXNzZW1ibHlGbGFncztcblxuICAvKipcbiAgICogUmVwcmVzZW50IGEgc2V0IG9mIGZsYWdzIGZvciBXZWJHTFxuICAgKi9cbiAgcmVhZG9ubHkgd2ViZ2w6IEVudi5XZWJHTEZsYWdzO1xuXG4gIC8qKlxuICAgKiBSZXByZXNlbnQgYSBzZXQgb2YgZmxhZ3MgZm9yIFdlYkdQVVxuICAgKi9cbiAgcmVhZG9ubHkgd2ViZ3B1OiBFbnYuV2ViR3B1RmxhZ3M7XG5cbiAgW25hbWU6IHN0cmluZ106IHVua25vd247XG59XG5cbi8qKlxuICogUmVwcmVzZW50IGEgc2V0IG9mIGZsYWdzIGFzIGEgZ2xvYmFsIHNpbmdsZXRvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IGVudjogRW52ID0gZW52SW1wbDtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3JUb0RhdGFVcmxPcHRpb25zLCBUZW5zb3JUb0ltYWdlRGF0YU9wdGlvbnN9IGZyb20gJy4vdGVuc29yLWNvbnZlcnNpb24uanMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4vdGVuc29yLmpzJztcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IudG9EYXRhVVJMKClcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvclRvRGF0YVVSTCA9ICh0ZW5zb3I6IFRlbnNvciwgb3B0aW9ucz86IFRlbnNvclRvRGF0YVVybE9wdGlvbnMpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjYW52YXMgPSB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykgOiAobmV3IE9mZnNjcmVlbkNhbnZhcygxLCAxKSk7XG4gIGNhbnZhcy53aWR0aCA9IHRlbnNvci5kaW1zWzNdO1xuICBjYW52YXMuaGVpZ2h0ID0gdGVuc29yLmRpbXNbMl07XG4gIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9XG4gICAgICBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhcyAoQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIHwgT2Zmc2NyZWVuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIHwgbnVsbCk7XG5cbiAgaWYgKHBpeGVsczJEQ29udGV4dCAhPSBudWxsKSB7XG4gICAgLy8gRGVmYXVsdCB2YWx1ZXMgZm9yIGhlaWdodCBhbmQgd2lkdGggJiBmb3JtYXRcbiAgICBsZXQgd2lkdGg6IG51bWJlcjtcbiAgICBsZXQgaGVpZ2h0OiBudW1iZXI7XG4gICAgaWYgKG9wdGlvbnM/LnRlbnNvckxheW91dCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMudGVuc29yTGF5b3V0ID09PSAnTkhXQycpIHtcbiAgICAgIHdpZHRoID0gdGVuc29yLmRpbXNbMl07XG4gICAgICBoZWlnaHQgPSB0ZW5zb3IuZGltc1szXTtcbiAgICB9IGVsc2UgeyAgLy8gRGVmYXVsdCBsYXlvdXQgaXMgTkNXSFxuICAgICAgd2lkdGggPSB0ZW5zb3IuZGltc1szXTtcbiAgICAgIGhlaWdodCA9IHRlbnNvci5kaW1zWzJdO1xuICAgIH1cblxuICAgIGNvbnN0IGlucHV0Zm9ybWF0ID0gb3B0aW9ucz8uZm9ybWF0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZvcm1hdCA6ICdSR0InO1xuXG4gICAgY29uc3Qgbm9ybSA9IG9wdGlvbnM/Lm5vcm07XG4gICAgbGV0IG5vcm1NZWFuOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICBsZXQgbm9ybUJpYXM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGlmIChub3JtID09PSB1bmRlZmluZWQgfHwgbm9ybS5tZWFuID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5vcm1NZWFuID0gWzI1NSwgMjU1LCAyNTUsIDI1NV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2YgKG5vcm0ubWVhbikgPT09ICdudW1iZXInKSB7XG4gICAgICAgIG5vcm1NZWFuID0gW25vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbl07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtTWVhbiA9IFtub3JtLm1lYW5bMF0sIG5vcm0ubWVhblsxXSwgbm9ybS5tZWFuWzJdLCAwXTtcbiAgICAgICAgaWYgKG5vcm0ubWVhblszXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbm9ybU1lYW5bM10gPSBub3JtLm1lYW5bM107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG5vcm0gPT09IHVuZGVmaW5lZCB8fCBub3JtLmJpYXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbm9ybUJpYXMgPSBbMCwgMCwgMCwgMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2YgKG5vcm0uYmlhcykgPT09ICdudW1iZXInKSB7XG4gICAgICAgIG5vcm1CaWFzID0gW25vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhc107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtQmlhcyA9IFtub3JtLmJpYXNbMF0sIG5vcm0uYmlhc1sxXSwgbm9ybS5iaWFzWzJdLCAwXTtcbiAgICAgICAgaWYgKG5vcm0uYmlhc1szXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbm9ybUJpYXNbM10gPSBub3JtLmJpYXNbM107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzdHJpZGUgPSBoZWlnaHQgKiB3aWR0aDtcbiAgICAvLyBEZWZhdWx0IHBvaW50ZXIgYXNzaWdubWVudHNcbiAgICBsZXQgclRlbnNvclBvaW50ZXIgPSAwLCBnVGVuc29yUG9pbnRlciA9IHN0cmlkZSwgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyLCBhVGVuc29yUG9pbnRlciA9IC0xO1xuXG4gICAgLy8gVXBkYXRpbmcgdGhlIHBvaW50ZXIgYXNzaWdubWVudHMgYmFzZWQgb24gdGhlIGlucHV0IGltYWdlIGZvcm1hdFxuICAgIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JHQkEnKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBnVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICAgIGFUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMztcbiAgICB9IGVsc2UgaWYgKGlucHV0Zm9ybWF0ID09PSAnUkdCJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgfSBlbHNlIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JCRycpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGVpZ2h0OyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgd2lkdGg7IGorKykge1xuICAgICAgICBjb25zdCBSID0gKCh0ZW5zb3IuZGF0YVtyVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbMF0pICogbm9ybU1lYW5bMF07ICAvLyBSIHZhbHVlXG4gICAgICAgIGNvbnN0IEcgPSAoKHRlbnNvci5kYXRhW2dUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1sxXSkgKiBub3JtTWVhblsxXTsgIC8vIEcgdmFsdWVcbiAgICAgICAgY29uc3QgQiA9ICgodGVuc29yLmRhdGFbYlRlbnNvclBvaW50ZXIrK10gYXMgbnVtYmVyKSAtIG5vcm1CaWFzWzJdKSAqIG5vcm1NZWFuWzJdOyAgLy8gQiB2YWx1ZVxuICAgICAgICBjb25zdCBBID0gYVRlbnNvclBvaW50ZXIgPT09IC0xID9cbiAgICAgICAgICAgIDI1NSA6XG4gICAgICAgICAgICAoKHRlbnNvci5kYXRhW2FUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1szXSkgKiBub3JtTWVhblszXTsgIC8vIEEgdmFsdWVcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9yZXN0cmljdC1wbHVzLW9wZXJhbmRzXG4gICAgICAgIHBpeGVsczJEQ29udGV4dC5maWxsU3R5bGUgPSAncmdiYSgnICsgUiArICcsJyArIEcgKyAnLCcgKyBCICsgJywnICsgQSArICcpJztcbiAgICAgICAgcGl4ZWxzMkRDb250ZXh0LmZpbGxSZWN0KGosIGksIDEsIDEpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoJ3RvRGF0YVVSTCcgaW4gY2FudmFzKSB7XG4gICAgICByZXR1cm4gY2FudmFzLnRvRGF0YVVSTCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RvRGF0YVVSTCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBhY2Nlc3MgaW1hZ2UgZGF0YScpO1xuICB9XG59O1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci50b0ltYWdlRGF0YSgpXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JUb0ltYWdlRGF0YSA9ICh0ZW5zb3I6IFRlbnNvciwgb3B0aW9ucz86IFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyk6IEltYWdlRGF0YSA9PiB7XG4gIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9IHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKSA6XG4gICAgICBuZXcgT2Zmc2NyZWVuQ2FudmFzKDEsIDEpLmdldENvbnRleHQoJzJkJykgYXMgT2Zmc2NyZWVuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEO1xuICBsZXQgaW1hZ2U6IEltYWdlRGF0YTtcbiAgaWYgKHBpeGVsczJEQ29udGV4dCAhPSBudWxsKSB7XG4gICAgLy8gRGVmYXVsdCB2YWx1ZXMgZm9yIGhlaWdodCBhbmQgd2lkdGggJiBmb3JtYXRcbiAgICBsZXQgd2lkdGg6IG51bWJlcjtcbiAgICBsZXQgaGVpZ2h0OiBudW1iZXI7XG4gICAgbGV0IGNoYW5uZWxzOiBudW1iZXI7XG4gICAgaWYgKG9wdGlvbnM/LnRlbnNvckxheW91dCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMudGVuc29yTGF5b3V0ID09PSAnTkhXQycpIHtcbiAgICAgIHdpZHRoID0gdGVuc29yLmRpbXNbMl07XG4gICAgICBoZWlnaHQgPSB0ZW5zb3IuZGltc1sxXTtcbiAgICAgIGNoYW5uZWxzID0gdGVuc29yLmRpbXNbM107XG4gICAgfSBlbHNlIHsgIC8vIERlZmF1bHQgbGF5b3V0IGlzIE5DV0hcbiAgICAgIHdpZHRoID0gdGVuc29yLmRpbXNbM107XG4gICAgICBoZWlnaHQgPSB0ZW5zb3IuZGltc1syXTtcbiAgICAgIGNoYW5uZWxzID0gdGVuc29yLmRpbXNbMV07XG4gICAgfVxuICAgIGNvbnN0IGlucHV0Zm9ybWF0ID0gb3B0aW9ucyAhPT0gdW5kZWZpbmVkID8gKG9wdGlvbnMuZm9ybWF0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZvcm1hdCA6ICdSR0InKSA6ICdSR0InO1xuXG4gICAgY29uc3Qgbm9ybSA9IG9wdGlvbnM/Lm5vcm07XG4gICAgbGV0IG5vcm1NZWFuOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgICBsZXQgbm9ybUJpYXM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgIGlmIChub3JtID09PSB1bmRlZmluZWQgfHwgbm9ybS5tZWFuID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5vcm1NZWFuID0gWzI1NSwgMjU1LCAyNTUsIDI1NV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2YgKG5vcm0ubWVhbikgPT09ICdudW1iZXInKSB7XG4gICAgICAgIG5vcm1NZWFuID0gW25vcm0ubWVhbiwgbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbl07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtTWVhbiA9IFtub3JtLm1lYW5bMF0sIG5vcm0ubWVhblsxXSwgbm9ybS5tZWFuWzJdLCAyNTVdO1xuICAgICAgICBpZiAobm9ybS5tZWFuWzNdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBub3JtTWVhblszXSA9IG5vcm0ubWVhblszXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobm9ybSA9PT0gdW5kZWZpbmVkIHx8IG5vcm0uYmlhcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBub3JtQmlhcyA9IFswLCAwLCAwLCAwXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiAobm9ybS5iaWFzKSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhcywgbm9ybS5iaWFzXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vcm1CaWFzID0gW25vcm0uYmlhc1swXSwgbm9ybS5iaWFzWzFdLCBub3JtLmJpYXNbMl0sIDBdO1xuICAgICAgICBpZiAobm9ybS5iaWFzWzNdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBub3JtQmlhc1szXSA9IG5vcm0uYmlhc1szXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN0cmlkZSA9IGhlaWdodCAqIHdpZHRoO1xuICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChvcHRpb25zLmZvcm1hdCAhPT0gdW5kZWZpbmVkICYmIChjaGFubmVscyA9PT0gNCAmJiBvcHRpb25zLmZvcm1hdCAhPT0gJ1JHQkEnKSB8fFxuICAgICAgICAgIChjaGFubmVscyA9PT0gMyAmJiAob3B0aW9ucy5mb3JtYXQgIT09ICdSR0InICYmIG9wdGlvbnMuZm9ybWF0ICE9PSAnQkdSJykpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGVuc29yIGZvcm1hdCBkb2VzblxcJ3QgbWF0Y2ggaW5wdXQgdGVuc29yIGRpbXMnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBEZWZhdWx0IHBvaW50ZXIgYXNzaWdubWVudHNcbiAgICBjb25zdCBzdGVwID0gNDtcbiAgICBsZXQgckltYWdlUG9pbnRlciA9IDAsIGdJbWFnZVBvaW50ZXIgPSAxLCBiSW1hZ2VQb2ludGVyID0gMiwgYUltYWdlUG9pbnRlciA9IDM7XG4gICAgbGV0IHJUZW5zb3JQb2ludGVyID0gMCwgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUsIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMiwgYVRlbnNvclBvaW50ZXIgPSAtMTtcblxuICAgIC8vIFVwZGF0aW5nIHRoZSBwb2ludGVyIGFzc2lnbm1lbnRzIGJhc2VkIG9uIHRoZSBpbnB1dCBpbWFnZSBmb3JtYXRcbiAgICBpZiAoaW5wdXRmb3JtYXQgPT09ICdSR0JBJykge1xuICAgICAgclRlbnNvclBvaW50ZXIgPSAwO1xuICAgICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDI7XG4gICAgICBhVGVuc29yUG9pbnRlciA9IHN0cmlkZSAqIDM7XG4gICAgfSBlbHNlIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JHQicpIHtcbiAgICAgIHJUZW5zb3JQb2ludGVyID0gMDtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlO1xuICAgICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICAgIH0gZWxzZSBpZiAoaW5wdXRmb3JtYXQgPT09ICdSQkcnKSB7XG4gICAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgICBiVGVuc29yUG9pbnRlciA9IHN0cmlkZTtcbiAgICAgIGdUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMjtcbiAgICB9XG5cbiAgICBpbWFnZSA9IHBpeGVsczJEQ29udGV4dC5jcmVhdGVJbWFnZURhdGEod2lkdGgsIGhlaWdodCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhlaWdodCAqIHdpZHRoO1xuICAgICAgICAgckltYWdlUG9pbnRlciArPSBzdGVwLCBnSW1hZ2VQb2ludGVyICs9IHN0ZXAsIGJJbWFnZVBvaW50ZXIgKz0gc3RlcCwgYUltYWdlUG9pbnRlciArPSBzdGVwLCBpKyspIHtcbiAgICAgIGltYWdlLmRhdGFbckltYWdlUG9pbnRlcl0gPSAoKHRlbnNvci5kYXRhW3JUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1swXSkgKiBub3JtTWVhblswXTsgIC8vIFIgdmFsdWVcbiAgICAgIGltYWdlLmRhdGFbZ0ltYWdlUG9pbnRlcl0gPSAoKHRlbnNvci5kYXRhW2dUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1sxXSkgKiBub3JtTWVhblsxXTsgIC8vIEcgdmFsdWVcbiAgICAgIGltYWdlLmRhdGFbYkltYWdlUG9pbnRlcl0gPSAoKHRlbnNvci5kYXRhW2JUZW5zb3JQb2ludGVyKytdIGFzIG51bWJlcikgLSBub3JtQmlhc1syXSkgKiBub3JtTWVhblsyXTsgIC8vIEIgdmFsdWVcbiAgICAgIGltYWdlLmRhdGFbYUltYWdlUG9pbnRlcl0gPSBhVGVuc29yUG9pbnRlciA9PT0gLTEgP1xuICAgICAgICAgIDI1NSA6XG4gICAgICAgICAgKCh0ZW5zb3IuZGF0YVthVGVuc29yUG9pbnRlcisrXSBhcyBudW1iZXIpIC0gbm9ybUJpYXNbM10pICogbm9ybU1lYW5bM107ICAvLyBBIHZhbHVlXG4gICAgfVxuXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IGFjY2VzcyBpbWFnZSBkYXRhJyk7XG4gIH1cbiAgcmV0dXJuIGltYWdlO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtPcHRpb25zRGltZW5zaW9ucywgT3B0aW9uc0Zvcm1hdCwgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzLCBPcHRpb25zVGVuc29yRm9ybWF0LCBPcHRpb25zVGVuc29yTGF5b3V0LCBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9ucywgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9ucywgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnMsIFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zLCBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnMsIFRlbnNvckZyb21VcmxPcHRpb25zfSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuL3RlbnNvci1pbXBsLmpzJztcbmltcG9ydCB7VGVuc29yIGFzIFRlbnNvckludGVyZmFjZX0gZnJvbSAnLi90ZW5zb3IuanMnO1xuXG5pbnRlcmZhY2UgQnVmZmVyVG9UZW5zb3JPcHRpb25zIGV4dGVuZHMgT3B0aW9uc0RpbWVuc2lvbnMsIE9wdGlvbnNUZW5zb3JMYXlvdXQsIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25zRm9ybWF0LCBPcHRpb25zVGVuc29yRm9ybWF0IHt9XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSBpbWFnZSBvYmplY3RcbiAqXG4gKiBAcGFyYW0gYnVmZmVyIC0gRXh0cmFjdGVkIGltYWdlIGJ1ZmZlciBkYXRhIC0gYXNzdW1pbmcgUkdCQSBmb3JtYXRcbiAqIEBwYXJhbSBpbWFnZUZvcm1hdCAtIGlucHV0IGltYWdlIGNvbmZpZ3VyYXRpb24gLSByZXF1aXJlZCBjb25maWd1cmF0aW9ucyBoZWlnaHQsIHdpZHRoLCBmb3JtYXRcbiAqIEBwYXJhbSB0ZW5zb3JGb3JtYXQgLSBvdXRwdXQgdGVuc29yIGNvbmZpZ3VyYXRpb24gLSBEZWZhdWx0IGlzIFJHQiBmb3JtYXRcbiAqL1xuZXhwb3J0IGNvbnN0IGJ1ZmZlclRvVGVuc29yID0gKGJ1ZmZlcjogVWludDhDbGFtcGVkQXJyYXl8dW5kZWZpbmVkLCBvcHRpb25zOiBCdWZmZXJUb1RlbnNvck9wdGlvbnMpOiBUZW5zb3IgPT4ge1xuICBpZiAoYnVmZmVyID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlIGJ1ZmZlciBtdXN0IGJlIGRlZmluZWQnKTtcbiAgfVxuICBpZiAob3B0aW9ucy5oZWlnaHQgPT09IHVuZGVmaW5lZCB8fCBvcHRpb25zLndpZHRoID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlIGhlaWdodCBhbmQgd2lkdGggbXVzdCBiZSBkZWZpbmVkJyk7XG4gIH1cbiAgaWYgKG9wdGlvbnMudGVuc29yTGF5b3V0ID09PSAnTkhXQycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05IV0MgVGVuc29yIGxheW91dCBpcyBub3Qgc3VwcG9ydGVkIHlldCcpO1xuICB9XG5cbiAgY29uc3Qge2hlaWdodCwgd2lkdGh9ID0gb3B0aW9ucztcblxuICBjb25zdCBub3JtID0gb3B0aW9ucy5ub3JtID8/IHttZWFuOiAyNTUsIGJpYXM6IDB9O1xuICBsZXQgbm9ybU1lYW46IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICBsZXQgbm9ybUJpYXM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuXG4gIGlmICh0eXBlb2YgKG5vcm0ubWVhbikgPT09ICdudW1iZXInKSB7XG4gICAgbm9ybU1lYW4gPSBbbm9ybS5tZWFuLCBub3JtLm1lYW4sIG5vcm0ubWVhbiwgbm9ybS5tZWFuXTtcbiAgfSBlbHNlIHtcbiAgICBub3JtTWVhbiA9IFtub3JtLm1lYW4hWzBdLCBub3JtLm1lYW4hWzFdLCBub3JtLm1lYW4hWzJdLCBub3JtLm1lYW4hWzNdID8/IDI1NV07XG4gIH1cblxuICBpZiAodHlwZW9mIChub3JtLmJpYXMpID09PSAnbnVtYmVyJykge1xuICAgIG5vcm1CaWFzID0gW25vcm0uYmlhcywgbm9ybS5iaWFzLCBub3JtLmJpYXMsIG5vcm0uYmlhc107XG4gIH0gZWxzZSB7XG4gICAgbm9ybUJpYXMgPSBbbm9ybS5iaWFzIVswXSwgbm9ybS5iaWFzIVsxXSwgbm9ybS5iaWFzIVsyXSwgbm9ybS5iaWFzIVszXSA/PyAwXTtcbiAgfVxuXG4gIGNvbnN0IGlucHV0Zm9ybWF0ID0gb3B0aW9ucy5mb3JtYXQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZm9ybWF0IDogJ1JHQkEnO1xuICAvLyBkZWZhdWx0IHZhbHVlIGlzIFJHQkEgc2luY2UgaW1hZ2VkYXRhIGFuZCBIVE1MSW1hZ2VFbGVtZW50IHVzZXMgaXRcblxuICBjb25zdCBvdXRwdXRmb3JtYXQgPVxuICAgICAgb3B0aW9ucy50ZW5zb3JGb3JtYXQgIT09IHVuZGVmaW5lZCA/IChvcHRpb25zLnRlbnNvckZvcm1hdCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy50ZW5zb3JGb3JtYXQgOiAnUkdCJykgOiAnUkdCJztcbiAgY29uc3Qgc3RyaWRlID0gaGVpZ2h0ICogd2lkdGg7XG4gIGNvbnN0IGZsb2F0MzJEYXRhID0gb3V0cHV0Zm9ybWF0ID09PSAnUkdCQScgPyBuZXcgRmxvYXQzMkFycmF5KHN0cmlkZSAqIDQpIDogbmV3IEZsb2F0MzJBcnJheShzdHJpZGUgKiAzKTtcblxuICAvLyBEZWZhdWx0IHBvaW50ZXIgYXNzaWdubWVudHNcbiAgbGV0IHN0ZXAgPSA0LCBySW1hZ2VQb2ludGVyID0gMCwgZ0ltYWdlUG9pbnRlciA9IDEsIGJJbWFnZVBvaW50ZXIgPSAyLCBhSW1hZ2VQb2ludGVyID0gMztcbiAgbGV0IHJUZW5zb3JQb2ludGVyID0gMCwgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUsIGJUZW5zb3JQb2ludGVyID0gc3RyaWRlICogMiwgYVRlbnNvclBvaW50ZXIgPSAtMTtcblxuICAvLyBVcGRhdGluZyB0aGUgcG9pbnRlciBhc3NpZ25tZW50cyBiYXNlZCBvbiB0aGUgaW5wdXQgaW1hZ2UgZm9ybWF0XG4gIGlmIChpbnB1dGZvcm1hdCA9PT0gJ1JHQicpIHtcbiAgICBzdGVwID0gMztcbiAgICBySW1hZ2VQb2ludGVyID0gMDtcbiAgICBnSW1hZ2VQb2ludGVyID0gMTtcbiAgICBiSW1hZ2VQb2ludGVyID0gMjtcbiAgICBhSW1hZ2VQb2ludGVyID0gLTE7XG4gIH1cblxuICAvLyBVcGRhdGluZyB0aGUgcG9pbnRlciBhc3NpZ25tZW50cyBiYXNlZCBvbiB0aGUgb3V0cHV0IHRlbnNvciBmb3JtYXRcbiAgaWYgKG91dHB1dGZvcm1hdCA9PT0gJ1JHQkEnKSB7XG4gICAgYVRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAzO1xuICB9IGVsc2UgaWYgKG91dHB1dGZvcm1hdCA9PT0gJ1JCRycpIHtcbiAgICByVGVuc29yUG9pbnRlciA9IDA7XG4gICAgYlRlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICB9IGVsc2UgaWYgKG91dHB1dGZvcm1hdCA9PT0gJ0JHUicpIHtcbiAgICBiVGVuc29yUG9pbnRlciA9IDA7XG4gICAgZ1RlbnNvclBvaW50ZXIgPSBzdHJpZGU7XG4gICAgclRlbnNvclBvaW50ZXIgPSBzdHJpZGUgKiAyO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdHJpZGU7XG4gICAgICAgaSsrLCBySW1hZ2VQb2ludGVyICs9IHN0ZXAsIGJJbWFnZVBvaW50ZXIgKz0gc3RlcCwgZ0ltYWdlUG9pbnRlciArPSBzdGVwLCBhSW1hZ2VQb2ludGVyICs9IHN0ZXApIHtcbiAgICBmbG9hdDMyRGF0YVtyVGVuc29yUG9pbnRlcisrXSA9IChidWZmZXJbckltYWdlUG9pbnRlcl0gKyBub3JtQmlhc1swXSkgLyBub3JtTWVhblswXTtcbiAgICBmbG9hdDMyRGF0YVtnVGVuc29yUG9pbnRlcisrXSA9IChidWZmZXJbZ0ltYWdlUG9pbnRlcl0gKyBub3JtQmlhc1sxXSkgLyBub3JtTWVhblsxXTtcbiAgICBmbG9hdDMyRGF0YVtiVGVuc29yUG9pbnRlcisrXSA9IChidWZmZXJbYkltYWdlUG9pbnRlcl0gKyBub3JtQmlhc1syXSkgLyBub3JtTWVhblsyXTtcbiAgICBpZiAoYVRlbnNvclBvaW50ZXIgIT09IC0xICYmIGFJbWFnZVBvaW50ZXIgIT09IC0xKSB7XG4gICAgICBmbG9hdDMyRGF0YVthVGVuc29yUG9pbnRlcisrXSA9IChidWZmZXJbYUltYWdlUG9pbnRlcl0gKyBub3JtQmlhc1szXSkgLyBub3JtTWVhblszXTtcbiAgICB9XG4gIH1cblxuICAvLyBGbG9hdDMyQXJyYXkgLT4gb3J0LlRlbnNvclxuICBjb25zdCBvdXRwdXRUZW5zb3IgPSBvdXRwdXRmb3JtYXQgPT09ICdSR0JBJyA/IG5ldyBUZW5zb3IoJ2Zsb2F0MzInLCBmbG9hdDMyRGF0YSwgWzEsIDQsIGhlaWdodCwgd2lkdGhdKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFRlbnNvcignZmxvYXQzMicsIGZsb2F0MzJEYXRhLCBbMSwgMywgaGVpZ2h0LCB3aWR0aF0pO1xuICByZXR1cm4gb3V0cHV0VGVuc29yO1xufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbUltYWdlKCkuXG4gKi9cbmV4cG9ydCBjb25zdCB0ZW5zb3JGcm9tSW1hZ2UgPSBhc3luYyhcbiAgICBpbWFnZTogSW1hZ2VEYXRhfEhUTUxJbWFnZUVsZW1lbnR8SW1hZ2VCaXRtYXB8c3RyaW5nLFxuICAgIG9wdGlvbnM/OiBUZW5zb3JGcm9tSW1hZ2VEYXRhT3B0aW9uc3xUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9uc3xUZW5zb3JGcm9tSW1hZ2VCaXRtYXBPcHRpb25zfFxuICAgIFRlbnNvckZyb21VcmxPcHRpb25zKTogUHJvbWlzZTxUZW5zb3I+ID0+IHtcbiAgLy8gY2hlY2tpbmcgdGhlIHR5cGUgb2YgaW1hZ2Ugb2JqZWN0XG4gIGNvbnN0IGlzSFRNTEltYWdlRWxlID0gdHlwZW9mIChIVE1MSW1hZ2VFbGVtZW50KSAhPT0gJ3VuZGVmaW5lZCcgJiYgaW1hZ2UgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50O1xuICBjb25zdCBpc0ltYWdlRGF0YUVsZSA9IHR5cGVvZiAoSW1hZ2VEYXRhKSAhPT0gJ3VuZGVmaW5lZCcgJiYgaW1hZ2UgaW5zdGFuY2VvZiBJbWFnZURhdGE7XG4gIGNvbnN0IGlzSW1hZ2VCaXRtYXAgPSB0eXBlb2YgKEltYWdlQml0bWFwKSAhPT0gJ3VuZGVmaW5lZCcgJiYgaW1hZ2UgaW5zdGFuY2VvZiBJbWFnZUJpdG1hcDtcbiAgY29uc3QgaXNTdHJpbmcgPSB0eXBlb2YgaW1hZ2UgPT09ICdzdHJpbmcnO1xuXG4gIGxldCBkYXRhOiBVaW50OENsYW1wZWRBcnJheXx1bmRlZmluZWQ7XG4gIGxldCBidWZmZXJUb1RlbnNvck9wdGlvbnM6IEJ1ZmZlclRvVGVuc29yT3B0aW9ucyA9IG9wdGlvbnMgPz8ge307XG5cbiAgY29uc3QgY3JlYXRlQ2FudmFzID0gKCkgPT4ge1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgT2Zmc2NyZWVuQ2FudmFzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIG5ldyBPZmZzY3JlZW5DYW52YXMoMSwgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2FudmFzIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH07XG4gIGNvbnN0IGNyZWF0ZUNhbnZhc0NvbnRleHQgPSAoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudHxPZmZzY3JlZW5DYW52YXMpID0+IHtcbiAgICBpZiAoY2FudmFzIGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQpIHtcbiAgICAgIHJldHVybiBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICB9IGVsc2UgaWYgKGNhbnZhcyBpbnN0YW5jZW9mIE9mZnNjcmVlbkNhbnZhcykge1xuICAgICAgcmV0dXJuIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpIGFzIE9mZnNjcmVlbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9O1xuICAvLyBmaWxsaW5nIGFuZCBjaGVja2luZyBpbWFnZSBjb25maWd1cmF0aW9uIG9wdGlvbnNcbiAgaWYgKGlzSFRNTEltYWdlRWxlKSB7XG4gICAgLy8gSFRNTEltYWdlRWxlbWVudCAtIGltYWdlIG9iamVjdCAtIGZvcm1hdCBpcyBSR0JBIGJ5IGRlZmF1bHRcbiAgICBjb25zdCBjYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcbiAgICBjYW52YXMud2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICBjYW52YXMuaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQoY2FudmFzKTtcblxuICAgIGlmIChwaXhlbHMyRENvbnRleHQgIT0gbnVsbCkge1xuICAgICAgbGV0IGhlaWdodCA9IGltYWdlLmhlaWdodDtcbiAgICAgIGxldCB3aWR0aCA9IGltYWdlLndpZHRoO1xuICAgICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnJlc2l6ZWRIZWlnaHQgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnJlc2l6ZWRXaWR0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGhlaWdodCA9IG9wdGlvbnMucmVzaXplZEhlaWdodDtcbiAgICAgICAgd2lkdGggPSBvcHRpb25zLnJlc2l6ZWRXaWR0aDtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICBpZiAob3B0aW9ucy50ZW5zb3JGb3JtYXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW1hZ2UgaW5wdXQgY29uZmlnIGZvcm1hdCBtdXN0IGJlIFJHQkEgZm9yIEhUTUxJbWFnZUVsZW1lbnQnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMudGVuc29yRm9ybWF0ID0gJ1JHQkEnO1xuICAgICAgICB9XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy53aWR0aCA9IHdpZHRoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLnRlbnNvckZvcm1hdCA9ICdSR0JBJztcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLmhlaWdodCA9IGhlaWdodDtcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLndpZHRoID0gd2lkdGg7XG4gICAgICB9XG5cbiAgICAgIHBpeGVsczJEQ29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIDAsIDApO1xuICAgICAgZGF0YSA9IHBpeGVsczJEQ29udGV4dC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCkuZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gbm90IGFjY2VzcyBpbWFnZSBkYXRhJyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzSW1hZ2VEYXRhRWxlKSB7XG4gICAgbGV0IGhlaWdodDogbnVtYmVyO1xuICAgIGxldCB3aWR0aDogbnVtYmVyO1xuXG4gICAgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnJlc2l6ZWRXaWR0aCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMucmVzaXplZEhlaWdodCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBoZWlnaHQgPSBvcHRpb25zLnJlc2l6ZWRIZWlnaHQ7XG4gICAgICB3aWR0aCA9IG9wdGlvbnMucmVzaXplZFdpZHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICBoZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgICB3aWR0aCA9IGltYWdlLndpZHRoO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxuICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy5mb3JtYXQgPSAnUkdCQSc7XG4gICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLmhlaWdodCA9IGhlaWdodDtcbiAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMud2lkdGggPSB3aWR0aDtcblxuICAgIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IHRlbXBDYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcblxuICAgICAgdGVtcENhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgICAgdGVtcENhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG5cbiAgICAgIGNvbnN0IHBpeGVsczJEQ29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQodGVtcENhbnZhcyk7XG5cbiAgICAgIGlmIChwaXhlbHMyRENvbnRleHQgIT0gbnVsbCkge1xuICAgICAgICBwaXhlbHMyRENvbnRleHQucHV0SW1hZ2VEYXRhKGltYWdlLCAwLCAwKTtcbiAgICAgICAgZGF0YSA9IHBpeGVsczJEQ29udGV4dC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCkuZGF0YTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBhY2Nlc3MgaW1hZ2UgZGF0YScpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBkYXRhID0gaW1hZ2UuZGF0YTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNJbWFnZUJpdG1hcCkge1xuICAgIC8vIEltYWdlQml0bWFwIC0gaW1hZ2Ugb2JqZWN0IC0gZm9ybWF0IG11c3QgYmUgcHJvdmlkZWQgYnkgdXNlclxuICAgIGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHByb3ZpZGUgaW1hZ2UgY29uZmlnIHdpdGggZm9ybWF0IGZvciBJbWFnZWJpdG1hcCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbnZhcyA9IGNyZWF0ZUNhbnZhcygpO1xuICAgIGNhbnZhcy53aWR0aCA9IGltYWdlLndpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgY29uc3QgcGl4ZWxzMkRDb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dChjYW52YXMpO1xuXG4gICAgaWYgKHBpeGVsczJEQ29udGV4dCAhPSBudWxsKSB7XG4gICAgICBjb25zdCBoZWlnaHQgPSBpbWFnZS5oZWlnaHQ7XG4gICAgICBjb25zdCB3aWR0aCA9IGltYWdlLndpZHRoO1xuICAgICAgcGl4ZWxzMkRDb250ZXh0LmRyYXdJbWFnZShpbWFnZSwgMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICBkYXRhID0gcGl4ZWxzMkRDb250ZXh0LmdldEltYWdlRGF0YSgwLCAwLCB3aWR0aCwgaGVpZ2h0KS5kYXRhO1xuICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLmhlaWdodCA9IGhlaWdodDtcbiAgICAgIGJ1ZmZlclRvVGVuc29yT3B0aW9ucy53aWR0aCA9IHdpZHRoO1xuICAgICAgcmV0dXJuIGJ1ZmZlclRvVGVuc29yKGRhdGEsIGJ1ZmZlclRvVGVuc29yT3B0aW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG5vdCBhY2Nlc3MgaW1hZ2UgZGF0YScpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc1N0cmluZykge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0KGNhbnZhcyk7XG4gICAgICBpZiAoIWltYWdlIHx8ICFjb250ZXh0KSB7XG4gICAgICAgIHJldHVybiByZWplY3QoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG5ld0ltYWdlID0gbmV3IEltYWdlKCk7XG4gICAgICBuZXdJbWFnZS5jcm9zc09yaWdpbiA9ICdBbm9ueW1vdXMnO1xuICAgICAgbmV3SW1hZ2Uuc3JjID0gaW1hZ2U7XG4gICAgICBuZXdJbWFnZS5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgIGNhbnZhcy53aWR0aCA9IG5ld0ltYWdlLndpZHRoO1xuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gbmV3SW1hZ2UuaGVpZ2h0O1xuICAgICAgICBjb250ZXh0LmRyYXdJbWFnZShuZXdJbWFnZSwgMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgICAgICAgY29uc3QgaW1nID0gY29udGV4dC5nZXRJbWFnZURhdGEoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcblxuICAgICAgICBidWZmZXJUb1RlbnNvck9wdGlvbnMuaGVpZ2h0ID0gY2FudmFzLmhlaWdodDtcbiAgICAgICAgYnVmZmVyVG9UZW5zb3JPcHRpb25zLndpZHRoID0gY2FudmFzLndpZHRoO1xuICAgICAgICByZXNvbHZlKGJ1ZmZlclRvVGVuc29yKGltZy5kYXRhLCBidWZmZXJUb1RlbnNvck9wdGlvbnMpKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBkYXRhIHByb3ZpZGVkIGlzIG5vdCBzdXBwb3J0ZWQgLSBhYm9ydGVkIHRlbnNvciBjcmVhdGlvbicpO1xuICB9XG5cbiAgaWYgKGRhdGEgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBidWZmZXJUb1RlbnNvcihkYXRhLCBidWZmZXJUb1RlbnNvck9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgZGF0YSBwcm92aWRlZCBpcyBub3Qgc3VwcG9ydGVkIC0gYWJvcnRlZCB0ZW5zb3IgY3JlYXRpb24nKTtcbiAgfVxufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbVRleHR1cmUoKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvckZyb21UZXh0dXJlID0gPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuVGV4dHVyZURhdGFUeXBlcz4oXG4gICAgdGV4dHVyZTogVGVuc29ySW50ZXJmYWNlLlRleHR1cmVUeXBlLCBvcHRpb25zOiBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnM8VD4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB7d2lkdGgsIGhlaWdodCwgZG93bmxvYWQsIGRpc3Bvc2V9ID0gb3B0aW9ucztcbiAgLy8gQWx3YXlzIGFzc3VtZSBSR0JBRjMyLiBUT0RPOiBzdXBwb3J0IGRpZmZlcmVudCB0ZXh0dXJlIGZvcm1hdFxuICBjb25zdCBkaW1zID0gWzEsIGhlaWdodCwgd2lkdGgsIDRdO1xuICByZXR1cm4gbmV3IFRlbnNvcih7bG9jYXRpb246ICd0ZXh0dXJlJywgdHlwZTogJ2Zsb2F0MzInLCB0ZXh0dXJlLCBkaW1zLCBkb3dubG9hZCwgZGlzcG9zZX0pO1xufTtcblxuLyoqXG4gKiBpbXBsZW1lbnRhdGlvbiBvZiBUZW5zb3IuZnJvbUdwdUJ1ZmZlcigpLlxuICovXG5leHBvcnQgY29uc3QgdGVuc29yRnJvbUdwdUJ1ZmZlciA9IDxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLkdwdUJ1ZmZlckRhdGFUeXBlcz4oXG4gICAgZ3B1QnVmZmVyOiBUZW5zb3JJbnRlcmZhY2UuR3B1QnVmZmVyVHlwZSwgb3B0aW9uczogVGVuc29yRnJvbUdwdUJ1ZmZlck9wdGlvbnM8VD4pOiBUZW5zb3IgPT4ge1xuICBjb25zdCB7ZGF0YVR5cGUsIGRpbXMsIGRvd25sb2FkLCBkaXNwb3NlfSA9IG9wdGlvbnM7XG4gIHJldHVybiBuZXcgVGVuc29yKHtsb2NhdGlvbjogJ2dwdS1idWZmZXInLCB0eXBlOiBkYXRhVHlwZSA/PyAnZmxvYXQzMicsIGdwdUJ1ZmZlciwgZGltcywgZG93bmxvYWQsIGRpc3Bvc2V9KTtcbn07XG5cbi8qKlxuICogaW1wbGVtZW50YXRpb24gb2YgVGVuc29yLmZyb21QaW5uZWRCdWZmZXIoKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvckZyb21QaW5uZWRCdWZmZXIgPSA8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5DcHVQaW5uZWREYXRhVHlwZXM+KFxuICAgIHR5cGU6IFQsIGJ1ZmZlcjogVGVuc29ySW50ZXJmYWNlLkRhdGFUeXBlTWFwW1RdLCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3IgPT5cbiAgICBuZXcgVGVuc29yKHtsb2NhdGlvbjogJ2NwdS1waW5uZWQnLCB0eXBlLCBkYXRhOiBidWZmZXIsIGRpbXM6IGRpbXMgPz8gW2J1ZmZlci5sZW5ndGhdfSk7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7VGVuc29yfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbmV4cG9ydCB0eXBlIFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnMgPSBGbG9hdDMyQXJyYXlDb25zdHJ1Y3RvcnxVaW50OEFycmF5Q29uc3RydWN0b3J8SW50OEFycmF5Q29uc3RydWN0b3J8XG4gICAgVWludDE2QXJyYXlDb25zdHJ1Y3RvcnxJbnQxNkFycmF5Q29uc3RydWN0b3J8SW50MzJBcnJheUNvbnN0cnVjdG9yfEJpZ0ludDY0QXJyYXlDb25zdHJ1Y3RvcnxVaW50OEFycmF5Q29uc3RydWN0b3J8XG4gICAgRmxvYXQ2NEFycmF5Q29uc3RydWN0b3J8VWludDMyQXJyYXlDb25zdHJ1Y3RvcnxCaWdVaW50NjRBcnJheUNvbnN0cnVjdG9yO1xuZXhwb3J0IHR5cGUgU3VwcG9ydGVkVHlwZWRBcnJheSA9IEluc3RhbmNlVHlwZTxTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzPjtcblxuLy8gYSBydW50aW1lIG1hcCB0aGF0IG1hcHMgdHlwZSBzdHJpbmcgdG8gVHlwZWRBcnJheSBjb25zdHJ1Y3Rvci4gU2hvdWxkIG1hdGNoIFRlbnNvci5EYXRhVHlwZU1hcC5cbmV4cG9ydCBjb25zdCBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQID0gbmV3IE1hcDxzdHJpbmcsIFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnM+KFtcbiAgWydmbG9hdDMyJywgRmxvYXQzMkFycmF5XSxcbiAgWyd1aW50OCcsIFVpbnQ4QXJyYXldLFxuICBbJ2ludDgnLCBJbnQ4QXJyYXldLFxuICBbJ3VpbnQxNicsIFVpbnQxNkFycmF5XSxcbiAgWydpbnQxNicsIEludDE2QXJyYXldLFxuICBbJ2ludDMyJywgSW50MzJBcnJheV0sXG4gIFsnYm9vbCcsIFVpbnQ4QXJyYXldLFxuICBbJ2Zsb2F0NjQnLCBGbG9hdDY0QXJyYXldLFxuICBbJ3VpbnQzMicsIFVpbnQzMkFycmF5XSxcbl0pO1xuXG4vLyBhIHJ1bnRpbWUgbWFwIHRoYXQgbWFwcyB0eXBlIHN0cmluZyB0byBUeXBlZEFycmF5IGNvbnN0cnVjdG9yLiBTaG91bGQgbWF0Y2ggVGVuc29yLkRhdGFUeXBlTWFwLlxuZXhwb3J0IGNvbnN0IE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAgPSBuZXcgTWFwPFN1cHBvcnRlZFR5cGVkQXJyYXlDb25zdHJ1Y3RvcnMsIFRlbnNvci5UeXBlPihbXG4gIFtGbG9hdDMyQXJyYXksICdmbG9hdDMyJ10sXG4gIFtVaW50OEFycmF5LCAndWludDgnXSxcbiAgW0ludDhBcnJheSwgJ2ludDgnXSxcbiAgW1VpbnQxNkFycmF5LCAndWludDE2J10sXG4gIFtJbnQxNkFycmF5LCAnaW50MTYnXSxcbiAgW0ludDMyQXJyYXksICdpbnQzMiddLFxuICBbRmxvYXQ2NEFycmF5LCAnZmxvYXQ2NCddLFxuICBbVWludDMyQXJyYXksICd1aW50MzInXSxcbl0pO1xuXG4vLyBhIGR1bW15IHR5cGUgZGVjbGFyYXRpb24gZm9yIEZsb2F0MTZBcnJheSBpbiBjYXNlIGFueSBwb2x5ZmlsbCBpcyBhdmFpbGFibGUuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24sIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgY29uc3QgRmxvYXQxNkFycmF5OiBhbnk7XG59XG5cbi8vIHRoZSBmb2xsb3dpbmcgY29kZSBhbGxvd3MgZGVsYXlpbmcgZXhlY3V0aW9uIG9mIEJpZ0ludC9GbG9hdDE2QXJyYXkgY2hlY2tpbmcuIFRoaXMgYWxsb3dzIGxhenkgaW5pdGlhbGl6YXRpb24gZm9yXG4vLyBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQIGFuZCBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQLCB3aGljaCBhbGxvd3MgQmlnSW50L0Zsb2F0MTZBcnJheVxuLy8gcG9seWZpbGwgaWYgYXZhaWxhYmxlLlxubGV0IGlzVHlwZWRBcnJheUNoZWNrZWQgPSBmYWxzZTtcbmV4cG9ydCBjb25zdCBjaGVja1R5cGVkQXJyYXkgPSAoKSA9PiB7XG4gIGlmICghaXNUeXBlZEFycmF5Q2hlY2tlZCkge1xuICAgIGlzVHlwZWRBcnJheUNoZWNrZWQgPSB0cnVlO1xuICAgIGNvbnN0IGlzQmlnSW50NjRBcnJheUF2YWlsYWJsZSA9IHR5cGVvZiBCaWdJbnQ2NEFycmF5ICE9PSAndW5kZWZpbmVkJyAmJiBCaWdJbnQ2NEFycmF5LmZyb207XG4gICAgY29uc3QgaXNCaWdVaW50NjRBcnJheUF2YWlsYWJsZSA9IHR5cGVvZiBCaWdVaW50NjRBcnJheSAhPT0gJ3VuZGVmaW5lZCcgJiYgQmlnVWludDY0QXJyYXkuZnJvbTtcbiAgICBjb25zdCBpc0Zsb2F0MTZBcnJheUF2YWlsYWJsZSA9IHR5cGVvZiBGbG9hdDE2QXJyYXkgIT09ICd1bmRlZmluZWQnICYmIEZsb2F0MTZBcnJheS5mcm9tO1xuXG4gICAgaWYgKGlzQmlnSW50NjRBcnJheUF2YWlsYWJsZSkge1xuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5zZXQoJ2ludDY0JywgQmlnSW50NjRBcnJheSk7XG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQLnNldChCaWdJbnQ2NEFycmF5LCAnaW50NjQnKTtcbiAgICB9XG4gICAgaWYgKGlzQmlnVWludDY0QXJyYXlBdmFpbGFibGUpIHtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAuc2V0KCd1aW50NjQnLCBCaWdVaW50NjRBcnJheSk7XG4gICAgICBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQLnNldChCaWdVaW50NjRBcnJheSwgJ3VpbnQ2NCcpO1xuICAgIH1cbiAgICBpZiAoaXNGbG9hdDE2QXJyYXlBdmFpbGFibGUpIHtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVfVE9fVFlQRURBUlJBWV9NQVAuc2V0KCdmbG9hdDE2JywgRmxvYXQxNkFycmF5KTtcbiAgICAgIE5VTUVSSUNfVEVOU09SX1RZUEVEQVJSQVlfVE9fVFlQRV9NQVAuc2V0KEZsb2F0MTZBcnJheSwgJ2Zsb2F0MTYnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgRmxvYXQxNkFycmF5IGlzIG5vdCBhdmFpbGFibGUsIHVzZSAnVWludDE2QXJyYXknIHRvIHN0b3JlIHRoZSBkYXRhLlxuICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5zZXQoJ2Zsb2F0MTYnLCBVaW50MTZBcnJheSk7XG4gICAgfVxuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0NwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVycywgR3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzLCBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzfSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuL3RlbnNvci1pbXBsLmpzJztcblxuLyoqXG4gKiBjYWxjdWxhdGUgc2l6ZSBmcm9tIGRpbXMuXG4gKlxuICogQHBhcmFtIGRpbXMgdGhlIGRpbXMgYXJyYXkuIE1heSBiZSBhbiBpbGxlZ2FsIGlucHV0LlxuICovXG5leHBvcnQgY29uc3QgY2FsY3VsYXRlU2l6ZSA9IChkaW1zOiByZWFkb25seSB1bmtub3duW10pOiBudW1iZXIgPT4ge1xuICBsZXQgc2l6ZSA9IDE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGltcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGRpbSA9IGRpbXNbaV07XG4gICAgaWYgKHR5cGVvZiBkaW0gIT09ICdudW1iZXInIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcihkaW0pKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBkaW1zWyR7aX1dIG11c3QgYmUgYW4gaW50ZWdlciwgZ290OiAke2RpbX1gKTtcbiAgICB9XG4gICAgaWYgKGRpbSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBkaW1zWyR7aX1dIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlciwgZ290OiAke2RpbX1gKTtcbiAgICB9XG4gICAgc2l6ZSAqPSBkaW07XG4gIH1cbiAgcmV0dXJuIHNpemU7XG59O1xuXG4vKipcbiAqIGltcGxlbWVudGF0aW9uIG9mIFRlbnNvci5yZXNoYXBlKClcbiAqL1xuZXhwb3J0IGNvbnN0IHRlbnNvclJlc2hhcGUgPSAodGVuc29yOiBUZW5zb3IsIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yID0+IHtcbiAgc3dpdGNoICh0ZW5zb3IubG9jYXRpb24pIHtcbiAgICBjYXNlICdjcHUnOlxuICAgICAgcmV0dXJuIG5ldyBUZW5zb3IodGVuc29yLnR5cGUsIHRlbnNvci5kYXRhLCBkaW1zKTtcbiAgICBjYXNlICdjcHUtcGlubmVkJzpcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKHtcbiAgICAgICAgbG9jYXRpb246ICdjcHUtcGlubmVkJyxcbiAgICAgICAgZGF0YTogdGVuc29yLmRhdGEgYXMgQ3B1UGlubmVkQ29uc3RydWN0b3JQYXJhbWV0ZXJzWydkYXRhJ10sXG4gICAgICAgIHR5cGU6IHRlbnNvci50eXBlIGFzIENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVyc1sndHlwZSddLFxuICAgICAgICBkaW1zLFxuICAgICAgfSk7XG4gICAgY2FzZSAndGV4dHVyZSc6XG4gICAgICByZXR1cm4gbmV3IFRlbnNvcih7XG4gICAgICAgIGxvY2F0aW9uOiAndGV4dHVyZScsXG4gICAgICAgIHRleHR1cmU6IHRlbnNvci50ZXh0dXJlLFxuICAgICAgICB0eXBlOiB0ZW5zb3IudHlwZSBhcyBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzWyd0eXBlJ10sXG4gICAgICAgIGRpbXMsXG4gICAgICB9KTtcbiAgICBjYXNlICdncHUtYnVmZmVyJzpcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKHtcbiAgICAgICAgbG9jYXRpb246ICdncHUtYnVmZmVyJyxcbiAgICAgICAgZ3B1QnVmZmVyOiB0ZW5zb3IuZ3B1QnVmZmVyLFxuICAgICAgICB0eXBlOiB0ZW5zb3IudHlwZSBhcyBHcHVCdWZmZXJDb25zdHJ1Y3RvclBhcmFtZXRlcnNbJ3R5cGUnXSxcbiAgICAgICAgZGltcyxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHRlbnNvclJlc2hhcGU6IHRlbnNvciBsb2NhdGlvbiAke3RlbnNvci5sb2NhdGlvbn0gaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge3RlbnNvclRvRGF0YVVSTCwgdGVuc29yVG9JbWFnZURhdGF9IGZyb20gJy4vdGVuc29yLWNvbnZlcnNpb24taW1wbC5qcyc7XG5pbXBvcnQge1RlbnNvclRvRGF0YVVybE9wdGlvbnMsIFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9uc30gZnJvbSAnLi90ZW5zb3ItY29udmVyc2lvbi5qcyc7XG5pbXBvcnQge3RlbnNvckZyb21HcHVCdWZmZXIsIHRlbnNvckZyb21JbWFnZSwgdGVuc29yRnJvbVBpbm5lZEJ1ZmZlciwgdGVuc29yRnJvbVRleHR1cmV9IGZyb20gJy4vdGVuc29yLWZhY3RvcnktaW1wbC5qcyc7XG5pbXBvcnQge0NwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVycywgR3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzLCBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9ucywgVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9ucywgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnMsIFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zLCBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnMsIFRlbnNvckZyb21VcmxPcHRpb25zLCBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzfSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcbmltcG9ydCB7Y2hlY2tUeXBlZEFycmF5LCBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLCBOVU1FUklDX1RFTlNPUl9UWVBFREFSUkFZX1RPX1RZUEVfTUFQLCBTdXBwb3J0ZWRUeXBlZEFycmF5LCBTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzfSBmcm9tICcuL3RlbnNvci1pbXBsLXR5cGUtbWFwcGluZy5qcyc7XG5pbXBvcnQge2NhbGN1bGF0ZVNpemUsIHRlbnNvclJlc2hhcGV9IGZyb20gJy4vdGVuc29yLXV0aWxzLWltcGwuanMnO1xuaW1wb3J0IHtUZW5zb3IgYXMgVGVuc29ySW50ZXJmYWNlfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbi8vIHR5cGUgYWxpYXNlcyBmb3IgdGhvc2UgZXhwb3J0ZWQgZnJvbSBUZW5zb3IgaW50ZXJmYWNlXG5cbnR5cGUgVGVuc29yVHlwZSA9IFRlbnNvckludGVyZmFjZS5UeXBlO1xudHlwZSBUZW5zb3JEYXRhVHlwZSA9IFRlbnNvckludGVyZmFjZS5EYXRhVHlwZTtcbnR5cGUgVGVuc29yRGF0YUxvY2F0aW9uID0gVGVuc29ySW50ZXJmYWNlLkRhdGFMb2NhdGlvbjtcbnR5cGUgVGVuc29yVGV4dHVyZVR5cGUgPSBUZW5zb3JJbnRlcmZhY2UuVGV4dHVyZVR5cGU7XG50eXBlIFRlbnNvckdwdUJ1ZmZlclR5cGUgPSBUZW5zb3JJbnRlcmZhY2UuR3B1QnVmZmVyVHlwZTtcblxuLyoqXG4gKiB0aGUgaW1wbGVtZW50YXRpb24gb2YgVGVuc29yIGludGVyZmFjZS5cbiAqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBUZW5zb3IgaW1wbGVtZW50cyBUZW5zb3JJbnRlcmZhY2Uge1xuICAvLyAjcmVnaW9uIGNvbnN0cnVjdG9yc1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgQ1BVIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gdHlwZSwgZGF0YSBhbmQgZGltcy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgdHlwZTogVGVuc29yVHlwZSwgZGF0YTogVGVuc29yRGF0YVR5cGV8cmVhZG9ubHkgc3RyaW5nW118cmVhZG9ubHkgbnVtYmVyW118cmVhZG9ubHkgYm9vbGVhbltdLFxuICAgICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTtcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBDUFUgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLiBUeXBlIGlzIGluZmVycmVkIGZyb20gZGF0YS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGRhdGE6IFRlbnNvckRhdGFUeXBlfHJlYWRvbmx5IHN0cmluZ1tdfHJlYWRvbmx5IGJvb2xlYW5bXSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTtcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIHBpbm5lZCBDUFUgZGF0YSB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkaW1zLlxuICAgKlxuICAgKiBUZW5zb3IncyBsb2NhdGlvbiB3aWxsIGJlIHNldCB0byAnY3B1LXBpbm5lZCcuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTcGVjaWZ5IHRoZSBwYXJhbWV0ZXJzIHRvIGNvbnN0cnVjdCB0aGUgdGVuc29yLlxuICAgKi9cbiAgY29uc3RydWN0b3IocGFyYW1zOiBDcHVQaW5uZWRDb25zdHJ1Y3RvclBhcmFtZXRlcnMpO1xuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgV2ViR0wgdGV4dHVyZSB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkaW1zLlxuICAgKlxuICAgKiBUZW5zb3IncyBsb2NhdGlvbiB3aWxsIGJlIHNldCB0byAndGV4dHVyZScuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBTcGVjaWZ5IHRoZSBwYXJhbWV0ZXJzIHRvIGNvbnN0cnVjdCB0aGUgdGVuc29yLlxuICAgKi9cbiAgY29uc3RydWN0b3IocGFyYW1zOiBUZXh0dXJlQ29uc3RydWN0b3JQYXJhbWV0ZXJzKTtcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIFdlYkdQVSBidWZmZXIgd2l0aCB0aGUgZ2l2ZW4gdHlwZSBhbmQgZGltcy5cbiAgICpcbiAgICogVGVuc29yJ3MgbG9jYXRpb24gd2lsbCBiZSBzZXQgdG8gJ2dwdS1idWZmZXInLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gU3BlY2lmeSB0aGUgcGFyYW1ldGVycyB0byBjb25zdHJ1Y3QgdGhlIHRlbnNvci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHBhcmFtczogR3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzKTtcblxuICAvKipcbiAgICogaW1wbGVtZW50YXRpb24uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIGFyZzA6IFRlbnNvclR5cGV8VGVuc29yRGF0YVR5cGV8cmVhZG9ubHkgc3RyaW5nW118cmVhZG9ubHkgYm9vbGVhbltdfENwdVBpbm5lZENvbnN0cnVjdG9yUGFyYW1ldGVyc3xcbiAgICAgIFRleHR1cmVDb25zdHJ1Y3RvclBhcmFtZXRlcnN8R3B1QnVmZmVyQ29uc3RydWN0b3JQYXJhbWV0ZXJzLFxuICAgICAgYXJnMT86IFRlbnNvckRhdGFUeXBlfHJlYWRvbmx5IG51bWJlcltdfHJlYWRvbmx5IHN0cmluZ1tdfHJlYWRvbmx5IGJvb2xlYW5bXSwgYXJnMj86IHJlYWRvbmx5IG51bWJlcltdKSB7XG4gICAgLy8gcGVyZm9ybSBvbmUtdGltZSBjaGVjayBmb3IgQmlnSW50L0Zsb2F0MTZBcnJheSBzdXBwb3J0XG4gICAgY2hlY2tUeXBlZEFycmF5KCk7XG5cbiAgICBsZXQgdHlwZTogVGVuc29yVHlwZTtcbiAgICBsZXQgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICBpZiAodHlwZW9mIGFyZzAgPT09ICdvYmplY3QnICYmICdsb2NhdGlvbicgaW4gYXJnMCkge1xuICAgICAgLy9cbiAgICAgIC8vIGNvbnN0cnVjdGluZyB0ZW5zb3IgZnJvbSBzcGVjaWZpYyBsb2NhdGlvblxuICAgICAgLy9cbiAgICAgIHRoaXMuZGF0YUxvY2F0aW9uID0gYXJnMC5sb2NhdGlvbjtcbiAgICAgIHR5cGUgPSBhcmcwLnR5cGU7XG4gICAgICBkaW1zID0gYXJnMC5kaW1zO1xuICAgICAgc3dpdGNoIChhcmcwLmxvY2F0aW9uKSB7XG4gICAgICAgIGNhc2UgJ2NwdS1waW5uZWQnOiB7XG4gICAgICAgICAgY29uc3QgZXhwZWN0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3IgPSBOVU1FUklDX1RFTlNPUl9UWVBFX1RPX1RZUEVEQVJSQVlfTUFQLmdldCh0eXBlKTtcbiAgICAgICAgICBpZiAoIWV4cGVjdGVkVHlwZWRBcnJheUNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGB1bnN1cHBvcnRlZCB0eXBlIFwiJHt0eXBlfVwiIHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbSBwaW5uZWQgYnVmZmVyYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghKGFyZzAuZGF0YSBpbnN0YW5jZW9mIGV4cGVjdGVkVHlwZWRBcnJheUNvbnN0cnVjdG9yKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgYnVmZmVyIHNob3VsZCBiZSBvZiB0eXBlICR7ZXhwZWN0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3IubmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5jcHVEYXRhID0gYXJnMC5kYXRhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ3RleHR1cmUnOiB7XG4gICAgICAgICAgaWYgKHR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZSBcIiR7dHlwZX1cIiB0byBjcmVhdGUgdGVuc29yIGZyb20gdGV4dHVyZWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmdwdVRleHR1cmVEYXRhID0gYXJnMC50ZXh0dXJlO1xuICAgICAgICAgIHRoaXMuZG93bmxvYWRlciA9IGFyZzAuZG93bmxvYWQ7XG4gICAgICAgICAgdGhpcy5kaXNwb3NlciA9IGFyZzAuZGlzcG9zZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdncHUtYnVmZmVyJzoge1xuICAgICAgICAgIGlmICgodHlwZSAhPT0gJ2Zsb2F0MzInICYmIHR5cGUgIT09ICdmbG9hdDE2JyAmJiB0eXBlICE9PSAnaW50MzInICYmIHR5cGUgIT09ICdpbnQ2NCcgJiYgdHlwZSAhPT0gJ3VpbnQzMicgJiZcbiAgICAgICAgICAgICAgIHR5cGUgIT09ICd1aW50OCcgJiYgdHlwZSAhPT0gJ2Jvb2wnKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZSBcIiR7dHlwZX1cIiB0byBjcmVhdGUgdGVuc29yIGZyb20gZ3B1IGJ1ZmZlcmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmdwdUJ1ZmZlckRhdGEgPSBhcmcwLmdwdUJ1ZmZlcjtcbiAgICAgICAgICB0aGlzLmRvd25sb2FkZXIgPSBhcmcwLmRvd25sb2FkO1xuICAgICAgICAgIHRoaXMuZGlzcG9zZXIgPSBhcmcwLmRpc3Bvc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbnNvciBjb25zdHJ1Y3RvcjogdW5zdXBwb3J0ZWQgbG9jYXRpb24gJyR7dGhpcy5kYXRhTG9jYXRpb259J2ApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvL1xuICAgICAgLy8gY29uc3RydWN0aW5nIHRlbnNvciBvZiBsb2NhdGlvbiAnY3B1J1xuICAgICAgLy9cbiAgICAgIGxldCBkYXRhOiBUZW5zb3JEYXRhVHlwZTtcbiAgICAgIGxldCBtYXliZURpbXM6IHR5cGVvZiBhcmcxfHR5cGVvZiBhcmcyO1xuICAgICAgLy8gY2hlY2sgd2hldGhlciBhcmcwIGlzIHR5cGUgb3IgZGF0YVxuICAgICAgaWYgKHR5cGVvZiBhcmcwID09PSAnc3RyaW5nJykge1xuICAgICAgICAvL1xuICAgICAgICAvLyBPdmVycmlkZTogY29uc3RydWN0b3IodHlwZSwgZGF0YSwgLi4uKVxuICAgICAgICAvL1xuICAgICAgICB0eXBlID0gYXJnMDtcbiAgICAgICAgbWF5YmVEaW1zID0gYXJnMjtcbiAgICAgICAgaWYgKGFyZzAgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgLy8gc3RyaW5nIHRlbnNvclxuICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcmcxKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQSBzdHJpbmcgdGVuc29yXFwncyBkYXRhIG11c3QgYmUgYSBzdHJpbmcgYXJyYXkuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHdlIGRvbid0IGNoZWNrIHdoZXRoZXIgZXZlcnkgZWxlbWVudCBpbiB0aGUgYXJyYXkgaXMgc3RyaW5nOyB0aGlzIGlzIHRvbyBzbG93LiB3ZSBhc3N1bWUgaXQncyBjb3JyZWN0IGFuZFxuICAgICAgICAgIC8vIGVycm9yIHdpbGwgYmUgcG9wdWxhdGVkIGF0IGluZmVyZW5jZVxuICAgICAgICAgIGRhdGEgPSBhcmcxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIG51bWVyaWMgdGVuc29yXG4gICAgICAgICAgY29uc3QgdHlwZWRBcnJheUNvbnN0cnVjdG9yID0gTlVNRVJJQ19URU5TT1JfVFlQRV9UT19UWVBFREFSUkFZX01BUC5nZXQoYXJnMCk7XG4gICAgICAgICAgaWYgKHR5cGVkQXJyYXlDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbnN1cHBvcnRlZCB0ZW5zb3IgdHlwZTogJHthcmcwfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnMSkpIHtcbiAgICAgICAgICAgIGlmIChhcmcwID09PSAnZmxvYXQxNicgJiYgdHlwZWRBcnJheUNvbnN0cnVjdG9yID09PSBVaW50MTZBcnJheSkge1xuICAgICAgICAgICAgICAvLyBXaGVuIG5vIEZsb2F0MTZBcnJheSBwb2x5ZmlsbCBpcyB1c2VkLCB3ZSBjYW5ub3QgY3JlYXRlICdmbG9hdDE2JyB0ZW5zb3IgZnJvbSBudW1iZXIgYXJyYXkuXG4gICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgIC8vIFRocm93IGVycm9yIGhlcmUgYmVjYXVzZSB3aGVuIHVzZXIgdHJ5IHRvIHVzZSBudW1iZXIgYXJyYXkgYXMgZGF0YSxcbiAgICAgICAgICAgICAgLy8gZS5nLiBuZXcgVGVuc29yKCdmbG9hdDE2JywgWzEsIDIsIDMsIDRdLCBkaW1zKSksIGl0IHdpbGwgYWN0dWFsbHkgY2FsbFxuICAgICAgICAgICAgICAvLyBVaW50MTZBcnJheS5mcm9tKGFyZzEpIHdoaWNoIGdlbmVyYXRlcyB3cm9uZyBkYXRhLlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgICAgICAgJ0NyZWF0aW5nIGEgZmxvYXQxNiB0ZW5zb3IgZnJvbSBudW1iZXIgYXJyYXkgaXMgbm90IHN1cHBvcnRlZC4gUGxlYXNlIHVzZSBVaW50MTZBcnJheSBhcyBkYXRhLicpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcwID09PSAndWludDY0JyB8fCBhcmcwID09PSAnaW50NjQnKSB7XG4gICAgICAgICAgICAgIC8vIHVzZSAnYXMgYW55JyBoZXJlIGJlY2F1c2U6XG4gICAgICAgICAgICAgIC8vIDEuIFR5cGVTY3JpcHQncyBjaGVjayBvbiB0eXBlIG9mICdBcnJheS5pc0FycmF5KCknIGRvZXMgbm90IHdvcmsgd2l0aCByZWFkb25seSBhcnJheXMuXG4gICAgICAgICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L1R5cGVTY3JpcHQvaXNzdWVzLzE3MDAyXG4gICAgICAgICAgICAgIC8vIDIuIFR5cGVTY3JpcHQncyBjaGVjayBvbiB1bmlvbiB0eXBlIG9mICcoQmlnSW50NjRBcnJheUNvbnN0cnVjdG9yfEJpZ1VpbnQ2NEFycmF5Q29uc3RydWN0b3IpLmZyb20oKSdcbiAgICAgICAgICAgICAgLy8gZG9lcyBub3QgYWNjZXB0IHBhcmFtZXRlciBtYXBGbi5cbiAgICAgICAgICAgICAgLy8gMy4gcGFyYW1ldGVycyBvZiAnU3VwcG9ydGVkVHlwZWRBcnJheUNvbnN0cnVjdG9ycy5mcm9tKCknIGRvZXMgbm90IG1hdGNoIHRoZSByZXF1aXJlbWVudCBvZiB0aGUgdW5pb25cbiAgICAgICAgICAgICAgLy8gdHlwZS5cblxuICAgICAgICAgICAgICAvLyBhc3N1bWUgJ2FyZzEnIGlzIG9mIHR5cGUgXCJyZWFkb25seSBudW1iZXJbXXxyZWFkb25seSBiaWdpbnRbXVwiIGhlcmUuXG5cbiAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgICAgICAgZGF0YSA9ICh0eXBlZEFycmF5Q29uc3RydWN0b3IgYXMgYW55KS5mcm9tKGFyZzEsIEJpZ0ludCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBhc3N1bWUgJ2FyZzEnIGlzIG9mIHR5cGUgXCJyZWFkb25seSBudW1iZXJbXVwiIGhlcmUuXG4gICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICAgIGRhdGEgPSAodHlwZWRBcnJheUNvbnN0cnVjdG9yIGFzIGFueSkuZnJvbShhcmcxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGFyZzEgaW5zdGFuY2VvZiB0eXBlZEFycmF5Q29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgIGRhdGEgPSBhcmcxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBBICR7dHlwZX0gdGVuc29yJ3MgZGF0YSBtdXN0IGJlIHR5cGUgb2YgJHt0eXBlZEFycmF5Q29uc3RydWN0b3J9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvL1xuICAgICAgICAvLyBPdmVycmlkZTogY29uc3RydWN0b3IoZGF0YSwgLi4uKVxuICAgICAgICAvL1xuICAgICAgICBtYXliZURpbXMgPSBhcmcxO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcwKSkge1xuICAgICAgICAgIC8vIG9ubHkgYm9vbGVhbltdIGFuZCBzdHJpbmdbXSBpcyBzdXBwb3J0ZWRcbiAgICAgICAgICBpZiAoYXJnMC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RlbnNvciB0eXBlIGNhbm5vdCBiZSBpbmZlcnJlZCBmcm9tIGFuIGVtcHR5IGFycmF5LicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBmaXJzdEVsZW1lbnRUeXBlID0gdHlwZW9mIGFyZzBbMF07XG4gICAgICAgICAgaWYgKGZpcnN0RWxlbWVudFR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0eXBlID0gJ3N0cmluZyc7XG4gICAgICAgICAgICBkYXRhID0gYXJnMDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGZpcnN0RWxlbWVudFR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgdHlwZSA9ICdib29sJztcbiAgICAgICAgICAgIC8vICdhcmcwJyBpcyBvZiB0eXBlICdib29sZWFuW10nLiBVaW50OEFycmF5LmZyb20oYm9vbGVhbltdKSBhY3R1YWxseSB3b3JrcywgYnV0IHR5cGVzY3JpcHQgdGhpbmtzIHRoaXMgaXNcbiAgICAgICAgICAgIC8vIHdyb25nIHR5cGUuIFdlIHVzZSAnYXMgYW55JyB0byBtYWtlIGl0IGhhcHB5LlxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgICAgIGRhdGEgPSBVaW50OEFycmF5LmZyb20oYXJnMCBhcyBhbnlbXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgZWxlbWVudCB0eXBlIG9mIGRhdGEgYXJyYXk6ICR7Zmlyc3RFbGVtZW50VHlwZX0uYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGdldCB0ZW5zb3IgdHlwZSBmcm9tIFR5cGVkQXJyYXlcbiAgICAgICAgICBjb25zdCBtYXBwZWRUeXBlID1cbiAgICAgICAgICAgICAgTlVNRVJJQ19URU5TT1JfVFlQRURBUlJBWV9UT19UWVBFX01BUC5nZXQoYXJnMC5jb25zdHJ1Y3RvciBhcyBTdXBwb3J0ZWRUeXBlZEFycmF5Q29uc3RydWN0b3JzKTtcbiAgICAgICAgICBpZiAobWFwcGVkVHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbnN1cHBvcnRlZCB0eXBlIGZvciB0ZW5zb3IgZGF0YTogJHthcmcwLmNvbnN0cnVjdG9yfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHlwZSA9IG1hcHBlZFR5cGU7XG4gICAgICAgICAgZGF0YSA9IGFyZzAgYXMgU3VwcG9ydGVkVHlwZWRBcnJheTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyB0eXBlIGFuZCBkYXRhIGlzIHByb2Nlc3NlZCwgbm93IHByb2Nlc3NpbmcgZGltc1xuICAgICAgaWYgKG1heWJlRGltcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIGFzc3VtZSAxLUQgdGVuc29yIGlmIGRpbXMgb21pdHRlZFxuICAgICAgICBtYXliZURpbXMgPSBbZGF0YS5sZW5ndGhdO1xuICAgICAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheShtYXliZURpbXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0EgdGVuc29yXFwncyBkaW1zIG11c3QgYmUgYSBudW1iZXIgYXJyYXknKTtcbiAgICAgIH1cbiAgICAgIGRpbXMgPSBtYXliZURpbXMgYXMgcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgICAgIHRoaXMuY3B1RGF0YSA9IGRhdGE7XG4gICAgICB0aGlzLmRhdGFMb2NhdGlvbiA9ICdjcHUnO1xuICAgIH1cblxuICAgIC8vIHBlcmZvcm0gY2hlY2sgb24gZGltc1xuICAgIGNvbnN0IHNpemUgPSBjYWxjdWxhdGVTaXplKGRpbXMpO1xuICAgIC8vIGlmIGRhdGEgaXMgb24gQ1BVLCBjaGVjayB3aGV0aGVyIGRhdGEgbGVuZ3RoIG1hdGNoZXMgdGVuc29yIHNpemVcbiAgICBpZiAodGhpcy5jcHVEYXRhICYmIHNpemUgIT09IHRoaXMuY3B1RGF0YS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yJ3Mgc2l6ZSgke3NpemV9KSBkb2VzIG5vdCBtYXRjaCBkYXRhIGxlbmd0aCgke3RoaXMuY3B1RGF0YS5sZW5ndGh9KS5gKTtcbiAgICB9XG5cbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMuZGltcyA9IGRpbXM7XG4gICAgdGhpcy5zaXplID0gc2l6ZTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBmYWN0b3J5XG4gIHN0YXRpYyBhc3luYyBmcm9tSW1hZ2UoXG4gICAgICBpbWFnZTogSW1hZ2VEYXRhfEhUTUxJbWFnZUVsZW1lbnR8SW1hZ2VCaXRtYXB8c3RyaW5nLFxuICAgICAgb3B0aW9ucz86IFRlbnNvckZyb21JbWFnZURhdGFPcHRpb25zfFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zfFRlbnNvckZyb21JbWFnZUJpdG1hcE9wdGlvbnN8XG4gICAgICBUZW5zb3JGcm9tVXJsT3B0aW9ucyk6IFByb21pc2U8VGVuc29ySW50ZXJmYWNlPiB7XG4gICAgcmV0dXJuIHRlbnNvckZyb21JbWFnZShpbWFnZSwgb3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgZnJvbVRleHR1cmU8VCBleHRlbmRzIFRlbnNvckludGVyZmFjZS5UZXh0dXJlRGF0YVR5cGVzPihcbiAgICAgIHRleHR1cmU6IFRlbnNvclRleHR1cmVUeXBlLCBvcHRpb25zOiBUZW5zb3JGcm9tVGV4dHVyZU9wdGlvbnM8VD4pOiBUZW5zb3JJbnRlcmZhY2Uge1xuICAgIHJldHVybiB0ZW5zb3JGcm9tVGV4dHVyZSh0ZXh0dXJlLCBvcHRpb25zKTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tR3B1QnVmZmVyPFQgZXh0ZW5kcyBUZW5zb3JJbnRlcmZhY2UuR3B1QnVmZmVyRGF0YVR5cGVzPihcbiAgICAgIGdwdUJ1ZmZlcjogVGVuc29yR3B1QnVmZmVyVHlwZSwgb3B0aW9uczogVGVuc29yRnJvbUdwdUJ1ZmZlck9wdGlvbnM8VD4pOiBUZW5zb3JJbnRlcmZhY2Uge1xuICAgIHJldHVybiB0ZW5zb3JGcm9tR3B1QnVmZmVyKGdwdUJ1ZmZlciwgb3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgZnJvbVBpbm5lZEJ1ZmZlcjxUIGV4dGVuZHMgVGVuc29ySW50ZXJmYWNlLkNwdVBpbm5lZERhdGFUeXBlcz4oXG4gICAgICB0eXBlOiBULCBidWZmZXI6IFRlbnNvckludGVyZmFjZS5EYXRhVHlwZU1hcFtUXSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yIHtcbiAgICByZXR1cm4gdGVuc29yRnJvbVBpbm5lZEJ1ZmZlcih0eXBlLCBidWZmZXIsIGRpbXMpO1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gY29udmVyc2lvbnNcbiAgdG9EYXRhVVJMKG9wdGlvbnM/OiBUZW5zb3JUb0RhdGFVcmxPcHRpb25zKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGVuc29yVG9EYXRhVVJMKHRoaXMsIG9wdGlvbnMpO1xuICB9XG5cbiAgdG9JbWFnZURhdGEob3B0aW9ucz86IFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyk6IEltYWdlRGF0YSB7XG4gICAgcmV0dXJuIHRlbnNvclRvSW1hZ2VEYXRhKHRoaXMsIG9wdGlvbnMpO1xuICB9XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHB1YmxpYyBmaWVsZHNcbiAgcmVhZG9ubHkgZGltczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHR5cGU6IFRlbnNvclR5cGU7XG4gIHJlYWRvbmx5IHNpemU6IG51bWJlcjtcbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcHJpdmF0ZSBmaWVsZHNcblxuICAvKipcbiAgICogc3RvcmVzIHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YS5cbiAgICovXG4gIHByaXZhdGUgZGF0YUxvY2F0aW9uOiBUZW5zb3JEYXRhTG9jYXRpb247XG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgZGF0YSBvbiBDUFUsIGlmIGxvY2F0aW9uIGlzICdjcHUnIG9yICdjcHUtcGlubmVkJy4gb3RoZXJ3aXNlIGVtcHR5LlxuICAgKi9cbiAgcHJpdmF0ZSBjcHVEYXRhPzogVGVuc29yRGF0YVR5cGU7XG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgdW5kZXJseWluZyB0ZXh0dXJlIHdoZW4gbG9jYXRpb24gaXMgJ3RleHR1cmUnLiBvdGhlcndpc2UgZW1wdHkuXG4gICAqL1xuICBwcml2YXRlIGdwdVRleHR1cmVEYXRhPzogVGVuc29yVGV4dHVyZVR5cGU7XG5cbiAgLyoqXG4gICAqIHN0b3JlcyB0aGUgdW5kZXJseWluZyBHUFUgYnVmZmVyIHdoZW4gbG9jYXRpb24gaXMgJ2dwdS1idWZmZXInLiBvdGhlcndpc2UgZW1wdHkuXG4gICAqL1xuICBwcml2YXRlIGdwdUJ1ZmZlckRhdGE/OiBUZW5zb3JHcHVCdWZmZXJUeXBlO1xuXG4gIC8qKlxuICAgKiBzdG9yZXMgYW4gb3B0aW9uYWwgZG93bmxvYWRlciBmdW5jdGlvbiB0byBkb3dubG9hZCBkYXRhIGZyb20gR1BVIHRvIENQVS5cbiAgICovXG4gIHByaXZhdGUgZG93bmxvYWRlcj8oKTogUHJvbWlzZTxUZW5zb3JEYXRhVHlwZT47XG5cbiAgLyoqXG4gICAqIGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGRhdGEgaXMgYmVpbmcgZG93bmxvYWRlZCBmcm9tIEdQVSB0byBDUFUuXG4gICAqL1xuICBwcml2YXRlIGlzRG93bmxvYWRpbmc/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBzdG9yZXMgYW4gb3B0aW9uYWwgZGlzcG9zZXIgZnVuY3Rpb24gdG8gZGlzcG9zZSB0aGUgdW5kZXJseWluZyBkYXRhLlxuICAgKi9cbiAgcHJpdmF0ZSBkaXNwb3Nlcj8oKTogdm9pZDtcbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcHJvcGVydGllc1xuICBnZXQgZGF0YSgpOiBUZW5zb3JEYXRhVHlwZSB7XG4gICAgdGhpcy5lbnN1cmVWYWxpZCgpO1xuICAgIGlmICghdGhpcy5jcHVEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ1RoZSBkYXRhIGlzIG5vdCBvbiBDUFUuIFVzZSBgZ2V0RGF0YSgpYCB0byBkb3dubG9hZCBHUFUgZGF0YSB0byBDUFUsICcgK1xuICAgICAgICAgICdvciB1c2UgYHRleHR1cmVgIG9yIGBncHVCdWZmZXJgIHByb3BlcnR5IHRvIGFjY2VzcyB0aGUgR1BVIGRhdGEgZGlyZWN0bHkuJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNwdURhdGE7XG4gIH1cblxuICBnZXQgbG9jYXRpb24oKTogVGVuc29yRGF0YUxvY2F0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhTG9jYXRpb247XG4gIH1cblxuICBnZXQgdGV4dHVyZSgpOiBUZW5zb3JUZXh0dXJlVHlwZSB7XG4gICAgdGhpcy5lbnN1cmVWYWxpZCgpO1xuICAgIGlmICghdGhpcy5ncHVUZXh0dXJlRGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZGF0YSBpcyBub3Qgc3RvcmVkIGFzIGEgV2ViR0wgdGV4dHVyZS4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ3B1VGV4dHVyZURhdGE7XG4gIH1cblxuICBnZXQgZ3B1QnVmZmVyKCk6IFRlbnNvckdwdUJ1ZmZlclR5cGUge1xuICAgIHRoaXMuZW5zdXJlVmFsaWQoKTtcbiAgICBpZiAoIXRoaXMuZ3B1QnVmZmVyRGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZGF0YSBpcyBub3Qgc3RvcmVkIGFzIGEgV2ViR1BVIGJ1ZmZlci4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ3B1QnVmZmVyRGF0YTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBtZXRob2RzXG5cbiAgYXN5bmMgZ2V0RGF0YShyZWxlYXNlRGF0YT86IGJvb2xlYW4pOiBQcm9taXNlPFRlbnNvckRhdGFUeXBlPiB7XG4gICAgdGhpcy5lbnN1cmVWYWxpZCgpO1xuICAgIHN3aXRjaCAodGhpcy5kYXRhTG9jYXRpb24pIHtcbiAgICAgIGNhc2UgJ2NwdSc6XG4gICAgICBjYXNlICdjcHUtcGlubmVkJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YTtcbiAgICAgIGNhc2UgJ3RleHR1cmUnOlxuICAgICAgY2FzZSAnZ3B1LWJ1ZmZlcic6IHtcbiAgICAgICAgaWYgKCF0aGlzLmRvd25sb2FkZXIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjdXJyZW50IHRlbnNvciBpcyBub3QgY3JlYXRlZCB3aXRoIGEgc3BlY2lmaWVkIGRhdGEgZG93bmxvYWRlci4nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5pc0Rvd25sb2FkaW5nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY3VycmVudCB0ZW5zb3IgaXMgYmVpbmcgZG93bmxvYWRlZC4nKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuaXNEb3dubG9hZGluZyA9IHRydWU7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuZG93bmxvYWRlcigpO1xuICAgICAgICAgIHRoaXMuZG93bmxvYWRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB0aGlzLmRhdGFMb2NhdGlvbiA9ICdjcHUnO1xuICAgICAgICAgIHRoaXMuY3B1RGF0YSA9IGRhdGE7XG5cbiAgICAgICAgICBpZiAocmVsZWFzZURhdGEgJiYgdGhpcy5kaXNwb3Nlcikge1xuICAgICAgICAgICAgdGhpcy5kaXNwb3NlcigpO1xuICAgICAgICAgICAgdGhpcy5kaXNwb3NlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZGF0YTtcblxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRoaXMuaXNEb3dubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCBnZXQgZGF0YSBmcm9tIGxvY2F0aW9uOiAke3RoaXMuZGF0YUxvY2F0aW9ufWApO1xuICAgIH1cbiAgfVxuXG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNEb3dubG9hZGluZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY3VycmVudCB0ZW5zb3IgaXMgYmVpbmcgZG93bmxvYWRlZC4nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5kaXNwb3Nlcikge1xuICAgICAgdGhpcy5kaXNwb3NlcigpO1xuICAgICAgdGhpcy5kaXNwb3NlciA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdGhpcy5jcHVEYXRhID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZ3B1VGV4dHVyZURhdGEgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5ncHVCdWZmZXJEYXRhID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZG93bmxvYWRlciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmlzRG93bmxvYWRpbmcgPSB1bmRlZmluZWQ7XG5cbiAgICB0aGlzLmRhdGFMb2NhdGlvbiA9ICdub25lJztcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHRlbnNvciB1dGlsaXRpZXNcbiAgcHJpdmF0ZSBlbnN1cmVWYWxpZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kYXRhTG9jYXRpb24gPT09ICdub25lJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgdGVuc29yIGlzIGRpc3Bvc2VkLicpO1xuICAgIH1cbiAgfVxuXG4gIHJlc2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3JJbnRlcmZhY2Uge1xuICAgIHRoaXMuZW5zdXJlVmFsaWQoKTtcbiAgICBpZiAodGhpcy5kb3dubG9hZGVyIHx8IHRoaXMuZGlzcG9zZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlc2hhcGUgYSB0ZW5zb3IgdGhhdCBvd25zIEdQVSByZXNvdXJjZS4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRlbnNvclJlc2hhcGUodGhpcywgZGltcyk7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvckZhY3Rvcnl9IGZyb20gJy4vdGVuc29yLWZhY3RvcnkuanMnO1xuaW1wb3J0IHtUZW5zb3IgYXMgVGVuc29ySW1wbH0gZnJvbSAnLi90ZW5zb3ItaW1wbC5qcyc7XG5pbXBvcnQge1R5cGVkVGVuc29yVXRpbHN9IGZyb20gJy4vdGVuc29yLXV0aWxzLmpzJztcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZSAqL1xuXG4vKipcbiAqIHJlcHJlc2VudCBhIGJhc2ljIHRlbnNvciB3aXRoIHNwZWNpZmllZCBkaW1lbnNpb25zIGFuZCBkYXRhIHR5cGUuXG4gKi9cbmludGVyZmFjZSBUeXBlZFRlbnNvckJhc2U8VCBleHRlbmRzIFRlbnNvci5UeXBlPiB7XG4gIC8qKlxuICAgKiBHZXQgdGhlIGRpbWVuc2lvbnMgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIHJlYWRvbmx5IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICAvKipcbiAgICogR2V0IHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIHJlYWRvbmx5IHR5cGU6IFQ7XG4gIC8qKlxuICAgKiBHZXQgdGhlIGJ1ZmZlciBkYXRhIG9mIHRoZSB0ZW5zb3IuXG4gICAqXG4gICAqIElmIHRoZSBkYXRhIGlzIG5vdCBvbiBDUFUgKGVnLiBpdCdzIGluIHRoZSBmb3JtIG9mIFdlYkdMIHRleHR1cmUgb3IgV2ViR1BVIGJ1ZmZlciksIHRocm93IGVycm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwW1RdO1xuICAvKipcbiAgICogR2V0IHRoZSBsb2NhdGlvbiBvZiB0aGUgZGF0YS5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiBUZW5zb3IuRGF0YUxvY2F0aW9uO1xuICAvKipcbiAgICogR2V0IHRoZSBXZWJHTCB0ZXh0dXJlIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBub3Qgb24gR1BVIGFzIFdlYkdMIHRleHR1cmUsIHRocm93IGVycm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgdGV4dHVyZTogVGVuc29yLlRleHR1cmVUeXBlO1xuICAvKipcbiAgICogR2V0IHRoZSBXZWJHUFUgYnVmZmVyIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBub3Qgb24gR1BVIGFzIFdlYkdQVSBidWZmZXIsIHRocm93IGVycm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgZ3B1QnVmZmVyOiBUZW5zb3IuR3B1QnVmZmVyVHlwZTtcblxuICAvKipcbiAgICogR2V0IHRoZSBidWZmZXIgZGF0YSBvZiB0aGUgdGVuc29yLlxuICAgKlxuICAgKiBJZiB0aGUgZGF0YSBpcyBvbiBDUFUsIHJldHVybnMgdGhlIGRhdGEgaW1tZWRpYXRlbHkuXG4gICAqIElmIHRoZSBkYXRhIGlzIG9uIEdQVSwgZG93bmxvYWRzIHRoZSBkYXRhIGFuZCByZXR1cm5zIHRoZSBwcm9taXNlLlxuICAgKlxuICAgKiBAcGFyYW0gcmVsZWFzZURhdGEgLSB3aGV0aGVyIHJlbGVhc2UgdGhlIGRhdGEgb24gR1BVLiBJZ25vcmUgaWYgZGF0YSBpcyBhbHJlYWR5IG9uIENQVS5cbiAgICovXG4gIGdldERhdGEocmVsZWFzZURhdGE/OiBib29sZWFuKTogUHJvbWlzZTxUZW5zb3IuRGF0YVR5cGVNYXBbVF0+O1xuXG4gIC8qKlxuICAgKiBEaXNwb3NlIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICpcbiAgICogSWYgdGhlIGRhdGEgaXMgb24gQ1BVLCByZW1vdmUgaXRzIGludGVybmFsIHJlZmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBkYXRhLlxuICAgKiBJZiB0aGUgZGF0YSBpcyBvbiBHUFUsIHJlbGVhc2UgdGhlIGRhdGEgb24gR1BVLlxuICAgKlxuICAgKiBBZnRlciBjYWxsaW5nIHRoaXMgZnVuY3Rpb24sIHRoZSB0ZW5zb3IgaXMgY29uc2lkZXJlZCBubyBsb25nZXIgdmFsaWQuIEl0cyBsb2NhdGlvbiB3aWxsIGJlIHNldCB0byAnbm9uZScuXG4gICAqL1xuICBkaXNwb3NlKCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBUZW5zb3Ige1xuICBpbnRlcmZhY2UgRGF0YVR5cGVNYXAge1xuICAgIGZsb2F0MzI6IEZsb2F0MzJBcnJheTtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQ4OiBJbnQ4QXJyYXk7XG4gICAgdWludDE2OiBVaW50MTZBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcbiAgICBpbnQzMjogSW50MzJBcnJheTtcbiAgICBpbnQ2NDogQmlnSW50NjRBcnJheTtcbiAgICBzdHJpbmc6IHN0cmluZ1tdO1xuICAgIGJvb2w6IFVpbnQ4QXJyYXk7XG4gICAgZmxvYXQxNjogVWludDE2QXJyYXk7ICAvLyBLZWVwIHVzaW5nIFVpbnQxNkFycmF5IHVudGlsIHdlIGhhdmUgYSBjb25jcmV0ZSBzb2x1dGlvbiBmb3IgZmxvYXQgMTYuXG4gICAgZmxvYXQ2NDogRmxvYXQ2NEFycmF5O1xuICAgIHVpbnQzMjogVWludDMyQXJyYXk7XG4gICAgdWludDY0OiBCaWdVaW50NjRBcnJheTtcbiAgICAvLyBjb21wbGV4NjQ6IG5ldmVyO1xuICAgIC8vIGNvbXBsZXgxMjg6IG5ldmVyO1xuICAgIC8vIGJmbG9hdDE2OiBuZXZlcjtcbiAgfVxuXG4gIGludGVyZmFjZSBFbGVtZW50VHlwZU1hcCB7XG4gICAgZmxvYXQzMjogbnVtYmVyO1xuICAgIHVpbnQ4OiBudW1iZXI7XG4gICAgaW50ODogbnVtYmVyO1xuICAgIHVpbnQxNjogbnVtYmVyO1xuICAgIGludDE2OiBudW1iZXI7XG4gICAgaW50MzI6IG51bWJlcjtcbiAgICBpbnQ2NDogYmlnaW50O1xuICAgIHN0cmluZzogc3RyaW5nO1xuICAgIGJvb2w6IGJvb2xlYW47XG4gICAgZmxvYXQxNjogbnVtYmVyOyAgLy8gS2VlcCB1c2luZyBVaW50MTZBcnJheSB1bnRpbCB3ZSBoYXZlIGEgY29uY3JldGUgc29sdXRpb24gZm9yIGZsb2F0IDE2LlxuICAgIGZsb2F0NjQ6IG51bWJlcjtcbiAgICB1aW50MzI6IG51bWJlcjtcbiAgICB1aW50NjQ6IGJpZ2ludDtcbiAgICAvLyBjb21wbGV4NjQ6IG5ldmVyO1xuICAgIC8vIGNvbXBsZXgxMjg6IG5ldmVyO1xuICAgIC8vIGJmbG9hdDE2OiBuZXZlcjtcbiAgfVxuXG4gIHR5cGUgRGF0YVR5cGUgPSBEYXRhVHlwZU1hcFtUeXBlXTtcbiAgdHlwZSBFbGVtZW50VHlwZSA9IEVsZW1lbnRUeXBlTWFwW1R5cGVdO1xuXG4gIC8qKlxuICAgKiBzdXBwb3J0ZWQgZGF0YSB0eXBlcyBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBwaW5uZWQgQ1BVIGJ1ZmZlclxuICAgKi9cbiAgZXhwb3J0IHR5cGUgQ3B1UGlubmVkRGF0YVR5cGVzID0gRXhjbHVkZTxUZW5zb3IuVHlwZSwgJ3N0cmluZyc+O1xuXG4gIC8qKlxuICAgKiB0eXBlIGFsaWFzIGZvciBXZWJHTCB0ZXh0dXJlXG4gICAqL1xuICBleHBvcnQgdHlwZSBUZXh0dXJlVHlwZSA9IFdlYkdMVGV4dHVyZTtcblxuICAvKipcbiAgICogc3VwcG9ydGVkIGRhdGEgdHlwZXMgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgV2ViR0wgdGV4dHVyZVxuICAgKi9cbiAgZXhwb3J0IHR5cGUgVGV4dHVyZURhdGFUeXBlcyA9ICdmbG9hdDMyJztcblxuICAvKipcbiAgICogdHlwZSBhbGlhcyBmb3IgV2ViR1BVIGJ1ZmZlclxuICAgKlxuICAgKiBUaGUgcmVhc29uIHdoeSB3ZSBkb24ndCB1c2UgdHlwZSBcIkdQVUJ1ZmZlclwiIGRlZmluZWQgaW4gd2ViZ3B1LmQudHMgZnJvbSBAd2ViZ3B1L3R5cGVzIGlzIGJlY2F1c2UgXCJAd2ViZ3B1L3R5cGVzXCJcbiAgICogcmVxdWlyZXMgXCJAdHlwZXMvZG9tLXdlYmNvZGVjc1wiIGFzIHBlZXIgZGVwZW5kZW5jeSB3aGVuIHVzaW5nIFR5cGVTY3JpcHQgPCB2NS4xIGFuZCBpdHMgdmVyc2lvbiBuZWVkIHRvIGJlIGNob3NlblxuICAgKiBjYXJlZnVsbHkgYWNjb3JkaW5nIHRvIHRoZSBUeXBlU2NyaXB0IHZlcnNpb24gYmVpbmcgdXNlZC4gVGhpcyBtZWFucyBzbyBmYXIgdGhlcmUgaXMgbm90IGEgd2F5IHRvIGtlZXAgZXZlcnlcbiAgICogVHlwZVNjcmlwdCB2ZXJzaW9uIGhhcHB5LiBJdCB0dXJucyBvdXQgdGhhdCB3ZSB3aWxsIGVhc2lseSBicm9rZSB1c2VycyBvbiBzb21lIFR5cGVTY3JpcHQgdmVyc2lvbi5cbiAgICpcbiAgICogZm9yIG1vcmUgaW5mbyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2dwdXdlYi90eXBlcy9pc3N1ZXMvMTI3XG4gICAqL1xuICBleHBvcnQgdHlwZSBHcHVCdWZmZXJUeXBlID0ge3NpemU6IG51bWJlcjsgbWFwU3RhdGU6ICd1bm1hcHBlZCcgfCAncGVuZGluZycgfCAnbWFwcGVkJ307XG5cbiAgLyoqXG4gICAqIHN1cHBvcnRlZCBkYXRhIHR5cGVzIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIFdlYkdQVSBidWZmZXJcbiAgICovXG4gIGV4cG9ydCB0eXBlIEdwdUJ1ZmZlckRhdGFUeXBlcyA9ICdmbG9hdDMyJ3wnZmxvYXQxNid8J2ludDMyJ3wnaW50NjQnfCd1aW50MzInfCd1aW50OCd8J2Jvb2wnO1xuXG4gIC8qKlxuICAgKiByZXByZXNlbnQgd2hlcmUgdGhlIHRlbnNvciBkYXRhIGlzIHN0b3JlZFxuICAgKi9cbiAgZXhwb3J0IHR5cGUgRGF0YUxvY2F0aW9uID0gJ25vbmUnfCdjcHUnfCdjcHUtcGlubmVkJ3wndGV4dHVyZSd8J2dwdS1idWZmZXInO1xuXG4gIC8qKlxuICAgKiByZXByZXNlbnQgdGhlIGRhdGEgdHlwZSBvZiBhIHRlbnNvclxuICAgKi9cbiAgZXhwb3J0IHR5cGUgVHlwZSA9IGtleW9mIERhdGFUeXBlTWFwO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBtdWx0aS1kaW1lbnNpb25hbCBhcnJheXMgdG8gZmVlZCB0byBvciBmZXRjaCBmcm9tIG1vZGVsIGluZmVyZW5jaW5nLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFR5cGVkVGVuc29yPFQgZXh0ZW5kcyBUZW5zb3IuVHlwZT4gZXh0ZW5kcyBUeXBlZFRlbnNvckJhc2U8VD4sIFR5cGVkVGVuc29yVXRpbHM8VD4ge31cbi8qKlxuICogUmVwcmVzZW50IG11bHRpLWRpbWVuc2lvbmFsIGFycmF5cyB0byBmZWVkIHRvIG9yIGZldGNoIGZyb20gbW9kZWwgaW5mZXJlbmNpbmcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yIGV4dGVuZHMgVHlwZWRUZW5zb3JCYXNlPFRlbnNvci5UeXBlPiwgVHlwZWRUZW5zb3JVdGlsczxUZW5zb3IuVHlwZT4ge31cblxuLyoqXG4gKiB0eXBlIFRlbnNvckNvbnN0cnVjdG9yIGRlZmluZXMgdGhlIGNvbnN0cnVjdG9ycyBvZiAnVGVuc29yJyB0byBjcmVhdGUgQ1BVIHRlbnNvciBpbnN0YW5jZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yQ29uc3RydWN0b3IgZXh0ZW5kcyBUZW5zb3JGYWN0b3J5IHtcbiAgLy8gI3JlZ2lvbiBDUFUgdGVuc29yIC0gc3BlY2lmeSBlbGVtZW50IHR5cGVcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBzdHJpbmcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3KHR5cGU6ICdzdHJpbmcnLCBkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbJ3N0cmluZyddfHJlYWRvbmx5IHN0cmluZ1tdLFxuICAgICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3N0cmluZyc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgYm9vbCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIHR5cGUsIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gU3BlY2lmeSB0aGUgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcodHlwZTogJ2Jvb2wnLCBkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbJ2Jvb2wnXXxyZWFkb25seSBib29sZWFuW10sIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdib29sJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyA2NC1iaXQgaW50ZWdlciB0eXBlZCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIHR5cGUsIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSB0eXBlIC0gU3BlY2lmeSB0aGUgZWxlbWVudCB0eXBlLlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXc8VCBleHRlbmRzICd1aW50NjQnfCdpbnQ2NCc+KFxuICAgICAgdHlwZTogVCwgZGF0YTogVGVuc29yLkRhdGFUeXBlTWFwW1RdfHJlYWRvbmx5IGJpZ2ludFtdfHJlYWRvbmx5IG51bWJlcltdLFxuICAgICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8VD47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBudW1lcmljIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gdHlwZSwgZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSBTcGVjaWZ5IHRoZSBlbGVtZW50IHR5cGUuXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldzxUIGV4dGVuZHMgRXhjbHVkZTxUZW5zb3IuVHlwZSwgJ3N0cmluZyd8J2Jvb2wnfCd1aW50NjQnfCdpbnQ2NCc+PihcbiAgICAgIHR5cGU6IFQsIGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUXXxyZWFkb25seSBudW1iZXJbXSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8VD47XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIENQVSB0ZW5zb3IgLSBpbmZlciBlbGVtZW50IHR5cGVzXG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBmbG9hdDMyIHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3KGRhdGE6IEZsb2F0MzJBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2Zsb2F0MzInPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGludDggdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcoZGF0YTogSW50OEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnaW50OCc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdWludDggdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcoZGF0YTogVWludDhBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3VpbnQ4Jz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyB1aW50MTYgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcoZGF0YTogVWludDE2QXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCd1aW50MTYnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IGludDE2IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3KGRhdGE6IEludDE2QXJyYXksIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdpbnQxNic+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgaW50MzIgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcoZGF0YTogSW50MzJBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2ludDMyJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBpbnQ2NCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyhkYXRhOiBCaWdJbnQ2NEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwnaW50NjQnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHN0cmluZyB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyhkYXRhOiByZWFkb25seSBzdHJpbmdbXSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3N0cmluZyc+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgYm9vbCB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyhkYXRhOiByZWFkb25seSBib29sZWFuW10sIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPCdib29sJz47XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBmbG9hdDY0IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3KGRhdGE6IEZsb2F0NjRBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J2Zsb2F0NjQnPjtcblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgbmV3IHVpbnQzMiB0ZW5zb3Igb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGEgYW5kIGRpbXMuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhIC0gU3BlY2lmeSB0aGUgQ1BVIHRlbnNvciBkYXRhLlxuICAgKiBAcGFyYW0gZGltcyAtIFNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICovXG4gIG5ldyhkYXRhOiBVaW50MzJBcnJheSwgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVHlwZWRUZW5zb3I8J3VpbnQzMic+O1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdWludDY0IHRlbnNvciBvYmplY3QgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBhbmQgZGltcy5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3KGRhdGE6IEJpZ1VpbnQ2NEFycmF5LCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUeXBlZFRlbnNvcjwndWludDY0Jz47XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gQ1BVIHRlbnNvciAtIGZhbGwgYmFjayB0byBub24tZ2VuZXJpYyB0ZW5zb3IgdHlwZSBkZWNsYXJhdGlvblxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB0eXBlLCBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFNwZWNpZnkgdGhlIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGRhdGEgLSBTcGVjaWZ5IHRoZSBDUFUgdGVuc29yIGRhdGEuXG4gICAqIEBwYXJhbSBkaW1zIC0gU3BlY2lmeSB0aGUgZGltZW5zaW9uIG9mIHRoZSB0ZW5zb3IuIElmIG9taXR0ZWQsIGEgMS1EIHRlbnNvciBpcyBhc3N1bWVkLlxuICAgKi9cbiAgbmV3KHR5cGU6IFRlbnNvci5UeXBlLCBkYXRhOiBUZW5zb3IuRGF0YVR5cGV8cmVhZG9ubHkgbnVtYmVyW118cmVhZG9ubHkgc3RyaW5nW118cmVhZG9ubHkgYmlnaW50W118cmVhZG9ubHkgYm9vbGVhbltdLFxuICAgICAgZGltcz86IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgYSBuZXcgdGVuc29yIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBkYXRhIGFuZCBkaW1zLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFNwZWNpZnkgdGhlIENQVSB0ZW5zb3IgZGF0YS5cbiAgICogQHBhcmFtIGRpbXMgLSBTcGVjaWZ5IHRoZSBkaW1lbnNpb24gb2YgdGhlIHRlbnNvci4gSWYgb21pdHRlZCwgYSAxLUQgdGVuc29yIGlzIGFzc3VtZWQuXG4gICAqL1xuICBuZXcoZGF0YTogVGVuc29yLkRhdGFUeXBlLCBkaW1zPzogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3I7XG4gIC8vICNlbmRyZWdpb25cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IFRlbnNvciA9IFRlbnNvckltcGwgYXMgVGVuc29yQ29uc3RydWN0b3I7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7ZW52fSBmcm9tICcuL2Vudi1pbXBsLmpzJztcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFDRSA9IChkZXZpY2VUeXBlOiBzdHJpbmcsIGxhYmVsOiBzdHJpbmcpID0+IHtcbiAgaWYgKHR5cGVvZiBlbnYudHJhY2UgPT09ICd1bmRlZmluZWQnID8gIWVudi53YXNtLnRyYWNlIDogIWVudi50cmFjZSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLnRpbWVTdGFtcChgJHtkZXZpY2VUeXBlfTo6T1JUOjoke2xhYmVsfWApO1xufTtcblxuY29uc3QgVFJBQ0VfRlVOQyA9IChtc2c6IHN0cmluZywgZXh0cmFNc2c/OiBzdHJpbmcpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgRXJyb3IoKS5zdGFjaz8uc3BsaXQoL1xcclxcbnxcXHJ8XFxuL2cpIHx8IFtdO1xuICBsZXQgaGFzVHJhY2VGdW5jID0gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhY2subGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaGFzVHJhY2VGdW5jICYmICFzdGFja1tpXS5pbmNsdWRlcygnVFJBQ0VfRlVOQycpKSB7XG4gICAgICBsZXQgbGFiZWwgPSBgRlVOQ18ke21zZ306OiR7c3RhY2tbaV0udHJpbSgpLnNwbGl0KCcgJylbMV19YDtcbiAgICAgIGlmIChleHRyYU1zZykge1xuICAgICAgICBsYWJlbCArPSBgOjoke2V4dHJhTXNnfWA7XG4gICAgICB9XG4gICAgICBUUkFDRSgnQ1BVJywgbGFiZWwpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RhY2tbaV0uaW5jbHVkZXMoJ1RSQUNFX0ZVTkMnKSkge1xuICAgICAgaGFzVHJhY2VGdW5jID0gdHJ1ZTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogQGlnbm9yZVxuICovXG5leHBvcnQgY29uc3QgVFJBQ0VfRlVOQ19CRUdJTiA9IChleHRyYU1zZz86IHN0cmluZykgPT4ge1xuICBpZiAodHlwZW9mIGVudi50cmFjZSA9PT0gJ3VuZGVmaW5lZCcgPyAhZW52Lndhc20udHJhY2UgOiAhZW52LnRyYWNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIFRSQUNFX0ZVTkMoJ0JFR0lOJywgZXh0cmFNc2cpO1xufTtcblxuLyoqXG4gKiBAaWdub3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUUkFDRV9GVU5DX0VORCA9IChleHRyYU1zZz86IHN0cmluZykgPT4ge1xuICBpZiAodHlwZW9mIGVudi50cmFjZSA9PT0gJ3VuZGVmaW5lZCcgPyAhZW52Lndhc20udHJhY2UgOiAhZW52LnRyYWNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIFRSQUNFX0ZVTkMoJ0VORCcsIGV4dHJhTXNnKTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7cmVzb2x2ZUJhY2tlbmRBbmRFeGVjdXRpb25Qcm92aWRlcnN9IGZyb20gJy4vYmFja2VuZC1pbXBsLmpzJztcbmltcG9ydCB7SW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXJ9IGZyb20gJy4vYmFja2VuZC5qcyc7XG5pbXBvcnQge0luZmVyZW5jZVNlc3Npb24gYXMgSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZX0gZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi5qcyc7XG5pbXBvcnQge09ubnhWYWx1ZX0gZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuL3RlbnNvci5qcyc7XG5pbXBvcnQge1RSQUNFX0ZVTkNfQkVHSU4sIFRSQUNFX0ZVTkNfRU5EfSBmcm9tICcuL3RyYWNlLmpzJztcblxudHlwZSBTZXNzaW9uT3B0aW9ucyA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuU2Vzc2lvbk9wdGlvbnM7XG50eXBlIFJ1bk9wdGlvbnMgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlJ1bk9wdGlvbnM7XG50eXBlIEZlZWRzVHlwZSA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuRmVlZHNUeXBlO1xudHlwZSBGZXRjaGVzVHlwZSA9IEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuRmV0Y2hlc1R5cGU7XG50eXBlIFJldHVyblR5cGUgPSBJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlLlJldHVyblR5cGU7XG5cbmV4cG9ydCBjbGFzcyBJbmZlcmVuY2VTZXNzaW9uIGltcGxlbWVudHMgSW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZSB7XG4gIHByaXZhdGUgY29uc3RydWN0b3IoaGFuZGxlcjogSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIpIHtcbiAgICB0aGlzLmhhbmRsZXIgPSBoYW5kbGVyO1xuICB9XG4gIHJ1bihmZWVkczogRmVlZHNUeXBlLCBvcHRpb25zPzogUnVuT3B0aW9ucyk6IFByb21pc2U8UmV0dXJuVHlwZT47XG4gIHJ1bihmZWVkczogRmVlZHNUeXBlLCBmZXRjaGVzOiBGZXRjaGVzVHlwZSwgb3B0aW9ucz86IFJ1bk9wdGlvbnMpOiBQcm9taXNlPFJldHVyblR5cGU+O1xuICBhc3luYyBydW4oZmVlZHM6IEZlZWRzVHlwZSwgYXJnMT86IEZldGNoZXNUeXBlfFJ1bk9wdGlvbnMsIGFyZzI/OiBSdW5PcHRpb25zKTogUHJvbWlzZTxSZXR1cm5UeXBlPiB7XG4gICAgVFJBQ0VfRlVOQ19CRUdJTigpO1xuICAgIGNvbnN0IGZldGNoZXM6IHtbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlfG51bGx9ID0ge307XG4gICAgbGV0IG9wdGlvbnM6IFJ1bk9wdGlvbnMgPSB7fTtcbiAgICAvLyBjaGVjayBpbnB1dHNcbiAgICBpZiAodHlwZW9mIGZlZWRzICE9PSAnb2JqZWN0JyB8fCBmZWVkcyA9PT0gbnVsbCB8fCBmZWVkcyBpbnN0YW5jZW9mIFRlbnNvciB8fCBBcnJheS5pc0FycmF5KGZlZWRzKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAnXFwnZmVlZHNcXCcgbXVzdCBiZSBhbiBvYmplY3QgdGhhdCB1c2UgaW5wdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLicpO1xuICAgIH1cblxuICAgIGxldCBpc0ZldGNoZXNFbXB0eSA9IHRydWU7XG4gICAgLy8gZGV0ZXJtaW5lIHdoaWNoIG92ZXJyaWRlIGlzIGJlaW5nIHVzZWRcbiAgICBpZiAodHlwZW9mIGFyZzEgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAoYXJnMSA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmV4cGVjdGVkIGFyZ3VtZW50WzFdOiBjYW5ub3QgYmUgbnVsbC4nKTtcbiAgICAgIH1cbiAgICAgIGlmIChhcmcxIGluc3RhbmNlb2YgVGVuc29yKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1xcJ2ZldGNoZXNcXCcgY2Fubm90IGJlIGEgVGVuc29yJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZzEpKSB7XG4gICAgICAgIGlmIChhcmcxLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1xcJ2ZldGNoZXNcXCcgY2Fubm90IGJlIGFuIGVtcHR5IGFycmF5LicpO1xuICAgICAgICB9XG4gICAgICAgIGlzRmV0Y2hlc0VtcHR5ID0gZmFsc2U7XG4gICAgICAgIC8vIG91dHB1dCBuYW1lc1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgYXJnMSkge1xuICAgICAgICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1xcJ2ZldGNoZXNcXCcgbXVzdCBiZSBhIHN0cmluZyBhcnJheSBvciBhbiBvYmplY3QuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0aGlzLm91dHB1dE5hbWVzLmluZGV4T2YobmFtZSkgPT09IC0xKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJ2ZldGNoZXMnIGNvbnRhaW5zIGludmFsaWQgb3V0cHV0IG5hbWU6ICR7bmFtZX0uYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZldGNoZXNbbmFtZV0gPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBhcmcyID09PSAnb2JqZWN0JyAmJiBhcmcyICE9PSBudWxsKSB7XG4gICAgICAgICAgb3B0aW9ucyA9IGFyZzI7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXFwnb3B0aW9uc1xcJyBtdXN0IGJlIGFuIG9iamVjdC4nKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZGVjaWRlIHdoZXRoZXIgYXJnMSBpcyBmZXRjaGVzIG9yIG9wdGlvbnNcbiAgICAgICAgLy8gaWYgYW55IG91dHB1dCBuYW1lIGlzIHByZXNlbnQgYW5kIGl0cyB2YWx1ZSBpcyB2YWxpZCBPbm54VmFsdWUsIHdlIGNvbnNpZGVyIGl0IGZldGNoZXNcbiAgICAgICAgbGV0IGlzRmV0Y2hlcyA9IGZhbHNlO1xuICAgICAgICBjb25zdCBhcmcxS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGFyZzEpO1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgdGhpcy5vdXRwdXROYW1lcykge1xuICAgICAgICAgIGlmIChhcmcxS2V5cy5pbmRleE9mKG5hbWUpICE9PSAtMSkge1xuICAgICAgICAgICAgY29uc3QgdiA9IChhcmcxIGFzIEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2UuTnVsbGFibGVPbm54VmFsdWVNYXBUeXBlKVtuYW1lXTtcbiAgICAgICAgICAgIGlmICh2ID09PSBudWxsIHx8IHYgaW5zdGFuY2VvZiBUZW5zb3IpIHtcbiAgICAgICAgICAgICAgaXNGZXRjaGVzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgaXNGZXRjaGVzRW1wdHkgPSBmYWxzZTtcbiAgICAgICAgICAgICAgZmV0Y2hlc1tuYW1lXSA9IHY7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzRmV0Y2hlcykge1xuICAgICAgICAgIGlmICh0eXBlb2YgYXJnMiA9PT0gJ29iamVjdCcgJiYgYXJnMiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IGFyZzI7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1xcJ29wdGlvbnNcXCcgbXVzdCBiZSBhbiBvYmplY3QuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9wdGlvbnMgPSBhcmcxIGFzIFJ1bk9wdGlvbnM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcxICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5leHBlY3RlZCBhcmd1bWVudFsxXTogbXVzdCBiZSBcXCdmZXRjaGVzXFwnIG9yIFxcJ29wdGlvbnNcXCcuJyk7XG4gICAgfVxuXG4gICAgLy8gY2hlY2sgaWYgYWxsIGlucHV0cyBhcmUgaW4gZmVlZFxuICAgIGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmlucHV0TmFtZXMpIHtcbiAgICAgIGlmICh0eXBlb2YgZmVlZHNbbmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXQgJyR7bmFtZX0nIGlzIG1pc3NpbmcgaW4gJ2ZlZWRzJy5gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpZiBubyBmZXRjaGVzIGlzIHNwZWNpZmllZCwgd2UgdXNlIHRoZSBmdWxsIG91dHB1dCBuYW1lcyBsaXN0XG4gICAgaWYgKGlzRmV0Y2hlc0VtcHR5KSB7XG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgdGhpcy5vdXRwdXROYW1lcykge1xuICAgICAgICBmZXRjaGVzW25hbWVdID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBmZWVkcywgZmV0Y2hlcyBhbmQgb3B0aW9ucyBhcmUgcHJlcGFyZWRcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmhhbmRsZXIucnVuKGZlZWRzLCBmZXRjaGVzLCBvcHRpb25zKTtcbiAgICBjb25zdCByZXR1cm5WYWx1ZToge1tuYW1lOiBzdHJpbmddOiBPbm54VmFsdWV9ID0ge307XG4gICAgZm9yIChjb25zdCBrZXkgaW4gcmVzdWx0cykge1xuICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdHMsIGtleSkpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcmVzdWx0c1trZXldO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgVGVuc29yKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVba2V5XSA9IHJlc3VsdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVtrZXldID0gbmV3IFRlbnNvcihyZXN1bHQudHlwZSwgcmVzdWx0LmRhdGEsIHJlc3VsdC5kaW1zKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBUUkFDRV9GVU5DX0VORCgpO1xuICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgfVxuXG4gIGFzeW5jIHJlbGVhc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlci5kaXNwb3NlKCk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlKHBhdGg6IHN0cmluZywgb3B0aW9ucz86IFNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPjtcbiAgc3RhdGljIGNyZWF0ZShidWZmZXI6IEFycmF5QnVmZmVyTGlrZSwgb3B0aW9ucz86IFNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPjtcbiAgc3RhdGljIGNyZWF0ZShidWZmZXI6IEFycmF5QnVmZmVyTGlrZSwgYnl0ZU9mZnNldDogbnVtYmVyLCBieXRlTGVuZ3RoPzogbnVtYmVyLCBvcHRpb25zPzogU2Vzc2lvbk9wdGlvbnMpOlxuICAgICAgUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uSW50ZXJmYWNlPjtcbiAgc3RhdGljIGNyZWF0ZShidWZmZXI6IFVpbnQ4QXJyYXksIG9wdGlvbnM/OiBTZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbkludGVyZmFjZT47XG4gIHN0YXRpYyBhc3luYyBjcmVhdGUoXG4gICAgICBhcmcwOiBzdHJpbmd8QXJyYXlCdWZmZXJMaWtlfFVpbnQ4QXJyYXksIGFyZzE/OiBTZXNzaW9uT3B0aW9uc3xudW1iZXIsIGFyZzI/OiBudW1iZXIsXG4gICAgICBhcmczPzogU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25JbnRlcmZhY2U+IHtcbiAgICBUUkFDRV9GVU5DX0JFR0lOKCk7XG4gICAgLy8gZWl0aGVyIGxvYWQgZnJvbSBhIGZpbGUgb3IgYnVmZmVyXG4gICAgbGV0IGZpbGVQYXRoT3JVaW50OEFycmF5OiBzdHJpbmd8VWludDhBcnJheTtcbiAgICBsZXQgb3B0aW9uczogU2Vzc2lvbk9wdGlvbnMgPSB7fTtcblxuICAgIGlmICh0eXBlb2YgYXJnMCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGZpbGVQYXRoT3JVaW50OEFycmF5ID0gYXJnMDtcbiAgICAgIGlmICh0eXBlb2YgYXJnMSA9PT0gJ29iamVjdCcgJiYgYXJnMSAhPT0gbnVsbCkge1xuICAgICAgICBvcHRpb25zID0gYXJnMTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1xcJ29wdGlvbnNcXCcgbXVzdCBiZSBhbiBvYmplY3QuJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChhcmcwIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgZmlsZVBhdGhPclVpbnQ4QXJyYXkgPSBhcmcwO1xuICAgICAgaWYgKHR5cGVvZiBhcmcxID09PSAnb2JqZWN0JyAmJiBhcmcxICE9PSBudWxsKSB7XG4gICAgICAgIG9wdGlvbnMgPSBhcmcxO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXFwnb3B0aW9uc1xcJyBtdXN0IGJlIGFuIG9iamVjdC4nKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgICBhcmcwIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHxcbiAgICAgICAgKHR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgYXJnMCBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyKSkge1xuICAgICAgY29uc3QgYnVmZmVyID0gYXJnMDtcbiAgICAgIGxldCBieXRlT2Zmc2V0ID0gMDtcbiAgICAgIGxldCBieXRlTGVuZ3RoID0gYXJnMC5ieXRlTGVuZ3RoO1xuICAgICAgaWYgKHR5cGVvZiBhcmcxID09PSAnb2JqZWN0JyAmJiBhcmcxICE9PSBudWxsKSB7XG4gICAgICAgIG9wdGlvbnMgPSBhcmcxO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgYnl0ZU9mZnNldCA9IGFyZzE7XG4gICAgICAgIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIoYnl0ZU9mZnNldCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnYnl0ZU9mZnNldFxcJyBtdXN0IGJlIGFuIGludGVnZXIuJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJ2J5dGVPZmZzZXQnIGlzIG91dCBvZiByYW5nZSBbMCwgJHtidWZmZXIuYnl0ZUxlbmd0aH0pLmApO1xuICAgICAgICB9XG4gICAgICAgIGJ5dGVMZW5ndGggPSBhcmcwLmJ5dGVMZW5ndGggLSBieXRlT2Zmc2V0O1xuICAgICAgICBpZiAodHlwZW9mIGFyZzIgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgYnl0ZUxlbmd0aCA9IGFyZzI7XG4gICAgICAgICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihieXRlTGVuZ3RoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ2J5dGVMZW5ndGhcXCcgbXVzdCBiZSBhbiBpbnRlZ2VyLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYnl0ZUxlbmd0aCA8PSAwIHx8IGJ5dGVPZmZzZXQgKyBieXRlTGVuZ3RoID4gYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAnYnl0ZUxlbmd0aCcgaXMgb3V0IG9mIHJhbmdlICgwLCAke2J1ZmZlci5ieXRlTGVuZ3RoIC0gYnl0ZU9mZnNldH1dLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHlwZW9mIGFyZzMgPT09ICdvYmplY3QnICYmIGFyZzMgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBhcmczO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcXCdvcHRpb25zXFwnIG11c3QgYmUgYW4gb2JqZWN0LicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcXCdieXRlTGVuZ3RoXFwnIG11c3QgYmUgYSBudW1iZXIuJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZzEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1xcJ29wdGlvbnNcXCcgbXVzdCBiZSBhbiBvYmplY3QuJyk7XG4gICAgICB9XG4gICAgICBmaWxlUGF0aE9yVWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1VuZXhwZWN0ZWQgYXJndW1lbnRbMF06IG11c3QgYmUgXFwncGF0aFxcJyBvciBcXCdidWZmZXJcXCcuJyk7XG4gICAgfVxuXG4gICAgLy8gcmVzb2x2ZSBiYWNrZW5kLCB1cGRhdGUgc2Vzc2lvbiBvcHRpb25zIHdpdGggdmFsaWRhdGVkIEVQcywgYW5kIGNyZWF0ZSBzZXNzaW9uIGhhbmRsZXJcbiAgICBjb25zdCBbYmFja2VuZCwgb3B0aW9uc1dpdGhWYWxpZGF0ZWRFUHNdID0gYXdhaXQgcmVzb2x2ZUJhY2tlbmRBbmRFeGVjdXRpb25Qcm92aWRlcnMob3B0aW9ucyk7XG4gICAgY29uc3QgaGFuZGxlciA9IGF3YWl0IGJhY2tlbmQuY3JlYXRlSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXIoZmlsZVBhdGhPclVpbnQ4QXJyYXksIG9wdGlvbnNXaXRoVmFsaWRhdGVkRVBzKTtcbiAgICBUUkFDRV9GVU5DX0VORCgpO1xuICAgIHJldHVybiBuZXcgSW5mZXJlbmNlU2Vzc2lvbihoYW5kbGVyKTtcbiAgfVxuXG4gIHN0YXJ0UHJvZmlsaW5nKCk6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlci5zdGFydFByb2ZpbGluZygpO1xuICB9XG4gIGVuZFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB0aGlzLmhhbmRsZXIuZW5kUHJvZmlsaW5nKCk7XG4gIH1cblxuICBnZXQgaW5wdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlci5pbnB1dE5hbWVzO1xuICB9XG4gIGdldCBvdXRwdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlci5vdXRwdXROYW1lcztcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlcjogSW5mZXJlbmNlU2Vzc2lvbkhhbmRsZXI7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7SW5mZXJlbmNlU2Vzc2lvbiBhcyBJbmZlcmVuY2VTZXNzaW9uSW1wbH0gZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi1pbXBsLmpzJztcbmltcG9ydCB7T25ueE1vZGVsT3B0aW9uc30gZnJvbSAnLi9vbm54LW1vZGVsLmpzJztcbmltcG9ydCB7T25ueFZhbHVlLCBPbm54VmFsdWVEYXRhTG9jYXRpb259IGZyb20gJy4vb25ueC12YWx1ZS5qcyc7XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmUgKi9cblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEluZmVyZW5jZVNlc3Npb24ge1xuICAvLyAjcmVnaW9uIGlucHV0L291dHB1dCB0eXBlc1xuXG4gIHR5cGUgT25ueFZhbHVlTWFwVHlwZSA9IHtyZWFkb25seSBbbmFtZTogc3RyaW5nXTogT25ueFZhbHVlfTtcbiAgdHlwZSBOdWxsYWJsZU9ubnhWYWx1ZU1hcFR5cGUgPSB7cmVhZG9ubHkgW25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZSB8IG51bGx9O1xuXG4gIC8qKlxuICAgKiBBIGZlZWRzIChtb2RlbCBpbnB1dHMpIGlzIGFuIG9iamVjdCB0aGF0IHVzZXMgaW5wdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKi9cbiAgdHlwZSBGZWVkc1R5cGUgPSBPbm54VmFsdWVNYXBUeXBlO1xuXG4gIC8qKlxuICAgKiBBIGZldGNoZXMgKG1vZGVsIG91dHB1dHMpIGNvdWxkIGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nOlxuICAgKlxuICAgKiAtIE9taXR0ZWQuIFVzZSBtb2RlbCdzIG91dHB1dCBuYW1lcyBkZWZpbml0aW9uLlxuICAgKiAtIEFuIGFycmF5IG9mIHN0cmluZyBpbmRpY2F0aW5nIHRoZSBvdXRwdXQgbmFtZXMuXG4gICAqIC0gQW4gb2JqZWN0IHRoYXQgdXNlIG91dHB1dCBuYW1lcyBhcyBrZXlzIGFuZCBPbm54VmFsdWUgb3IgbnVsbCBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICpcbiAgICogQHJlbWFya1xuICAgKiBkaWZmZXJlbnQgZnJvbSBpbnB1dCBhcmd1bWVudCwgaW4gb3V0cHV0LCBPbm54VmFsdWUgaXMgb3B0aW9uYWwuIElmIGFuIE9ubnhWYWx1ZSBpcyBwcmVzZW50IGl0IHdpbGwgYmVcbiAgICogdXNlZCBhcyBhIHByZS1hbGxvY2F0ZWQgdmFsdWUgYnkgdGhlIGluZmVyZW5jZSBlbmdpbmU7IGlmIG9taXR0ZWQsIGluZmVyZW5jZSBlbmdpbmUgd2lsbCBhbGxvY2F0ZSBidWZmZXJcbiAgICogaW50ZXJuYWxseS5cbiAgICovXG4gIHR5cGUgRmV0Y2hlc1R5cGUgPSByZWFkb25seSBzdHJpbmdbXXxOdWxsYWJsZU9ubnhWYWx1ZU1hcFR5cGU7XG5cbiAgLyoqXG4gICAqIEEgaW5mZXJlbmNpbmcgcmV0dXJuIHR5cGUgaXMgYW4gb2JqZWN0IHRoYXQgdXNlcyBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKi9cbiAgdHlwZSBSZXR1cm5UeXBlID0gT25ueFZhbHVlTWFwVHlwZTtcblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBzZXNzaW9uIG9wdGlvbnNcblxuICAvKipcbiAgICogQSBzZXQgb2YgY29uZmlndXJhdGlvbnMgZm9yIHNlc3Npb24gYmVoYXZpb3IuXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFNlc3Npb25PcHRpb25zIGV4dGVuZHMgT25ueE1vZGVsT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogQW4gYXJyYXkgb2YgZXhlY3V0aW9uIHByb3ZpZGVyIG9wdGlvbnMuXG4gICAgICpcbiAgICAgKiBBbiBleGVjdXRpb24gcHJvdmlkZXIgb3B0aW9uIGNhbiBiZSBhIHN0cmluZyBpbmRpY2F0aW5nIHRoZSBuYW1lIG9mIHRoZSBleGVjdXRpb24gcHJvdmlkZXIsXG4gICAgICogb3IgYW4gb2JqZWN0IG9mIGNvcnJlc3BvbmRpbmcgdHlwZS5cbiAgICAgKi9cbiAgICBleGVjdXRpb25Qcm92aWRlcnM/OiByZWFkb25seSBFeGVjdXRpb25Qcm92aWRlckNvbmZpZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGludHJhIE9QIHRocmVhZHMgbnVtYmVyLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkuXG4gICAgICovXG4gICAgaW50cmFPcE51bVRocmVhZHM/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaW50ZXIgT1AgdGhyZWFkcyBudW1iZXIuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKS5cbiAgICAgKi9cbiAgICBpbnRlck9wTnVtVGhyZWFkcz86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBmcmVlIGRpbWVuc2lvbiBvdmVycmlkZS5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBmcmVlRGltZW5zaW9uT3ZlcnJpZGVzPzoge3JlYWRvbmx5IFtkaW1lbnNpb25OYW1lOiBzdHJpbmddOiBudW1iZXJ9O1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wdGltaXphdGlvbiBsZXZlbC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBncmFwaE9wdGltaXphdGlvbkxldmVsPzogJ2Rpc2FibGVkJ3wnYmFzaWMnfCdleHRlbmRlZCd8J2FsbCc7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIGVuYWJsZSBDUFUgbWVtb3J5IGFyZW5hLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGVuYWJsZUNwdU1lbUFyZW5hPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZW5hYmxlIG1lbW9yeSBwYXR0ZXJuLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIGVuYWJsZU1lbVBhdHRlcm4/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogRXhlY3V0aW9uIG1vZGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgZXhlY3V0aW9uTW9kZT86ICdzZXF1ZW50aWFsJ3wncGFyYWxsZWwnO1xuXG4gICAgLyoqXG4gICAgICogT3B0aW1pemVkIG1vZGVsIGZpbGUgcGF0aC5cbiAgICAgKlxuICAgICAqIElmIHRoaXMgc2V0dGluZyBpcyBzcGVjaWZpZWQsIHRoZSBvcHRpbWl6ZWQgbW9kZWwgd2lsbCBiZSBkdW1wZWQuIEluIGJyb3dzZXIsIGEgYmxvYiB3aWxsIGJlIGNyZWF0ZWRcbiAgICAgKiB3aXRoIGEgcG9wLXVwIHdpbmRvdy5cbiAgICAgKi9cbiAgICBvcHRpbWl6ZWRNb2RlbEZpbGVQYXRoPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBlbmFibGUgcHJvZmlsaW5nLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGEgZnV0dXJlIHVzZS5cbiAgICAgKi9cbiAgICBlbmFibGVQcm9maWxpbmc/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogRmlsZSBwcmVmaXggZm9yIHByb2ZpbGluZy5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhIHBsYWNlaG9sZGVyIGZvciBhIGZ1dHVyZSB1c2UuXG4gICAgICovXG4gICAgcHJvZmlsZUZpbGVQcmVmaXg/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBMb2cgSUQuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgbG9nSWQ/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBMb2cgc2V2ZXJpdHkgbGV2ZWwuIFNlZVxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueHJ1bnRpbWUvYmxvYi9tYWluL2luY2x1ZGUvb25ueHJ1bnRpbWUvY29yZS9jb21tb24vbG9nZ2luZy9zZXZlcml0eS5oXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgKE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlKSBvciBXZWJBc3NlbWJseSBiYWNrZW5kXG4gICAgICovXG4gICAgbG9nU2V2ZXJpdHlMZXZlbD86IDB8MXwyfDN8NDtcblxuICAgIC8qKlxuICAgICAqIExvZyB2ZXJib3NpdHkgbGV2ZWwuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICovXG4gICAgbG9nVmVyYm9zaXR5TGV2ZWw/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHN0cmluZyBhcyBhIHByZWZlcnJlZCBkYXRhIGxvY2F0aW9uIGZvciBhbGwgb3V0cHV0cywgb3IgYW4gb2JqZWN0IHRoYXQgdXNlIG91dHB1dCBuYW1lcyBhcyBrZXlzIGFuZCBhXG4gICAgICogcHJlZmVycmVkIGRhdGEgbG9jYXRpb24gYXMgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gT05OWFJ1bnRpbWUgV2ViIGZvciBXZWJHTCBhbmQgV2ViR1BVIEVQLlxuICAgICAqL1xuICAgIHByZWZlcnJlZE91dHB1dExvY2F0aW9uPzogT25ueFZhbHVlRGF0YUxvY2F0aW9ufHtyZWFkb25seSBbb3V0cHV0TmFtZTogc3RyaW5nXTogT25ueFZhbHVlRGF0YUxvY2F0aW9ufTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZW5hYmxlIGdyYXBoIGNhcHR1cmUuXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIFdlYiBmb3IgV2ViR1BVIEVQLlxuICAgICAqL1xuICAgIGVuYWJsZUdyYXBoQ2FwdHVyZT86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBTdG9yZSBjb25maWd1cmF0aW9ucyBmb3IgYSBzZXNzaW9uLiBTZWVcbiAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhydW50aW1lL2Jsb2IvbWFpbi9pbmNsdWRlL29ubnhydW50aW1lL2NvcmUvc2Vzc2lvbi9cbiAgICAgKiBvbm54cnVudGltZV9zZXNzaW9uX29wdGlvbnNfY29uZmlnX2tleXMuaFxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIFdlYkFzc2VtYmx5IGJhY2tlbmQuIFdpbGwgc3VwcG9ydCBOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSBsYXRlclxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGV4dHJhOiB7XG4gICAgICogICBzZXNzaW9uOiB7XG4gICAgICogICAgIHNldF9kZW5vcm1hbF9hc196ZXJvOiBcIjFcIixcbiAgICAgKiAgICAgZGlzYWJsZV9wcmVwYWNraW5nOiBcIjFcIlxuICAgICAqICAgfSxcbiAgICAgKiAgIG9wdGltaXphdGlvbjoge1xuICAgICAqICAgICBlbmFibGVfZ2VsdV9hcHByb3hpbWF0aW9uOiBcIjFcIlxuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBleHRyYT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB9XG5cbiAgLy8gI3JlZ2lvbiBleGVjdXRpb24gcHJvdmlkZXJzXG5cbiAgLy8gQ3VycmVudGx5LCB3ZSBoYXZlIHRoZSBmb2xsb3dpbmcgYmFja2VuZHMgdG8gc3VwcG9ydCBleGVjdXRpb24gcHJvdmlkZXJzOlxuICAvLyBCYWNrZW5kIE5vZGUuanMgYmluZGluZzogc3VwcG9ydHMgJ2NwdScsICdkbWwnICh3aW4zMiksICdjb3JlbWwnIChtYWNPUykgYW5kICdjdWRhJyAobGludXgpLlxuICAvLyBCYWNrZW5kIFdlYkFzc2VtYmx5OiBzdXBwb3J0cyAnY3B1JywgJ3dhc20nLCAnd2ViZ3B1JyBhbmQgJ3dlYm5uJy5cbiAgLy8gQmFja2VuZCBPTk5YLmpzOiBzdXBwb3J0cyAnd2ViZ2wnLlxuICAvLyBCYWNrZW5kIFJlYWN0IE5hdGl2ZTogc3VwcG9ydHMgJ2NwdScsICd4bm5wYWNrJywgJ2NvcmVtbCcgKGlPUyksICdubmFwaScgKEFuZHJvaWQpLlxuICBpbnRlcmZhY2UgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb25NYXAge1xuICAgIGNvcmVtbDogQ29yZU1MRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgY3B1OiBDcHVFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBjdWRhOiBDdWRhRXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgZG1sOiBEbWxFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICBubmFwaTogTm5hcGlFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICB0ZW5zb3JydDogVGVuc29yUnRFeGVjdXRpb25Qcm92aWRlck9wdGlvbjtcbiAgICB3YXNtOiBXZWJBc3NlbWJseUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHdlYmdsOiBXZWJHTEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICAgIHdlYmdwdTogV2ViR3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgd2Vibm46IFdlYk5ORXhlY3V0aW9uUHJvdmlkZXJPcHRpb247XG4gICAgeG5ucGFjazogWG5ucGFja0V4ZWN1dGlvblByb3ZpZGVyT3B0aW9uO1xuICB9XG5cbiAgdHlwZSBFeGVjdXRpb25Qcm92aWRlck5hbWUgPSBrZXlvZiBFeGVjdXRpb25Qcm92aWRlck9wdGlvbk1hcDtcbiAgdHlwZSBFeGVjdXRpb25Qcm92aWRlckNvbmZpZyA9XG4gICAgICBFeGVjdXRpb25Qcm92aWRlck9wdGlvbk1hcFtFeGVjdXRpb25Qcm92aWRlck5hbWVdfEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9ufEV4ZWN1dGlvblByb3ZpZGVyTmFtZXxzdHJpbmc7XG5cbiAgZXhwb3J0IGludGVyZmFjZSBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ2NwdSc7XG4gICAgdXNlQXJlbmE/OiBib29sZWFuO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ3VkYUV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdjdWRhJztcbiAgICBkZXZpY2VJZD86IG51bWJlcjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIERtbEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICdkbWwnO1xuICAgIGRldmljZUlkPzogbnVtYmVyO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVGVuc29yUnRFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAndGVuc29ycnQnO1xuICAgIGRldmljZUlkPzogbnVtYmVyO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViQXNzZW1ibHlFeGVjdXRpb25Qcm92aWRlck9wdGlvbiBleHRlbmRzIEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIHtcbiAgICByZWFkb25seSBuYW1lOiAnd2FzbSc7XG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBXZWJHTEV4ZWN1dGlvblByb3ZpZGVyT3B0aW9uIGV4dGVuZHMgRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24ge1xuICAgIHJlYWRvbmx5IG5hbWU6ICd3ZWJnbCc7XG4gICAgLy8gVE9ETzogYWRkIGZsYWdzXG4gIH1cbiAgZXhwb3J0IGludGVyZmFjZSBYbm5wYWNrRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3hubnBhY2snO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgV2ViR3B1RXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3dlYmdwdSc7XG4gICAgcHJlZmVycmVkTGF5b3V0PzogJ05DSFcnfCdOSFdDJztcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIFdlYk5ORXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ3dlYm5uJztcbiAgICBkZXZpY2VUeXBlPzogJ2NwdSd8J2dwdSd8J25wdSc7XG4gICAgbnVtVGhyZWFkcz86IG51bWJlcjtcbiAgICBwb3dlclByZWZlcmVuY2U/OiAnZGVmYXVsdCd8J2xvdy1wb3dlcid8J2hpZ2gtcGVyZm9ybWFuY2UnO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29yZU1MRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ2NvcmVtbCc7XG4gICAgLyoqXG4gICAgICogVGhlIGJpdCBmbGFncyBmb3IgQ29yZU1MIGV4ZWN1dGlvbiBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqIENPUkVNTF9GTEFHX1VTRV9DUFVfT05MWSA9IDB4MDAxXG4gICAgICogQ09SRU1MX0ZMQUdfRU5BQkxFX09OX1NVQkdSQVBIID0gMHgwMDJcbiAgICAgKiBDT1JFTUxfRkxBR19PTkxZX0VOQUJMRV9ERVZJQ0VfV0lUSF9BTkUgPSAweDAwNFxuICAgICAqIENPUkVNTF9GTEFHX09OTFlfQUxMT1dfU1RBVElDX0lOUFVUX1NIQVBFUyA9IDB4MDA4XG4gICAgICogQ09SRU1MX0ZMQUdfQ1JFQVRFX01MUFJPR1JBTSA9IDB4MDEwXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBTZWUgaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL3Byb3ZpZGVycy9jb3JlbWwvY29yZW1sX3Byb3ZpZGVyX2ZhY3RvcnkuaCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogVGhpcyBmbGFnIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcpLlxuICAgICAqL1xuICAgIGNvcmVNbEZsYWdzPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgd2hldGhlciB0byB1c2UgQ1BVIG9ubHkgaW4gQ29yZU1MIEVQLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChyZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIHVzZUNQVU9ubHk/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgd2hldGhlciB0byBlbmFibGUgQ29yZU1MIEVQIG9uIHN1YmdyYXBoLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChyZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIGVuYWJsZU9uU3ViZ3JhcGg/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgd2hldGhlciB0byBvbmx5IGVuYWJsZSBDb3JlTUwgRVAgZm9yIEFwcGxlIGRldmljZXMgd2l0aCBBTkUgKEFwcGxlIE5ldXJhbCBFbmdpbmUpLlxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChyZWFjdC1uYXRpdmUpLlxuICAgICAqL1xuICAgIG9ubHlFbmFibGVEZXZpY2VXaXRoQU5FPzogYm9vbGVhbjtcbiAgfVxuICBleHBvcnQgaW50ZXJmYWNlIE5uYXBpRXhlY3V0aW9uUHJvdmlkZXJPcHRpb24gZXh0ZW5kcyBFeGVjdXRpb25Qcm92aWRlck9wdGlvbiB7XG4gICAgcmVhZG9ubHkgbmFtZTogJ25uYXBpJztcbiAgICB1c2VGUDE2PzogYm9vbGVhbjtcbiAgICB1c2VOQ0hXPzogYm9vbGVhbjtcbiAgICBjcHVEaXNhYmxlZD86IGJvb2xlYW47XG4gICAgY3B1T25seT86IGJvb2xlYW47XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHJ1biBvcHRpb25zXG5cbiAgLyoqXG4gICAqIEEgc2V0IG9mIGNvbmZpZ3VyYXRpb25zIGZvciBpbmZlcmVuY2UgcnVuIGJlaGF2aW9yXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFJ1bk9wdGlvbnMge1xuICAgIC8qKlxuICAgICAqIExvZyBzZXZlcml0eSBsZXZlbC4gU2VlXG4gICAgICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS9ibG9iL21haW4vaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL2NvbW1vbi9sb2dnaW5nL3NldmVyaXR5LmhcbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBPTk5YUnVudGltZSAoTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUpIG9yIFdlYkFzc2VtYmx5IGJhY2tlbmRcbiAgICAgKi9cbiAgICBsb2dTZXZlcml0eUxldmVsPzogMHwxfDJ8M3w0O1xuXG4gICAgLyoqXG4gICAgICogTG9nIHZlcmJvc2l0eSBsZXZlbC5cbiAgICAgKlxuICAgICAqIFRoaXMgc2V0dGluZyBpcyBhdmFpbGFibGUgb25seSBpbiBXZWJBc3NlbWJseSBiYWNrZW5kLiBXaWxsIHN1cHBvcnQgTm9kZS5qcyBiaW5kaW5nIGFuZCByZWFjdC1uYXRpdmUgbGF0ZXJcbiAgICAgKi9cbiAgICBsb2dWZXJib3NpdHlMZXZlbD86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFRlcm1pbmF0ZSBhbGwgaW5jb21wbGV0ZSBPcnRSdW4gY2FsbHMgYXMgc29vbiBhcyBwb3NzaWJsZSBpZiB0cnVlXG4gICAgICpcbiAgICAgKiBUaGlzIHNldHRpbmcgaXMgYXZhaWxhYmxlIG9ubHkgaW4gV2ViQXNzZW1ibHkgYmFja2VuZC4gV2lsbCBzdXBwb3J0IE5vZGUuanMgYmluZGluZyBhbmQgcmVhY3QtbmF0aXZlIGxhdGVyXG4gICAgICovXG4gICAgdGVybWluYXRlPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEEgdGFnIGZvciB0aGUgUnVuKCkgY2FsbHMgdXNpbmcgdGhpc1xuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIE9OTlhSdW50aW1lIChOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSkgb3IgV2ViQXNzZW1ibHkgYmFja2VuZFxuICAgICAqL1xuICAgIHRhZz86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFNldCBhIHNpbmdsZSBydW4gY29uZmlndXJhdGlvbiBlbnRyeS4gU2VlXG4gICAgICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9vbm54cnVudGltZS9ibG9iL21haW4vaW5jbHVkZS9vbm54cnVudGltZS9jb3JlL3Nlc3Npb24vXG4gICAgICogb25ueHJ1bnRpbWVfcnVuX29wdGlvbnNfY29uZmlnX2tleXMuaFxuICAgICAqXG4gICAgICogVGhpcyBzZXR0aW5nIGlzIGF2YWlsYWJsZSBvbmx5IGluIFdlYkFzc2VtYmx5IGJhY2tlbmQuIFdpbGwgc3VwcG9ydCBOb2RlLmpzIGJpbmRpbmcgYW5kIHJlYWN0LW5hdGl2ZSBsYXRlclxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogZXh0cmE6IHtcbiAgICAgKiAgIG1lbW9yeToge1xuICAgICAqICAgICBlbmFibGVfbWVtb3J5X2FyZW5hX3Nocmlua2FnZTogXCIxXCIsXG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGV4dHJhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiB2YWx1ZSBtZXRhZGF0YVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktaW50ZXJmYWNlXG4gIGludGVyZmFjZSBWYWx1ZU1ldGFkYXRhIHtcbiAgICAvLyBUQkRcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cbn1cblxuLyoqXG4gKiBSZXByZXNlbnQgYSBydW50aW1lIGluc3RhbmNlIG9mIGFuIE9OTlggbW9kZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlU2Vzc2lvbiB7XG4gIC8vICNyZWdpb24gcnVuKClcblxuICAvKipcbiAgICogRXhlY3V0ZSB0aGUgbW9kZWwgYXN5bmNocm9ub3VzbHkgd2l0aCB0aGUgZ2l2ZW4gZmVlZHMgYW5kIG9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmZWVkcyAtIFJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlbCBpbnB1dC4gU2VlIHR5cGUgZGVzY3JpcHRpb24gb2YgYEluZmVyZW5jZVNlc3Npb24uSW5wdXRUeXBlYCBmb3IgZGV0YWlsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsLiBBIHNldCBvZiBvcHRpb25zIHRoYXQgY29udHJvbHMgdGhlIGJlaGF2aW9yIG9mIG1vZGVsIGluZmVyZW5jZS5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBtYXAsIHdoaWNoIHVzZXMgb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICovXG4gIHJ1bihmZWVkczogSW5mZXJlbmNlU2Vzc2lvbi5GZWVkc1R5cGUsIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24uUmV0dXJuVHlwZT47XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgdGhlIG1vZGVsIGFzeW5jaHJvbm91c2x5IHdpdGggdGhlIGdpdmVuIGZlZWRzLCBmZXRjaGVzIGFuZCBvcHRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gZmVlZHMgLSBSZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWwgaW5wdXQuIFNlZSB0eXBlIGRlc2NyaXB0aW9uIG9mIGBJbmZlcmVuY2VTZXNzaW9uLklucHV0VHlwZWAgZm9yIGRldGFpbC5cbiAgICogQHBhcmFtIGZldGNoZXMgLSBSZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWwgb3V0cHV0LiBTZWUgdHlwZSBkZXNjcmlwdGlvbiBvZiBgSW5mZXJlbmNlU2Vzc2lvbi5PdXRwdXRUeXBlYCBmb3JcbiAgICogZGV0YWlsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsLiBBIHNldCBvZiBvcHRpb25zIHRoYXQgY29udHJvbHMgdGhlIGJlaGF2aW9yIG9mIG1vZGVsIGluZmVyZW5jZS5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBtYXAsIHdoaWNoIHVzZXMgb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICovXG4gIHJ1bihmZWVkczogSW5mZXJlbmNlU2Vzc2lvbi5GZWVkc1R5cGUsIGZldGNoZXM6IEluZmVyZW5jZVNlc3Npb24uRmV0Y2hlc1R5cGUsXG4gICAgICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uLlJldHVyblR5cGU+O1xuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHJlbGVhc2UoKVxuXG4gIC8qKlxuICAgKiBSZWxlYXNlIHRoZSBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgdGhlIHVuZGVybHlpbmcgcmVzb3VyY2VzLlxuICAgKi9cbiAgcmVsZWFzZSgpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHByb2ZpbGluZ1xuXG4gIC8qKlxuICAgKiBTdGFydCBwcm9maWxpbmcuXG4gICAqL1xuICBzdGFydFByb2ZpbGluZygpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBFbmQgcHJvZmlsaW5nLlxuICAgKi9cbiAgZW5kUHJvZmlsaW5nKCk6IHZvaWQ7XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gbWV0YWRhdGFcblxuICAvKipcbiAgICogR2V0IGlucHV0IG5hbWVzIG9mIHRoZSBsb2FkZWQgbW9kZWwuXG4gICAqL1xuICByZWFkb25seSBpbnB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKipcbiAgICogR2V0IG91dHB1dCBuYW1lcyBvZiB0aGUgbG9hZGVkIG1vZGVsLlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8vIC8qKlxuICAvLyAgKiBHZXQgaW5wdXQgbWV0YWRhdGEgb2YgdGhlIGxvYWRlZCBtb2RlbC5cbiAgLy8gICovXG4gIC8vIHJlYWRvbmx5IGlucHV0TWV0YWRhdGE6IFJlYWRvbmx5QXJyYXk8UmVhZG9ubHk8SW5mZXJlbmNlU2Vzc2lvbi5WYWx1ZU1ldGFkYXRhPj47XG5cbiAgLy8gLyoqXG4gIC8vICAqIEdldCBvdXRwdXQgbWV0YWRhdGEgb2YgdGhlIGxvYWRlZCBtb2RlbC5cbiAgLy8gICovXG4gIC8vIHJlYWRvbmx5IG91dHB1dE1ldGFkYXRhOiBSZWFkb25seUFycmF5PFJlYWRvbmx5PEluZmVyZW5jZVNlc3Npb24uVmFsdWVNZXRhZGF0YT4+O1xuXG4gIC8vICNlbmRyZWdpb25cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbmZlcmVuY2VTZXNzaW9uRmFjdG9yeSB7XG4gIC8vICNyZWdpb24gY3JlYXRlKClcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uIGFuZCBsb2FkIG1vZGVsIGFzeW5jaHJvbm91c2x5IGZyb20gYW4gT05OWCBtb2RlbCBmaWxlLlxuICAgKlxuICAgKiBAcGFyYW0gdXJpIC0gVGhlIFVSSSBvciBmaWxlIHBhdGggb2YgdGhlIG1vZGVsIHRvIGxvYWQuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gc3BlY2lmeSBjb25maWd1cmF0aW9uIGZvciBjcmVhdGluZyBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gSW5mZXJlbmNlU2Vzc2lvbiBvYmplY3QuXG4gICAqL1xuICBjcmVhdGUodXJpOiBzdHJpbmcsIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uPjtcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGluZmVyZW5jZSBzZXNzaW9uIGFuZCBsb2FkIG1vZGVsIGFzeW5jaHJvbm91c2x5IGZyb20gYW4gYXJyYXkgYnVmZXIuXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSBBbiBBcnJheUJ1ZmZlciByZXByZXNlbnRhdGlvbiBvZiBhbiBPTk5YIG1vZGVsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgY3JlYXRpbmcgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEluZmVyZW5jZVNlc3Npb24gb2JqZWN0LlxuICAgKi9cbiAgY3JlYXRlKGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbj47XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgbG9hZCBtb2RlbCBhc3luY2hyb25vdXNseSBmcm9tIHNlZ21lbnQgb2YgYW4gYXJyYXkgYnVmZXIuXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSBBbiBBcnJheUJ1ZmZlciByZXByZXNlbnRhdGlvbiBvZiBhbiBPTk5YIG1vZGVsLlxuICAgKiBAcGFyYW0gYnl0ZU9mZnNldCAtIFRoZSBiZWdpbm5pbmcgb2YgdGhlIHNwZWNpZmllZCBwb3J0aW9uIG9mIHRoZSBhcnJheSBidWZmZXIuXG4gICAqIEBwYXJhbSBieXRlTGVuZ3RoIC0gVGhlIGxlbmd0aCBpbiBieXRlcyBvZiB0aGUgYXJyYXkgYnVmZmVyLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgY3JlYXRpbmcgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEluZmVyZW5jZVNlc3Npb24gb2JqZWN0LlxuICAgKi9cbiAgY3JlYXRlKGJ1ZmZlcjogQXJyYXlCdWZmZXJMaWtlLCBieXRlT2Zmc2V0OiBudW1iZXIsIGJ5dGVMZW5ndGg/OiBudW1iZXIsIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTpcbiAgICAgIFByb21pc2U8SW5mZXJlbmNlU2Vzc2lvbj47XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBpbmZlcmVuY2Ugc2Vzc2lvbiBhbmQgbG9hZCBtb2RlbCBhc3luY2hyb25vdXNseSBmcm9tIGEgVWludDhBcnJheS5cbiAgICpcbiAgICogQHBhcmFtIGJ1ZmZlciAtIEEgVWludDhBcnJheSByZXByZXNlbnRhdGlvbiBvZiBhbiBPTk5YIG1vZGVsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgY3JlYXRpbmcgYSBuZXcgaW5mZXJlbmNlIHNlc3Npb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEluZmVyZW5jZVNlc3Npb24gb2JqZWN0LlxuICAgKi9cbiAgY3JlYXRlKGJ1ZmZlcjogVWludDhBcnJheSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24+O1xuXG4gIC8vICNlbmRyZWdpb25cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IEluZmVyZW5jZVNlc3Npb246IEluZmVyZW5jZVNlc3Npb25GYWN0b3J5ID0gSW5mZXJlbmNlU2Vzc2lvbkltcGw7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7T3B0aW9uc0Zvcm1hdCwgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzLCBPcHRpb25zVGVuc29yTGF5b3V0fSBmcm9tICcuL3RlbnNvci1mYWN0b3J5LmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JUb0RhdGFVcmxPcHRpb25zIGV4dGVuZHMgT3B0aW9uc1RlbnNvckxheW91dCwgT3B0aW9uc0Zvcm1hdCwgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yVG9JbWFnZURhdGFPcHRpb25zIGV4dGVuZHMgT3B0aW9uc1RlbnNvckxheW91dCwgT3B0aW9uc0Zvcm1hdCwgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udmVyc2lvblV0aWxzIHtcbiAgLyoqXG4gICAqIGNyZWF0ZXMgYSBEYXRhVVJMIGluc3RhbmNlIGZyb20gdGVuc29yXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyBhIERhdGFVUkwgaW5zdGFuY2UgZnJvbSB0aGUgdGVuc29yLlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGBmb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIEByZXR1cm5zIGEgRGF0YVVSTCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBpbWFnZSBjb252ZXJ0ZWQgZnJvbSB0ZW5zb3IgZGF0YVxuICAgKi9cbiAgdG9EYXRhVVJMKG9wdGlvbnM/OiBUZW5zb3JUb0RhdGFVcmxPcHRpb25zKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBjcmVhdGVzIGFuIEltYWdlRGF0YSBpbnN0YW5jZSBmcm9tIHRlbnNvclxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgYW4gSW1hZ2VEYXRhIGluc3RhbmNlIGZyb20gdGhlIHRlbnNvci5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBkZWZhdWx0IHNldHRpbmdzIHdpbGwgYmUgYXBwbGllZDpcbiAgICogLSBgZm9ybWF0YDogYCdSR0InYFxuICAgKiAtIGB0ZW5zb3JMYXlvdXRgOiBgJ05DSFcnYFxuICAgKiBAcmV0dXJucyBhbiBJbWFnZURhdGEgaW5zdGFuY2UgcmVwcmVzZW50aW5nIHRoZSBpbWFnZSBjb252ZXJ0ZWQgZnJvbSB0ZW5zb3IgZGF0YVxuICAgKi9cbiAgdG9JbWFnZURhdGEob3B0aW9ucz86IFRlbnNvclRvSW1hZ2VEYXRhT3B0aW9ucyk6IEltYWdlRGF0YTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3IsIFR5cGVkVGVuc29yfSBmcm9tICcuL3RlbnNvci5qcyc7XG5cbmV4cG9ydCB0eXBlIEltYWdlRm9ybWF0ID0gJ1JHQid8J1JHQkEnfCdCR1InfCdSQkcnO1xuZXhwb3J0IHR5cGUgSW1hZ2VUZW5zb3JMYXlvdXQgPSAnTkhXQyd8J05DSFcnO1xuXG4vLyB0aGUgZm9sbG93aW5nIHJlZ2lvbiBjb250YWlucyB0eXBlIGRlZmluaXRpb25zIGZvciBjb25zdHJ1Y3RpbmcgdGVuc29yIGZyb20gYSBzcGVjaWZpYyBsb2NhdGlvbi5cblxuLy8gI3JlZ2lvbiB0eXBlcyBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBzcGVjaWZpYyBsb2NhdGlvblxuXG4vKipcbiAqIHJlcHJlc2VudCBjb21tb24gcHJvcGVydGllcyBvZiB0aGUgcGFyYW1ldGVyIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIHNwZWNpZmljIGxvY2F0aW9uLlxuICovXG5pbnRlcmZhY2UgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IGV4dGVuZHMgUGljazxUZW5zb3IsICdkaW1zJz4ge1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgZGF0YSB0eXBlIG9mIHRoZSB0ZW5zb3IuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiBUO1xufVxuXG4vKipcbiAqIHJlcHJlc2VudCB0aGUgcGFyYW1ldGVyIGZvciBjb25zdHJ1Y3RpbmcgYSB0ZW5zb3IgZnJvbSBhIEdQVSByZXNvdXJjZS5cbiAqL1xuaW50ZXJmYWNlIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQgZXh0ZW5kcyBUZW5zb3IuVHlwZT4ge1xuICAvKipcbiAgICogYW4gb3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24gdG8gZG93bmxvYWQgZGF0YSBmcm9tIEdQVSB0byBDUFUuXG4gICAqXG4gICAqIElmIG5vdCBwcm92aWRlZCwgdGhlIHRlbnNvciB0cmVhdCB0aGUgR1BVIGRhdGEgYXMgZXh0ZXJuYWwgcmVzb3VyY2UuXG4gICAqL1xuICBkb3dubG9hZD8oKTogUHJvbWlzZTxUZW5zb3IuRGF0YVR5cGVNYXBbVF0+O1xuXG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBjYWxsYmFjayBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIHRlbnNvciBpcyBkaXNwb3NlZC5cbiAgICpcbiAgICogSWYgbm90IHByb3ZpZGVkLCB0aGUgdGVuc29yIHRyZWF0IHRoZSBHUFUgZGF0YSBhcyBleHRlcm5hbCByZXNvdXJjZS5cbiAgICovXG4gIGRpc3Bvc2U/KCk6IHZvaWQ7XG59XG5cbi8qKlxuICogcmVwcmVzZW50IHRoZSBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgcGlubmVkIENQVSBidWZmZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDcHVQaW5uZWRDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VCBleHRlbmRzIFRlbnNvci5DcHVQaW5uZWREYXRhVHlwZXMgPSBUZW5zb3IuQ3B1UGlubmVkRGF0YVR5cGVzPiBleHRlbmRzXG4gICAgQ29tbW9uQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIHRvIGJlICdjcHUtcGlubmVkJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAnY3B1LXBpbm5lZCc7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBDUFUgcGlubmVkIGJ1ZmZlciB0aGF0IGhvbGRzIHRoZSB0ZW5zb3IgZGF0YS5cbiAgICovXG4gIHJlYWRvbmx5IGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUXTtcbn1cblxuLyoqXG4gKiByZXByZXNlbnQgdGhlIHBhcmFtZXRlciBmb3IgY29uc3RydWN0aW5nIGEgdGVuc29yIGZyb20gYSBXZWJHTCB0ZXh0dXJlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLlRleHR1cmVEYXRhVHlwZXMgPSBUZW5zb3IuVGV4dHVyZURhdGFUeXBlcz4gZXh0ZW5kc1xuICAgIENvbW1vbkNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiwgR3B1UmVzb3VyY2VDb25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4ge1xuICAvKipcbiAgICogU3BlY2lmeSB0aGUgbG9jYXRpb24gb2YgdGhlIGRhdGEgdG8gYmUgJ3RleHR1cmUnLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9jYXRpb246ICd0ZXh0dXJlJztcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIFdlYkdMIHRleHR1cmUgdGhhdCBob2xkcyB0aGUgdGVuc29yIGRhdGEuXG4gICAqL1xuICByZWFkb25seSB0ZXh0dXJlOiBUZW5zb3IuVGV4dHVyZVR5cGU7XG59XG5cbi8qKlxuICogcmVwcmVzZW50IHRoZSBwYXJhbWV0ZXIgZm9yIGNvbnN0cnVjdGluZyBhIHRlbnNvciBmcm9tIGEgV2ViR1BVIGJ1ZmZlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdwdUJ1ZmZlckNvbnN0cnVjdG9yUGFyYW1ldGVyczxUIGV4dGVuZHMgVGVuc29yLkdwdUJ1ZmZlckRhdGFUeXBlcyA9IFRlbnNvci5HcHVCdWZmZXJEYXRhVHlwZXM+IGV4dGVuZHNcbiAgICBDb21tb25Db25zdHJ1Y3RvclBhcmFtZXRlcnM8VD4sIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+IHtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIHRvIGJlICdncHUtYnVmZmVyJy5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2F0aW9uOiAnZ3B1LWJ1ZmZlcic7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBXZWJHUFUgYnVmZmVyIHRoYXQgaG9sZHMgdGhlIHRlbnNvciBkYXRhLlxuICAgKi9cbiAgcmVhZG9ubHkgZ3B1QnVmZmVyOiBUZW5zb3IuR3B1QnVmZmVyVHlwZTtcbn1cblxuLy8gI2VuZHJlZ2lvblxuXG4vLyB0aGUgZm9sbG93aW5nIHJlZ2lvbiBjb250YWlucyB0eXBlIGRlZmluaXRpb25zIG9mIGVhY2ggaW5kaXZpZHVhbCBvcHRpb25zLlxuLy8gdGhlIHRlbnNvciBmYWN0b3J5IGZ1bmN0aW9ucyB1c2UgYSBjb21wb3NpdGlvbiBvZiB0aG9zZSBvcHRpb25zIGFzIHRoZSBwYXJhbWV0ZXIgdHlwZS5cblxuLy8gI3JlZ2lvbiBPcHRpb25zIGZpZWxkc1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNGb3JtYXQge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBmb3JtYXQgcmVwcmVzZW50ZWQgaW4gUkdCQSBjb2xvciBzcGFjZS5cbiAgICovXG4gIGZvcm1hdD86IEltYWdlRm9ybWF0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNUZW5zb3JGb3JtYXQge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBpbWFnZSBmb3JtYXQgb2YgdGhlIHRlbnNvci5cbiAgICpcbiAgICogTk9URTogdGhpcyBpcyBkaWZmZXJlbnQgZnJvbSBvcHRpb24gJ2Zvcm1hdCcuIFdoaWxlIG9wdGlvbiAnZm9ybWF0JyByZXByZXNlbnRzIHRoZSBvcmlnaW5hbCBpbWFnZSwgJ3RlbnNvckZvcm1hdCdcbiAgICogcmVwcmVzZW50cyB0aGUgdGFyZ2V0IGZvcm1hdCBvZiB0aGUgdGVuc29yLiBBIHRyYW5zcG9zZSB3aWxsIGJlIHBlcmZvcm1lZCBpZiB0aGV5IGFyZSBkaWZmZXJlbnQuXG4gICAqL1xuICB0ZW5zb3JGb3JtYXQ/OiBJbWFnZUZvcm1hdDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zVGVuc29yRGF0YVR5cGUge1xuICAvKipcbiAgICogRGVzY3JpYmVzIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHRlbnNvci5cbiAgICovXG4gIGRhdGFUeXBlPzogJ2Zsb2F0MzInfCd1aW50OCc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uc1RlbnNvckxheW91dCB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIHRlbnNvciBsYXlvdXQgd2hlbiByZXByZXNlbnRpbmcgZGF0YSBvZiBvbmUgb3IgbW9yZSBpbWFnZShzKS5cbiAgICovXG4gIHRlbnNvckxheW91dD86IEltYWdlVGVuc29yTGF5b3V0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnNEaW1lbnNpb25zIHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyB0aGUgaW1hZ2UgaGVpZ2h0IGluIHBpeGVsXG4gICAqL1xuICBoZWlnaHQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIGltYWdlIHdpZHRoIGluIHBpeGVsXG4gICAqL1xuICB3aWR0aD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcHRpb25SZXNpemVkRGltZW5zaW9ucyB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIHJlc2l6ZWQgaGVpZ2h0LiBJZiBvbWl0dGVkLCBvcmlnaW5hbCBoZWlnaHQgd2lsbCBiZSB1c2VkLlxuICAgKi9cbiAgcmVzaXplZEhlaWdodD86IG51bWJlcjtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyByZXNpemVkIHdpZHRoIC0gY2FuIGJlIGFjY2Vzc2VkIHZpYSB0ZW5zb3IgZGltZW5zaW9ucyBhcyB3ZWxsXG4gICAqL1xuICByZXNpemVkV2lkdGg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9uc05vcm1hbGl6YXRpb25QYXJhbWV0ZXJzIHtcbiAgLyoqXG4gICAqIERlc2NyaWJlcyBub3JtYWxpemF0aW9uIHBhcmFtZXRlcnMgd2hlbiBwcmVwcm9jZXNzaW5nIHRoZSBpbWFnZSBhcyBtb2RlbCBpbnB1dC5cbiAgICpcbiAgICogRGF0YSBlbGVtZW50IGFyZSByYW5nZWQgZnJvbSAwIHRvIDI1NS5cbiAgICovXG4gIG5vcm0/OiB7XG4gICAgLyoqXG4gICAgICogVGhlICdiaWFzJyB2YWx1ZSBmb3IgaW1hZ2Ugbm9ybWFsaXphdGlvbi5cbiAgICAgKiAtIElmIG9taXR0ZWQsIHVzZSBkZWZhdWx0IHZhbHVlIDAuXG4gICAgICogLSBJZiBpdCdzIGEgc2luZ2xlIG51bWJlciwgYXBwbHkgdG8gZWFjaCBjaGFubmVsXG4gICAgICogLSBJZiBpdCdzIGFuIGFycmF5IG9mIDMgb3IgNCBudW1iZXJzLCBhcHBseSBlbGVtZW50LXdpc2UuIE51bWJlciBvZiBlbGVtZW50cyBuZWVkIHRvIG1hdGNoIHRoZSBudW1iZXIgb2YgY2hhbm5lbHNcbiAgICAgKiBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgaW1hZ2UgZm9ybWF0XG4gICAgICovXG4gICAgYmlhcz86IG51bWJlcnxbbnVtYmVyLCBudW1iZXIsIG51bWJlcl18W251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgLyoqXG4gICAgICogVGhlICdtZWFuJyB2YWx1ZSBmb3IgaW1hZ2Ugbm9ybWFsaXphdGlvbi5cbiAgICAgKiAtIElmIG9taXR0ZWQsIHVzZSBkZWZhdWx0IHZhbHVlIDI1NS5cbiAgICAgKiAtIElmIGl0J3MgYSBzaW5nbGUgbnVtYmVyLCBhcHBseSB0byBlYWNoIGNoYW5uZWxcbiAgICAgKiAtIElmIGl0J3MgYW4gYXJyYXkgb2YgMyBvciA0IG51bWJlcnMsIGFwcGx5IGVsZW1lbnQtd2lzZS4gTnVtYmVyIG9mIGVsZW1lbnRzIG5lZWQgdG8gbWF0Y2ggdGhlIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAqIGZvciB0aGUgY29ycmVzcG9uZGluZyBpbWFnZSBmb3JtYXRcbiAgICAgKi9cbiAgICBtZWFuPzogbnVtYmVyIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gIH07XG59XG5cbi8vICNlbmRyZWdpb25cblxuLy8gI3JlZ2lvbiBPcHRpb25zIGNvbXBvc2l0aW9uXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29yRnJvbUltYWdlRGF0YU9wdGlvbnMgZXh0ZW5kcyBPcHRpb25SZXNpemVkRGltZW5zaW9ucywgT3B0aW9uc1RlbnNvckZvcm1hdCwgT3B0aW9uc1RlbnNvckxheW91dCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21JbWFnZUVsZW1lbnRPcHRpb25zIGV4dGVuZHMgT3B0aW9uUmVzaXplZERpbWVuc2lvbnMsIE9wdGlvbnNUZW5zb3JGb3JtYXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uc1RlbnNvckxheW91dCwgT3B0aW9uc1RlbnNvckRhdGFUeXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21VcmxPcHRpb25zIGV4dGVuZHMgT3B0aW9uc0RpbWVuc2lvbnMsIE9wdGlvblJlc2l6ZWREaW1lbnNpb25zLCBPcHRpb25zVGVuc29yRm9ybWF0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbnNUZW5zb3JMYXlvdXQsIE9wdGlvbnNUZW5zb3JEYXRhVHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25zTm9ybWFsaXphdGlvblBhcmFtZXRlcnMge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tSW1hZ2VCaXRtYXBPcHRpb25zIGV4dGVuZHMgT3B0aW9uUmVzaXplZERpbWVuc2lvbnMsIE9wdGlvbnNUZW5zb3JGb3JtYXQsIE9wdGlvbnNUZW5zb3JMYXlvdXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25zVGVuc29yRGF0YVR5cGUsIE9wdGlvbnNOb3JtYWxpemF0aW9uUGFyYW1ldGVycyB7fVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZyb21UZXh0dXJlT3B0aW9uczxUIGV4dGVuZHMgVGVuc29yLlRleHR1cmVEYXRhVHlwZXM+IGV4dGVuZHNcbiAgICBSZXF1aXJlZDxPcHRpb25zRGltZW5zaW9ucz4sIE9wdGlvbnNGb3JtYXQsIEdwdVJlc291cmNlQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFQ+LyogVE9ETzogYWRkIG1vcmUgKi8ge31cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JGcm9tR3B1QnVmZmVyT3B0aW9uczxUIGV4dGVuZHMgVGVuc29yLkdwdUJ1ZmZlckRhdGFUeXBlcz4gZXh0ZW5kc1xuICAgIFBpY2s8VGVuc29yLCAnZGltcyc+LCBHcHVSZXNvdXJjZUNvbnN0cnVjdG9yUGFyYW1ldGVyczxUPiB7XG4gIC8qKlxuICAgKiBEZXNjcmliZXMgdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLlxuICAgKi9cbiAgZGF0YVR5cGU/OiBUO1xufVxuXG4vLyAjZW5kcmVnaW9uXG5cbi8qKlxuICogdHlwZSBUZW5zb3JGYWN0b3J5IGRlZmluZXMgdGhlIGZhY3RvcnkgZnVuY3Rpb25zIG9mICdUZW5zb3InIHRvIGNyZWF0ZSB0ZW5zb3IgaW5zdGFuY2VzIGZyb20gZXhpc3RpbmcgZGF0YSBvclxuICogcmVzb3VyY2VzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRlbnNvckZhY3Rvcnkge1xuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYW4gSW1hZ2VEYXRhIG9iamVjdFxuICAgKlxuICAgKiBAcGFyYW0gaW1hZ2VEYXRhIC0gdGhlIEltYWdlRGF0YSBvYmplY3QgdG8gY3JlYXRlIHRlbnNvciBmcm9tXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBJbWFnZURhdGEuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZShpbWFnZURhdGE6IEltYWdlRGF0YSwgb3B0aW9ucz86IFRlbnNvckZyb21JbWFnZURhdGFPcHRpb25zKTpcbiAgICAgIFByb21pc2U8VHlwZWRUZW5zb3I8J2Zsb2F0MzInPnxUeXBlZFRlbnNvcjwndWludDgnPj47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIHRlbnNvciBmcm9tIGEgSFRNTEltYWdlRWxlbWVudCBvYmplY3RcbiAgICpcbiAgICogQHBhcmFtIGltYWdlRWxlbWVudCAtIHRoZSBIVE1MSW1hZ2VFbGVtZW50IG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIEhUTUxJbWFnZUVsZW1lbnQuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZShpbWFnZUVsZW1lbnQ6IEhUTUxJbWFnZUVsZW1lbnQsIG9wdGlvbnM/OiBUZW5zb3JGcm9tSW1hZ2VFbGVtZW50T3B0aW9ucyk6XG4gICAgICBQcm9taXNlPFR5cGVkVGVuc29yPCdmbG9hdDMyJz58VHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBVUkxcbiAgICpcbiAgICogQHBhcmFtIHVybFNvdXJjZSAtIGEgc3RyaW5nIGFzIGEgVVJMIHRvIHRoZSBpbWFnZSBvciBhIGRhdGEgVVJMIGNvbnRhaW5pbmcgdGhlIGltYWdlIGRhdGEuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW4gb3B0aW9uYWwgb2JqZWN0IHJlcHJlc2VudGluZyBvcHRpb25zIGZvciBjcmVhdGluZyB0ZW5zb3IgZnJvbSBVUkwuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgZGVmYXVsdCBzZXR0aW5ncyB3aWxsIGJlIGFwcGxpZWQ6XG4gICAqIC0gYHRlbnNvckZvcm1hdGA6IGAnUkdCJ2BcbiAgICogLSBgdGVuc29yTGF5b3V0YDogYCdOQ0hXJ2BcbiAgICogLSBgZGF0YVR5cGVgOiBgJ2Zsb2F0MzInYFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIHRlbnNvciBvYmplY3RcbiAgICovXG4gIGZyb21JbWFnZSh1cmxTb3VyY2U6IHN0cmluZywgb3B0aW9ucz86IFRlbnNvckZyb21VcmxPcHRpb25zKTogUHJvbWlzZTxUeXBlZFRlbnNvcjwnZmxvYXQzMic+fFR5cGVkVGVuc29yPCd1aW50OCc+PjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYW4gSW1hZ2VCaXRtYXAgb2JqZWN0XG4gICAqXG4gICAqIEBwYXJhbSBiaXRtYXAgLSB0aGUgSW1hZ2VCaXRtYXAgb2JqZWN0IHRvIGNyZWF0ZSB0ZW5zb3IgZnJvbVxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuIG9wdGlvbmFsIG9iamVjdCByZXByZXNlbnRpbmcgb3B0aW9ucyBmb3IgY3JlYXRpbmcgdGVuc29yIGZyb20gVVJMLlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGRlZmF1bHQgc2V0dGluZ3Mgd2lsbCBiZSBhcHBsaWVkOlxuICAgKiAtIGB0ZW5zb3JGb3JtYXRgOiBgJ1JHQidgXG4gICAqIC0gYHRlbnNvckxheW91dGA6IGAnTkNIVydgXG4gICAqIC0gYGRhdGFUeXBlYDogYCdmbG9hdDMyJ2BcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tSW1hZ2UoYml0bWFwOiBJbWFnZUJpdG1hcCwgb3B0aW9uczogVGVuc29yRnJvbUltYWdlQml0bWFwT3B0aW9ucyk6XG4gICAgICBQcm9taXNlPFR5cGVkVGVuc29yPCdmbG9hdDMyJz58VHlwZWRUZW5zb3I8J3VpbnQ4Jz4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYSB0ZW5zb3IgZnJvbSBhIFdlYkdMIHRleHR1cmVcbiAgICpcbiAgICogQHBhcmFtIHRleHR1cmUgLSB0aGUgV2ViR0xUZXh0dXJlIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIFdlYkdMIHRleHR1cmUuXG4gICAqXG4gICAqIFRoZSBvcHRpb25zIGluY2x1ZGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gICAqIC0gYHdpZHRoYDogdGhlIHdpZHRoIG9mIHRoZSB0ZXh0dXJlLiBSZXF1aXJlZC5cbiAgICogLSBgaGVpZ2h0YDogdGhlIGhlaWdodCBvZiB0aGUgdGV4dHVyZS4gUmVxdWlyZWQuXG4gICAqIC0gYGZvcm1hdGA6IHRoZSBmb3JtYXQgb2YgdGhlIHRleHR1cmUuIElmIG9taXR0ZWQsIGFzc3VtZSAnUkdCQScuXG4gICAqIC0gYGRvd25sb2FkYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZG93bmxvYWQgdGhlIHRlbnNvciBkYXRhIGZyb20gR1BVIHRvIENQVS4gSWYgb21pdHRlZCwgdGhlIEdQVSBkYXRhXG4gICAqIHdpbGwgbm90IGJlIGFibGUgdG8gZG93bmxvYWQuIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgYSBHUFUgYmFja2VuZCBmb3IgdGhlIGluZmVyZW5jZSBvdXRwdXRzLiBVc2VycyBkb24ndFxuICAgKiBuZWVkIHRvIHByb3ZpZGUgdGhpcyBmdW5jdGlvbi5cbiAgICogLSBgZGlzcG9zZWA6IGFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGRpc3Bvc2UgdGhlIHRlbnNvciBkYXRhIG9uIEdQVS4gSWYgb21pdHRlZCwgdGhlIEdQVSBkYXRhIHdpbGwgbm90IGJlIGRpc3Bvc2VkLlxuICAgKiBVc3VhbGx5LCB0aGlzIGlzIHByb3ZpZGVkIGJ5IGEgR1BVIGJhY2tlbmQgZm9yIHRoZSBpbmZlcmVuY2Ugb3V0cHV0cy4gVXNlcnMgZG9uJ3QgbmVlZCB0byBwcm92aWRlIHRoaXMgZnVuY3Rpb24uXG4gICAqXG4gICAqIEByZXR1cm5zIGEgdGVuc29yIG9iamVjdFxuICAgKi9cbiAgZnJvbVRleHR1cmU8VCBleHRlbmRzIFRlbnNvci5UZXh0dXJlRGF0YVR5cGVzID0gJ2Zsb2F0MzInPihcbiAgICAgIHRleHR1cmU6IFRlbnNvci5UZXh0dXJlVHlwZSwgb3B0aW9uczogVGVuc29yRnJvbVRleHR1cmVPcHRpb25zPFQ+KTogVHlwZWRUZW5zb3I8J2Zsb2F0MzInPjtcblxuICAvKipcbiAgICogY3JlYXRlIGEgdGVuc29yIGZyb20gYSBXZWJHUFUgYnVmZmVyXG4gICAqXG4gICAqIEBwYXJhbSBidWZmZXIgLSB0aGUgR1BVQnVmZmVyIG9iamVjdCB0byBjcmVhdGUgdGVuc29yIGZyb21cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBBbiBvcHRpb25hbCBvYmplY3QgcmVwcmVzZW50aW5nIG9wdGlvbnMgZm9yIGNyZWF0aW5nIHRlbnNvciBmcm9tIFdlYkdQVSBidWZmZXIuXG4gICAqXG4gICAqIFRoZSBvcHRpb25zIGluY2x1ZGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gICAqIC0gYGRhdGFUeXBlYDogdGhlIGRhdGEgdHlwZSBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhc3N1bWUgJ2Zsb2F0MzInLlxuICAgKiAtIGBkaW1zYDogdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBSZXF1aXJlZC5cbiAgICogLSBgZG93bmxvYWRgOiBhbiBvcHRpb25hbCBmdW5jdGlvbiB0byBkb3dubG9hZCB0aGUgdGVuc29yIGRhdGEgZnJvbSBHUFUgdG8gQ1BVLiBJZiBvbWl0dGVkLCB0aGUgR1BVIGRhdGFcbiAgICogd2lsbCBub3QgYmUgYWJsZSB0byBkb3dubG9hZC4gVXN1YWxseSwgdGhpcyBpcyBwcm92aWRlZCBieSBhIEdQVSBiYWNrZW5kIGZvciB0aGUgaW5mZXJlbmNlIG91dHB1dHMuIFVzZXJzIGRvbid0XG4gICAqIG5lZWQgdG8gcHJvdmlkZSB0aGlzIGZ1bmN0aW9uLlxuICAgKiAtIGBkaXNwb3NlYDogYW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZGlzcG9zZSB0aGUgdGVuc29yIGRhdGEgb24gR1BVLiBJZiBvbWl0dGVkLCB0aGUgR1BVIGRhdGEgd2lsbCBub3QgYmUgZGlzcG9zZWQuXG4gICAqIFVzdWFsbHksIHRoaXMgaXMgcHJvdmlkZWQgYnkgYSBHUFUgYmFja2VuZCBmb3IgdGhlIGluZmVyZW5jZSBvdXRwdXRzLiBVc2VycyBkb24ndCBuZWVkIHRvIHByb3ZpZGUgdGhpcyBmdW5jdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMgYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tR3B1QnVmZmVyPFQgZXh0ZW5kcyBUZW5zb3IuR3B1QnVmZmVyRGF0YVR5cGVzPihcbiAgICAgIGJ1ZmZlcjogVGVuc29yLkdwdUJ1ZmZlclR5cGUsIG9wdGlvbnM6IFRlbnNvckZyb21HcHVCdWZmZXJPcHRpb25zPFQ+KTogVHlwZWRUZW5zb3I8VD47XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhIHRlbnNvciBmcm9tIGEgcHJlLWFsbG9jYXRlZCBidWZmZXIuIFRoZSBidWZmZXIgd2lsbCBiZSB1c2VkIGFzIGEgcGlubmVkIGJ1ZmZlci5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSB0aGUgdGVuc29yIGVsZW1lbnQgdHlwZS5cbiAgICogQHBhcmFtIGJ1ZmZlciAtIGEgVHlwZWRBcnJheSBjb3JyZXNwb25kaW5nIHRvIHRoZSB0eXBlLlxuICAgKiBAcGFyYW0gZGltcyAtIHNwZWNpZnkgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGVuc29yLiBJZiBvbWl0dGVkLCBhIDEtRCB0ZW5zb3IgaXMgYXNzdW1lZC5cbiAgICpcbiAgICogQHJldHVybnMgYSB0ZW5zb3Igb2JqZWN0XG4gICAqL1xuICBmcm9tUGlubmVkQnVmZmVyPFQgZXh0ZW5kcyBFeGNsdWRlPFRlbnNvci5UeXBlLCAnc3RyaW5nJz4+KFxuICAgICAgdHlwZTogVCwgYnVmZmVyOiBUZW5zb3IuRGF0YVR5cGVNYXBbVF0sIGRpbXM/OiByZWFkb25seSBudW1iZXJbXSk6IFR5cGVkVGVuc29yPFQ+O1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKipcbiAqIEEgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyBhIGZpbGUncyBVUkwgb3IgcGF0aC5cbiAqXG4gKiBQYXRoIGlzIHZhaWxhYmxlIG9ubHkgaW4gb25ueHJ1bnRpbWUtbm9kZSBvciBvbm54cnVudGltZS13ZWIgcnVubmluZyBpbiBOb2RlLmpzLlxuICovXG5leHBvcnQgdHlwZSBGaWxlVXJsT3JQYXRoID0gc3RyaW5nO1xuXG4vKipcbiAqIEEgQmxvYiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgZmlsZS5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZUJsb2IgPSBCbG9iO1xuXG4vKipcbiAqIEEgVWludDhBcnJheSwgQXJyYXlCdWZmZXIgb3IgU2hhcmVkQXJyYXlCdWZmZXIgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhIGZpbGUgY29udGVudC5cbiAqXG4gKiBXaGVuIGl0IGlzIGFuIEFycmF5QnVmZmVyIG9yIFNoYXJlZEFycmF5QnVmZmVyLCB0aGUgd2hvbGUgYnVmZmVyIGlzIGFzc3VtZWQgdG8gYmUgdGhlIGZpbGUgY29udGVudC5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZURhdGEgPSBVaW50OEFycmF5fEFycmF5QnVmZmVyTGlrZTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgZmlsZSB0aGF0IGNhbiBiZSBsb2FkZWQgYnkgdGhlIE9OTlggUnVudGltZSBKYXZhU2NyaXB0IEFQSS5cbiAqL1xuZXhwb3J0IHR5cGUgRmlsZVR5cGUgPSBGaWxlVXJsT3JQYXRofEZpbGVCbG9ifEZpbGVEYXRhO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gZXh0ZXJuYWwgZGF0YSBmaWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVybmFsRGF0YUZpbGVEZXNjcmlwdGlvbiB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5IHRoZSBleHRlcm5hbCBkYXRhIGZpbGUuXG4gICAqL1xuICBkYXRhOiBGaWxlVHlwZTtcbiAgLyoqXG4gICAqIFNwZWNpZnkgdGhlIGZpbGUgcGF0aC5cbiAgICovXG4gIHBhdGg6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIGV4dGVybmFsIGRhdGEgZmlsZS5cbiAqXG4gKiBXaGVuIHVzaW5nIGEgc3RyaW5nLCBpdCBzaG91bGQgYmUgYSBmaWxlIFVSTCBvciBwYXRoIHRoYXQgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGFzIHRoZSBtb2RlbCBmaWxlLlxuICovXG5leHBvcnQgdHlwZSBFeHRlcm5hbERhdGFGaWxlVHlwZSA9IEV4dGVybmFsRGF0YUZpbGVEZXNjcmlwdGlvbnxGaWxlVXJsT3JQYXRoO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIG1vZGVsIGxvYWRpbmcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT25ueE1vZGVsT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBTcGVjaWZ5aW5nIGEgbGlzdCBvZiBmaWxlcyB0aGF0IHJlcHJlc2VudHMgdGhlIGV4dGVybmFsIGRhdGEuXG4gICAqL1xuICBleHRlcm5hbERhdGE/OiByZWFkb25seSBFeHRlcm5hbERhdGFGaWxlVHlwZVtdO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi90ZW5zb3IuanMnO1xuXG5leHBvcnQgdHlwZSBOb25UZW5zb3JUeXBlID0gbmV2ZXI7XG5cbi8qKlxuICogVHlwZSBPbm54VmFsdWUgUmVwcmVzZW50cyBib3RoIHRlbnNvcnMgYW5kIG5vbi10ZW5zb3JzIHZhbHVlIGZvciBtb2RlbCdzIGlucHV0cy9vdXRwdXRzLlxuICpcbiAqIE5PVEU6IGN1cnJlbnRseSBub3Qgc3VwcG9ydCBub24tdGVuc29yXG4gKi9cbmV4cG9ydCB0eXBlIE9ubnhWYWx1ZSA9IFRlbnNvcnxOb25UZW5zb3JUeXBlO1xuXG4vKipcbiAqIFR5cGUgT25ueFZhbHVlRGF0YUxvY2F0aW9uIHJlcHJlc2VudHMgdGhlIGxvY2F0aW9uIG9mIHRoZSBkYXRhIG9mIGFuIE9ubnhWYWx1ZS5cbiAqL1xuZXhwb3J0IHR5cGUgT25ueFZhbHVlRGF0YUxvY2F0aW9uID0gVGVuc29yLkRhdGFMb2NhdGlvbjtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtyZXNvbHZlQmFja2VuZEFuZEV4ZWN1dGlvblByb3ZpZGVyc30gZnJvbSAnLi9iYWNrZW5kLWltcGwuanMnO1xuaW1wb3J0IHtTZXNzaW9uSGFuZGxlciwgVHJhaW5pbmdTZXNzaW9uSGFuZGxlcn0gZnJvbSAnLi9iYWNrZW5kLmpzJztcbmltcG9ydCB7SW5mZXJlbmNlU2Vzc2lvbiBhcyBJbmZlcmVuY2VTZXNzaW9ufSBmcm9tICcuL2luZmVyZW5jZS1zZXNzaW9uLmpzJztcbmltcG9ydCB7T25ueFZhbHVlfSBmcm9tICcuL29ubngtdmFsdWUuanMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4vdGVuc29yLmpzJztcbmltcG9ydCB7VHJhaW5pbmdTZXNzaW9uIGFzIFRyYWluaW5nU2Vzc2lvbkludGVyZmFjZSwgVHJhaW5pbmdTZXNzaW9uQ3JlYXRlT3B0aW9uc30gZnJvbSAnLi90cmFpbmluZy1zZXNzaW9uLmpzJztcblxudHlwZSBTZXNzaW9uT3B0aW9ucyA9IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnM7XG50eXBlIEZlZWRzVHlwZSA9IEluZmVyZW5jZVNlc3Npb24uRmVlZHNUeXBlO1xudHlwZSBGZXRjaGVzVHlwZSA9IEluZmVyZW5jZVNlc3Npb24uRmV0Y2hlc1R5cGU7XG50eXBlIFJldHVyblR5cGUgPSBJbmZlcmVuY2VTZXNzaW9uLlJldHVyblR5cGU7XG50eXBlIFJ1bk9wdGlvbnMgPSBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnM7XG5cbmNvbnN0IG5vQmFja2VuZEVyck1zZzogc3RyaW5nID0gJ1RyYWluaW5nIGJhY2tlbmQgY291bGQgbm90IGJlIHJlc29sdmVkLiAnICtcbiAgICAnTWFrZSBzdXJlIHlvdVxcJ3JlIHVzaW5nIHRoZSBjb3JyZWN0IGNvbmZpZ3VyYXRpb24gJiBXZWJBc3NlbWJseSBmaWxlcy4nO1xuXG5leHBvcnQgY2xhc3MgVHJhaW5pbmdTZXNzaW9uIGltcGxlbWVudHMgVHJhaW5pbmdTZXNzaW9uSW50ZXJmYWNlIHtcbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihoYW5kbGVyOiBUcmFpbmluZ1Nlc3Npb25IYW5kbGVyLCBoYXNPcHRpbWl6ZXJNb2RlbDogYm9vbGVhbiwgaGFzRXZhbE1vZGVsOiBib29sZWFuKSB7XG4gICAgdGhpcy5oYW5kbGVyID0gaGFuZGxlcjtcbiAgICB0aGlzLmhhc09wdGltaXplck1vZGVsID0gaGFzT3B0aW1pemVyTW9kZWw7XG4gICAgdGhpcy5oYXNFdmFsTW9kZWwgPSBoYXNFdmFsTW9kZWw7XG4gIH1cbiAgcHJpdmF0ZSBoYW5kbGVyOiBUcmFpbmluZ1Nlc3Npb25IYW5kbGVyO1xuICBwcml2YXRlIGhhc09wdGltaXplck1vZGVsOiBib29sZWFuO1xuICBwcml2YXRlIGhhc0V2YWxNb2RlbDogYm9vbGVhbjtcblxuICBnZXQgdHJhaW5pbmdJbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVyLmlucHV0TmFtZXM7XG4gIH1cbiAgZ2V0IHRyYWluaW5nT3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIub3V0cHV0TmFtZXM7XG4gIH1cblxuICBnZXQgZXZhbElucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIGlmICh0aGlzLmhhc0V2YWxNb2RlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlci5ldmFsSW5wdXROYW1lcztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHRyYWluaW5nIHNlc3Npb24gaGFzIG5vIGV2YWxNb2RlbCBsb2FkZWQuJyk7XG4gICAgfVxuICB9XG4gIGdldCBldmFsT3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIGlmICh0aGlzLmhhc0V2YWxNb2RlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlci5ldmFsT3V0cHV0TmFtZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhpcyB0cmFpbmluZyBzZXNzaW9uIGhhcyBubyBldmFsTW9kZWwgbG9hZGVkLicpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBjcmVhdGUodHJhaW5pbmdPcHRpb25zOiBUcmFpbmluZ1Nlc3Npb25DcmVhdGVPcHRpb25zLCBzZXNzaW9uT3B0aW9ucz86IFNlc3Npb25PcHRpb25zKTpcbiAgICAgIFByb21pc2U8VHJhaW5pbmdTZXNzaW9uPiB7XG4gICAgY29uc3QgZXZhbE1vZGVsOiBzdHJpbmd8VWludDhBcnJheSA9IHRyYWluaW5nT3B0aW9ucy5ldmFsTW9kZWwgfHwgJyc7XG4gICAgY29uc3Qgb3B0aW1pemVyTW9kZWw6IHN0cmluZ3xVaW50OEFycmF5ID0gdHJhaW5pbmdPcHRpb25zLm9wdGltaXplck1vZGVsIHx8ICcnO1xuICAgIGNvbnN0IG9wdGlvbnM6IFNlc3Npb25PcHRpb25zID0gc2Vzc2lvbk9wdGlvbnMgfHwge307XG5cbiAgICAvLyByZXNvbHZlIGJhY2tlbmQsIHVwZGF0ZSBzZXNzaW9uIG9wdGlvbnMgd2l0aCB2YWxpZGF0ZWQgRVBzLCBhbmQgY3JlYXRlIHNlc3Npb24gaGFuZGxlclxuICAgIGNvbnN0IFtiYWNrZW5kLCBvcHRpb25zV2l0aFZhbGlkYXRlZEVQc10gPSBhd2FpdCByZXNvbHZlQmFja2VuZEFuZEV4ZWN1dGlvblByb3ZpZGVycyhvcHRpb25zKTtcbiAgICBpZiAoYmFja2VuZC5jcmVhdGVUcmFpbmluZ1Nlc3Npb25IYW5kbGVyKSB7XG4gICAgICBjb25zdCBoYW5kbGVyID0gYXdhaXQgYmFja2VuZC5jcmVhdGVUcmFpbmluZ1Nlc3Npb25IYW5kbGVyKFxuICAgICAgICAgIHRyYWluaW5nT3B0aW9ucy5jaGVja3BvaW50U3RhdGUsIHRyYWluaW5nT3B0aW9ucy50cmFpbk1vZGVsLCBldmFsTW9kZWwsIG9wdGltaXplck1vZGVsLFxuICAgICAgICAgIG9wdGlvbnNXaXRoVmFsaWRhdGVkRVBzKTtcbiAgICAgIHJldHVybiBuZXcgVHJhaW5pbmdTZXNzaW9uKGhhbmRsZXIsICEhdHJhaW5pbmdPcHRpb25zLm9wdGltaXplck1vZGVsLCAhIXRyYWluaW5nT3B0aW9ucy5ldmFsTW9kZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3Iobm9CYWNrZW5kRXJyTXNnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIGZ1bmN0aW9uIGZvciBydW5UcmFpblN0ZXAgYW5kIGZ1dHVyZSBydW5TdGVwIG1ldGhvZHMgdGhhdCBoYW5kbGVzIHRoZSB0eXBlLW5hcnJvd2luZyBjb252ZXJzaW9uIGZyb21cbiAgICogdGhlIGdpdmVuIHBhcmFtZXRlcnMgdG8gU2Vzc2lvbkhhbmRsZXIuRmV0Y2hlc1R5cGUgYW5kIFJ1bk9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBpbnB1dE5hbWVzIHRoZSBmZWVkcyBvYmplY3QgaXMgY2hlY2tlZCB0aGF0IHRoZXkgY29udGFpbiBhbGwgaW5wdXQgbmFtZXMgaW4gdGhlIHByb3ZpZGVkIGxpc3Qgb2YgaW5wdXRcbiAgICogbmFtZXMuXG4gICAqIEBwYXJhbSBvdXRwdXROYW1lcyB0aGUgZmV0Y2hlcyBvYmplY3QgaXMgY2hlY2tlZCB0aGF0IHRoZWlyIGtleXMgbWF0Y2ggdXAgd2l0aCB2YWxpZCBuYW1lcyBpbiB0aGUgbGlzdCBvZiBvdXRwdXRcbiAgICogbmFtZXMuXG4gICAqIEBwYXJhbSBmZWVkcyB0aGUgcmVxdWlyZWQgaW5wdXRcbiAgICogQHBhcmFtIGFyZzEgbmFycm93ZWQgJiBjb252ZXJ0ZWQgaW50byB0aGUgU2Vzc2lvbkhhbmRsZXIuRmV0Y2hlc1R5cGUgb3IgUnVuT3B0aW9ucyBvYmplY3RcbiAgICogQHBhcmFtIGFyZzIgb3B0aW9uYWwgUnVuT3B0aW9ucyBvYmplY3QuXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICB0eXBlTmFycm93aW5nRm9yUnVuU3RlcChcbiAgICAgIGlucHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdLCBvdXRwdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW10sIGZlZWRzOiBGZWVkc1R5cGUsIGFyZzE/OiBGZXRjaGVzVHlwZXxSdW5PcHRpb25zLFxuICAgICAgYXJnMj86IFJ1bk9wdGlvbnMpOiBbU2Vzc2lvbkhhbmRsZXIuRmV0Y2hlc1R5cGUsIFJ1bk9wdGlvbnNdIHtcbiAgICBjb25zdCBmZXRjaGVzOiB7W25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZXxudWxsfSA9IHt9O1xuICAgIGxldCBvcHRpb25zOiBSdW5PcHRpb25zID0ge307XG4gICAgLy8gY2hlY2sgaW5wdXRzXG4gICAgaWYgKHR5cGVvZiBmZWVkcyAhPT0gJ29iamVjdCcgfHwgZmVlZHMgPT09IG51bGwgfHwgZmVlZHMgaW5zdGFuY2VvZiBUZW5zb3IgfHwgQXJyYXkuaXNBcnJheShmZWVkcykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgJ1xcJ2ZlZWRzXFwnIG11c3QgYmUgYW4gb2JqZWN0IHRoYXQgdXNlIGlucHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nIHZhbHVlcy4nKTtcbiAgICB9XG5cbiAgICBsZXQgaXNGZXRjaGVzRW1wdHkgPSB0cnVlO1xuICAgIC8vIGRldGVybWluZSB3aGljaCBvdmVycmlkZSBpcyBiZWluZyB1c2VkXG4gICAgaWYgKHR5cGVvZiBhcmcxID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKGFyZzEgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5leHBlY3RlZCBhcmd1bWVudFsxXTogY2Fubm90IGJlIG51bGwuJyk7XG4gICAgICB9XG4gICAgICBpZiAoYXJnMSBpbnN0YW5jZW9mIFRlbnNvcikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcXCdmZXRjaGVzXFwnIGNhbm5vdCBiZSBhIFRlbnNvcicpO1xuICAgICAgfVxuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcxKSkge1xuICAgICAgICBpZiAoYXJnMS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcXCdmZXRjaGVzXFwnIGNhbm5vdCBiZSBhbiBlbXB0eSBhcnJheS4nKTtcbiAgICAgICAgfVxuICAgICAgICBpc0ZldGNoZXNFbXB0eSA9IGZhbHNlO1xuICAgICAgICAvLyBvdXRwdXQgbmFtZXNcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIGFyZzEpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcXCdmZXRjaGVzXFwnIG11c3QgYmUgYSBzdHJpbmcgYXJyYXkgb3IgYW4gb2JqZWN0LicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAob3V0cHV0TmFtZXMuaW5kZXhPZihuYW1lKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAnZmV0Y2hlcycgY29udGFpbnMgaW52YWxpZCBvdXRwdXQgbmFtZTogJHtuYW1lfS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZmV0Y2hlc1tuYW1lXSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGFyZzIgPT09ICdvYmplY3QnICYmIGFyZzIgIT09IG51bGwpIHtcbiAgICAgICAgICBvcHRpb25zID0gYXJnMjtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcXCdvcHRpb25zXFwnIG11c3QgYmUgYW4gb2JqZWN0LicpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBkZWNpZGUgd2hldGhlciBhcmcxIGlzIGZldGNoZXMgb3Igb3B0aW9uc1xuICAgICAgICAvLyBpZiBhbnkgb3V0cHV0IG5hbWUgaXMgcHJlc2VudCBhbmQgaXRzIHZhbHVlIGlzIHZhbGlkIE9ubnhWYWx1ZSwgd2UgY29uc2lkZXIgaXQgZmV0Y2hlc1xuICAgICAgICBsZXQgaXNGZXRjaGVzID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGFyZzFLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoYXJnMSk7XG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBvdXRwdXROYW1lcykge1xuICAgICAgICAgIGlmIChhcmcxS2V5cy5pbmRleE9mKG5hbWUpICE9PSAtMSkge1xuICAgICAgICAgICAgY29uc3QgdiA9IChhcmcxIGFzIEluZmVyZW5jZVNlc3Npb24uTnVsbGFibGVPbm54VmFsdWVNYXBUeXBlKVtuYW1lXTtcbiAgICAgICAgICAgIGlmICh2ID09PSBudWxsIHx8IHYgaW5zdGFuY2VvZiBUZW5zb3IpIHtcbiAgICAgICAgICAgICAgaXNGZXRjaGVzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgaXNGZXRjaGVzRW1wdHkgPSBmYWxzZTtcbiAgICAgICAgICAgICAgZmV0Y2hlc1tuYW1lXSA9IHY7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzRmV0Y2hlcykge1xuICAgICAgICAgIGlmICh0eXBlb2YgYXJnMiA9PT0gJ29iamVjdCcgJiYgYXJnMiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgb3B0aW9ucyA9IGFyZzI7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1xcJ29wdGlvbnNcXCcgbXVzdCBiZSBhbiBvYmplY3QuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9wdGlvbnMgPSBhcmcxIGFzIFJ1bk9wdGlvbnM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcxICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5leHBlY3RlZCBhcmd1bWVudFsxXTogbXVzdCBiZSBcXCdmZXRjaGVzXFwnIG9yIFxcJ29wdGlvbnNcXCcuJyk7XG4gICAgfVxuXG4gICAgLy8gY2hlY2sgaWYgYWxsIGlucHV0cyBhcmUgaW4gZmVlZFxuICAgIGZvciAoY29uc3QgbmFtZSBvZiBpbnB1dE5hbWVzKSB7XG4gICAgICBpZiAodHlwZW9mIGZlZWRzW25hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0ICcke25hbWV9JyBpcyBtaXNzaW5nIGluICdmZWVkcycuYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gaWYgbm8gZmV0Y2hlcyBpcyBzcGVjaWZpZWQsIHdlIHVzZSB0aGUgZnVsbCBvdXRwdXQgbmFtZXMgbGlzdFxuICAgIGlmIChpc0ZldGNoZXNFbXB0eSkge1xuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIG91dHB1dE5hbWVzKSB7XG4gICAgICAgIGZldGNoZXNbbmFtZV0gPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbZmV0Y2hlcywgb3B0aW9uc107XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIG1ldGhvZCBmb3IgcnVuVHJhaW5TdGVwIGFuZCBhbnkgb3RoZXIgcnVuU3RlcCBtZXRob2RzLiBUYWtlcyB0aGUgUmV0dXJuVHlwZSByZXN1bHQgZnJvbSB0aGUgU2Vzc2lvbkhhbmRsZXJcbiAgICogYW5kIGNoYW5nZXMgaXQgaW50byBhIG1hcCBvZiBUZW5zb3JzLlxuICAgKlxuICAgKiBAcGFyYW0gcmVzdWx0c1xuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgY29udmVydEhhbmRsZXJSZXR1cm5UeXBlVG9NYXBPZlRlbnNvcnMocmVzdWx0czogU2Vzc2lvbkhhbmRsZXIuUmV0dXJuVHlwZSk6IFJldHVyblR5cGUge1xuICAgIGNvbnN0IHJldHVyblZhbHVlOiB7W25hbWU6IHN0cmluZ106IE9ubnhWYWx1ZX0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiByZXN1bHRzKSB7XG4gICAgICBpZiAoT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwocmVzdWx0cywga2V5KSkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSByZXN1bHRzW2tleV07XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBUZW5zb3IpIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVtrZXldID0gcmVzdWx0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVyblZhbHVlW2tleV0gPSBuZXcgVGVuc29yKHJlc3VsdC50eXBlLCByZXN1bHQuZGF0YSwgcmVzdWx0LmRpbXMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgfVxuXG4gIGFzeW5jIGxhenlSZXNldEdyYWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5oYW5kbGVyLmxhenlSZXNldEdyYWQoKTtcbiAgfVxuXG4gIHJ1blRyYWluU3RlcChmZWVkczogRmVlZHNUeXBlLCBvcHRpb25zPzogUnVuT3B0aW9ucyk6IFByb21pc2U8UmV0dXJuVHlwZT47XG4gIHJ1blRyYWluU3RlcChmZWVkczogRmVlZHNUeXBlLCBmZXRjaGVzOiBGZXRjaGVzVHlwZSwgb3B0aW9ucz86IFJ1bk9wdGlvbnMpOiBQcm9taXNlPFJldHVyblR5cGU+O1xuICBhc3luYyBydW5UcmFpblN0ZXAoZmVlZHM6IEZlZWRzVHlwZSwgYXJnMT86IEZldGNoZXNUeXBlfFJ1bk9wdGlvbnMsIGFyZzI/OiBSdW5PcHRpb25zKTogUHJvbWlzZTxSZXR1cm5UeXBlPiB7XG4gICAgY29uc3QgW2ZldGNoZXMsIG9wdGlvbnNdID1cbiAgICAgICAgdGhpcy50eXBlTmFycm93aW5nRm9yUnVuU3RlcCh0aGlzLnRyYWluaW5nSW5wdXROYW1lcywgdGhpcy50cmFpbmluZ091dHB1dE5hbWVzLCBmZWVkcywgYXJnMSwgYXJnMik7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuaGFuZGxlci5ydW5UcmFpblN0ZXAoZmVlZHMsIGZldGNoZXMsIG9wdGlvbnMpO1xuICAgIHJldHVybiB0aGlzLmNvbnZlcnRIYW5kbGVyUmV0dXJuVHlwZVRvTWFwT2ZUZW5zb3JzKHJlc3VsdHMpO1xuICB9XG5cbiAgYXN5bmMgcnVuT3B0aW1pemVyU3RlcChvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zfHVuZGVmaW5lZCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmhhc09wdGltaXplck1vZGVsKSB7XG4gICAgICBhd2FpdCB0aGlzLmhhbmRsZXIucnVuT3B0aW1pemVyU3RlcChvcHRpb25zIHx8IHt9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIFRyYWluaW5nU2Vzc2lvbiBoYXMgbm8gT3B0aW1pemVyTW9kZWwgbG9hZGVkLicpO1xuICAgIH1cbiAgfVxuXG4gIHJ1bkV2YWxTdGVwKGZlZWRzOiBGZWVkc1R5cGUsIG9wdGlvbnM/OiBSdW5PcHRpb25zfHVuZGVmaW5lZCk6IFByb21pc2U8UmV0dXJuVHlwZT47XG4gIHJ1bkV2YWxTdGVwKGZlZWRzOiBGZWVkc1R5cGUsIGZldGNoZXM6IEZldGNoZXNUeXBlLCBvcHRpb25zPzogUnVuT3B0aW9uc3x1bmRlZmluZWQpOiBQcm9taXNlPFJldHVyblR5cGU+O1xuICBhc3luYyBydW5FdmFsU3RlcChmZWVkczogRmVlZHNUeXBlLCBhcmcxPzogRmV0Y2hlc1R5cGV8UnVuT3B0aW9ucywgYXJnMj86IFJ1bk9wdGlvbnMpOiBQcm9taXNlPFJldHVyblR5cGU+IHtcbiAgICBpZiAodGhpcy5oYXNFdmFsTW9kZWwpIHtcbiAgICAgIGNvbnN0IFtmZXRjaGVzLCBvcHRpb25zXSA9XG4gICAgICAgICAgdGhpcy50eXBlTmFycm93aW5nRm9yUnVuU3RlcCh0aGlzLmV2YWxJbnB1dE5hbWVzLCB0aGlzLmV2YWxPdXRwdXROYW1lcywgZmVlZHMsIGFyZzEsIGFyZzIpO1xuICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuaGFuZGxlci5ydW5FdmFsU3RlcChmZWVkcywgZmV0Y2hlcywgb3B0aW9ucyk7XG4gICAgICByZXR1cm4gdGhpcy5jb252ZXJ0SGFuZGxlclJldHVyblR5cGVUb01hcE9mVGVuc29ycyhyZXN1bHRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIFRyYWluaW5nU2Vzc2lvbiBoYXMgbm8gRXZhbE1vZGVsIGxvYWRlZC4nKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBnZXRQYXJhbWV0ZXJzU2l6ZSh0cmFpbmFibGVPbmx5ID0gdHJ1ZSk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlci5nZXRQYXJhbWV0ZXJzU2l6ZSh0cmFpbmFibGVPbmx5KTtcbiAgfVxuXG4gIGFzeW5jIGxvYWRQYXJhbWV0ZXJzQnVmZmVyKGFycmF5OiBVaW50OEFycmF5LCB0cmFpbmFibGVPbmx5ID0gdHJ1ZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBhcmFtc1NpemUgPSBhd2FpdCB0aGlzLmdldFBhcmFtZXRlcnNTaXplKHRyYWluYWJsZU9ubHkpO1xuICAgIC8vIGNoZWNraW5nIHRoYXQgdGhlIHNpemUgb2YgdGhlIFVpbnQ4QXJyYXkgaXMgZXF1aXZhbGVudCB0byB0aGUgYnl0ZSBsZW5ndGggb2YgYSBGbG9hdDMyQXJyYXkgb2YgdGhlIG51bWJlclxuICAgIC8vIG9mIHBhcmFtZXRlcnNcbiAgICBpZiAoYXJyYXkubGVuZ3RoICE9PSA0ICogcGFyYW1zU2l6ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdTaXplIG9mIHRoZSBidWZmZXIgcGFzc2VkIGludG8gbG9hZFBhcmFtZXRlcnNCdWZmZXIgbXVzdCBtYXRjaCB0aGUgbnVtYmVyIG9mIHBhcmFtZXRlcnMgaW4gJyArXG4gICAgICAgICAgJ3RoZSBtb2RlbC4gUGxlYXNlIHVzZSBnZXRQYXJhbWV0ZXJzU2l6ZSBtZXRob2QgdG8gY2hlY2suJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmhhbmRsZXIubG9hZFBhcmFtZXRlcnNCdWZmZXIoYXJyYXksIHRyYWluYWJsZU9ubHkpO1xuICB9XG5cbiAgYXN5bmMgZ2V0Q29udGlndW91c1BhcmFtZXRlcnModHJhaW5hYmxlT25seSA9IHRydWUpOiBQcm9taXNlPE9ubnhWYWx1ZT4ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIuZ2V0Q29udGlndW91c1BhcmFtZXRlcnModHJhaW5hYmxlT25seSk7XG4gIH1cblxuICBhc3luYyByZWxlYXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXIuZGlzcG9zZSgpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7SW5mZXJlbmNlU2Vzc2lvbn0gZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi5qcyc7XG5pbXBvcnQge09ubnhWYWx1ZX0gZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcbmltcG9ydCB7VHJhaW5pbmdTZXNzaW9uIGFzIFRyYWluaW5nU2Vzc2lvbkltcGx9IGZyb20gJy4vdHJhaW5pbmctc2Vzc2lvbi1pbXBsLmpzJztcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZSAqL1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgVHJhaW5pbmdTZXNzaW9uIHtcbiAgLyoqXG4gICAqIEVpdGhlciBVUkkgZmlsZSBwYXRoIChzdHJpbmcpIG9yIFVpbnQ4QXJyYXkgY29udGFpbmluZyBtb2RlbCBvciBjaGVja3BvaW50IGluZm9ybWF0aW9uLlxuICAgKi9cbiAgdHlwZSBVcmlPckJ1ZmZlciA9IHN0cmluZ3xVaW50OEFycmF5O1xufVxuXG4vKipcbiAqIFJlcHJlc2VudCBhIHJ1bnRpbWUgaW5zdGFuY2Ugb2YgYW4gT05OWCB0cmFpbmluZyBzZXNzaW9uLFxuICogd2hpY2ggY29udGFpbnMgYSBtb2RlbCB0aGF0IGNhbiBiZSB0cmFpbmVkLCBhbmQsIG9wdGlvbmFsbHksXG4gKiBhbiBldmFsIGFuZCBvcHRpbWl6ZXIgbW9kZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaW5pbmdTZXNzaW9uIHtcbiAgLy8gI3JlZ2lvbiBydW4oKVxuXG4gIC8qKlxuICAgKiBMYXppbHkgcmVzZXRzIHRoZSBncmFkaWVudHMgb2YgYWxsIHRyYWluYWJsZSBwYXJhbWV0ZXJzIHRvIHplcm8uIFNob3VsZCBoYXBwZW4gYWZ0ZXIgdGhlIGludm9jYXRpb24gb2ZcbiAgICogcnVuT3B0aW1pemVyU3RlcC5cbiAgICovXG4gIGxhenlSZXNldEdyYWQoKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogUnVuIFRyYWluU3RlcCBhc3luY2hyb25vdXNseSB3aXRoIHRoZSBnaXZlbiBmZWVkcyBhbmQgb3B0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIGZlZWRzIC0gUmVwcmVzZW50YXRpb24gb2YgdGhlIG1vZGVsIGlucHV0LiBTZWUgdHlwZSBkZXNjcmlwdGlvbiBvZiBgSW5mZXJlbmNlU2Vzc2lvbi5JbnB1dFR5cGVgIGZvclxuICAgZGV0YWlsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsLiBBIHNldCBvZiBvcHRpb25zIHRoYXQgY29udHJvbHMgdGhlIGJlaGF2aW9yIG9mIG1vZGVsIHRyYWluaW5nLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIG1hcCwgd2hpY2ggdXNlcyBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgKi9cbiAgcnVuVHJhaW5TdGVwKGZlZWRzOiBJbmZlcmVuY2VTZXNzaW9uLkZlZWRzVHlwZSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyk6XG4gICAgICBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24uUmV0dXJuVHlwZT47XG5cbiAgLyoqXG4gICAqIFJ1biBhIHNpbmdsZSB0cmFpbiBzdGVwIHdpdGggdGhlIGdpdmVuIGlucHV0cyBhbmQgb3B0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIGZlZWRzIC0gUmVwcmVzZW50YXRpb24gb2YgdGhlIG1vZGVsIGlucHV0LlxuICAgKiBAcGFyYW0gZmV0Y2hlcyAtIFJlcHJlc2VudGF0aW9uIG9mIHRoZSBtb2RlbCBvdXRwdXQuXG4gICAqIGRldGFpbC5cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25hbC4gQSBzZXQgb2Ygb3B0aW9ucyB0aGF0IGNvbnRyb2xzIHRoZSBiZWhhdmlvciBvZiBtb2RlbCB0cmFpbmluZy5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBtYXAsIHdoaWNoIHVzZXMgb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nXG4gICB2YWx1ZXMuXG4gICAqL1xuICBydW5UcmFpblN0ZXAoXG4gICAgICBmZWVkczogSW5mZXJlbmNlU2Vzc2lvbi5GZWVkc1R5cGUsIGZldGNoZXM6IEluZmVyZW5jZVNlc3Npb24uRmV0Y2hlc1R5cGUsXG4gICAgICBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zKTogUHJvbWlzZTxJbmZlcmVuY2VTZXNzaW9uLlJldHVyblR5cGU+O1xuXG4gIC8qKlxuICAgKiBSdW5zIGEgc2luZ2xlIG9wdGltaXplciBzdGVwLCB3aGljaCBwZXJmb3JtcyB3ZWlnaHQgdXBkYXRlcyBmb3IgdGhlIHRyYWluYWJsZSBwYXJhbWV0ZXJzIHVzaW5nIHRoZSBvcHRpbWl6ZXIgbW9kZWwuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwuIEEgc2V0IG9mIG9wdGlvbnMgdGhhdCBjb250cm9scyB0aGUgYmVoYXZpb3Igb2YgbW9kZWwgb3B0aW1pemluZy5cbiAgICovXG4gIHJ1bk9wdGltaXplclN0ZXAob3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyk6IFByb21pc2U8dm9pZD47XG5cbiAgLyoqXG4gICAqIFJ1biBhIHNpbmdsZSBldmFsIHN0ZXAgd2l0aCB0aGUgZ2l2ZW4gaW5wdXRzIGFuZCBvcHRpb25zIHVzaW5nIHRoZSBldmFsIG1vZGVsLlxuICAgKlxuICAgKiBAcGFyYW0gZmVlZHMgLSBSZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWwgaW5wdXQuXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwuIEEgc2V0IG9mIG9wdGlvbnMgdGhhdCBjb250cm9scyB0aGUgYmVoYXZpb3Igb2YgbW9kZWwgZXZhbCBzdGVwLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIG1hcCwgd2hpY2ggdXNlcyBvdXRwdXQgbmFtZXMgYXMga2V5cyBhbmQgT25ueFZhbHVlIGFzIGNvcnJlc3BvbmRpbmdcbiAgIHZhbHVlcy5cbiAgICovXG4gIHJ1bkV2YWxTdGVwKGZlZWRzOiBJbmZlcmVuY2VTZXNzaW9uLkZlZWRzVHlwZSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyk6XG4gICAgICBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24uUmV0dXJuVHlwZT47XG5cbiAgLyoqXG4gICAqIFJ1biBhIHNpbmdsZSBldmFsIHN0ZXAgd2l0aCB0aGUgZ2l2ZW4gaW5wdXRzIGFuZCBvcHRpb25zIHVzaW5nIHRoZSBldmFsIG1vZGVsLlxuICAgKlxuICAgKiBAcGFyYW0gZmVlZHMgLSBSZXByZXNlbnRhdGlvbiBvZiB0aGUgbW9kZWwgaW5wdXQuXG4gICAqIEBwYXJhbSBmZXRjaGVzIC0gUmVwcmVzZW50YXRpb24gb2YgdGhlIG1vZGVsIG91dHB1dC5cbiAgICogZGV0YWlsLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsLiBBIHNldCBvZiBvcHRpb25zIHRoYXQgY29udHJvbHMgdGhlIGJlaGF2aW9yIG9mIG1vZGVsIGV2YWwgc3RlcC5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBtYXAsIHdoaWNoIHVzZXMgb3V0cHV0IG5hbWVzIGFzIGtleXMgYW5kIE9ubnhWYWx1ZSBhcyBjb3JyZXNwb25kaW5nXG4gICB2YWx1ZXMuXG4gICAqL1xuICBydW5FdmFsU3RlcChcbiAgICAgIGZlZWRzOiBJbmZlcmVuY2VTZXNzaW9uLkZlZWRzVHlwZSwgZmV0Y2hlczogSW5mZXJlbmNlU2Vzc2lvbi5GZXRjaGVzVHlwZSxcbiAgICAgIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMpOiBQcm9taXNlPEluZmVyZW5jZVNlc3Npb24uUmV0dXJuVHlwZT47XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gY29weSBwYXJhbWV0ZXJzXG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgc2l6ZSBvZiBhbGwgcGFyYW1ldGVycyBmb3IgdGhlIHRyYWluaW5nIHN0YXRlLiBDYWxjdWxhdGVzIHRoZSB0b3RhbCBudW1iZXIgb2YgcHJpbWl0aXZlIChkYXRhdHlwZSBvZlxuICAgKiB0aGUgcGFyYW1ldGVycykgZWxlbWVudHMgb2YgYWxsIHRoZSBwYXJhbWV0ZXJzIGluIHRoZSB0cmFpbmluZyBzdGF0ZS5cbiAgICpcbiAgICogQHBhcmFtIHRyYWluYWJsZU9ubHkgLSBXaGVuIHNldCB0byB0cnVlLCB0aGUgc2l6ZSBpcyBjYWxjdWxhdGVkIGZvciB0cmFpbmFibGUgcGFyYW1zIG9ubHkuIERlZmF1bHQgdmFsdWUgaXMgdHJ1ZS5cbiAgICovXG4gIGdldFBhcmFtZXRlcnNTaXplKHRyYWluYWJsZU9ubHk6IGJvb2xlYW4pOiBQcm9taXNlPG51bWJlcj47XG5cbiAgLyoqXG4gICAqIENvcGllcyBwYXJhbWV0ZXIgdmFsdWVzIGZyb20gdGhlIGdpdmVuIGJ1ZmZlciB0byB0aGUgdHJhaW5pbmcgc3RhdGUuIEN1cnJlbnRseSwgb25seSBzdXBwb3J0aW5nIG1vZGVscyB3aXRoXG4gICAqIHBhcmFtZXRlcnMgb2YgdHlwZSBGbG9hdDMyLlxuICAgKlxuICAgKiBAcGFyYW0gYnVmZmVyIC0gQSBVaW50OEFycmF5IHJlcHJlc2VudGF0aW9uIG9mIEZsb2F0MzIgcGFyYW1ldGVycy5cbiAgICogQHBhcmFtIHRyYWluYWJsZU9ubHkgLSBUcnVlIGlmIHRyYWluYWJsZSBwYXJhbWV0ZXJzIG9ubHkgdG8gYmUgbW9kaWZpZWQsIGZhbHNlIG90aGVyd2lzZS4gRGVmYXVsdCB2YWx1ZSBpcyB0cnVlLlxuICAgKi9cbiAgbG9hZFBhcmFtZXRlcnNCdWZmZXIoYnVmZmVyOiBVaW50OEFycmF5LCB0cmFpbmFibGVPbmx5OiBib29sZWFuKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogQ29waWVzIHRoZSBtb2RlbCBwYXJhbWV0ZXJzIHRvIGEgY29udGlndW91cyBidWZmZXIuIFVzdWFsbHkgdXNlZCBpbiB0aGUgY29udGV4dCBvZiBGZWRlcmF0ZWQgTGVhcm5pbmcuXG4gICAqIEN1cnJlbnRseSwgb25seSBzdXBwb3J0aW5nIG1vZGVscyB3aXRoIHBhcmFtZXRlcnMgb2YgdHlwZSBGbG9hdDMyLlxuICAgKlxuICAgKiBAcGFyYW0gdHJhaW5hYmxlT25seSAtIFdoZW4gc2V0IHRvIHRydWUsIG9ubHkgdHJhaW5hYmxlIHBhcmFtZXRlcnMgYXJlIGNvcGllZC4gVHJhaW5hYmxlIHBhcmFtZXRlcnMgYXJlIHBhcmFtZXRlcnNcbiAgICogZm9yIHdoaWNoIHJlcXVpcmVzX2dyYWQgaXMgc2V0IHRvIHRydWUuIERlZmF1bHQgdmFsdWUgaXMgdHJ1ZS5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBGbG9hdDMyIE9ubnhWYWx1ZSBvZiB0aGUgcmVxdWVzdGVkIHBhcmFtZXRlcnMuXG4gICAqL1xuICBnZXRDb250aWd1b3VzUGFyYW1ldGVycyh0cmFpbmFibGVPbmx5OiBib29sZWFuKTogUHJvbWlzZTxPbm54VmFsdWU+O1xuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiByZWxlYXNlKClcblxuICAvKipcbiAgICogUmVsZWFzZSB0aGUgaW5mZXJlbmNlIHNlc3Npb24gYW5kIHRoZSB1bmRlcmx5aW5nIHJlc291cmNlcy5cbiAgICovXG4gIHJlbGVhc2UoKTogUHJvbWlzZTx2b2lkPjtcbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gbWV0YWRhdGFcblxuICAvKipcbiAgICogR2V0IGlucHV0IG5hbWVzIG9mIHRoZSBsb2FkZWQgdHJhaW5pbmcgbW9kZWwuXG4gICAqL1xuICByZWFkb25seSB0cmFpbmluZ0lucHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBHZXQgb3V0cHV0IG5hbWVzIG9mIHRoZSBsb2FkZWQgdHJhaW5pbmcgbW9kZWwuXG4gICAqL1xuICByZWFkb25seSB0cmFpbmluZ091dHB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKipcbiAgICogR2V0IGlucHV0IG5hbWVzIG9mIHRoZSBsb2FkZWQgZXZhbCBtb2RlbC4gSXMgYW4gZW1wdHkgYXJyYXkgaWYgbm8gZXZhbCBtb2RlbCBpcyBsb2FkZWQuXG4gICAqL1xuICByZWFkb25seSBldmFsSW5wdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEdldCBvdXRwdXQgbmFtZXMgb2YgdGhlIGxvYWRlZCBldmFsIG1vZGVsLiBJcyBhbiBlbXB0eSBhcnJheSBpZiBubyBldmFsIG1vZGVsIGlzIGxvYWRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGV2YWxPdXRwdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgLy8gI2VuZHJlZ2lvblxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIG9wdGlvbmFsIHBhcmFtZXRlcnMgdGhhdCBjYW4gYmUgcGFzc2VkIGludG8gdGhlIFRyYWluaW5nU2Vzc2lvbkZhY3RvcnkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaW5pbmdTZXNzaW9uQ3JlYXRlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBVUkkgb3IgYnVmZmVyIGZvciBhIC5ja3B0IGZpbGUgdGhhdCBjb250YWlucyB0aGUgY2hlY2twb2ludCBmb3IgdGhlIHRyYWluaW5nIG1vZGVsLlxuICAgKi9cbiAgY2hlY2twb2ludFN0YXRlOiBUcmFpbmluZ1Nlc3Npb24uVXJpT3JCdWZmZXI7XG4gIC8qKlxuICAgKiBVUkkgb3IgYnVmZmVyIGZvciB0aGUgLm9ubnggdHJhaW5pbmcgZmlsZS5cbiAgICovXG4gIHRyYWluTW9kZWw6IFRyYWluaW5nU2Vzc2lvbi5VcmlPckJ1ZmZlcjtcbiAgLyoqXG4gICAqIE9wdGlvbmFsLiBVUkkgb3IgYnVmZmVyIGZvciB0aGUgLm9ubnggb3B0aW1pemVyIG1vZGVsIGZpbGUuXG4gICAqL1xuICBvcHRpbWl6ZXJNb2RlbD86IFRyYWluaW5nU2Vzc2lvbi5VcmlPckJ1ZmZlcjtcbiAgLyoqXG4gICAqIE9wdGlvbmFsLiBVUkkgb3IgYnVmZmVyIGZvciB0aGUgLm9ubnggZXZhbCBtb2RlbCBmaWxlLlxuICAgKi9cbiAgZXZhbE1vZGVsPzogVHJhaW5pbmdTZXNzaW9uLlVyaU9yQnVmZmVyO1xufVxuXG4vKipcbiAqIERlZmluZXMgbWV0aG9kIG92ZXJsb2FkIHBvc3NpYmlsaXRpZXMgZm9yIGNyZWF0aW5nIGEgVHJhaW5pbmdTZXNzaW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRyYWluaW5nU2Vzc2lvbkZhY3Rvcnkge1xuICAvLyAjcmVnaW9uIGNyZWF0ZSgpXG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgVHJhaW5pbmdTZXNzaW9uIGFuZCBhc3luY2hyb25vdXNseSBsb2FkcyBhbnkgbW9kZWxzIHBhc3NlZCBpbiB0aHJvdWdoIHRyYWluaW5nT3B0aW9uc1xuICAgKlxuICAgKiBAcGFyYW0gdHJhaW5pbmdPcHRpb25zIHNwZWNpZnkgbW9kZWxzIGFuZCBjaGVja3BvaW50cyB0byBsb2FkIGludG8gdGhlIFRyYWluaW5nIFNlc3Npb25cbiAgICogQHBhcmFtIHNlc3Npb25PcHRpb25zIHNwZWNpZnkgY29uZmlndXJhdGlvbiBmb3IgdHJhaW5pbmcgc2Vzc2lvbiBiZWhhdmlvclxuICAgKlxuICAgKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBUcmFpbmluZ1Nlc3Npb24gb2JqZWN0XG4gICAqL1xuICBjcmVhdGUodHJhaW5pbmdPcHRpb25zOiBUcmFpbmluZ1Nlc3Npb25DcmVhdGVPcHRpb25zLCBzZXNzaW9uT3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOlxuICAgICAgUHJvbWlzZTxUcmFpbmluZ1Nlc3Npb24+O1xuXG4gIC8vICNlbmRyZWdpb25cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IFRyYWluaW5nU2Vzc2lvbjogVHJhaW5pbmdTZXNzaW9uRmFjdG9yeSA9IFRyYWluaW5nU2Vzc2lvbkltcGw7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qKlxuICogIyBPTk5YIFJ1bnRpbWUgSmF2YVNjcmlwdCBBUElcbiAqXG4gKiBPTk5YIFJ1bnRpbWUgSmF2YVNjcmlwdCBBUEkgaXMgYSB1bmlmaWVkIEFQSSBmb3IgYWxsIEphdmFTY3JpcHQgdXNhZ2VzLCBpbmNsdWRpbmcgdGhlIGZvbGxvd2luZyBOUE0gcGFja2FnZXM6XG4gKlxuICogLSBbb25ueHJ1bnRpbWUtbm9kZV0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2Uvb25ueHJ1bnRpbWUtbm9kZSlcbiAqIC0gW29ubnhydW50aW1lLXdlYl0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2Uvb25ueHJ1bnRpbWUtd2ViKVxuICogLSBbb25ueHJ1bnRpbWUtcmVhY3QtbmF0aXZlXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9vbm54cnVudGltZS1yZWFjdC1uYXRpdmUpXG4gKlxuICogU2VlIGFsc286XG4gKiAtIFtHZXQgU3RhcnRlZF0oaHR0cHM6Ly9vbm54cnVudGltZS5haS9kb2NzL2dldC1zdGFydGVkL3dpdGgtamF2YXNjcmlwdC8pXG4gKiAtIFtJbmZlcmVuY2UgZXhhbXBsZXNdKGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueHJ1bnRpbWUtaW5mZXJlbmNlLWV4YW1wbGVzL3RyZWUvbWFpbi9qcylcbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2JhY2tlbmQuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9lbnYuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9pbmZlcmVuY2Utc2Vzc2lvbi5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3RlbnNvci5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3RlbnNvci1jb252ZXJzaW9uLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdGVuc29yLWZhY3RvcnkuanMnO1xuZXhwb3J0ICogZnJvbSAnLi90cmFjZS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL29ubngtbW9kZWwuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9vbm54LXZhbHVlLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdHJhaW5pbmctc2Vzc2lvbi5qcyc7XG4iLCAiZXhwb3J0IGNvbnN0IHJlYWRGaWxlID0gdW5kZWZpbmVkO2V4cG9ydCBjb25zdCByZWFkRmlsZVN5bmMgPSB1bmRlZmluZWQ7ZXhwb3J0IGNvbnN0IGNyZWF0ZVJlYWRTdHJlYW0gPSB1bmRlZmluZWQ7IiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0Vudn0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHtXZWJHTENvbnRleHR9IGZyb20gJy4vYmFja2VuZHMvd2ViZ2wvd2ViZ2wtY29udGV4dCc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBMb2dnZXIge1xuICBleHBvcnQgaW50ZXJmYWNlIFNldmVyaXR5VHlwZU1hcCB7XG4gICAgdmVyYm9zZTogJ3YnO1xuICAgIGluZm86ICdpJztcbiAgICB3YXJuaW5nOiAndyc7XG4gICAgZXJyb3I6ICdlJztcbiAgICBmYXRhbDogJ2YnO1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgU2V2ZXJpdHkgPSBrZXlvZiBTZXZlcml0eVR5cGVNYXA7XG5cbiAgZXhwb3J0IHR5cGUgUHJvdmlkZXIgPSAnbm9uZSd8J2NvbnNvbGUnO1xuXG4gIC8qKlxuICAgKiBMb2dnaW5nIGNvbmZpZyB0aGF0IHVzZWQgdG8gY29udHJvbCB0aGUgYmVoYXZpb3Igb2YgbG9nZ2VyXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgbG9nZ2luZyBwcm92aWRlci4gJ2NvbnNvbGUnIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBwcm92aWRlcj86IFByb3ZpZGVyO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgdGhlIG1pbmltYWwgbG9nZ2VyIHNlcnZlcml0eS4gJ3dhcm5pbmcnIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBtaW5pbWFsU2V2ZXJpdHk/OiBMb2dnZXIuU2V2ZXJpdHk7XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0byBvdXRwdXQgZGF0ZSB0aW1lIGluIGxvZy4gdHJ1ZSBieSBkZWZhdWx0XG4gICAgICovXG4gICAgbG9nRGF0ZVRpbWU/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdG8gb3V0cHV0IHNvdXJjZSBpbmZvcm1hdGlvbiAoTm90IHlldCBzdXBwb3J0ZWQpLiBmYWxzZSBieSBkZWZhdWx0XG4gICAgICovXG4gICAgbG9nU291cmNlTG9jYXRpb24/OiBib29sZWFuO1xuICB9XG5cbiAgZXhwb3J0IGludGVyZmFjZSBDYXRlZ29yaXplZExvZ2dlciB7XG4gICAgdmVyYm9zZShjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIGluZm8oY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgICB3YXJuaW5nKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gICAgZXJyb3IoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgICBmYXRhbChjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlXG5leHBvcnQgaW50ZXJmYWNlIExvZ2dlciB7XG4gIChjYXRlZ29yeTogc3RyaW5nKTogTG9nZ2VyLkNhdGVnb3JpemVkTG9nZ2VyO1xuXG4gIHZlcmJvc2UoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgdmVyYm9zZShjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBpbmZvKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGluZm8oY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgd2FybmluZyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB3YXJuaW5nKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGVycm9yKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGVycm9yKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGZhdGFsKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGZhdGFsKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRoZSBsb2dnZXIgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIGNvbmZpZyBzcGVjaWZ5IGFuIG9wdGlvbmFsIGRlZmF1bHQgY29uZmlnXG4gICAqL1xuICByZXNldChjb25maWc/OiBMb2dnZXIuQ29uZmlnKTogdm9pZDtcbiAgLyoqXG4gICAqIFNldCB0aGUgbG9nZ2VyJ3MgYmVoYXZpb3Igb24gdGhlIGdpdmVuIGNhdGVnb3J5XG4gICAqIEBwYXJhbSBjYXRlZ29yeSBzcGVjaWZ5IGEgY2F0ZWdvcnkgc3RyaW5nLiBJZiAnKicgaXMgc3BlY2lmaWVkLCBhbGwgcHJldmlvdXMgY29uZmlndXJhdGlvbiB3aWxsIGJlIG92ZXJ3cml0dGVuLiBJZlxuICAgKiAnJyBpcyBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IGJlaGF2aW9yIHdpbGwgYmUgdXBkYXRlZC5cbiAgICogQHBhcmFtIGNvbmZpZyB0aGUgY29uZmlnIG9iamVjdCB0byBpbmRpY2F0ZSB0aGUgbG9nZ2VyJ3MgYmVoYXZpb3JcbiAgICovXG4gIHNldChjYXRlZ29yeTogc3RyaW5nLCBjb25maWc6IExvZ2dlci5Db25maWcpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGxvZ2dlcidzIGJlaGF2aW9yIGZyb20gb3J0LWNvbW1vbiBlbnZcbiAgICogQHBhcmFtIGVudiB0aGUgZW52IHVzZWQgdG8gc2V0IGxvZ2dlci4gQ3VycmVudGx5IG9ubHkgc2V0dGluZyBsb2dsZXZlbCBpcyBzdXBwb3J0ZWQgdGhyb3VnaCBFbnYuXG4gICAqL1xuICBzZXRXaXRoRW52KGVudjogRW52KTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIExvZ2dlclByb3ZpZGVyIHtcbiAgbG9nKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGNvbnRlbnQ6IHN0cmluZywgY2F0ZWdvcnk/OiBzdHJpbmcpOiB2b2lkO1xufVxuY2xhc3MgTm9PcExvZ2dlclByb3ZpZGVyIGltcGxlbWVudHMgTG9nZ2VyUHJvdmlkZXIge1xuICBsb2coX3NldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIF9jb250ZW50OiBzdHJpbmcsIF9jYXRlZ29yeT86IHN0cmluZykge1xuICAgIC8vIGRvIG5vdGhpbmdcbiAgfVxufVxuY2xhc3MgQ29uc29sZUxvZ2dlclByb3ZpZGVyIGltcGxlbWVudHMgTG9nZ2VyUHJvdmlkZXIge1xuICBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nLCBjYXRlZ29yeT86IHN0cmluZykge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS5sb2coYCR7dGhpcy5jb2xvcihzZXZlcml0eSl9ICR7Y2F0ZWdvcnkgPyAnXFx4MWJbMzVtJyArIGNhdGVnb3J5ICsgJ1xceDFiWzBtICcgOiAnJ30ke2NvbnRlbnR9YCk7XG4gIH1cblxuICBwcml2YXRlIGNvbG9yKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHkpIHtcbiAgICBzd2l0Y2ggKHNldmVyaXR5KSB7XG4gICAgICBjYXNlICd2ZXJib3NlJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszNDs0MG12XFx4MWJbMG0nO1xuICAgICAgY2FzZSAnaW5mbyc6XG4gICAgICAgIHJldHVybiAnXFx4MWJbMzJtaVxceDFiWzBtJztcbiAgICAgIGNhc2UgJ3dhcm5pbmcnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzMwOzQzbXdcXHgxYlswbSc7XG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIHJldHVybiAnXFx4MWJbMzE7NDBtZVxceDFiWzBtJztcbiAgICAgIGNhc2UgJ2ZhdGFsJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlsxMDFtZlxceDFiWzBtJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgc2V2ZXJpdHk6ICR7c2V2ZXJpdHl9YCk7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IFNFVkVSSVRZX1ZBTFVFID0ge1xuICB2ZXJib3NlOiAxMDAwLFxuICBpbmZvOiAyMDAwLFxuICB3YXJuaW5nOiA0MDAwLFxuICBlcnJvcjogNTAwMCxcbiAgZmF0YWw6IDYwMDBcbn07XG5cbmNvbnN0IExPR0dFUl9QUk9WSURFUl9NQVA6IHtyZWFkb25seSBbcHJvdmlkZXI6IHN0cmluZ106IFJlYWRvbmx5PExvZ2dlclByb3ZpZGVyPn0gPSB7XG4gIFsnbm9uZSddOiBuZXcgTm9PcExvZ2dlclByb3ZpZGVyKCksXG4gIFsnY29uc29sZSddOiBuZXcgQ29uc29sZUxvZ2dlclByb3ZpZGVyKClcbn07XG5jb25zdCBMT0dHRVJfREVGQVVMVF9DT05GSUcgPSB7XG4gIHByb3ZpZGVyOiAnY29uc29sZScsXG4gIG1pbmltYWxTZXZlcml0eTogJ3dhcm5pbmcnLFxuICBsb2dEYXRlVGltZTogdHJ1ZSxcbiAgbG9nU291cmNlTG9jYXRpb246IGZhbHNlXG59O1xubGV0IExPR0dFUl9DT05GSUdfTUFQOlxuICAgIHtbY2F0ZWdvcnk6IHN0cmluZ106IFJlYWRvbmx5PFJlcXVpcmVkPExvZ2dlci5Db25maWc+Pn0gPSB7WycnXTogTE9HR0VSX0RFRkFVTFRfQ09ORklHIGFzIFJlcXVpcmVkPExvZ2dlci5Db25maWc+fTtcblxuZnVuY3Rpb24gbG9nKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXI7XG5mdW5jdGlvbiBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nKTogdm9pZDtcbmZ1bmN0aW9uIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuZnVuY3Rpb24gbG9nKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGFyZzE6IHN0cmluZywgYXJnMj86IHN0cmluZyk6IHZvaWQ7XG5mdW5jdGlvbiBsb2coXG4gICAgYXJnMDogc3RyaW5nfExvZ2dlci5TZXZlcml0eSwgYXJnMT86IHN0cmluZywgYXJnMj86IHN0cmluZ3xudW1iZXIsIGFyZzM/OiBudW1iZXIpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXJ8dm9pZCB7XG4gIGlmIChhcmcxID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlcjtcbiAgICByZXR1cm4gY3JlYXRlQ2F0ZWdvcml6ZWRMb2dnZXIoYXJnMCk7XG4gIH0gZWxzZSBpZiAoYXJnMiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjb250ZW50KTtcbiAgICBsb2dJbnRlcm5hbChhcmcwIGFzIExvZ2dlci5TZXZlcml0eSwgYXJnMSwgMSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgPT09ICdudW1iZXInICYmIGFyZzMgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGxvZyhzZXZlcml0eSwgY29udGVudCwgc3RhY2spXG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzEsIGFyZzIpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyID09PSAnc3RyaW5nJyAmJiBhcmczID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coc2V2ZXJpdHksIGNhdGVnb3J5LCBjb250ZW50KVxuICAgIGxvZ0ludGVybmFsKGFyZzAgYXMgTG9nZ2VyLlNldmVyaXR5LCBhcmcyLCAxLCBhcmcxKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIGFyZzMgPT09ICdudW1iZXInKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjYXRlZ29yeSwgY29udGVudCwgc3RhY2spXG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzIsIGFyZzMsIGFyZzEpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2lucHV0IGlzIHZhbGlkJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2F0ZWdvcml6ZWRMb2dnZXIoY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlciB7XG4gIHJldHVybiB7XG4gICAgdmVyYm9zZTogbG9nLnZlcmJvc2UuYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgaW5mbzogbG9nLmluZm8uYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgd2FybmluZzogbG9nLndhcm5pbmcuYmluZChudWxsLCBjYXRlZ29yeSksXG4gICAgZXJyb3I6IGxvZy5lcnJvci5iaW5kKG51bGwsIGNhdGVnb3J5KSxcbiAgICBmYXRhbDogbG9nLmZhdGFsLmJpbmQobnVsbCwgY2F0ZWdvcnkpXG4gIH07XG59XG5cbi8vIE5PVEU6IGFyZ3VtZW50ICdjYXRlZ29yeScgaXMgcHV0IHRoZSBsYXN0IHBhcmFtZXRlciBiZWFjYXVzZSB0eXBlc2NyaXB0XG4vLyBkb2Vzbid0IGFsbG93IG9wdGlvbmFsIGFyZ3VtZW50IHB1dCBpbiBmcm9udCBvZiByZXF1aXJlZCBhcmd1bWVudC4gVGhpc1xuLy8gb3JkZXIgaXMgZGlmZmVyZW50IGZyb20gYSB1c3VhbCBsb2dnaW5nIEFQSS5cbmZ1bmN0aW9uIGxvZ0ludGVybmFsKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGNvbnRlbnQ6IHN0cmluZywgX3N0YWNrOiBudW1iZXIsIGNhdGVnb3J5Pzogc3RyaW5nKSB7XG4gIGNvbnN0IGNvbmZpZyA9IExPR0dFUl9DT05GSUdfTUFQW2NhdGVnb3J5IHx8ICcnXSB8fCBMT0dHRVJfQ09ORklHX01BUFsnJ107XG4gIGlmIChTRVZFUklUWV9WQUxVRVtzZXZlcml0eV0gPCBTRVZFUklUWV9WQUxVRVtjb25maWcubWluaW1hbFNldmVyaXR5XSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChjb25maWcubG9nRGF0ZVRpbWUpIHtcbiAgICBjb250ZW50ID0gYCR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfXwke2NvbnRlbnR9YDtcbiAgfVxuXG4gIGlmIChjb25maWcubG9nU291cmNlTG9jYXRpb24pIHtcbiAgICAvLyBUT0RPOiBjYWxjdWxhdGUgc291cmNlIGxvY2F0aW9uIGZyb20gJ3N0YWNrJ1xuICB9XG5cbiAgTE9HR0VSX1BST1ZJREVSX01BUFtjb25maWcucHJvdmlkZXJdLmxvZyhzZXZlcml0eSwgY29udGVudCwgY2F0ZWdvcnkpO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5hbWVzcGFjZVxubmFtZXNwYWNlIGxvZyB7XG4gIGV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB2ZXJib3NlKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygndmVyYm9zZScsIGFyZzAsIGFyZzEpO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiBpbmZvKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBpbmZvKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBpbmZvKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygnaW5mbycsIGFyZzAsIGFyZzEpO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiB3YXJuaW5nKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB3YXJuaW5nKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiB3YXJuaW5nKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygnd2FybmluZycsIGFyZzAsIGFyZzEpO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiBlcnJvcihjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gZXJyb3IoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGVycm9yKGFyZzA6IHN0cmluZywgYXJnMT86IHN0cmluZykge1xuICAgIGxvZygnZXJyb3InLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gZmF0YWwoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGZhdGFsKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBmYXRhbChhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ2ZhdGFsJywgYXJnMCwgYXJnMSk7XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gcmVzZXQoY29uZmlnPzogTG9nZ2VyLkNvbmZpZyk6IHZvaWQge1xuICAgIExPR0dFUl9DT05GSUdfTUFQID0ge307XG4gICAgc2V0KCcnLCBjb25maWcgfHwge30pO1xuICB9XG4gIGV4cG9ydCBmdW5jdGlvbiBzZXQoY2F0ZWdvcnk6IHN0cmluZywgY29uZmlnOiBMb2dnZXIuQ29uZmlnKTogdm9pZCB7XG4gICAgaWYgKGNhdGVnb3J5ID09PSAnKicpIHtcbiAgICAgIHJlc2V0KGNvbmZpZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHByZXZpb3VzQ29uZmlnID0gTE9HR0VSX0NPTkZJR19NQVBbY2F0ZWdvcnldIHx8IExPR0dFUl9ERUZBVUxUX0NPTkZJRztcbiAgICAgIExPR0dFUl9DT05GSUdfTUFQW2NhdGVnb3J5XSA9IHtcbiAgICAgICAgcHJvdmlkZXI6IGNvbmZpZy5wcm92aWRlciB8fCBwcmV2aW91c0NvbmZpZy5wcm92aWRlcixcbiAgICAgICAgbWluaW1hbFNldmVyaXR5OiBjb25maWcubWluaW1hbFNldmVyaXR5IHx8IHByZXZpb3VzQ29uZmlnLm1pbmltYWxTZXZlcml0eSxcbiAgICAgICAgbG9nRGF0ZVRpbWU6IChjb25maWcubG9nRGF0ZVRpbWUgPT09IHVuZGVmaW5lZCkgPyBwcmV2aW91c0NvbmZpZy5sb2dEYXRlVGltZSA6IGNvbmZpZy5sb2dEYXRlVGltZSxcbiAgICAgICAgbG9nU291cmNlTG9jYXRpb246IChjb25maWcubG9nU291cmNlTG9jYXRpb24gPT09IHVuZGVmaW5lZCkgPyBwcmV2aW91c0NvbmZpZy5sb2dTb3VyY2VMb2NhdGlvbiA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLmxvZ1NvdXJjZUxvY2F0aW9uXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFRPRE86IHdlIHdhbnQgdG8gc3VwcG9ydCB3aWxkY2FyZCBvciByZWdleD9cbiAgfVxuXG4gIGV4cG9ydCBmdW5jdGlvbiBzZXRXaXRoRW52KGVudjogRW52KTogdm9pZCB7XG4gICAgY29uc3QgY29uZmlnOiBMb2dnZXIuQ29uZmlnID0ge307XG4gICAgaWYgKGVudi5sb2dMZXZlbCkge1xuICAgICAgY29uZmlnLm1pbmltYWxTZXZlcml0eSA9IGVudi5sb2dMZXZlbCBhcyBMb2dnZXIuU2V2ZXJpdHk7XG4gICAgfVxuICAgIHNldCgnJywgY29uZmlnKTtcbiAgfVxufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZSwgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5leHBvcnQgY29uc3QgTG9nZ2VyOiBMb2dnZXIgPSBsb2c7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBQcm9maWxlciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnIHtcbiAgICBtYXhOdW1iZXJFdmVudHM/OiBudW1iZXI7XG4gICAgZmx1c2hCYXRjaFNpemU/OiBudW1iZXI7XG4gICAgZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgRXZlbnRDYXRlZ29yeSA9ICdzZXNzaW9uJ3wnbm9kZSd8J29wJ3wnYmFja2VuZCc7XG5cbiAgZXhwb3J0IGludGVyZmFjZSBFdmVudCB7XG4gICAgZW5kKCk6IHZvaWR8UHJvbWlzZTx2b2lkPjtcbiAgfVxufVxuLy8gVE9ET1xuLy8gY2xhc3MgV2ViR0xFdmVudCBpbXBsZW1lbnRzIFByb2ZpbGVyLkV2ZW50IHt9XG5cbmNsYXNzIEV2ZW50IGltcGxlbWVudHMgUHJvZmlsZXIuRXZlbnQge1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIHB1YmxpYyBjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSwgcHVibGljIG5hbWU6IHN0cmluZywgcHVibGljIHN0YXJ0VGltZTogbnVtYmVyLFxuICAgICAgcHJpdmF0ZSBlbmRDYWxsYmFjazogKGU6IEV2ZW50KSA9PiB2b2lkfFByb21pc2U8dm9pZD4sIHB1YmxpYyB0aW1lcj86IFdlYkdMUXVlcnksIHB1YmxpYyBjdHg/OiBXZWJHTENvbnRleHQpIHt9XG5cbiAgYXN5bmMgZW5kKCkge1xuICAgIHJldHVybiB0aGlzLmVuZENhbGxiYWNrKHRoaXMpO1xuICB9XG5cbiAgYXN5bmMgY2hlY2tUaW1lcigpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGlmICh0aGlzLmN0eCA9PT0gdW5kZWZpbmVkIHx8IHRoaXMudGltZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB3ZWJnbCB0aW1lciBmb3VuZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmN0eC5lbmRUaW1lcigpO1xuICAgICAgcmV0dXJuIHRoaXMuY3R4LndhaXRGb3JRdWVyeUFuZEdldFRpbWUodGhpcy50aW1lcik7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIEV2ZW50UmVjb3JkIHtcbiAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksIHB1YmxpYyBuYW1lOiBzdHJpbmcsIHB1YmxpYyBzdGFydFRpbWU6IG51bWJlciwgcHVibGljIGVuZFRpbWU6IG51bWJlcikge31cbn1cblxuZXhwb3J0IGNsYXNzIFByb2ZpbGVyIHtcbiAgc3RhdGljIGNyZWF0ZShjb25maWc/OiBQcm9maWxlci5Db25maWcpOiBQcm9maWxlciB7XG4gICAgaWYgKGNvbmZpZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gbmV3IHRoaXMoKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyB0aGlzKGNvbmZpZy5tYXhOdW1iZXJFdmVudHMsIGNvbmZpZy5mbHVzaEJhdGNoU2l6ZSwgY29uZmlnLmZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKG1heE51bWJlckV2ZW50cz86IG51bWJlciwgZmx1c2hCYXRjaFNpemU/OiBudW1iZXIsIGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcz86IG51bWJlcikge1xuICAgIHRoaXMuX3N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9tYXhOdW1iZXJFdmVudHMgPSBtYXhOdW1iZXJFdmVudHMgPT09IHVuZGVmaW5lZCA/IDEwMDAwIDogbWF4TnVtYmVyRXZlbnRzO1xuICAgIHRoaXMuX2ZsdXNoQmF0Y2hTaXplID0gZmx1c2hCYXRjaFNpemUgPT09IHVuZGVmaW5lZCA/IDEwIDogZmx1c2hCYXRjaFNpemU7XG4gICAgdGhpcy5fZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzID0gZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzID09PSB1bmRlZmluZWQgPyA1MDAwIDogZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzO1xuICB9XG5cbiAgLy8gc3RhcnQgcHJvZmlsaW5nXG4gIHN0YXJ0KCkge1xuICAgIHRoaXMuX3N0YXJ0ZWQgPSB0cnVlO1xuICAgIHRoaXMuX3RpbWluZ0V2ZW50cyA9IFtdO1xuICAgIHRoaXMuX2ZsdXNoVGltZSA9IG5vdygpO1xuICAgIHRoaXMuX2ZsdXNoUG9pbnRlciA9IDA7XG4gIH1cblxuICAvLyBzdG9wIHByb2ZpbGluZ1xuICBzdG9wKCkge1xuICAgIHRoaXMuX3N0YXJ0ZWQgPSBmYWxzZTtcbiAgICBmb3IgKDsgdGhpcy5fZmx1c2hQb2ludGVyIDwgdGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aDsgdGhpcy5fZmx1c2hQb2ludGVyKyspIHtcbiAgICAgIHRoaXMubG9nT25lRXZlbnQodGhpcy5fdGltaW5nRXZlbnRzW3RoaXMuX2ZsdXNoUG9pbnRlcl0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIGNyZWF0ZSBhbiBldmVudCBzY29wZSBmb3IgdGhlIHNwZWNpZmljIGZ1bmN0aW9uXG4gIGV2ZW50PFQ+KGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LCBuYW1lOiBzdHJpbmcsIGZ1bmM6ICgpID0+IFQsIGN0eD86IFdlYkdMQ29udGV4dCk6IFQ7XG4gIGV2ZW50PFQ+KGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LCBuYW1lOiBzdHJpbmcsIGZ1bmM6ICgpID0+IFByb21pc2U8VD4sIGN0eD86IFdlYkdMQ29udGV4dCk6IFByb21pc2U8VD47XG5cbiAgZXZlbnQ8VD4oY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksIG5hbWU6IHN0cmluZywgZnVuYzogKCkgPT4gVCB8IFByb21pc2U8VD4sIGN0eD86IFdlYkdMQ29udGV4dCk6IFRcbiAgICAgIHxQcm9taXNlPFQ+IHtcbiAgICBjb25zdCBldmVudCA9IHRoaXMuX3N0YXJ0ZWQgPyB0aGlzLmJlZ2luKGNhdGVnb3J5LCBuYW1lLCBjdHgpIDogdW5kZWZpbmVkO1xuICAgIGxldCBpc1Byb21pc2UgPSBmYWxzZTtcblxuICAgIGNvbnN0IHJlcyA9IGZ1bmMoKTtcblxuICAgIC8vIHdlIGNvbnNpZGVyIGEgdGhlbi1hYmxlIG9iamVjdCBpcyBhIHByb21pc2VcbiAgICBpZiAocmVzICYmIHR5cGVvZiAocmVzIGFzIFByb21pc2U8VD4pLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlzUHJvbWlzZSA9IHRydWU7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2U8VD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAocmVzIGFzIFByb21pc2U8VD4pXG4gICAgICAgICAgICAudGhlbihcbiAgICAgICAgICAgICAgICBhc3luYyB2YWx1ZSA9PiB7ICAvLyBmdWxmaWxsZWRcbiAgICAgICAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBldmVudC5lbmQoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYXN5bmMgcmVhc29uID0+IHsgIC8vIHJlamVjdGVkXG4gICAgICAgICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZXZlbnQuZW5kKCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICByZWplY3QocmVhc29uKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoIWlzUHJvbWlzZSAmJiBldmVudCkge1xuICAgICAgY29uc3QgZXZlbnRSZXMgPSBldmVudC5lbmQoKTtcbiAgICAgIGlmIChldmVudFJlcyAmJiB0eXBlb2YgZXZlbnRSZXMudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8VD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIChldmVudFJlcykudGhlbihcbiAgICAgICAgICAgICAgKCkgPT4geyAgLy8gZnVsZmlsbGVkXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAocmVhc29uKSA9PiB7ICAvLyByZWplY3RlZFxuICAgICAgICAgICAgICAgIHJlamVjdChyZWFzb24pO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICAvLyBiZWdpbiBhbiBldmVudFxuICBiZWdpbihjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSwgbmFtZTogc3RyaW5nLCBjdHg/OiBXZWJHTENvbnRleHQpOiBFdmVudCB7XG4gICAgaWYgKCF0aGlzLl9zdGFydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2ZpbGVyIGlzIG5vdCBzdGFydGVkIHlldCcpO1xuICAgIH1cbiAgICBpZiAoY3R4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IG5vdygpO1xuICAgICAgdGhpcy5mbHVzaChzdGFydFRpbWUpO1xuICAgICAgcmV0dXJuIG5ldyBFdmVudChjYXRlZ29yeSwgbmFtZSwgc3RhcnRUaW1lLCBlID0+IHRoaXMuZW5kU3luYyhlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRpbWVyOiBXZWJHTFF1ZXJ5ID0gY3R4LmJlZ2luVGltZXIoKTtcbiAgICAgIHJldHVybiBuZXcgRXZlbnQoY2F0ZWdvcnksIG5hbWUsIDAsIGFzeW5jIGUgPT4gdGhpcy5lbmQoZSksIHRpbWVyLCBjdHgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVuZCB0aGUgc3BlY2lmaWMgZXZlbnRcbiAgcHJpdmF0ZSBhc3luYyBlbmQoZXZlbnQ6IEV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZW5kVGltZTogbnVtYmVyID0gYXdhaXQgZXZlbnQuY2hlY2tUaW1lcigpO1xuICAgIGlmICh0aGlzLl90aW1pbmdFdmVudHMubGVuZ3RoIDwgdGhpcy5fbWF4TnVtYmVyRXZlbnRzKSB7XG4gICAgICB0aGlzLl90aW1pbmdFdmVudHMucHVzaChuZXcgRXZlbnRSZWNvcmQoZXZlbnQuY2F0ZWdvcnksIGV2ZW50Lm5hbWUsIGV2ZW50LnN0YXJ0VGltZSwgZW5kVGltZSkpO1xuICAgICAgdGhpcy5mbHVzaChlbmRUaW1lKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVuZFN5bmMoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZW5kVGltZTogbnVtYmVyID0gbm93KCk7XG4gICAgaWYgKHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGggPCB0aGlzLl9tYXhOdW1iZXJFdmVudHMpIHtcbiAgICAgIHRoaXMuX3RpbWluZ0V2ZW50cy5wdXNoKG5ldyBFdmVudFJlY29yZChldmVudC5jYXRlZ29yeSwgZXZlbnQubmFtZSwgZXZlbnQuc3RhcnRUaW1lLCBlbmRUaW1lKSk7XG4gICAgICB0aGlzLmZsdXNoKGVuZFRpbWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbG9nT25lRXZlbnQoZXZlbnQ6IEV2ZW50UmVjb3JkKSB7XG4gICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgIGBQcm9maWxlci4ke2V2ZW50LmNhdGVnb3J5fWAsXG4gICAgICAgIGAkeyhldmVudC5lbmRUaW1lIC0gZXZlbnQuc3RhcnRUaW1lKS50b0ZpeGVkKDIpfW1zIG9uIGV2ZW50ICcke2V2ZW50Lm5hbWV9JyBhdCAke2V2ZW50LmVuZFRpbWUudG9GaXhlZCgyKX1gKTtcbiAgfVxuXG4gIHByaXZhdGUgZmx1c2goY3VycmVudFRpbWU6IG51bWJlcikge1xuICAgIGlmICh0aGlzLl90aW1pbmdFdmVudHMubGVuZ3RoIC0gdGhpcy5fZmx1c2hQb2ludGVyID49IHRoaXMuX2ZsdXNoQmF0Y2hTaXplIHx8XG4gICAgICAgIGN1cnJlbnRUaW1lIC0gdGhpcy5fZmx1c2hUaW1lID49IHRoaXMuX2ZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcykge1xuICAgICAgLy8gc2hvdWxkIGZsdXNoIHdoZW4gZWl0aGVyIGJhdGNoIHNpemUgYWNjdW1sYXRlZCBvciBpbnRlcnZhbCBlbGVwc2VkXG5cbiAgICAgIGZvciAoY29uc3QgcHJldmlvdXNQb2ludGVyID0gdGhpcy5fZmx1c2hQb2ludGVyOyB0aGlzLl9mbHVzaFBvaW50ZXIgPCBwcmV2aW91c1BvaW50ZXIgKyB0aGlzLl9mbHVzaEJhdGNoU2l6ZSAmJlxuICAgICAgICAgICB0aGlzLl9mbHVzaFBvaW50ZXIgPCB0aGlzLl90aW1pbmdFdmVudHMubGVuZ3RoO1xuICAgICAgICAgICB0aGlzLl9mbHVzaFBvaW50ZXIrKykge1xuICAgICAgICB0aGlzLmxvZ09uZUV2ZW50KHRoaXMuX3RpbWluZ0V2ZW50c1t0aGlzLl9mbHVzaFBvaW50ZXJdKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fZmx1c2hUaW1lID0gbm93KCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHN0YXJ0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXJ0ZWQ7XG4gIH1cbiAgcHJpdmF0ZSBfc3RhcnRlZCA9IGZhbHNlO1xuICBwcml2YXRlIF90aW1pbmdFdmVudHM6IEV2ZW50UmVjb3JkW107XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfbWF4TnVtYmVyRXZlbnRzOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZmx1c2hCYXRjaFNpemU6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBfZmx1c2hJbnRlcnZhbEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSBfZmx1c2hUaW1lOiBudW1iZXI7XG4gIHByaXZhdGUgX2ZsdXNoUG9pbnRlciA9IDA7XG59XG5cbi8qKlxuICogcmV0dXJucyBhIG51bWJlciB0byByZXByZXNlbnQgdGhlIGN1cnJlbnQgdGltZXN0YW1wIGluIGEgcmVzb2x1dGlvbiBhcyBoaWdoIGFzIHBvc3NpYmxlLlxuICovXG5leHBvcnQgY29uc3Qgbm93ID0gKHR5cGVvZiBwZXJmb3JtYW5jZSAhPT0gJ3VuZGVmaW5lZCcgJiYgcGVyZm9ybWFuY2Uubm93KSA/ICgpID0+IHBlcmZvcm1hbmNlLm5vdygpIDogRGF0ZS5ub3c7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7R3JhcGh9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuL29wZXJhdG9ycyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BTZXQge1xuICBkb21haW46IHN0cmluZztcbiAgdmVyc2lvbjogbnVtYmVyO1xufVxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIE9wU2V0IHtcbiAgLyoqXG4gICAqIERvbWFpbiBvZiBhbiBvcHNldCwgaXQgY2FuIGJlIGFuIGVtcHR5IHN0cmluZyhkZWZhdWx0IHZhbHVlLCByZXByZXNlbnQgZm9yIGFpLm9ubngpLCBvciAnYWkub25ueC5tbCdcbiAgICovXG4gIHR5cGUgRG9tYWluID0gJyd8J2FpLm9ubngubWwnfCdjb20ubWljcm9zb2Z0JztcbiAgLyoqXG4gICAqIEEgcmVzb2x2ZSBydWxlIGNvbnNpc3RzIG9mIDQgb3IgNSBpdGVtczogb3BUeXBlLCBvcFNldERvbWFpbiwgdmVyc2lvblNlbGVjdG9yLCBvcGVyYXRvckltcGxlbWVudGF0aW9uIGFuZFxuICAgKiBvcGVyYXRvckluaXRpYWxpemF0aW9uIChvcHRpb25hbClcbiAgICovXG4gIHR5cGUgUmVzb2x2ZVJ1bGUgPSBbXG4gICAgc3RyaW5nLCBEb21haW4sIHN0cmluZywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxHcmFwaC5Ob2RlPlxuICBdfFtzdHJpbmcsIERvbWFpbiwgc3RyaW5nLCBPcGVyYXRvckltcGxlbWVudGF0aW9uPHVua25vd24+LCBPcGVyYXRvckluaXRpYWxpemF0aW9uPHVua25vd24+XTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVPcGVyYXRvcihub2RlOiBHcmFwaC5Ob2RlLCBvcHNldHM6IHJlYWRvbmx5IE9wU2V0W10sIHJ1bGVzOiByZWFkb25seSBPcFNldC5SZXNvbHZlUnVsZVtdKSB7XG4gIGZvciAoY29uc3QgcnVsZSBvZiBydWxlcykge1xuICAgIGNvbnN0IG9wVHlwZSA9IHJ1bGVbMF07XG4gICAgY29uc3QgZG9tYWluID0gcnVsZVsxXTtcbiAgICBjb25zdCB2ZXJzaW9uU2VsZWN0b3IgPSBydWxlWzJdO1xuICAgIGNvbnN0IG9wSW1wbCA9IHJ1bGVbM107XG4gICAgY29uc3Qgb3BJbml0ID0gcnVsZVs0XTtcblxuICAgIGlmIChub2RlLm9wVHlwZSA9PT0gb3BUeXBlKSB7ICAvLyBvcGVyYXRvciB0eXBlIG1hdGNoZXNcbiAgICAgIGZvciAoY29uc3Qgb3BzZXQgb2Ygb3BzZXRzKSB7XG4gICAgICAgIC8vIG9wc2V0ICcnIGFuZCAnYWkub25ueCcgYXJlIGNvbnNpZGVyZWQgdGhlIHNhbWUuXG4gICAgICAgIGlmIChvcHNldC5kb21haW4gPT09IGRvbWFpbiB8fCAob3BzZXQuZG9tYWluID09PSAnYWkub25ueCcgJiYgZG9tYWluID09PSAnJykpIHsgIC8vIG9wc2V0IGRvbWFpbiBmb3VuZFxuICAgICAgICAgIGlmIChtYXRjaFNlbGVjdG9yKG9wc2V0LnZlcnNpb24sIHZlcnNpb25TZWxlY3RvcikpIHtcbiAgICAgICAgICAgIHJldHVybiB7b3BJbXBsLCBvcEluaXR9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoYGNhbm5vdCByZXNvbHZlIG9wZXJhdG9yICcke25vZGUub3BUeXBlfScgd2l0aCBvcHNldHM6ICR7XG4gICAgICBvcHNldHMubWFwKHNldCA9PiBgJHtzZXQuZG9tYWluIHx8ICdhaS5vbm54J30gdiR7c2V0LnZlcnNpb259YCkuam9pbignLCAnKX1gKTtcbn1cblxuZnVuY3Rpb24gbWF0Y2hTZWxlY3Rvcih2ZXJzaW9uOiBudW1iZXIsIHNlbGVjdG9yOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKHNlbGVjdG9yLmVuZHNXaXRoKCcrJykpIHtcbiAgICAvLyBtaW5pbXVtIHZlcnNpb24gbWF0Y2ggKCc3KycgZXhwZWN0cyB2ZXJzaW9uPj03KVxuICAgIGNvbnN0IHJhbmdlU3RhcnQgPSBOdW1iZXIucGFyc2VJbnQoc2VsZWN0b3Iuc3Vic3RyaW5nKDAsIHNlbGVjdG9yLmxlbmd0aCAtIDEpLCAxMCk7XG4gICAgcmV0dXJuICFpc05hTihyYW5nZVN0YXJ0KSAmJiByYW5nZVN0YXJ0IDw9IHZlcnNpb247XG4gIH0gZWxzZSBpZiAoc2VsZWN0b3Iuc3BsaXQoJy0nKS5sZW5ndGggPT09IDIpIHtcbiAgICAvLyByYW5nZSBtYXRjaCAoJzYtOCcgZXhwZWN0cyA2PD12ZXJzaW9uPD04KVxuICAgIGNvbnN0IHBhaXIgPSBzZWxlY3Rvci5zcGxpdCgnLScpO1xuICAgIGNvbnN0IHJhbmdlU3RhcnQgPSBOdW1iZXIucGFyc2VJbnQocGFpclswXSwgMTApO1xuICAgIGNvbnN0IHJhbmdlRW5kID0gTnVtYmVyLnBhcnNlSW50KHBhaXJbMV0sIDEwKTtcbiAgICByZXR1cm4gIWlzTmFOKHJhbmdlU3RhcnQpICYmICFpc05hTihyYW5nZUVuZCkgJiYgcmFuZ2VTdGFydCA8PSB2ZXJzaW9uICYmIHZlcnNpb24gPD0gcmFuZ2VFbmQ7XG4gIH0gZWxzZSB7XG4gICAgLy8gZXhhY3QgbWF0Y2ggKCc3JyBleHBlY3RzIHZlcnNpb249PT03KVxuICAgIHJldHVybiBOdW1iZXIucGFyc2VJbnQoc2VsZWN0b3IsIDEwKSA9PT0gdmVyc2lvbjtcbiAgfVxufVxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xyXG52YXIgR3VpZCA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIEd1aWQoZ3VpZCkge1xyXG4gICAgICAgIGlmICghZ3VpZCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhcmd1bWVudDsgYHZhbHVlYCBoYXMgbm8gdmFsdWUuXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnZhbHVlID0gR3VpZC5FTVBUWTtcclxuICAgICAgICBpZiAoZ3VpZCAmJiBHdWlkLmlzR3VpZChndWlkKSkge1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gZ3VpZDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBHdWlkLmlzR3VpZCA9IGZ1bmN0aW9uIChndWlkKSB7XHJcbiAgICAgICAgdmFyIHZhbHVlID0gZ3VpZC50b1N0cmluZygpO1xyXG4gICAgICAgIHJldHVybiBndWlkICYmIChndWlkIGluc3RhbmNlb2YgR3VpZCB8fCBHdWlkLnZhbGlkYXRvci50ZXN0KHZhbHVlKSk7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBHdWlkKFtHdWlkLmdlbigyKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMyldLmpvaW4oXCItXCIpKTtcclxuICAgIH07XHJcbiAgICBHdWlkLmNyZWF0ZUVtcHR5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgR3VpZChcImVtcHR5Z3VpZFwiKTtcclxuICAgIH07XHJcbiAgICBHdWlkLnBhcnNlID0gZnVuY3Rpb24gKGd1aWQpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEd1aWQoZ3VpZCk7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5yYXcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIFtHdWlkLmdlbigyKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMyldLmpvaW4oXCItXCIpO1xyXG4gICAgfTtcclxuICAgIEd1aWQuZ2VuID0gZnVuY3Rpb24gKGNvdW50KSB7XHJcbiAgICAgICAgdmFyIG91dCA9IFwiXCI7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XHJcbiAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1iaXR3aXNlXHJcbiAgICAgICAgICAgIG91dCArPSAoKCgxICsgTWF0aC5yYW5kb20oKSkgKiAweDEwMDAwKSB8IDApLnRvU3RyaW5nKDE2KS5zdWJzdHJpbmcoMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvdXQ7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKG90aGVyKSB7XHJcbiAgICAgICAgLy8gQ29tcGFyaW5nIHN0cmluZyBgdmFsdWVgIGFnYWluc3QgcHJvdmlkZWQgYGd1aWRgIHdpbGwgYXV0by1jYWxsXHJcbiAgICAgICAgLy8gdG9TdHJpbmcgb24gYGd1aWRgIGZvciBjb21wYXJpc29uXHJcbiAgICAgICAgcmV0dXJuIEd1aWQuaXNHdWlkKG90aGVyKSAmJiB0aGlzLnZhbHVlID09PSBvdGhlci50b1N0cmluZygpO1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWUgPT09IEd1aWQuRU1QVFk7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlXHJcbiAgICAgICAgfTtcclxuICAgIH07XHJcbiAgICBHdWlkLnZhbGlkYXRvciA9IG5ldyBSZWdFeHAoXCJeW2EtejAtOV17OH0tW2EtejAtOV17NH0tW2EtejAtOV17NH0tW2EtejAtOV17NH0tW2EtejAtOV17MTJ9JFwiLCBcImlcIik7XHJcbiAgICBHdWlkLkVNUFRZID0gXCIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIjtcclxuICAgIHJldHVybiBHdWlkO1xyXG59KCkpO1xyXG5leHBvcnRzLkd1aWQgPSBHdWlkO1xyXG4iLCAiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMDkgVGhlIENsb3N1cmUgTGlicmFyeSBBdXRob3JzXG4gKiBDb3B5cmlnaHQgMjAyMCBEYW5pZWwgV2lydHogLyBUaGUgbG9uZy5qcyBBdXRob3JzLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5cbi8vIFdlYkFzc2VtYmx5IG9wdGltaXphdGlvbnMgdG8gZG8gbmF0aXZlIGk2NCBtdWx0aXBsaWNhdGlvbiBhbmQgZGl2aWRlXG52YXIgd2FzbSA9IG51bGw7XG50cnkge1xuICB3YXNtID0gbmV3IFdlYkFzc2VtYmx5Lkluc3RhbmNlKG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobmV3IFVpbnQ4QXJyYXkoW1xuICAgIDAsIDk3LCAxMTUsIDEwOSwgMSwgMCwgMCwgMCwgMSwgMTMsIDIsIDk2LCAwLCAxLCAxMjcsIDk2LCA0LCAxMjcsIDEyNywgMTI3LCAxMjcsIDEsIDEyNywgMywgNywgNiwgMCwgMSwgMSwgMSwgMSwgMSwgNiwgNiwgMSwgMTI3LCAxLCA2NSwgMCwgMTEsIDcsIDUwLCA2LCAzLCAxMDksIDExNywgMTA4LCAwLCAxLCA1LCAxMDAsIDEwNSwgMTE4LCA5NSwgMTE1LCAwLCAyLCA1LCAxMDAsIDEwNSwgMTE4LCA5NSwgMTE3LCAwLCAzLCA1LCAxMTQsIDEwMSwgMTA5LCA5NSwgMTE1LCAwLCA0LCA1LCAxMTQsIDEwMSwgMTA5LCA5NSwgMTE3LCAwLCA1LCA4LCAxMDMsIDEwMSwgMTE2LCA5NSwgMTA0LCAxMDUsIDEwMywgMTA0LCAwLCAwLCAxMCwgMTkxLCAxLCA2LCA0LCAwLCAzNSwgMCwgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEyNiwgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMSwgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI3LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LCAxNjcsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjgsIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEyOSwgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMSwgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTMwLCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LCAxNjcsIDExXG4gIF0pKSwge30pLmV4cG9ydHM7XG59IGNhdGNoIChlKSB7XG4gIC8vIG5vIHdhc20gc3VwcG9ydCA6KFxufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSA2NCBiaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyLCBnaXZlbiBpdHMgbG93IGFuZCBoaWdoIDMyIGJpdCB2YWx1ZXMgYXMgKnNpZ25lZCogaW50ZWdlcnMuXG4gKiAgU2VlIHRoZSBmcm9tKiBmdW5jdGlvbnMgYmVsb3cgZm9yIG1vcmUgY29udmVuaWVudCB3YXlzIG9mIGNvbnN0cnVjdGluZyBMb25ncy5cbiAqIEBleHBvcnRzIExvbmdcbiAqIEBjbGFzcyBBIExvbmcgY2xhc3MgZm9yIHJlcHJlc2VudGluZyBhIDY0IGJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIgdmFsdWUuXG4gKiBAcGFyYW0ge251bWJlcn0gbG93IFRoZSBsb3cgKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2ggVGhlIGhpZ2ggKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIExvbmcobG93LCBoaWdoLCB1bnNpZ25lZCkge1xuXG4gIC8qKlxuICAgKiBUaGUgbG93IDMyIGJpdHMgYXMgYSBzaWduZWQgdmFsdWUuXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICB0aGlzLmxvdyA9IGxvdyB8IDA7XG5cbiAgLyoqXG4gICAqIFRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgdmFsdWUuXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICB0aGlzLmhpZ2ggPSBoaWdoIHwgMDtcblxuICAvKipcbiAgICogV2hldGhlciB1bnNpZ25lZCBvciBub3QuXG4gICAqIEB0eXBlIHtib29sZWFufVxuICAgKi9cbiAgdGhpcy51bnNpZ25lZCA9ICEhdW5zaWduZWQ7XG59XG5cbi8vIFRoZSBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiBhIGxvbmcgaXMgdGhlIHR3byBnaXZlbiBzaWduZWQsIDMyLWJpdCB2YWx1ZXMuXG4vLyBXZSB1c2UgMzItYml0IHBpZWNlcyBiZWNhdXNlIHRoZXNlIGFyZSB0aGUgc2l6ZSBvZiBpbnRlZ2VycyBvbiB3aGljaFxuLy8gSmF2YXNjcmlwdCBwZXJmb3JtcyBiaXQtb3BlcmF0aW9ucy4gIEZvciBvcGVyYXRpb25zIGxpa2UgYWRkaXRpb24gYW5kXG4vLyBtdWx0aXBsaWNhdGlvbiwgd2Ugc3BsaXQgZWFjaCBudW1iZXIgaW50byAxNiBiaXQgcGllY2VzLCB3aGljaCBjYW4gZWFzaWx5IGJlXG4vLyBtdWx0aXBsaWVkIHdpdGhpbiBKYXZhc2NyaXB0J3MgZmxvYXRpbmctcG9pbnQgcmVwcmVzZW50YXRpb24gd2l0aG91dCBvdmVyZmxvd1xuLy8gb3IgY2hhbmdlIGluIHNpZ24uXG4vL1xuLy8gSW4gdGhlIGFsZ29yaXRobXMgYmVsb3csIHdlIGZyZXF1ZW50bHkgcmVkdWNlIHRoZSBuZWdhdGl2ZSBjYXNlIHRvIHRoZVxuLy8gcG9zaXRpdmUgY2FzZSBieSBuZWdhdGluZyB0aGUgaW5wdXQocykgYW5kIHRoZW4gcG9zdC1wcm9jZXNzaW5nIHRoZSByZXN1bHQuXG4vLyBOb3RlIHRoYXQgd2UgbXVzdCBBTFdBWVMgY2hlY2sgc3BlY2lhbGx5IHdoZXRoZXIgdGhvc2UgdmFsdWVzIGFyZSBNSU5fVkFMVUVcbi8vICgtMl42MykgYmVjYXVzZSAtTUlOX1ZBTFVFID09IE1JTl9WQUxVRSAoc2luY2UgMl42MyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgYXNcbi8vIGEgcG9zaXRpdmUgbnVtYmVyLCBpdCBvdmVyZmxvd3MgYmFjayBpbnRvIGEgbmVnYXRpdmUpLiAgTm90IGhhbmRsaW5nIHRoaXNcbi8vIGNhc2Ugd291bGQgb2Z0ZW4gcmVzdWx0IGluIGluZmluaXRlIHJlY3Vyc2lvbi5cbi8vXG4vLyBDb21tb24gY29uc3RhbnQgdmFsdWVzIFpFUk8sIE9ORSwgTkVHX09ORSwgZXRjLiBhcmUgZGVmaW5lZCBiZWxvdyB0aGUgZnJvbSpcbi8vIG1ldGhvZHMgb24gd2hpY2ggdGhleSBkZXBlbmQuXG5cbi8qKlxuICogQW4gaW5kaWNhdG9yIHVzZWQgdG8gcmVsaWFibHkgZGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBpcyBhIExvbmcgb3Igbm90LlxuICogQHR5cGUge2Jvb2xlYW59XG4gKiBAY29uc3RcbiAqIEBwcml2YXRlXG4gKi9cbkxvbmcucHJvdG90eXBlLl9faXNMb25nX187XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShMb25nLnByb3RvdHlwZSwgXCJfX2lzTG9uZ19fXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cbi8qKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyp9IG9iaiBPYmplY3RcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICogQGlubmVyXG4gKi9cbmZ1bmN0aW9uIGlzTG9uZyhvYmopIHtcbiAgcmV0dXJuIChvYmogJiYgb2JqW1wiX19pc0xvbmdfX1wiXSkgPT09IHRydWU7XG59XG5cbi8qKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyp9IHZhbHVlIG51bWJlclxuICogQHJldHVybnMge251bWJlcn1cbiAqIEBpbm5lclxuICovXG5mdW5jdGlvbiBjdHozMih2YWx1ZSkge1xuICB2YXIgYyA9IE1hdGguY2x6MzIodmFsdWUgJiAtdmFsdWUpO1xuICByZXR1cm4gdmFsdWUgPyAzMSAtIGMgOiBjO1xufVxuXG4vKipcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IGlzIGEgTG9uZy5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZy5pc0xvbmcgPSBpc0xvbmc7XG5cbi8qKlxuICogQSBjYWNoZSBvZiB0aGUgTG9uZyByZXByZXNlbnRhdGlvbnMgb2Ygc21hbGwgaW50ZWdlciB2YWx1ZXMuXG4gKiBAdHlwZSB7IU9iamVjdH1cbiAqIEBpbm5lclxuICovXG52YXIgSU5UX0NBQ0hFID0ge307XG5cbi8qKlxuICogQSBjYWNoZSBvZiB0aGUgTG9uZyByZXByZXNlbnRhdGlvbnMgb2Ygc21hbGwgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuXG4gKiBAdHlwZSB7IU9iamVjdH1cbiAqIEBpbm5lclxuICovXG52YXIgVUlOVF9DQUNIRSA9IHt9O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWRcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG5mdW5jdGlvbiBmcm9tSW50KHZhbHVlLCB1bnNpZ25lZCkge1xuICB2YXIgb2JqLCBjYWNoZWRPYmosIGNhY2hlO1xuICBpZiAodW5zaWduZWQpIHtcbiAgICB2YWx1ZSA+Pj49IDA7XG4gICAgaWYgKGNhY2hlID0gKDAgPD0gdmFsdWUgJiYgdmFsdWUgPCAyNTYpKSB7XG4gICAgICBjYWNoZWRPYmogPSBVSU5UX0NBQ0hFW3ZhbHVlXTtcbiAgICAgIGlmIChjYWNoZWRPYmopXG4gICAgICAgIHJldHVybiBjYWNoZWRPYmo7XG4gICAgfVxuICAgIG9iaiA9IGZyb21CaXRzKHZhbHVlLCAwLCB0cnVlKTtcbiAgICBpZiAoY2FjaGUpXG4gICAgICBVSU5UX0NBQ0hFW3ZhbHVlXSA9IG9iajtcbiAgICByZXR1cm4gb2JqO1xuICB9IGVsc2Uge1xuICAgIHZhbHVlIHw9IDA7XG4gICAgaWYgKGNhY2hlID0gKC0xMjggPD0gdmFsdWUgJiYgdmFsdWUgPCAxMjgpKSB7XG4gICAgICBjYWNoZWRPYmogPSBJTlRfQ0FDSEVbdmFsdWVdO1xuICAgICAgaWYgKGNhY2hlZE9iailcbiAgICAgICAgcmV0dXJuIGNhY2hlZE9iajtcbiAgICB9XG4gICAgb2JqID0gZnJvbUJpdHModmFsdWUsIHZhbHVlIDwgMCA/IC0xIDogMCwgZmFsc2UpO1xuICAgIGlmIChjYWNoZSlcbiAgICAgIElOVF9DQUNIRVt2YWx1ZV0gPSBvYmo7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gMzIgYml0IGludGVnZXIgdmFsdWUuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgMzIgYml0IGludGVnZXIgaW4gcXVlc3Rpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICovXG5Mb25nLmZyb21JbnQgPSBmcm9tSW50O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWRcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG5mdW5jdGlvbiBmcm9tTnVtYmVyKHZhbHVlLCB1bnNpZ25lZCkge1xuICBpZiAoaXNOYU4odmFsdWUpKVxuICAgIHJldHVybiB1bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcbiAgaWYgKHVuc2lnbmVkKSB7XG4gICAgaWYgKHZhbHVlIDwgMClcbiAgICAgIHJldHVybiBVWkVSTztcbiAgICBpZiAodmFsdWUgPj0gVFdPX1BXUl82NF9EQkwpXG4gICAgICByZXR1cm4gTUFYX1VOU0lHTkVEX1ZBTFVFO1xuICB9IGVsc2Uge1xuICAgIGlmICh2YWx1ZSA8PSAtVFdPX1BXUl82M19EQkwpXG4gICAgICByZXR1cm4gTUlOX1ZBTFVFO1xuICAgIGlmICh2YWx1ZSArIDEgPj0gVFdPX1BXUl82M19EQkwpXG4gICAgICByZXR1cm4gTUFYX1ZBTFVFO1xuICB9XG4gIGlmICh2YWx1ZSA8IDApXG4gICAgcmV0dXJuIGZyb21OdW1iZXIoLXZhbHVlLCB1bnNpZ25lZCkubmVnKCk7XG4gIHJldHVybiBmcm9tQml0cygodmFsdWUgJSBUV09fUFdSXzMyX0RCTCkgfCAwLCAodmFsdWUgLyBUV09fUFdSXzMyX0RCTCkgfCAwLCB1bnNpZ25lZCk7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiB2YWx1ZSwgcHJvdmlkZWQgdGhhdCBpdCBpcyBhIGZpbml0ZSBudW1iZXIuIE90aGVyd2lzZSwgemVybyBpcyByZXR1cm5lZC5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBudW1iZXIgaW4gcXVlc3Rpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICovXG5Mb25nLmZyb21OdW1iZXIgPSBmcm9tTnVtYmVyO1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBsb3dCaXRzXG4gKiBAcGFyYW0ge251bWJlcn0gaGlnaEJpdHNcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbUJpdHMobG93Qml0cywgaGlnaEJpdHMsIHVuc2lnbmVkKSB7XG4gIHJldHVybiBuZXcgTG9uZyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgNjQgYml0IGludGVnZXIgdGhhdCBjb21lcyBieSBjb25jYXRlbmF0aW5nIHRoZSBnaXZlbiBsb3cgYW5kIGhpZ2ggYml0cy4gRWFjaCBpc1xuICogIGFzc3VtZWQgdG8gdXNlIDMyIGJpdHMuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSBsb3dCaXRzIFRoZSBsb3cgMzIgYml0c1xuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzIFRoZSBoaWdoIDMyIGJpdHNcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICovXG5Mb25nLmZyb21CaXRzID0gZnJvbUJpdHM7XG5cbi8qKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gYmFzZVxuICogQHBhcmFtIHtudW1iZXJ9IGV4cG9uZW50XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICogQGlubmVyXG4gKi9cbnZhciBwb3dfZGJsID0gTWF0aC5wb3c7IC8vIFVzZWQgNCB0aW1lcyAoNCo4IHRvIDE1KzQpXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICogQHBhcmFtIHsoYm9vbGVhbnxudW1iZXIpPX0gdW5zaWduZWRcbiAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXhcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG5mdW5jdGlvbiBmcm9tU3RyaW5nKHN0ciwgdW5zaWduZWQsIHJhZGl4KSB7XG4gIGlmIChzdHIubGVuZ3RoID09PSAwKVxuICAgIHRocm93IEVycm9yKCdlbXB0eSBzdHJpbmcnKTtcbiAgaWYgKHR5cGVvZiB1bnNpZ25lZCA9PT0gJ251bWJlcicpIHtcbiAgICAvLyBGb3IgZ29vZy5tYXRoLmxvbmcgY29tcGF0aWJpbGl0eVxuICAgIHJhZGl4ID0gdW5zaWduZWQ7XG4gICAgdW5zaWduZWQgPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICB1bnNpZ25lZCA9ICEhdW5zaWduZWQ7XG4gIH1cbiAgaWYgKHN0ciA9PT0gXCJOYU5cIiB8fCBzdHIgPT09IFwiSW5maW5pdHlcIiB8fCBzdHIgPT09IFwiK0luZmluaXR5XCIgfHwgc3RyID09PSBcIi1JbmZpbml0eVwiKVxuICAgIHJldHVybiB1bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcbiAgcmFkaXggPSByYWRpeCB8fCAxMDtcbiAgaWYgKHJhZGl4IDwgMiB8fCAzNiA8IHJhZGl4KVxuICAgIHRocm93IFJhbmdlRXJyb3IoJ3JhZGl4Jyk7XG5cbiAgdmFyIHA7XG4gIGlmICgocCA9IHN0ci5pbmRleE9mKCctJykpID4gMClcbiAgICB0aHJvdyBFcnJvcignaW50ZXJpb3IgaHlwaGVuJyk7XG4gIGVsc2UgaWYgKHAgPT09IDApIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyhzdHIuc3Vic3RyaW5nKDEpLCB1bnNpZ25lZCwgcmFkaXgpLm5lZygpO1xuICB9XG5cbiAgLy8gRG8gc2V2ZXJhbCAoOCkgZGlnaXRzIGVhY2ggdGltZSB0aHJvdWdoIHRoZSBsb29wLCBzbyBhcyB0b1xuICAvLyBtaW5pbWl6ZSB0aGUgY2FsbHMgdG8gdGhlIHZlcnkgZXhwZW5zaXZlIGVtdWxhdGVkIGRpdi5cbiAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgOCkpO1xuXG4gIHZhciByZXN1bHQgPSBaRVJPO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkgKz0gOCkge1xuICAgIHZhciBzaXplID0gTWF0aC5taW4oOCwgc3RyLmxlbmd0aCAtIGkpLFxuICAgICAgdmFsdWUgPSBwYXJzZUludChzdHIuc3Vic3RyaW5nKGksIGkgKyBzaXplKSwgcmFkaXgpO1xuICAgIGlmIChzaXplIDwgOCkge1xuICAgICAgdmFyIHBvd2VyID0gZnJvbU51bWJlcihwb3dfZGJsKHJhZGl4LCBzaXplKSk7XG4gICAgICByZXN1bHQgPSByZXN1bHQubXVsKHBvd2VyKS5hZGQoZnJvbU51bWJlcih2YWx1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQubXVsKHJhZGl4VG9Qb3dlcik7XG4gICAgICByZXN1bHQgPSByZXN1bHQuYWRkKGZyb21OdW1iZXIodmFsdWUpKTtcbiAgICB9XG4gIH1cbiAgcmVzdWx0LnVuc2lnbmVkID0gdW5zaWduZWQ7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIHN0cmluZywgd3JpdHRlbiB1c2luZyB0aGUgc3BlY2lmaWVkIHJhZGl4LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBMb25nXG4gKiBAcGFyYW0geyhib29sZWFufG51bWJlcik9fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4IFRoZSByYWRpeCBpbiB3aGljaCB0aGUgdGV4dCBpcyB3cml0dGVuICgyLTM2KSwgZGVmYXVsdHMgdG8gMTBcbiAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICovXG5Mb25nLmZyb21TdHJpbmcgPSBmcm9tU3RyaW5nO1xuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfCF7bG93OiBudW1iZXIsIGhpZ2g6IG51bWJlciwgdW5zaWduZWQ6IGJvb2xlYW59fSB2YWxcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xuZnVuY3Rpb24gZnJvbVZhbHVlKHZhbCwgdW5zaWduZWQpIHtcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKVxuICAgIHJldHVybiBmcm9tTnVtYmVyKHZhbCwgdW5zaWduZWQpO1xuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpXG4gICAgcmV0dXJuIGZyb21TdHJpbmcodmFsLCB1bnNpZ25lZCk7XG4gIC8vIFRocm93cyBmb3Igbm9uLW9iamVjdHMsIGNvbnZlcnRzIG5vbi1pbnN0YW5jZW9mIExvbmc6XG4gIHJldHVybiBmcm9tQml0cyh2YWwubG93LCB2YWwuaGlnaCwgdHlwZW9mIHVuc2lnbmVkID09PSAnYm9vbGVhbicgPyB1bnNpZ25lZCA6IHZhbC51bnNpZ25lZCk7XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIHNwZWNpZmllZCB2YWx1ZSB0byBhIExvbmcgdXNpbmcgdGhlIGFwcHJvcHJpYXRlIGZyb20qIGZ1bmN0aW9uIGZvciBpdHMgdHlwZS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfCF7bG93OiBudW1iZXIsIGhpZ2g6IG51bWJlciwgdW5zaWduZWQ6IGJvb2xlYW59fSB2YWwgVmFsdWVcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqL1xuTG9uZy5mcm9tVmFsdWUgPSBmcm9tVmFsdWU7XG5cbi8vIE5PVEU6IHRoZSBjb21waWxlciBzaG91bGQgaW5saW5lIHRoZXNlIGNvbnN0YW50IHZhbHVlcyBiZWxvdyBhbmQgdGhlbiByZW1vdmUgdGhlc2UgdmFyaWFibGVzLCBzbyB0aGVyZSBzaG91bGQgYmVcbi8vIG5vIHJ1bnRpbWUgcGVuYWx0eSBmb3IgdGhlc2UuXG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzE2X0RCTCA9IDEgPDwgMTY7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzI0X0RCTCA9IDEgPDwgMjQ7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzMyX0RCTCA9IFRXT19QV1JfMTZfREJMICogVFdPX1BXUl8xNl9EQkw7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzY0X0RCTCA9IFRXT19QV1JfMzJfREJMICogVFdPX1BXUl8zMl9EQkw7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICogQGlubmVyXG4gKi9cbnZhciBUV09fUFdSXzYzX0RCTCA9IFRXT19QV1JfNjRfREJMIC8gMjtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAY29uc3RcbiAqIEBpbm5lclxuICovXG52YXIgVFdPX1BXUl8yNCA9IGZyb21JbnQoVFdPX1BXUl8yNF9EQkwpO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgWkVSTyA9IGZyb21JbnQoMCk7XG5cbi8qKlxuICogU2lnbmVkIHplcm8uXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuWkVSTyA9IFpFUk87XG5cbi8qKlxuICogQHR5cGUgeyFMb25nfVxuICogQGlubmVyXG4gKi9cbnZhciBVWkVSTyA9IGZyb21JbnQoMCwgdHJ1ZSk7XG5cbi8qKlxuICogVW5zaWduZWQgemVyby5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5VWkVSTyA9IFVaRVJPO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgT05FID0gZnJvbUludCgxKTtcblxuLyoqXG4gKiBTaWduZWQgb25lLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLk9ORSA9IE9ORTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIFVPTkUgPSBmcm9tSW50KDEsIHRydWUpO1xuXG4vKipcbiAqIFVuc2lnbmVkIG9uZS5cbiAqIEB0eXBlIHshTG9uZ31cbiAqL1xuTG9uZy5VT05FID0gVU9ORTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIE5FR19PTkUgPSBmcm9tSW50KC0xKTtcblxuLyoqXG4gKiBTaWduZWQgbmVnYXRpdmUgb25lLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLk5FR19PTkUgPSBORUdfT05FO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgTUFYX1ZBTFVFID0gZnJvbUJpdHMoMHhGRkZGRkZGRiB8IDAsIDB4N0ZGRkZGRkYgfCAwLCBmYWxzZSk7XG5cbi8qKlxuICogTWF4aW11bSBzaWduZWQgdmFsdWUuXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuTUFYX1ZBTFVFID0gTUFYX1ZBTFVFO1xuXG4vKipcbiAqIEB0eXBlIHshTG9uZ31cbiAqIEBpbm5lclxuICovXG52YXIgTUFYX1VOU0lHTkVEX1ZBTFVFID0gZnJvbUJpdHMoMHhGRkZGRkZGRiB8IDAsIDB4RkZGRkZGRkYgfCAwLCB0cnVlKTtcblxuLyoqXG4gKiBNYXhpbXVtIHVuc2lnbmVkIHZhbHVlLlxuICogQHR5cGUgeyFMb25nfVxuICovXG5Mb25nLk1BWF9VTlNJR05FRF9WQUxVRSA9IE1BWF9VTlNJR05FRF9WQUxVRTtcblxuLyoqXG4gKiBAdHlwZSB7IUxvbmd9XG4gKiBAaW5uZXJcbiAqL1xudmFyIE1JTl9WQUxVRSA9IGZyb21CaXRzKDAsIDB4ODAwMDAwMDAgfCAwLCBmYWxzZSk7XG5cbi8qKlxuICogTWluaW11bSBzaWduZWQgdmFsdWUuXG4gKiBAdHlwZSB7IUxvbmd9XG4gKi9cbkxvbmcuTUlOX1ZBTFVFID0gTUlOX1ZBTFVFO1xuXG4vKipcbiAqIEBhbGlhcyBMb25nLnByb3RvdHlwZVxuICogQGlubmVyXG4gKi9cbnZhciBMb25nUHJvdG90eXBlID0gTG9uZy5wcm90b3R5cGU7XG5cbi8qKlxuICogQ29udmVydHMgdGhlIExvbmcgdG8gYSAzMiBiaXQgaW50ZWdlciwgYXNzdW1pbmcgaXQgaXMgYSAzMiBiaXQgaW50ZWdlci5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUudG9JbnQgPSBmdW5jdGlvbiB0b0ludCgpIHtcbiAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyB0aGlzLmxvdyA+Pj4gMCA6IHRoaXMubG93O1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgTG9uZyB0byBhIHRoZSBuZWFyZXN0IGZsb2F0aW5nLXBvaW50IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgdmFsdWUgKGRvdWJsZSwgNTMgYml0IG1hbnRpc3NhKS5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUudG9OdW1iZXIgPSBmdW5jdGlvbiB0b051bWJlcigpIHtcbiAgaWYgKHRoaXMudW5zaWduZWQpXG4gICAgcmV0dXJuICgodGhpcy5oaWdoID4+PiAwKSAqIFRXT19QV1JfMzJfREJMKSArICh0aGlzLmxvdyA+Pj4gMCk7XG4gIHJldHVybiB0aGlzLmhpZ2ggKiBUV09fUFdSXzMyX0RCTCArICh0aGlzLmxvdyA+Pj4gMCk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgc3RyaW5nIHdyaXR0ZW4gaW4gdGhlIHNwZWNpZmllZCByYWRpeC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXggUmFkaXggKDItMzYpLCBkZWZhdWx0cyB0byAxMFxuICogQHJldHVybnMge3N0cmluZ31cbiAqIEBvdmVycmlkZVxuICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYHJhZGl4YCBpcyBvdXQgb2YgcmFuZ2VcbiAqL1xuTG9uZ1Byb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKHJhZGl4KSB7XG4gIHJhZGl4ID0gcmFkaXggfHwgMTA7XG4gIGlmIChyYWRpeCA8IDIgfHwgMzYgPCByYWRpeClcbiAgICB0aHJvdyBSYW5nZUVycm9yKCdyYWRpeCcpO1xuICBpZiAodGhpcy5pc1plcm8oKSlcbiAgICByZXR1cm4gJzAnO1xuICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIHsgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXG4gICAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSkge1xuICAgICAgLy8gV2UgbmVlZCB0byBjaGFuZ2UgdGhlIExvbmcgdmFsdWUgYmVmb3JlIGl0IGNhbiBiZSBuZWdhdGVkLCBzbyB3ZSByZW1vdmVcbiAgICAgIC8vIHRoZSBib3R0b20tbW9zdCBkaWdpdCBpbiB0aGlzIGJhc2UgYW5kIHRoZW4gcmVjdXJzZSB0byBkbyB0aGUgcmVzdC5cbiAgICAgIHZhciByYWRpeExvbmcgPSBmcm9tTnVtYmVyKHJhZGl4KSxcbiAgICAgICAgZGl2ID0gdGhpcy5kaXYocmFkaXhMb25nKSxcbiAgICAgICAgcmVtMSA9IGRpdi5tdWwocmFkaXhMb25nKS5zdWIodGhpcyk7XG4gICAgICByZXR1cm4gZGl2LnRvU3RyaW5nKHJhZGl4KSArIHJlbTEudG9JbnQoKS50b1N0cmluZyhyYWRpeCk7XG4gICAgfSBlbHNlXG4gICAgICByZXR1cm4gJy0nICsgdGhpcy5uZWcoKS50b1N0cmluZyhyYWRpeCk7XG4gIH1cblxuICAvLyBEbyBzZXZlcmFsICg2KSBkaWdpdHMgZWFjaCB0aW1lIHRocm91Z2ggdGhlIGxvb3AsIHNvIGFzIHRvXG4gIC8vIG1pbmltaXplIHRoZSBjYWxscyB0byB0aGUgdmVyeSBleHBlbnNpdmUgZW11bGF0ZWQgZGl2LlxuICB2YXIgcmFkaXhUb1Bvd2VyID0gZnJvbU51bWJlcihwb3dfZGJsKHJhZGl4LCA2KSwgdGhpcy51bnNpZ25lZCksXG4gICAgcmVtID0gdGhpcztcbiAgdmFyIHJlc3VsdCA9ICcnO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHZhciByZW1EaXYgPSByZW0uZGl2KHJhZGl4VG9Qb3dlciksXG4gICAgICBpbnR2YWwgPSByZW0uc3ViKHJlbURpdi5tdWwocmFkaXhUb1Bvd2VyKSkudG9JbnQoKSA+Pj4gMCxcbiAgICAgIGRpZ2l0cyA9IGludHZhbC50b1N0cmluZyhyYWRpeCk7XG4gICAgcmVtID0gcmVtRGl2O1xuICAgIGlmIChyZW0uaXNaZXJvKCkpXG4gICAgICByZXR1cm4gZGlnaXRzICsgcmVzdWx0O1xuICAgIGVsc2Uge1xuICAgICAgd2hpbGUgKGRpZ2l0cy5sZW5ndGggPCA2KVxuICAgICAgICBkaWdpdHMgPSAnMCcgKyBkaWdpdHM7XG4gICAgICByZXN1bHQgPSAnJyArIGRpZ2l0cyArIHJlc3VsdDtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogR2V0cyB0aGUgaGlnaCAzMiBiaXRzIGFzIGEgc2lnbmVkIGludGVnZXIuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgaGlnaCBiaXRzXG4gKi9cbkxvbmdQcm90b3R5cGUuZ2V0SGlnaEJpdHMgPSBmdW5jdGlvbiBnZXRIaWdoQml0cygpIHtcbiAgcmV0dXJuIHRoaXMuaGlnaDtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgaGlnaCAzMiBiaXRzIGFzIGFuIHVuc2lnbmVkIGludGVnZXIuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBoaWdoIGJpdHNcbiAqL1xuTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0SGlnaEJpdHNVbnNpZ25lZCgpIHtcbiAgcmV0dXJuIHRoaXMuaGlnaCA+Pj4gMDtcbn07XG5cbi8qKlxuICogR2V0cyB0aGUgbG93IDMyIGJpdHMgYXMgYSBzaWduZWQgaW50ZWdlci5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFNpZ25lZCBsb3cgYml0c1xuICovXG5Mb25nUHJvdG90eXBlLmdldExvd0JpdHMgPSBmdW5jdGlvbiBnZXRMb3dCaXRzKCkge1xuICByZXR1cm4gdGhpcy5sb3c7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIGxvdyAzMiBiaXRzIGFzIGFuIHVuc2lnbmVkIGludGVnZXIuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBsb3cgYml0c1xuICovXG5Mb25nUHJvdG90eXBlLmdldExvd0JpdHNVbnNpZ25lZCA9IGZ1bmN0aW9uIGdldExvd0JpdHNVbnNpZ25lZCgpIHtcbiAgcmV0dXJuIHRoaXMubG93ID4+PiAwO1xufTtcblxuLyoqXG4gKiBHZXRzIHRoZSBudW1iZXIgb2YgYml0cyBuZWVkZWQgdG8gcmVwcmVzZW50IHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGlzIExvbmcuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLmdldE51bUJpdHNBYnMgPSBmdW5jdGlvbiBnZXROdW1CaXRzQWJzKCkge1xuICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxuICAgIHJldHVybiB0aGlzLmVxKE1JTl9WQUxVRSkgPyA2NCA6IHRoaXMubmVnKCkuZ2V0TnVtQml0c0FicygpO1xuICB2YXIgdmFsID0gdGhpcy5oaWdoICE9IDAgPyB0aGlzLmhpZ2ggOiB0aGlzLmxvdztcbiAgZm9yICh2YXIgYml0ID0gMzE7IGJpdCA+IDA7IGJpdC0tKVxuICAgIGlmICgodmFsICYgKDEgPDwgYml0KSkgIT0gMClcbiAgICAgIGJyZWFrO1xuICByZXR1cm4gdGhpcy5oaWdoICE9IDAgPyBiaXQgKyAzMyA6IGJpdCArIDE7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB6ZXJvLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuaXNaZXJvID0gZnVuY3Rpb24gaXNaZXJvKCkge1xuICByZXR1cm4gdGhpcy5oaWdoID09PSAwICYmIHRoaXMubG93ID09PSAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgemVyby4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNpc1plcm99LlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuZXF6ID0gTG9uZ1Byb3RvdHlwZS5pc1plcm87XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbmVnYXRpdmUuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5pc05lZ2F0aXZlID0gZnVuY3Rpb24gaXNOZWdhdGl2ZSgpIHtcbiAgcmV0dXJuICF0aGlzLnVuc2lnbmVkICYmIHRoaXMuaGlnaCA8IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIHBvc2l0aXZlIG9yIHplcm8uXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5pc1Bvc2l0aXZlID0gZnVuY3Rpb24gaXNQb3NpdGl2ZSgpIHtcbiAgcmV0dXJuIHRoaXMudW5zaWduZWQgfHwgdGhpcy5oaWdoID49IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIG9kZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmlzT2RkID0gZnVuY3Rpb24gaXNPZGQoKSB7XG4gIHJldHVybiAodGhpcy5sb3cgJiAxKSA9PT0gMTtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZXZlbi5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmlzRXZlbiA9IGZ1bmN0aW9uIGlzRXZlbigpIHtcbiAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSlcbiAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XG4gIGlmICh0aGlzLnVuc2lnbmVkICE9PSBvdGhlci51bnNpZ25lZCAmJiAodGhpcy5oaWdoID4+PiAzMSkgPT09IDEgJiYgKG90aGVyLmhpZ2ggPj4+IDMxKSA9PT0gMSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0aGlzLmhpZ2ggPT09IG90aGVyLmhpZ2ggJiYgdGhpcy5sb3cgPT09IG90aGVyLmxvdztcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNlcXVhbHN9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5lcSA9IExvbmdQcm90b3R5cGUuZXF1YWxzO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHMgPSBmdW5jdGlvbiBub3RFcXVhbHMob3RoZXIpIHtcbiAgcmV0dXJuICF0aGlzLmVxKC8qIHZhbGlkYXRlcyAqLyBvdGhlcik7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUubmVxID0gTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHM7XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNub3RFcXVhbHN9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5uZSA9IExvbmdQcm90b3R5cGUubm90RXF1YWxzO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbiA9IGZ1bmN0aW9uIGxlc3NUaGFuKG90aGVyKSB7XG4gIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA8IDA7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW59LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5sdCA9IExvbmdQcm90b3R5cGUubGVzc1RoYW47XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmxlc3NUaGFuT3JFcXVhbCA9IGZ1bmN0aW9uIGxlc3NUaGFuT3JFcXVhbChvdGhlcikge1xuICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPD0gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbk9yRXF1YWx9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5sdGUgPSBMb25nUHJvdG90eXBlLmxlc3NUaGFuT3JFcXVhbDtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFuT3JFcXVhbH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmxlID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWw7XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQncy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuID0gZnVuY3Rpb24gZ3JlYXRlclRoYW4ob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID4gMDtcbn07XG5cbi8qKlxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbn0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmd0ID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbjtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsID0gZnVuY3Rpb24gZ3JlYXRlclRoYW5PckVxdWFsKG90aGVyKSB7XG4gIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA+PSAwO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2dyZWF0ZXJUaGFuT3JFcXVhbH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5Mb25nUHJvdG90eXBlLmd0ZSA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsO1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW5PckVxdWFsfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkxvbmdQcm90b3R5cGUuZ2UgPSBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbDtcblxuLyoqXG4gKiBDb21wYXJlcyB0aGlzIExvbmcncyB2YWx1ZSB3aXRoIHRoZSBzcGVjaWZpZWQncy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIDEgaWYgdGhlIHRoaXMgaXMgZ3JlYXRlciBhbmQgLTFcbiAqICBpZiB0aGUgZ2l2ZW4gb25lIGlzIGdyZWF0ZXJcbiAqL1xuTG9uZ1Byb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZShvdGhlcikge1xuICBpZiAoIWlzTG9uZyhvdGhlcikpXG4gICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICBpZiAodGhpcy5lcShvdGhlcikpXG4gICAgcmV0dXJuIDA7XG4gIHZhciB0aGlzTmVnID0gdGhpcy5pc05lZ2F0aXZlKCksXG4gICAgb3RoZXJOZWcgPSBvdGhlci5pc05lZ2F0aXZlKCk7XG4gIGlmICh0aGlzTmVnICYmICFvdGhlck5lZylcbiAgICByZXR1cm4gLTE7XG4gIGlmICghdGhpc05lZyAmJiBvdGhlck5lZylcbiAgICByZXR1cm4gMTtcbiAgLy8gQXQgdGhpcyBwb2ludCB0aGUgc2lnbiBiaXRzIGFyZSB0aGUgc2FtZVxuICBpZiAoIXRoaXMudW5zaWduZWQpXG4gICAgcmV0dXJuIHRoaXMuc3ViKG90aGVyKS5pc05lZ2F0aXZlKCkgPyAtMSA6IDE7XG4gIC8vIEJvdGggYXJlIHBvc2l0aXZlIGlmIGF0IGxlYXN0IG9uZSBpcyB1bnNpZ25lZFxuICByZXR1cm4gKG90aGVyLmhpZ2ggPj4+IDApID4gKHRoaXMuaGlnaCA+Pj4gMCkgfHwgKG90aGVyLmhpZ2ggPT09IHRoaXMuaGlnaCAmJiAob3RoZXIubG93ID4+PiAwKSA+ICh0aGlzLmxvdyA+Pj4gMCkpID8gLTEgOiAxO1xufTtcblxuLyoqXG4gKiBDb21wYXJlcyB0aGlzIExvbmcncyB2YWx1ZSB3aXRoIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNjb21wYXJlfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxuICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxuICogIGlmIHRoZSBnaXZlbiBvbmUgaXMgZ3JlYXRlclxuICovXG5Mb25nUHJvdG90eXBlLmNvbXAgPSBMb25nUHJvdG90eXBlLmNvbXBhcmU7XG5cbi8qKlxuICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUubmVnYXRlID0gZnVuY3Rpb24gbmVnYXRlKCkge1xuICBpZiAoIXRoaXMudW5zaWduZWQgJiYgdGhpcy5lcShNSU5fVkFMVUUpKVxuICAgIHJldHVybiBNSU5fVkFMVUU7XG4gIHJldHVybiB0aGlzLm5vdCgpLmFkZChPTkUpO1xufTtcblxuLyoqXG4gKiBOZWdhdGVzIHRoaXMgTG9uZydzIHZhbHVlLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI25lZ2F0ZX0uXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUubmVnID0gTG9uZ1Byb3RvdHlwZS5uZWdhdGU7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3VtIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gYWRkZW5kIEFkZGVuZFxuICogQHJldHVybnMgeyFMb25nfSBTdW1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQoYWRkZW5kKSB7XG4gIGlmICghaXNMb25nKGFkZGVuZCkpXG4gICAgYWRkZW5kID0gZnJvbVZhbHVlKGFkZGVuZCk7XG5cbiAgLy8gRGl2aWRlIGVhY2ggbnVtYmVyIGludG8gNCBjaHVua3Mgb2YgMTYgYml0cywgYW5kIHRoZW4gc3VtIHRoZSBjaHVua3MuXG5cbiAgdmFyIGE0OCA9IHRoaXMuaGlnaCA+Pj4gMTY7XG4gIHZhciBhMzIgPSB0aGlzLmhpZ2ggJiAweEZGRkY7XG4gIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XG4gIHZhciBhMDAgPSB0aGlzLmxvdyAmIDB4RkZGRjtcblxuICB2YXIgYjQ4ID0gYWRkZW5kLmhpZ2ggPj4+IDE2O1xuICB2YXIgYjMyID0gYWRkZW5kLmhpZ2ggJiAweEZGRkY7XG4gIHZhciBiMTYgPSBhZGRlbmQubG93ID4+PiAxNjtcbiAgdmFyIGIwMCA9IGFkZGVuZC5sb3cgJiAweEZGRkY7XG5cbiAgdmFyIGM0OCA9IDAsIGMzMiA9IDAsIGMxNiA9IDAsIGMwMCA9IDA7XG4gIGMwMCArPSBhMDAgKyBiMDA7XG4gIGMxNiArPSBjMDAgPj4+IDE2O1xuICBjMDAgJj0gMHhGRkZGO1xuICBjMTYgKz0gYTE2ICsgYjE2O1xuICBjMzIgKz0gYzE2ID4+PiAxNjtcbiAgYzE2ICY9IDB4RkZGRjtcbiAgYzMyICs9IGEzMiArIGIzMjtcbiAgYzQ4ICs9IGMzMiA+Pj4gMTY7XG4gIGMzMiAmPSAweEZGRkY7XG4gIGM0OCArPSBhNDggKyBiNDg7XG4gIGM0OCAmPSAweEZGRkY7XG4gIHJldHVybiBmcm9tQml0cygoYzE2IDw8IDE2KSB8IGMwMCwgKGM0OCA8PCAxNikgfCBjMzIsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gc3VidHJhaGVuZCBTdWJ0cmFoZW5kXG4gKiBAcmV0dXJucyB7IUxvbmd9IERpZmZlcmVuY2VcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdCA9IGZ1bmN0aW9uIHN1YnRyYWN0KHN1YnRyYWhlbmQpIHtcbiAgaWYgKCFpc0xvbmcoc3VidHJhaGVuZCkpXG4gICAgc3VidHJhaGVuZCA9IGZyb21WYWx1ZShzdWJ0cmFoZW5kKTtcbiAgcmV0dXJuIHRoaXMuYWRkKHN1YnRyYWhlbmQubmVnKCkpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzdWJ0cmFjdH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gc3VidHJhaGVuZCBTdWJ0cmFoZW5kXG4gKiBAcmV0dXJucyB7IUxvbmd9IERpZmZlcmVuY2VcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zdWIgPSBMb25nUHJvdG90eXBlLnN1YnRyYWN0O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBtdWx0aXBsaWVyIE11bHRpcGxpZXJcbiAqIEByZXR1cm5zIHshTG9uZ30gUHJvZHVjdFxuICovXG5Mb25nUHJvdG90eXBlLm11bHRpcGx5ID0gZnVuY3Rpb24gbXVsdGlwbHkobXVsdGlwbGllcikge1xuICBpZiAodGhpcy5pc1plcm8oKSlcbiAgICByZXR1cm4gdGhpcztcbiAgaWYgKCFpc0xvbmcobXVsdGlwbGllcikpXG4gICAgbXVsdGlwbGllciA9IGZyb21WYWx1ZShtdWx0aXBsaWVyKTtcblxuICAvLyB1c2Ugd2FzbSBzdXBwb3J0IGlmIHByZXNlbnRcbiAgaWYgKHdhc20pIHtcbiAgICB2YXIgbG93ID0gd2FzbVtcIm11bFwiXSh0aGlzLmxvdyxcbiAgICAgIHRoaXMuaGlnaCxcbiAgICAgIG11bHRpcGxpZXIubG93LFxuICAgICAgbXVsdGlwbGllci5oaWdoKTtcbiAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtW1wiZ2V0X2hpZ2hcIl0oKSwgdGhpcy51bnNpZ25lZCk7XG4gIH1cblxuICBpZiAobXVsdGlwbGllci5pc1plcm8oKSlcbiAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcbiAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSlcbiAgICByZXR1cm4gbXVsdGlwbGllci5pc09kZCgpID8gTUlOX1ZBTFVFIDogWkVSTztcbiAgaWYgKG11bHRpcGxpZXIuZXEoTUlOX1ZBTFVFKSlcbiAgICByZXR1cm4gdGhpcy5pc09kZCgpID8gTUlOX1ZBTFVFIDogWkVSTztcblxuICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIHtcbiAgICBpZiAobXVsdGlwbGllci5pc05lZ2F0aXZlKCkpXG4gICAgICByZXR1cm4gdGhpcy5uZWcoKS5tdWwobXVsdGlwbGllci5uZWcoKSk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMubmVnKCkubXVsKG11bHRpcGxpZXIpLm5lZygpO1xuICB9IGVsc2UgaWYgKG11bHRpcGxpZXIuaXNOZWdhdGl2ZSgpKVxuICAgIHJldHVybiB0aGlzLm11bChtdWx0aXBsaWVyLm5lZygpKS5uZWcoKTtcblxuICAvLyBJZiBib3RoIGxvbmdzIGFyZSBzbWFsbCwgdXNlIGZsb2F0IG11bHRpcGxpY2F0aW9uXG4gIGlmICh0aGlzLmx0KFRXT19QV1JfMjQpICYmIG11bHRpcGxpZXIubHQoVFdPX1BXUl8yNCkpXG4gICAgcmV0dXJuIGZyb21OdW1iZXIodGhpcy50b051bWJlcigpICogbXVsdGlwbGllci50b051bWJlcigpLCB0aGlzLnVuc2lnbmVkKTtcblxuICAvLyBEaXZpZGUgZWFjaCBsb25nIGludG8gNCBjaHVua3Mgb2YgMTYgYml0cywgYW5kIHRoZW4gYWRkIHVwIDR4NCBwcm9kdWN0cy5cbiAgLy8gV2UgY2FuIHNraXAgcHJvZHVjdHMgdGhhdCB3b3VsZCBvdmVyZmxvdy5cblxuICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcbiAgdmFyIGEzMiA9IHRoaXMuaGlnaCAmIDB4RkZGRjtcbiAgdmFyIGExNiA9IHRoaXMubG93ID4+PiAxNjtcbiAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhGRkZGO1xuXG4gIHZhciBiNDggPSBtdWx0aXBsaWVyLmhpZ2ggPj4+IDE2O1xuICB2YXIgYjMyID0gbXVsdGlwbGllci5oaWdoICYgMHhGRkZGO1xuICB2YXIgYjE2ID0gbXVsdGlwbGllci5sb3cgPj4+IDE2O1xuICB2YXIgYjAwID0gbXVsdGlwbGllci5sb3cgJiAweEZGRkY7XG5cbiAgdmFyIGM0OCA9IDAsIGMzMiA9IDAsIGMxNiA9IDAsIGMwMCA9IDA7XG4gIGMwMCArPSBhMDAgKiBiMDA7XG4gIGMxNiArPSBjMDAgPj4+IDE2O1xuICBjMDAgJj0gMHhGRkZGO1xuICBjMTYgKz0gYTE2ICogYjAwO1xuICBjMzIgKz0gYzE2ID4+PiAxNjtcbiAgYzE2ICY9IDB4RkZGRjtcbiAgYzE2ICs9IGEwMCAqIGIxNjtcbiAgYzMyICs9IGMxNiA+Pj4gMTY7XG4gIGMxNiAmPSAweEZGRkY7XG4gIGMzMiArPSBhMzIgKiBiMDA7XG4gIGM0OCArPSBjMzIgPj4+IDE2O1xuICBjMzIgJj0gMHhGRkZGO1xuICBjMzIgKz0gYTE2ICogYjE2O1xuICBjNDggKz0gYzMyID4+PiAxNjtcbiAgYzMyICY9IDB4RkZGRjtcbiAgYzMyICs9IGEwMCAqIGIzMjtcbiAgYzQ4ICs9IGMzMiA+Pj4gMTY7XG4gIGMzMiAmPSAweEZGRkY7XG4gIGM0OCArPSBhNDggKiBiMDAgKyBhMzIgKiBiMTYgKyBhMTYgKiBiMzIgKyBhMDAgKiBiNDg7XG4gIGM0OCAmPSAweEZGRkY7XG4gIHJldHVybiBmcm9tQml0cygoYzE2IDw8IDE2KSB8IGMwMCwgKGM0OCA8PCAxNikgfCBjMzIsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBwcm9kdWN0IG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNtdWx0aXBseX0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gbXVsdGlwbGllciBNdWx0aXBsaWVyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFByb2R1Y3RcbiAqL1xuTG9uZ1Byb3RvdHlwZS5tdWwgPSBMb25nUHJvdG90eXBlLm11bHRpcGx5O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhlIHJlc3VsdCBpcyBzaWduZWQgaWYgdGhpcyBMb25nIGlzIHNpZ25lZCBvclxuICogIHVuc2lnbmVkIGlmIHRoaXMgTG9uZyBpcyB1bnNpZ25lZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XG4gKi9cbkxvbmdQcm90b3R5cGUuZGl2aWRlID0gZnVuY3Rpb24gZGl2aWRlKGRpdmlzb3IpIHtcbiAgaWYgKCFpc0xvbmcoZGl2aXNvcikpXG4gICAgZGl2aXNvciA9IGZyb21WYWx1ZShkaXZpc29yKTtcbiAgaWYgKGRpdmlzb3IuaXNaZXJvKCkpXG4gICAgdGhyb3cgRXJyb3IoJ2RpdmlzaW9uIGJ5IHplcm8nKTtcblxuICAvLyB1c2Ugd2FzbSBzdXBwb3J0IGlmIHByZXNlbnRcbiAgaWYgKHdhc20pIHtcbiAgICAvLyBndWFyZCBhZ2FpbnN0IHNpZ25lZCBkaXZpc2lvbiBvdmVyZmxvdzogdGhlIGxhcmdlc3RcbiAgICAvLyBuZWdhdGl2ZSBudW1iZXIgLyAtMSB3b3VsZCBiZSAxIGxhcmdlciB0aGFuIHRoZSBsYXJnZXN0XG4gICAgLy8gcG9zaXRpdmUgbnVtYmVyLCBkdWUgdG8gdHdvJ3MgY29tcGxlbWVudC5cbiAgICBpZiAoIXRoaXMudW5zaWduZWQgJiZcbiAgICAgIHRoaXMuaGlnaCA9PT0gLTB4ODAwMDAwMDAgJiZcbiAgICAgIGRpdmlzb3IubG93ID09PSAtMSAmJiBkaXZpc29yLmhpZ2ggPT09IC0xKSB7XG4gICAgICAvLyBiZSBjb25zaXN0ZW50IHdpdGggbm9uLXdhc20gY29kZSBwYXRoXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdmFyIGxvdyA9ICh0aGlzLnVuc2lnbmVkID8gd2FzbVtcImRpdl91XCJdIDogd2FzbVtcImRpdl9zXCJdKShcbiAgICAgIHRoaXMubG93LFxuICAgICAgdGhpcy5oaWdoLFxuICAgICAgZGl2aXNvci5sb3csXG4gICAgICBkaXZpc29yLmhpZ2hcbiAgICApO1xuICAgIHJldHVybiBmcm9tQml0cyhsb3csIHdhc21bXCJnZXRfaGlnaFwiXSgpLCB0aGlzLnVuc2lnbmVkKTtcbiAgfVxuXG4gIGlmICh0aGlzLmlzWmVybygpKVxuICAgIHJldHVybiB0aGlzLnVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xuICB2YXIgYXBwcm94LCByZW0sIHJlcztcbiAgaWYgKCF0aGlzLnVuc2lnbmVkKSB7XG4gICAgLy8gVGhpcyBzZWN0aW9uIGlzIG9ubHkgcmVsZXZhbnQgZm9yIHNpZ25lZCBsb25ncyBhbmQgaXMgZGVyaXZlZCBmcm9tIHRoZVxuICAgIC8vIGNsb3N1cmUgbGlicmFyeSBhcyBhIHdob2xlLlxuICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcbiAgICAgIGlmIChkaXZpc29yLmVxKE9ORSkgfHwgZGl2aXNvci5lcShORUdfT05FKSlcbiAgICAgICAgcmV0dXJuIE1JTl9WQUxVRTsgIC8vIHJlY2FsbCB0aGF0IC1NSU5fVkFMVUUgPT0gTUlOX1ZBTFVFXG4gICAgICBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpXG4gICAgICAgIHJldHVybiBPTkU7XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgd2UgaGF2ZSB8b3RoZXJ8ID49IDIsIHNvIHx0aGlzL290aGVyfCA8IHxNSU5fVkFMVUV8LlxuICAgICAgICB2YXIgaGFsZlRoaXMgPSB0aGlzLnNocigxKTtcbiAgICAgICAgYXBwcm94ID0gaGFsZlRoaXMuZGl2KGRpdmlzb3IpLnNobCgxKTtcbiAgICAgICAgaWYgKGFwcHJveC5lcShaRVJPKSkge1xuICAgICAgICAgIHJldHVybiBkaXZpc29yLmlzTmVnYXRpdmUoKSA/IE9ORSA6IE5FR19PTkU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVtID0gdGhpcy5zdWIoZGl2aXNvci5tdWwoYXBwcm94KSk7XG4gICAgICAgICAgcmVzID0gYXBwcm94LmFkZChyZW0uZGl2KGRpdmlzb3IpKTtcbiAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpXG4gICAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcbiAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIHtcbiAgICAgIGlmIChkaXZpc29yLmlzTmVnYXRpdmUoKSlcbiAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkuZGl2KGRpdmlzb3IubmVnKCkpO1xuICAgICAgcmV0dXJuIHRoaXMubmVnKCkuZGl2KGRpdmlzb3IpLm5lZygpO1xuICAgIH0gZWxzZSBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpXG4gICAgICByZXR1cm4gdGhpcy5kaXYoZGl2aXNvci5uZWcoKSkubmVnKCk7XG4gICAgcmVzID0gWkVSTztcbiAgfSBlbHNlIHtcbiAgICAvLyBUaGUgYWxnb3JpdGhtIGJlbG93IGhhcyBub3QgYmVlbiBtYWRlIGZvciB1bnNpZ25lZCBsb25ncy4gSXQncyB0aGVyZWZvcmVcbiAgICAvLyByZXF1aXJlZCB0byB0YWtlIHNwZWNpYWwgY2FyZSBvZiB0aGUgTVNCIHByaW9yIHRvIHJ1bm5pbmcgaXQuXG4gICAgaWYgKCFkaXZpc29yLnVuc2lnbmVkKVxuICAgICAgZGl2aXNvciA9IGRpdmlzb3IudG9VbnNpZ25lZCgpO1xuICAgIGlmIChkaXZpc29yLmd0KHRoaXMpKVxuICAgICAgcmV0dXJuIFVaRVJPO1xuICAgIGlmIChkaXZpc29yLmd0KHRoaXMuc2hydSgxKSkpIC8vIDE1ID4+PiAxID0gNyA7IHdpdGggZGl2aXNvciA9IDggOyB0cnVlXG4gICAgICByZXR1cm4gVU9ORTtcbiAgICByZXMgPSBVWkVSTztcbiAgfVxuXG4gIC8vIFJlcGVhdCB0aGUgZm9sbG93aW5nIHVudGlsIHRoZSByZW1haW5kZXIgaXMgbGVzcyB0aGFuIG90aGVyOiAgZmluZCBhXG4gIC8vIGZsb2F0aW5nLXBvaW50IHRoYXQgYXBwcm94aW1hdGVzIHJlbWFpbmRlciAvIG90aGVyICpmcm9tIGJlbG93KiwgYWRkIHRoaXNcbiAgLy8gaW50byB0aGUgcmVzdWx0LCBhbmQgc3VidHJhY3QgaXQgZnJvbSB0aGUgcmVtYWluZGVyLiAgSXQgaXMgY3JpdGljYWwgdGhhdFxuICAvLyB0aGUgYXBwcm94aW1hdGUgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSByZWFsIHZhbHVlIHNvIHRoYXQgdGhlXG4gIC8vIHJlbWFpbmRlciBuZXZlciBiZWNvbWVzIG5lZ2F0aXZlLlxuICByZW0gPSB0aGlzO1xuICB3aGlsZSAocmVtLmd0ZShkaXZpc29yKSkge1xuICAgIC8vIEFwcHJveGltYXRlIHRoZSByZXN1bHQgb2YgZGl2aXNpb24uIFRoaXMgbWF5IGJlIGEgbGl0dGxlIGdyZWF0ZXIgb3JcbiAgICAvLyBzbWFsbGVyIHRoYW4gdGhlIGFjdHVhbCB2YWx1ZS5cbiAgICBhcHByb3ggPSBNYXRoLm1heCgxLCBNYXRoLmZsb29yKHJlbS50b051bWJlcigpIC8gZGl2aXNvci50b051bWJlcigpKSk7XG5cbiAgICAvLyBXZSB3aWxsIHR3ZWFrIHRoZSBhcHByb3hpbWF0ZSByZXN1bHQgYnkgY2hhbmdpbmcgaXQgaW4gdGhlIDQ4LXRoIGRpZ2l0IG9yXG4gICAgLy8gdGhlIHNtYWxsZXN0IG5vbi1mcmFjdGlvbmFsIGRpZ2l0LCB3aGljaGV2ZXIgaXMgbGFyZ2VyLlxuICAgIHZhciBsb2cyID0gTWF0aC5jZWlsKE1hdGgubG9nKGFwcHJveCkgLyBNYXRoLkxOMiksXG4gICAgICBkZWx0YSA9IChsb2cyIDw9IDQ4KSA/IDEgOiBwb3dfZGJsKDIsIGxvZzIgLSA0OCksXG5cbiAgICAgIC8vIERlY3JlYXNlIHRoZSBhcHByb3hpbWF0aW9uIHVudGlsIGl0IGlzIHNtYWxsZXIgdGhhbiB0aGUgcmVtYWluZGVyLiAgTm90ZVxuICAgICAgLy8gdGhhdCBpZiBpdCBpcyB0b28gbGFyZ2UsIHRoZSBwcm9kdWN0IG92ZXJmbG93cyBhbmQgaXMgbmVnYXRpdmUuXG4gICAgICBhcHByb3hSZXMgPSBmcm9tTnVtYmVyKGFwcHJveCksXG4gICAgICBhcHByb3hSZW0gPSBhcHByb3hSZXMubXVsKGRpdmlzb3IpO1xuICAgIHdoaWxlIChhcHByb3hSZW0uaXNOZWdhdGl2ZSgpIHx8IGFwcHJveFJlbS5ndChyZW0pKSB7XG4gICAgICBhcHByb3ggLT0gZGVsdGE7XG4gICAgICBhcHByb3hSZXMgPSBmcm9tTnVtYmVyKGFwcHJveCwgdGhpcy51bnNpZ25lZCk7XG4gICAgICBhcHByb3hSZW0gPSBhcHByb3hSZXMubXVsKGRpdmlzb3IpO1xuICAgIH1cblxuICAgIC8vIFdlIGtub3cgdGhlIGFuc3dlciBjYW4ndCBiZSB6ZXJvLi4uIGFuZCBhY3R1YWxseSwgemVybyB3b3VsZCBjYXVzZVxuICAgIC8vIGluZmluaXRlIHJlY3Vyc2lvbiBzaW5jZSB3ZSB3b3VsZCBtYWtlIG5vIHByb2dyZXNzLlxuICAgIGlmIChhcHByb3hSZXMuaXNaZXJvKCkpXG4gICAgICBhcHByb3hSZXMgPSBPTkU7XG5cbiAgICByZXMgPSByZXMuYWRkKGFwcHJveFJlcyk7XG4gICAgcmVtID0gcmVtLnN1YihhcHByb3hSZW0pO1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNkaXZpZGV9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxuICogQHJldHVybnMgeyFMb25nfSBRdW90aWVudFxuICovXG5Mb25nUHJvdG90eXBlLmRpdiA9IExvbmdQcm90b3R5cGUuZGl2aWRlO1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIG1vZHVsbyB0aGUgc3BlY2lmaWVkLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcbiAqIEByZXR1cm5zIHshTG9uZ30gUmVtYWluZGVyXG4gKi9cbkxvbmdQcm90b3R5cGUubW9kdWxvID0gZnVuY3Rpb24gbW9kdWxvKGRpdmlzb3IpIHtcbiAgaWYgKCFpc0xvbmcoZGl2aXNvcikpXG4gICAgZGl2aXNvciA9IGZyb21WYWx1ZShkaXZpc29yKTtcblxuICAvLyB1c2Ugd2FzbSBzdXBwb3J0IGlmIHByZXNlbnRcbiAgaWYgKHdhc20pIHtcbiAgICB2YXIgbG93ID0gKHRoaXMudW5zaWduZWQgPyB3YXNtW1wicmVtX3VcIl0gOiB3YXNtW1wicmVtX3NcIl0pKFxuICAgICAgdGhpcy5sb3csXG4gICAgICB0aGlzLmhpZ2gsXG4gICAgICBkaXZpc29yLmxvdyxcbiAgICAgIGRpdmlzb3IuaGlnaFxuICAgICk7XG4gICAgcmV0dXJuIGZyb21CaXRzKGxvdywgd2FzbVtcImdldF9oaWdoXCJdKCksIHRoaXMudW5zaWduZWQpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuc3ViKHRoaXMuZGl2KGRpdmlzb3IpLm11bChkaXZpc29yKSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIG1vZHVsbyB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI21vZHVsb30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxuICovXG5Mb25nUHJvdG90eXBlLm1vZCA9IExvbmdQcm90b3R5cGUubW9kdWxvO1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIG1vZHVsbyB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI21vZHVsb30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxuICovXG5Mb25nUHJvdG90eXBlLnJlbSA9IExvbmdQcm90b3R5cGUubW9kdWxvO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGJpdHdpc2UgTk9UIG9mIHRoaXMgTG9uZy5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshTG9uZ31cbiAqL1xuTG9uZ1Byb3RvdHlwZS5ub3QgPSBmdW5jdGlvbiBub3QoKSB7XG4gIHJldHVybiBmcm9tQml0cyh+dGhpcy5sb3csIH50aGlzLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGNvdW50IGxlYWRpbmcgemVyb3Mgb2YgdGhpcyBMb25nLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUuY291bnRMZWFkaW5nWmVyb3MgPSBmdW5jdGlvbiBjb3VudExlYWRpbmdaZXJvcygpIHtcbiAgcmV0dXJuIHRoaXMuaGlnaCA/IE1hdGguY2x6MzIodGhpcy5oaWdoKSA6IE1hdGguY2x6MzIodGhpcy5sb3cpICsgMzI7XG59O1xuXG4vKipcbiAqIFJldHVybnMgY291bnQgbGVhZGluZyB6ZXJvcy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNjb3VudExlYWRpbmdaZXJvc30uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IW51bWJlcn1cbiAqL1xuTG9uZ1Byb3RvdHlwZS5jbHogPSBMb25nUHJvdG90eXBlLmNvdW50TGVhZGluZ1plcm9zO1xuXG4vKipcbiAqIFJldHVybnMgY291bnQgdHJhaWxpbmcgemVyb3Mgb2YgdGhpcyBMb25nLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFudW1iZXJ9XG4gKi9cbkxvbmdQcm90b3R5cGUuY291bnRUcmFpbGluZ1plcm9zID0gZnVuY3Rpb24gY291bnRUcmFpbGluZ1plcm9zKCkge1xuICByZXR1cm4gdGhpcy5sb3cgPyBjdHozMih0aGlzLmxvdykgOiBjdHozMih0aGlzLmhpZ2gpICsgMzI7XG59O1xuXG4vKipcbiAqIFJldHVybnMgY291bnQgdHJhaWxpbmcgemVyb3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY291bnRUcmFpbGluZ1plcm9zfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHshTG9uZ31cbiAqIEByZXR1cm5zIHshbnVtYmVyfVxuICovXG5Mb25nUHJvdG90eXBlLmN0eiA9IExvbmdQcm90b3R5cGUuY291bnRUcmFpbGluZ1plcm9zO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGJpdHdpc2UgQU5EIG9mIHRoaXMgTG9uZyBhbmQgdGhlIHNwZWNpZmllZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xuICogQHJldHVybnMgeyFMb25nfVxuICovXG5Mb25nUHJvdG90eXBlLmFuZCA9IGZ1bmN0aW9uIGFuZChvdGhlcikge1xuICBpZiAoIWlzTG9uZyhvdGhlcikpXG4gICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgJiBvdGhlci5sb3csIHRoaXMuaGlnaCAmIG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIE9SIG9mIHRoaXMgTG9uZyBhbmQgdGhlIHNwZWNpZmllZC5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xuICogQHJldHVybnMgeyFMb25nfVxuICovXG5Mb25nUHJvdG90eXBlLm9yID0gZnVuY3Rpb24gb3Iob3RoZXIpIHtcbiAgaWYgKCFpc0xvbmcob3RoZXIpKVxuICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcbiAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IHwgb3RoZXIubG93LCB0aGlzLmhpZ2ggfCBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgYml0d2lzZSBYT1Igb2YgdGhpcyBMb25nIGFuZCB0aGUgZ2l2ZW4gb25lLlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXG4gKiBAcmV0dXJucyB7IUxvbmd9XG4gKi9cbkxvbmdQcm90b3R5cGUueG9yID0gZnVuY3Rpb24geG9yKG90aGVyKSB7XG4gIGlmICghaXNMb25nKG90aGVyKSlcbiAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyBeIG90aGVyLmxvdywgdGhpcy5oaWdoIF4gb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQgPSBmdW5jdGlvbiBzaGlmdExlZnQobnVtQml0cykge1xuICBpZiAoaXNMb25nKG51bUJpdHMpKVxuICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XG4gIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApXG4gICAgcmV0dXJuIHRoaXM7XG4gIGVsc2UgaWYgKG51bUJpdHMgPCAzMilcbiAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgPDwgbnVtQml0cywgKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gKDMyIC0gbnVtQml0cykpLCB0aGlzLnVuc2lnbmVkKTtcbiAgZWxzZVxuICAgIHJldHVybiBmcm9tQml0cygwLCB0aGlzLmxvdyA8PCAobnVtQml0cyAtIDMyKSwgdGhpcy51bnNpZ25lZCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRMZWZ0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hsID0gTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQ7XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0ID0gZnVuY3Rpb24gc2hpZnRSaWdodChudW1CaXRzKSB7XG4gIGlmIChpc0xvbmcobnVtQml0cykpXG4gICAgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcbiAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMClcbiAgICByZXR1cm4gdGhpcztcbiAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxuICAgIHJldHVybiBmcm9tQml0cygodGhpcy5sb3cgPj4+IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA8PCAoMzIgLSBudW1CaXRzKSksIHRoaXMuaGlnaCA+PiBudW1CaXRzLCB0aGlzLnVuc2lnbmVkKTtcbiAgZWxzZVxuICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmhpZ2ggPj4gKG51bUJpdHMgLSAzMiksIHRoaXMuaGlnaCA+PSAwID8gMCA6IC0xLCB0aGlzLnVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnNociA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodDtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQgPSBmdW5jdGlvbiBzaGlmdFJpZ2h0VW5zaWduZWQobnVtQml0cykge1xuICBpZiAoaXNMb25nKG51bUJpdHMpKSBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xuICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKSByZXR1cm4gdGhpcztcbiAgaWYgKG51bUJpdHMgPCAzMikgcmV0dXJuIGZyb21CaXRzKCh0aGlzLmxvdyA+Pj4gbnVtQml0cykgfCAodGhpcy5oaWdoIDw8ICgzMiAtIG51bUJpdHMpKSwgdGhpcy5oaWdoID4+PiBudW1CaXRzLCB0aGlzLnVuc2lnbmVkKTtcbiAgaWYgKG51bUJpdHMgPT09IDMyKSByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoLCAwLCB0aGlzLnVuc2lnbmVkKTtcbiAgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCA+Pj4gKG51bUJpdHMgLSAzMiksIDAsIHRoaXMudW5zaWduZWQpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUuc2hydSA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodFVuc2lnbmVkO1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdFJpZ2h0VW5zaWduZWR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5zaHJfdSA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodFVuc2lnbmVkO1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyByb3RhdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBSb3RhdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5yb3RhdGVMZWZ0ID0gZnVuY3Rpb24gcm90YXRlTGVmdChudW1CaXRzKSB7XG4gIHZhciBiO1xuICBpZiAoaXNMb25nKG51bUJpdHMpKSBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xuICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKSByZXR1cm4gdGhpcztcbiAgaWYgKG51bUJpdHMgPT09IDMyKSByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoLCB0aGlzLmxvdywgdGhpcy51bnNpZ25lZCk7XG4gIGlmIChudW1CaXRzIDwgMzIpIHtcbiAgICBiID0gKDMyIC0gbnVtQml0cyk7XG4gICAgcmV0dXJuIGZyb21CaXRzKCgodGhpcy5sb3cgPDwgbnVtQml0cykgfCAodGhpcy5oaWdoID4+PiBiKSksICgodGhpcy5oaWdoIDw8IG51bUJpdHMpIHwgKHRoaXMubG93ID4+PiBiKSksIHRoaXMudW5zaWduZWQpO1xuICB9XG4gIG51bUJpdHMgLT0gMzI7XG4gIGIgPSAoMzIgLSBudW1CaXRzKTtcbiAgcmV0dXJuIGZyb21CaXRzKCgodGhpcy5oaWdoIDw8IG51bUJpdHMpIHwgKHRoaXMubG93ID4+PiBiKSksICgodGhpcy5sb3cgPDwgbnVtQml0cykgfCAodGhpcy5oaWdoID4+PiBiKSksIHRoaXMudW5zaWduZWQpO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgcm90YXRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3JvdGF0ZUxlZnR9LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xuICogQHJldHVybnMgeyFMb25nfSBSb3RhdGVkIExvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS5yb3RsID0gTG9uZ1Byb3RvdHlwZS5yb3RhdGVMZWZ0O1xuXG4vKipcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyByb3RhdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxuICogQHRoaXMgeyFMb25nfVxuICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcbiAqIEByZXR1cm5zIHshTG9uZ30gUm90YXRlZCBMb25nXG4gKi9cbkxvbmdQcm90b3R5cGUucm90YXRlUmlnaHQgPSBmdW5jdGlvbiByb3RhdGVSaWdodChudW1CaXRzKSB7XG4gIHZhciBiO1xuICBpZiAoaXNMb25nKG51bUJpdHMpKSBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xuICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKSByZXR1cm4gdGhpcztcbiAgaWYgKG51bUJpdHMgPT09IDMyKSByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoLCB0aGlzLmxvdywgdGhpcy51bnNpZ25lZCk7XG4gIGlmIChudW1CaXRzIDwgMzIpIHtcbiAgICBiID0gKDMyIC0gbnVtQml0cyk7XG4gICAgcmV0dXJuIGZyb21CaXRzKCgodGhpcy5oaWdoIDw8IGIpIHwgKHRoaXMubG93ID4+PiBudW1CaXRzKSksICgodGhpcy5sb3cgPDwgYikgfCAodGhpcy5oaWdoID4+PiBudW1CaXRzKSksIHRoaXMudW5zaWduZWQpO1xuICB9XG4gIG51bUJpdHMgLT0gMzI7XG4gIGIgPSAoMzIgLSBudW1CaXRzKTtcbiAgcmV0dXJuIGZyb21CaXRzKCgodGhpcy5sb3cgPDwgYikgfCAodGhpcy5oaWdoID4+PiBudW1CaXRzKSksICgodGhpcy5oaWdoIDw8IGIpIHwgKHRoaXMubG93ID4+PiBudW1CaXRzKSksIHRoaXMudW5zaWduZWQpO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgcm90YXRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNyb3RhdGVSaWdodH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXG4gKiBAcmV0dXJucyB7IUxvbmd9IFJvdGF0ZWQgTG9uZ1xuICovXG5Mb25nUHJvdG90eXBlLnJvdHIgPSBMb25nUHJvdG90eXBlLnJvdGF0ZVJpZ2h0O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBzaWduZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUxvbmd9IFNpZ25lZCBsb25nXG4gKi9cbkxvbmdQcm90b3R5cGUudG9TaWduZWQgPSBmdW5jdGlvbiB0b1NpZ25lZCgpIHtcbiAgaWYgKCF0aGlzLnVuc2lnbmVkKVxuICAgIHJldHVybiB0aGlzO1xuICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgZmFsc2UpO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gdW5zaWduZWQuXG4gKiBAdGhpcyB7IUxvbmd9XG4gKiBAcmV0dXJucyB7IUxvbmd9IFVuc2lnbmVkIGxvbmdcbiAqL1xuTG9uZ1Byb3RvdHlwZS50b1Vuc2lnbmVkID0gZnVuY3Rpb24gdG9VbnNpZ25lZCgpIHtcbiAgaWYgKHRoaXMudW5zaWduZWQpXG4gICAgcmV0dXJuIHRoaXM7XG4gIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdywgdGhpcy5oaWdoLCB0cnVlKTtcbn07XG5cbi8qKlxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBieXRlIHJlcHJlc2VudGF0aW9uLlxuICogQHBhcmFtIHtib29sZWFuPX0gbGUgV2hldGhlciBsaXR0bGUgb3IgYmlnIGVuZGlhbiwgZGVmYXVsdHMgdG8gYmlnIGVuZGlhblxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQnl0ZSByZXByZXNlbnRhdGlvblxuICovXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXMgPSBmdW5jdGlvbiB0b0J5dGVzKGxlKSB7XG4gIHJldHVybiBsZSA/IHRoaXMudG9CeXRlc0xFKCkgOiB0aGlzLnRvQnl0ZXNCRSgpO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGxpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEB0aGlzIHshTG9uZ31cbiAqIEByZXR1cm5zIHshQXJyYXkuPG51bWJlcj59IExpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvblxuICovXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXNMRSA9IGZ1bmN0aW9uIHRvQnl0ZXNMRSgpIHtcbiAgdmFyIGhpID0gdGhpcy5oaWdoLFxuICAgIGxvID0gdGhpcy5sb3c7XG4gIHJldHVybiBbXG4gICAgbG8gJiAweGZmLFxuICAgIGxvID4+PiA4ICYgMHhmZixcbiAgICBsbyA+Pj4gMTYgJiAweGZmLFxuICAgIGxvID4+PiAyNCxcbiAgICBoaSAmIDB4ZmYsXG4gICAgaGkgPj4+IDggJiAweGZmLFxuICAgIGhpID4+PiAxNiAmIDB4ZmYsXG4gICAgaGkgPj4+IDI0XG4gIF07XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgYmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxuICogQHRoaXMgeyFMb25nfVxuICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXG4gKi9cbkxvbmdQcm90b3R5cGUudG9CeXRlc0JFID0gZnVuY3Rpb24gdG9CeXRlc0JFKCkge1xuICB2YXIgaGkgPSB0aGlzLmhpZ2gsXG4gICAgbG8gPSB0aGlzLmxvdztcbiAgcmV0dXJuIFtcbiAgICBoaSA+Pj4gMjQsXG4gICAgaGkgPj4+IDE2ICYgMHhmZixcbiAgICBoaSA+Pj4gOCAmIDB4ZmYsXG4gICAgaGkgJiAweGZmLFxuICAgIGxvID4+PiAyNCxcbiAgICBsbyA+Pj4gMTYgJiAweGZmLFxuICAgIGxvID4+PiA4ICYgMHhmZixcbiAgICBsbyAmIDB4ZmZcbiAgXTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBCeXRlIHJlcHJlc2VudGF0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gc2lnbmVkXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBsZSBXaGV0aGVyIGxpdHRsZSBvciBiaWcgZW5kaWFuLCBkZWZhdWx0cyB0byBiaWcgZW5kaWFuXG4gKiBAcmV0dXJucyB7TG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxuICovXG5Mb25nLmZyb21CeXRlcyA9IGZ1bmN0aW9uIGZyb21CeXRlcyhieXRlcywgdW5zaWduZWQsIGxlKSB7XG4gIHJldHVybiBsZSA/IExvbmcuZnJvbUJ5dGVzTEUoYnl0ZXMsIHVuc2lnbmVkKSA6IExvbmcuZnJvbUJ5dGVzQkUoYnl0ZXMsIHVuc2lnbmVkKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgbGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxuICogQHBhcmFtIHshQXJyYXkuPG51bWJlcj59IGJ5dGVzIExpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvblxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxuICogQHJldHVybnMge0xvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcbiAqL1xuTG9uZy5mcm9tQnl0ZXNMRSA9IGZ1bmN0aW9uIGZyb21CeXRlc0xFKGJ5dGVzLCB1bnNpZ25lZCkge1xuICByZXR1cm4gbmV3IExvbmcoXG4gICAgYnl0ZXNbMF0gfFxuICAgIGJ5dGVzWzFdIDw8IDggfFxuICAgIGJ5dGVzWzJdIDw8IDE2IHxcbiAgICBieXRlc1szXSA8PCAyNCxcbiAgICBieXRlc1s0XSB8XG4gICAgYnl0ZXNbNV0gPDwgOCB8XG4gICAgYnl0ZXNbNl0gPDwgMTYgfFxuICAgIGJ5dGVzWzddIDw8IDI0LFxuICAgIHVuc2lnbmVkXG4gICk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBMb25nIGZyb20gaXRzIGJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cbiAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBCaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcbiAqIEByZXR1cm5zIHtMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXG4gKi9cbkxvbmcuZnJvbUJ5dGVzQkUgPSBmdW5jdGlvbiBmcm9tQnl0ZXNCRShieXRlcywgdW5zaWduZWQpIHtcbiAgcmV0dXJuIG5ldyBMb25nKFxuICAgIGJ5dGVzWzRdIDw8IDI0IHxcbiAgICBieXRlc1s1XSA8PCAxNiB8XG4gICAgYnl0ZXNbNl0gPDwgOCB8XG4gICAgYnl0ZXNbN10sXG4gICAgYnl0ZXNbMF0gPDwgMjQgfFxuICAgIGJ5dGVzWzFdIDw8IDE2IHxcbiAgICBieXRlc1syXSA8PCA4IHxcbiAgICBieXRlc1szXSxcbiAgICB1bnNpZ25lZFxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgTG9uZztcbiIsICIvLy8gQGZpbGVcbi8vLyBAYWRkdG9ncm91cCBmbGF0YnVmZmVyc19qYXZhc2NyaXB0X2FwaVxuLy8vIEB7XG4vLy8gQGNvbmQgRkxBVEJVRkZFUlNfSU5URVJOQUxcblxuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3XG4gKlxuICogTmVlZCB0byBzdXBwcmVzcyAnZ2xvYmFsIHRoaXMnIGVycm9yIHNvIHRoZSBOb2RlLmpzIGV4cG9ydCBsaW5lIGRvZXNuJ3QgY2F1c2VcbiAqIGNsb3N1cmUgY29tcGlsZSB0byBlcnJvciBvdXQuXG4gKiBAc3VwcHJlc3Mge2dsb2JhbFRoaXN9XG4gKi9cblxuLyoqXG4gKiBAY29uc3RcbiAqIEBuYW1lc3BhY2VcbiAqL1xudmFyIGZsYXRidWZmZXJzID0ge307XG5cbi8qKlxuICogQHR5cGVkZWYge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuT2Zmc2V0O1xuXG4vKipcbiAqIEB0eXBlZGVmIHt7XG4gKiAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLFxuICogICBiYl9wb3M6IG51bWJlclxuICogfX1cbiAqL1xuZmxhdGJ1ZmZlcnMuVGFibGU7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICovXG5mbGF0YnVmZmVycy5TSVpFT0ZfU0hPUlQgPSAyO1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqL1xuZmxhdGJ1ZmZlcnMuU0laRU9GX0lOVCA9IDQ7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICovXG5mbGF0YnVmZmVycy5GSUxFX0lERU5USUZJRVJfTEVOR1RIID0gNDtcblxuLyoqXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQGNvbnN0XG4gKi9cbmZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCA9IDQ7XG5cbi8qKlxuICogQGVudW0ge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuRW5jb2RpbmcgPSB7XG4gIFVURjhfQllURVM6IDEsXG4gIFVURjE2X1NUUklORzogMlxufTtcblxuLyoqXG4gKiBAdHlwZSB7SW50MzJBcnJheX1cbiAqIEBjb25zdFxuICovXG5mbGF0YnVmZmVycy5pbnQzMiA9IG5ldyBJbnQzMkFycmF5KDIpO1xuXG4vKipcbiAqIEB0eXBlIHtGbG9hdDMyQXJyYXl9XG4gKiBAY29uc3RcbiAqL1xuZmxhdGJ1ZmZlcnMuZmxvYXQzMiA9IG5ldyBGbG9hdDMyQXJyYXkoZmxhdGJ1ZmZlcnMuaW50MzIuYnVmZmVyKTtcblxuLyoqXG4gKiBAdHlwZSB7RmxvYXQ2NEFycmF5fVxuICogQGNvbnN0XG4gKi9cbmZsYXRidWZmZXJzLmZsb2F0NjQgPSBuZXcgRmxvYXQ2NEFycmF5KGZsYXRidWZmZXJzLmludDMyLmJ1ZmZlcik7XG5cbi8qKlxuICogQHR5cGUge2Jvb2xlYW59XG4gKiBAY29uc3RcbiAqL1xuZmxhdGJ1ZmZlcnMuaXNMaXR0bGVFbmRpYW4gPSBuZXcgVWludDE2QXJyYXkobmV3IFVpbnQ4QXJyYXkoWzEsIDBdKS5idWZmZXIpWzBdID09PSAxO1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtudW1iZXJ9IGxvd1xuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hcbiAqL1xuZmxhdGJ1ZmZlcnMuTG9uZyA9IGZ1bmN0aW9uKGxvdywgaGlnaCkge1xuICAvKipcbiAgICogQHR5cGUge251bWJlcn1cbiAgICogQGNvbnN0XG4gICAqL1xuICB0aGlzLmxvdyA9IGxvdyB8IDA7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqIEBjb25zdFxuICAgKi9cbiAgdGhpcy5oaWdoID0gaGlnaCB8IDA7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBsb3dcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoXG4gKiBAcmV0dXJucyB7IWZsYXRidWZmZXJzLkxvbmd9XG4gKi9cbmZsYXRidWZmZXJzLkxvbmcuY3JlYXRlID0gZnVuY3Rpb24obG93LCBoaWdoKSB7XG4gIC8vIFNwZWNpYWwtY2FzZSB6ZXJvIHRvIGF2b2lkIEdDIG92ZXJoZWFkIGZvciBkZWZhdWx0IHZhbHVlc1xuICByZXR1cm4gbG93ID09IDAgJiYgaGlnaCA9PSAwID8gZmxhdGJ1ZmZlcnMuTG9uZy5aRVJPIDogbmV3IGZsYXRidWZmZXJzLkxvbmcobG93LCBoaWdoKTtcbn07XG5cbi8qKlxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuTG9uZy5wcm90b3R5cGUudG9GbG9hdDY0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAodGhpcy5sb3cgPj4+IDApICsgdGhpcy5oaWdoICogMHgxMDAwMDAwMDA7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuTG9uZ30gb3RoZXJcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mbGF0YnVmZmVycy5Mb25nLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbihvdGhlcikge1xuICByZXR1cm4gdGhpcy5sb3cgPT0gb3RoZXIubG93ICYmIHRoaXMuaGlnaCA9PSBvdGhlci5oaWdoO1xufTtcblxuLyoqXG4gKiBAdHlwZSB7IWZsYXRidWZmZXJzLkxvbmd9XG4gKiBAY29uc3RcbiAqL1xuZmxhdGJ1ZmZlcnMuTG9uZy5aRVJPID0gbmV3IGZsYXRidWZmZXJzLkxvbmcoMCwgMCk7XG5cbi8vLyBAZW5kY29uZFxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8qKlxuICogQ3JlYXRlIGEgRmxhdEJ1ZmZlckJ1aWxkZXIuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9pbml0aWFsX3NpemVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlciA9IGZ1bmN0aW9uKG9wdF9pbml0aWFsX3NpemUpIHtcbiAgaWYgKCFvcHRfaW5pdGlhbF9zaXplKSB7XG4gICAgdmFyIGluaXRpYWxfc2l6ZSA9IDEwMjQ7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGluaXRpYWxfc2l6ZSA9IG9wdF9pbml0aWFsX3NpemU7XG4gIH1cblxuICAvKipcbiAgICogQHR5cGUge2ZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ9XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0aGlzLmJiID0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5hbGxvY2F0ZShpbml0aWFsX3NpemUpO1xuXG4gIC8qKlxuICAgKiBSZW1haW5pbmcgc3BhY2UgaW4gdGhlIEJ5dGVCdWZmZXIuXG4gICAqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0aGlzLnNwYWNlID0gaW5pdGlhbF9zaXplO1xuXG4gIC8qKlxuICAgKiBNaW5pbXVtIGFsaWdubWVudCBlbmNvdW50ZXJlZCBzbyBmYXIuXG4gICAqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0aGlzLm1pbmFsaWduID0gMTtcblxuICAvKipcbiAgICogVGhlIHZ0YWJsZSBmb3IgdGhlIGN1cnJlbnQgdGFibGUuXG4gICAqXG4gICAqIEB0eXBlIHtBcnJheS48bnVtYmVyPn1cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHRoaXMudnRhYmxlID0gbnVsbDtcblxuICAvKipcbiAgICogVGhlIGFtb3VudCBvZiBmaWVsZHMgd2UncmUgYWN0dWFsbHkgdXNpbmcuXG4gICAqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0aGlzLnZ0YWJsZV9pbl91c2UgPSAwO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHdlIGFyZSBjdXJyZW50bHkgc2VyaWFsaXppbmcgYSB0YWJsZS5cbiAgICpcbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0aGlzLmlzTmVzdGVkID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIFN0YXJ0aW5nIG9mZnNldCBvZiB0aGUgY3VycmVudCBzdHJ1Y3QvdGFibGUuXG4gICAqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0aGlzLm9iamVjdF9zdGFydCA9IDA7XG5cbiAgLyoqXG4gICAqIExpc3Qgb2Ygb2Zmc2V0cyBvZiBhbGwgdnRhYmxlcy5cbiAgICpcbiAgICogQHR5cGUge0FycmF5LjxudW1iZXI+fVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy52dGFibGVzID0gW107XG5cbiAgLyoqXG4gICAqIEZvciB0aGUgY3VycmVudCB2ZWN0b3IgYmVpbmcgYnVpbHQuXG4gICAqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0aGlzLnZlY3Rvcl9udW1fZWxlbXMgPSAwO1xuXG4gIC8qKlxuICAgKiBGYWxzZSBvbWl0cyBkZWZhdWx0IHZhbHVlcyBmcm9tIHRoZSBzZXJpYWxpemVkIGRhdGFcbiAgICpcbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0aGlzLmZvcmNlX2RlZmF1bHRzID0gZmFsc2U7XG59O1xuXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmJiLmNsZWFyKCk7XG4gIHRoaXMuc3BhY2UgPSB0aGlzLmJiLmNhcGFjaXR5KCk7XG4gIHRoaXMubWluYWxpZ24gPSAxO1xuICB0aGlzLnZ0YWJsZSA9IG51bGw7XG4gIHRoaXMudnRhYmxlX2luX3VzZSA9IDA7XG4gIHRoaXMuaXNOZXN0ZWQgPSBmYWxzZTtcbiAgdGhpcy5vYmplY3Rfc3RhcnQgPSAwO1xuICB0aGlzLnZ0YWJsZXMgPSBbXTtcbiAgdGhpcy52ZWN0b3JfbnVtX2VsZW1zID0gMDtcbiAgdGhpcy5mb3JjZV9kZWZhdWx0cyA9IGZhbHNlO1xufTtcblxuLyoqXG4gKiBJbiBvcmRlciB0byBzYXZlIHNwYWNlLCBmaWVsZHMgdGhhdCBhcmUgc2V0IHRvIHRoZWlyIGRlZmF1bHQgdmFsdWVcbiAqIGRvbid0IGdldCBzZXJpYWxpemVkIGludG8gdGhlIGJ1ZmZlci4gRm9yY2luZyBkZWZhdWx0cyBwcm92aWRlcyBhXG4gKiB3YXkgdG8gbWFudWFsbHkgZGlzYWJsZSB0aGlzIG9wdGltaXphdGlvbi5cbiAqXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGZvcmNlRGVmYXVsdHMgdHJ1ZSBhbHdheXMgc2VyaWFsaXplcyBkZWZhdWx0IHZhbHVlc1xuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5mb3JjZURlZmF1bHRzID0gZnVuY3Rpb24oZm9yY2VEZWZhdWx0cykge1xuICB0aGlzLmZvcmNlX2RlZmF1bHRzID0gZm9yY2VEZWZhdWx0cztcbn07XG5cbi8qKlxuICogR2V0IHRoZSBCeXRlQnVmZmVyIHJlcHJlc2VudGluZyB0aGUgRmxhdEJ1ZmZlci4gT25seSBjYWxsIHRoaXMgYWZ0ZXIgeW91J3ZlXG4gKiBjYWxsZWQgZmluaXNoKCkuIFRoZSBhY3R1YWwgZGF0YSBzdGFydHMgYXQgdGhlIEJ5dGVCdWZmZXIncyBjdXJyZW50IHBvc2l0aW9uLFxuICogbm90IG5lY2Vzc2FyaWx5IGF0IDAuXG4gKlxuICogQHJldHVybnMge2ZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmRhdGFCdWZmZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuYmI7XG59O1xuXG4vKipcbiAqIEdldCB0aGUgYnl0ZXMgcmVwcmVzZW50aW5nIHRoZSBGbGF0QnVmZmVyLiBPbmx5IGNhbGwgdGhpcyBhZnRlciB5b3UndmVcbiAqIGNhbGxlZCBmaW5pc2goKS5cbiAqXG4gKiBAcmV0dXJucyB7IVVpbnQ4QXJyYXl9XG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFzVWludDhBcnJheSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5iYi5ieXRlcygpLnN1YmFycmF5KHRoaXMuYmIucG9zaXRpb24oKSwgdGhpcy5iYi5wb3NpdGlvbigpICsgdGhpcy5vZmZzZXQoKSk7XG59O1xuXG4vLy8gQGNvbmQgRkxBVEJVRkZFUlNfSU5URVJOQUxcbi8qKlxuICogUHJlcGFyZSB0byB3cml0ZSBhbiBlbGVtZW50IG9mIGBzaXplYCBhZnRlciBgYWRkaXRpb25hbF9ieXRlc2AgaGF2ZSBiZWVuXG4gKiB3cml0dGVuLCBlLmcuIGlmIHlvdSB3cml0ZSBhIHN0cmluZywgeW91IG5lZWQgdG8gYWxpZ24gc3VjaCB0aGUgaW50IGxlbmd0aFxuICogZmllbGQgaXMgYWxpZ25lZCB0byA0IGJ5dGVzLCBhbmQgdGhlIHN0cmluZyBkYXRhIGZvbGxvd3MgaXQgZGlyZWN0bHkuIElmIGFsbFxuICogeW91IG5lZWQgdG8gZG8gaXMgYWxpZ25tZW50LCBgYWRkaXRpb25hbF9ieXRlc2Agd2lsbCBiZSAwLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIFRoaXMgaXMgdGhlIG9mIHRoZSBuZXcgZWxlbWVudCB0byB3cml0ZVxuICogQHBhcmFtIHtudW1iZXJ9IGFkZGl0aW9uYWxfYnl0ZXMgVGhlIHBhZGRpbmcgc2l6ZVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5wcmVwID0gZnVuY3Rpb24oc2l6ZSwgYWRkaXRpb25hbF9ieXRlcykge1xuICAvLyBUcmFjayB0aGUgYmlnZ2VzdCB0aGluZyB3ZSd2ZSBldmVyIGFsaWduZWQgdG8uXG4gIGlmIChzaXplID4gdGhpcy5taW5hbGlnbikge1xuICAgIHRoaXMubWluYWxpZ24gPSBzaXplO1xuICB9XG5cbiAgLy8gRmluZCB0aGUgYW1vdW50IG9mIGFsaWdubWVudCBuZWVkZWQgc3VjaCB0aGF0IGBzaXplYCBpcyBwcm9wZXJseVxuICAvLyBhbGlnbmVkIGFmdGVyIGBhZGRpdGlvbmFsX2J5dGVzYFxuICB2YXIgYWxpZ25fc2l6ZSA9ICgofih0aGlzLmJiLmNhcGFjaXR5KCkgLSB0aGlzLnNwYWNlICsgYWRkaXRpb25hbF9ieXRlcykpICsgMSkgJiAoc2l6ZSAtIDEpO1xuXG4gIC8vIFJlYWxsb2NhdGUgdGhlIGJ1ZmZlciBpZiBuZWVkZWQuXG4gIHdoaWxlICh0aGlzLnNwYWNlIDwgYWxpZ25fc2l6ZSArIHNpemUgKyBhZGRpdGlvbmFsX2J5dGVzKSB7XG4gICAgdmFyIG9sZF9idWZfc2l6ZSA9IHRoaXMuYmIuY2FwYWNpdHkoKTtcbiAgICB0aGlzLmJiID0gZmxhdGJ1ZmZlcnMuQnVpbGRlci5ncm93Qnl0ZUJ1ZmZlcih0aGlzLmJiKTtcbiAgICB0aGlzLnNwYWNlICs9IHRoaXMuYmIuY2FwYWNpdHkoKSAtIG9sZF9idWZfc2l6ZTtcbiAgfVxuXG4gIHRoaXMucGFkKGFsaWduX3NpemUpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gYnl0ZV9zaXplXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLnBhZCA9IGZ1bmN0aW9uKGJ5dGVfc2l6ZSkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVfc2l6ZTsgaSsrKSB7XG4gICAgdGhpcy5iYi53cml0ZUludDgoLS10aGlzLnNwYWNlLCAwKTtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5iYi53cml0ZUludDgodGhpcy5zcGFjZSAtPSAxLCB2YWx1ZSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS53cml0ZUludDE2ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5iYi53cml0ZUludDE2KHRoaXMuc3BhY2UgLT0gMiwgdmFsdWUpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUud3JpdGVJbnQzMiA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHRoaXMuYmIud3JpdGVJbnQzMih0aGlzLnNwYWNlIC09IDQsIHZhbHVlKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5Mb25nfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS53cml0ZUludDY0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5iYi53cml0ZUludDY0KHRoaXMuc3BhY2UgLT0gOCwgdmFsdWUpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUud3JpdGVGbG9hdDMyID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5iYi53cml0ZUZsb2F0MzIodGhpcy5zcGFjZSAtPSA0LCB2YWx1ZSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS53cml0ZUZsb2F0NjQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICB0aGlzLmJiLndyaXRlRmxvYXQ2NCh0aGlzLnNwYWNlIC09IDgsIHZhbHVlKTtcbn07XG4vLy8gQGVuZGNvbmRcblxuLyoqXG4gKiBBZGQgYW4gYGludDhgIHRvIHRoZSBidWZmZXIsIHByb3Blcmx5IGFsaWduZWQsIGFuZCBncm93cyB0aGUgYnVmZmVyIChpZiBuZWNlc3NhcnkpLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBgaW50OGAgdG8gYWRkIHRoZSB0aGUgYnVmZmVyLlxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5hZGRJbnQ4ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5wcmVwKDEsIDApO1xuICB0aGlzLndyaXRlSW50OCh2YWx1ZSk7XG59O1xuXG4vKipcbiAqIEFkZCBhbiBgaW50MTZgIHRvIHRoZSBidWZmZXIsIHByb3Blcmx5IGFsaWduZWQsIGFuZCBncm93cyB0aGUgYnVmZmVyIChpZiBuZWNlc3NhcnkpLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBgaW50MTZgIHRvIGFkZCB0aGUgdGhlIGJ1ZmZlci5cbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkSW50MTYgPSBmdW5jdGlvbih2YWx1ZSkge1xuICB0aGlzLnByZXAoMiwgMCk7XG4gIHRoaXMud3JpdGVJbnQxNih2YWx1ZSk7XG59O1xuXG4vKipcbiAqIEFkZCBhbiBgaW50MzJgIHRvIHRoZSBidWZmZXIsIHByb3Blcmx5IGFsaWduZWQsIGFuZCBncm93cyB0aGUgYnVmZmVyIChpZiBuZWNlc3NhcnkpLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBgaW50MzJgIHRvIGFkZCB0aGUgdGhlIGJ1ZmZlci5cbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkSW50MzIgPSBmdW5jdGlvbih2YWx1ZSkge1xuICB0aGlzLnByZXAoNCwgMCk7XG4gIHRoaXMud3JpdGVJbnQzMih2YWx1ZSk7XG59O1xuXG4vKipcbiAqIEFkZCBhbiBgaW50NjRgIHRvIHRoZSBidWZmZXIsIHByb3Blcmx5IGFsaWduZWQsIGFuZCBncm93cyB0aGUgYnVmZmVyIChpZiBuZWNlc3NhcnkpLlxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5Mb25nfSB2YWx1ZSBUaGUgYGludDY0YCB0byBhZGQgdGhlIHRoZSBidWZmZXIuXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFkZEludDY0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5wcmVwKDgsIDApO1xuICB0aGlzLndyaXRlSW50NjQodmFsdWUpO1xufTtcblxuLyoqXG4gKiBBZGQgYSBgZmxvYXQzMmAgdG8gdGhlIGJ1ZmZlciwgcHJvcGVybHkgYWxpZ25lZCwgYW5kIGdyb3dzIHRoZSBidWZmZXIgKGlmIG5lY2Vzc2FyeSkuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIGBmbG9hdDMyYCB0byBhZGQgdGhlIHRoZSBidWZmZXIuXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFkZEZsb2F0MzIgPSBmdW5jdGlvbih2YWx1ZSkge1xuICB0aGlzLnByZXAoNCwgMCk7XG4gIHRoaXMud3JpdGVGbG9hdDMyKHZhbHVlKTtcbn07XG5cbi8qKlxuICogQWRkIGEgYGZsb2F0NjRgIHRvIHRoZSBidWZmZXIsIHByb3Blcmx5IGFsaWduZWQsIGFuZCBncm93cyB0aGUgYnVmZmVyIChpZiBuZWNlc3NhcnkpLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBgZmxvYXQ2NGAgdG8gYWRkIHRoZSB0aGUgYnVmZmVyLlxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5hZGRGbG9hdDY0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5wcmVwKDgsIDApO1xuICB0aGlzLndyaXRlRmxvYXQ2NCh2YWx1ZSk7XG59O1xuXG4vLy8gQGNvbmQgRkxBVEJVRkZFUlNfSU5URVJOQUxcbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHZvZmZzZXRcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICogQHBhcmFtIHtudW1iZXJ9IGRlZmF1bHRWYWx1ZVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5hZGRGaWVsZEludDggPSBmdW5jdGlvbih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgIHRoaXMuYWRkSW50OCh2YWx1ZSk7XG4gICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICB9XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2b2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWZhdWx0VmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkRmllbGRJbnQxNiA9IGZ1bmN0aW9uKHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgdGhpcy5hZGRJbnQxNih2YWx1ZSk7XG4gICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICB9XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2b2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWZhdWx0VmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkRmllbGRJbnQzMiA9IGZ1bmN0aW9uKHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgdGhpcy5hZGRJbnQzMih2YWx1ZSk7XG4gICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICB9XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2b2Zmc2V0XG4gKiBAcGFyYW0ge2ZsYXRidWZmZXJzLkxvbmd9IHZhbHVlXG4gKiBAcGFyYW0ge2ZsYXRidWZmZXJzLkxvbmd9IGRlZmF1bHRWYWx1ZVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5hZGRGaWVsZEludDY0ID0gZnVuY3Rpb24odm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCAhdmFsdWUuZXF1YWxzKGRlZmF1bHRWYWx1ZSkpIHtcbiAgICB0aGlzLmFkZEludDY0KHZhbHVlKTtcbiAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gIH1cbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHZvZmZzZXRcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICogQHBhcmFtIHtudW1iZXJ9IGRlZmF1bHRWYWx1ZVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5hZGRGaWVsZEZsb2F0MzIgPSBmdW5jdGlvbih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgIHRoaXMuYWRkRmxvYXQzMih2YWx1ZSk7XG4gICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICB9XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2b2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWZhdWx0VmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkRmllbGRGbG9hdDY0ID0gZnVuY3Rpb24odm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCB2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICB0aGlzLmFkZEZsb2F0NjQodmFsdWUpO1xuICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdm9mZnNldFxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5PZmZzZXR9IHZhbHVlXG4gKiBAcGFyYW0ge2ZsYXRidWZmZXJzLk9mZnNldH0gZGVmYXVsdFZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFkZEZpZWxkT2Zmc2V0ID0gZnVuY3Rpb24odm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCB2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICB0aGlzLmFkZE9mZnNldCh2YWx1ZSk7XG4gICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICB9XG59O1xuXG4vKipcbiAqIFN0cnVjdHMgYXJlIHN0b3JlZCBpbmxpbmUsIHNvIG5vdGhpbmcgYWRkaXRpb25hbCBpcyBiZWluZyBhZGRlZC4gYGRgIGlzIGFsd2F5cyAwLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB2b2Zmc2V0XG4gKiBAcGFyYW0ge2ZsYXRidWZmZXJzLk9mZnNldH0gdmFsdWVcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuT2Zmc2V0fSBkZWZhdWx0VmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkRmllbGRTdHJ1Y3QgPSBmdW5jdGlvbih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICB0aGlzLm5lc3RlZCh2YWx1ZSk7XG4gICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICB9XG59O1xuXG4vKipcbiAqIFN0cnVjdHVyZXMgYXJlIGFsd2F5cyBzdG9yZWQgaW5saW5lLCB0aGV5IG5lZWQgdG8gYmUgY3JlYXRlZCByaWdodFxuICogd2hlcmUgdGhleSdyZSB1c2VkLiAgWW91J2xsIGdldCB0aGlzIGFzc2VydGlvbiBmYWlsdXJlIGlmIHlvdVxuICogY3JlYXRlZCBpdCBlbHNld2hlcmUuXG4gKlxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5PZmZzZXR9IG9iaiBUaGUgb2Zmc2V0IG9mIHRoZSBjcmVhdGVkIG9iamVjdFxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5uZXN0ZWQgPSBmdW5jdGlvbihvYmopIHtcbiAgaWYgKG9iaiAhPSB0aGlzLm9mZnNldCgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogc3RydWN0IG11c3QgYmUgc2VyaWFsaXplZCBpbmxpbmUuJyk7XG4gIH1cbn07XG5cbi8qKlxuICogU2hvdWxkIG5vdCBiZSBjcmVhdGluZyBhbnkgb3RoZXIgb2JqZWN0LCBzdHJpbmcgb3IgdmVjdG9yXG4gKiB3aGlsZSBhbiBvYmplY3QgaXMgYmVpbmcgY29uc3RydWN0ZWRcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUubm90TmVzdGVkID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLmlzTmVzdGVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogb2JqZWN0IHNlcmlhbGl6YXRpb24gbXVzdCBub3QgYmUgbmVzdGVkLicpO1xuICB9XG59O1xuXG4vKipcbiAqIFNldCB0aGUgY3VycmVudCB2dGFibGUgYXQgYHZvZmZzZXRgIHRvIHRoZSBjdXJyZW50IGxvY2F0aW9uIGluIHRoZSBidWZmZXIuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHZvZmZzZXRcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuc2xvdCA9IGZ1bmN0aW9uKHZvZmZzZXQpIHtcbiAgdGhpcy52dGFibGVbdm9mZnNldF0gPSB0aGlzLm9mZnNldCgpO1xufTtcblxuLyoqXG4gKiBAcmV0dXJucyB7ZmxhdGJ1ZmZlcnMuT2Zmc2V0fSBPZmZzZXQgcmVsYXRpdmUgdG8gdGhlIGVuZCBvZiB0aGUgYnVmZmVyLlxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5vZmZzZXQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuYmIuY2FwYWNpdHkoKSAtIHRoaXMuc3BhY2U7XG59O1xuXG4vKipcbiAqIERvdWJsZXMgdGhlIHNpemUgb2YgdGhlIGJhY2tpbmcgQnl0ZUJ1ZmZlciBhbmQgY29waWVzIHRoZSBvbGQgZGF0YSB0b3dhcmRzXG4gKiB0aGUgZW5kIG9mIHRoZSBuZXcgYnVmZmVyIChzaW5jZSB3ZSBidWlsZCB0aGUgYnVmZmVyIGJhY2t3YXJkcykuXG4gKlxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5CeXRlQnVmZmVyfSBiYiBUaGUgY3VycmVudCBidWZmZXIgd2l0aCB0aGUgZXhpc3RpbmcgZGF0YVxuICogQHJldHVybnMgeyFmbGF0YnVmZmVycy5CeXRlQnVmZmVyfSBBIG5ldyBieXRlIGJ1ZmZlciB3aXRoIHRoZSBvbGQgZGF0YSBjb3BpZWRcbiAqIHRvIGl0LiBUaGUgZGF0YSBpcyBsb2NhdGVkIGF0IHRoZSBlbmQgb2YgdGhlIGJ1ZmZlci5cbiAqXG4gKiB1aW50OEFycmF5LnNldCgpIGZvcm1hbGx5IHRha2VzIHtBcnJheTxudW1iZXI+fEFycmF5QnVmZmVyVmlld30sIHNvIHRvIHBhc3NcbiAqIGl0IGEgdWludDhBcnJheSB3ZSBuZWVkIHRvIHN1cHByZXNzIHRoZSB0eXBlIGNoZWNrOlxuICogQHN1cHByZXNzIHtjaGVja1R5cGVzfVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLmdyb3dCeXRlQnVmZmVyID0gZnVuY3Rpb24oYmIpIHtcbiAgdmFyIG9sZF9idWZfc2l6ZSA9IGJiLmNhcGFjaXR5KCk7XG5cbiAgLy8gRW5zdXJlIHdlIGRvbid0IGdyb3cgYmV5b25kIHdoYXQgZml0cyBpbiBhbiBpbnQuXG4gIGlmIChvbGRfYnVmX3NpemUgJiAweEMwMDAwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogY2Fubm90IGdyb3cgYnVmZmVyIGJleW9uZCAyIGdpZ2FieXRlcy4nKTtcbiAgfVxuXG4gIHZhciBuZXdfYnVmX3NpemUgPSBvbGRfYnVmX3NpemUgPDwgMTtcbiAgdmFyIG5iYiA9IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIuYWxsb2NhdGUobmV3X2J1Zl9zaXplKTtcbiAgbmJiLnNldFBvc2l0aW9uKG5ld19idWZfc2l6ZSAtIG9sZF9idWZfc2l6ZSk7XG4gIG5iYi5ieXRlcygpLnNldChiYi5ieXRlcygpLCBuZXdfYnVmX3NpemUgLSBvbGRfYnVmX3NpemUpO1xuICByZXR1cm4gbmJiO1xufTtcbi8vLyBAZW5kY29uZFxuXG4vKipcbiAqIEFkZHMgb24gb2Zmc2V0LCByZWxhdGl2ZSB0byB3aGVyZSBpdCB3aWxsIGJlIHdyaXR0ZW4uXG4gKlxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5PZmZzZXR9IG9mZnNldCBUaGUgb2Zmc2V0IHRvIGFkZC5cbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkT2Zmc2V0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gIHRoaXMucHJlcChmbGF0YnVmZmVycy5TSVpFT0ZfSU5ULCAwKTsgLy8gRW5zdXJlIGFsaWdubWVudCBpcyBhbHJlYWR5IGRvbmUuXG4gIHRoaXMud3JpdGVJbnQzMih0aGlzLm9mZnNldCgpIC0gb2Zmc2V0ICsgZmxhdGJ1ZmZlcnMuU0laRU9GX0lOVCk7XG59O1xuXG4vLy8gQGNvbmQgRkxBVEJVRkZFUlNfSU5URVJOQUxcbi8qKlxuICogU3RhcnQgZW5jb2RpbmcgYSBuZXcgb2JqZWN0IGluIHRoZSBidWZmZXIuICBVc2VycyB3aWxsIG5vdCB1c3VhbGx5IG5lZWQgdG9cbiAqIGNhbGwgdGhpcyBkaXJlY3RseS4gVGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyIHdpbGwgZ2VuZXJhdGUgaGVscGVyIG1ldGhvZHNcbiAqIHRoYXQgY2FsbCB0aGlzIG1ldGhvZCBpbnRlcm5hbGx5LlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW1maWVsZHNcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuc3RhcnRPYmplY3QgPSBmdW5jdGlvbihudW1maWVsZHMpIHtcbiAgdGhpcy5ub3ROZXN0ZWQoKTtcbiAgaWYgKHRoaXMudnRhYmxlID09IG51bGwpIHtcbiAgICB0aGlzLnZ0YWJsZSA9IFtdO1xuICB9XG4gIHRoaXMudnRhYmxlX2luX3VzZSA9IG51bWZpZWxkcztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1maWVsZHM7IGkrKykge1xuICAgIHRoaXMudnRhYmxlW2ldID0gMDsgLy8gVGhpcyB3aWxsIHB1c2ggYWRkaXRpb25hbCBlbGVtZW50cyBhcyBuZWVkZWRcbiAgfVxuICB0aGlzLmlzTmVzdGVkID0gdHJ1ZTtcbiAgdGhpcy5vYmplY3Rfc3RhcnQgPSB0aGlzLm9mZnNldCgpO1xufTtcblxuLyoqXG4gKiBGaW5pc2ggb2ZmIHdyaXRpbmcgdGhlIG9iamVjdCB0aGF0IGlzIHVuZGVyIGNvbnN0cnVjdGlvbi5cbiAqXG4gKiBAcmV0dXJucyB7ZmxhdGJ1ZmZlcnMuT2Zmc2V0fSBUaGUgb2Zmc2V0IHRvIHRoZSBvYmplY3QgaW5zaWRlIGBkYXRhQnVmZmVyYFxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5lbmRPYmplY3QgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMudnRhYmxlID09IG51bGwgfHwgIXRoaXMuaXNOZXN0ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXRCdWZmZXJzOiBlbmRPYmplY3QgY2FsbGVkIHdpdGhvdXQgc3RhcnRPYmplY3QnKTtcbiAgfVxuXG4gIHRoaXMuYWRkSW50MzIoMCk7XG4gIHZhciB2dGFibGVsb2MgPSB0aGlzLm9mZnNldCgpO1xuXG4gIC8vIFRyaW0gdHJhaWxpbmcgemVyb2VzLlxuICB2YXIgaSA9IHRoaXMudnRhYmxlX2luX3VzZSAtIDE7XG4gIGZvciAoOyBpID49IDAgJiYgdGhpcy52dGFibGVbaV0gPT0gMDsgaS0tKSB7fVxuICB2YXIgdHJpbW1lZF9zaXplID0gaSArIDE7XG5cbiAgLy8gV3JpdGUgb3V0IHRoZSBjdXJyZW50IHZ0YWJsZS5cbiAgZm9yICg7IGkgPj0gMDsgaS0tKSB7XG4gICAgLy8gT2Zmc2V0IHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgdGFibGUuXG4gICAgdGhpcy5hZGRJbnQxNih0aGlzLnZ0YWJsZVtpXSAhPSAwID8gdnRhYmxlbG9jIC0gdGhpcy52dGFibGVbaV0gOiAwKTtcbiAgfVxuXG4gIHZhciBzdGFuZGFyZF9maWVsZHMgPSAyOyAvLyBUaGUgZmllbGRzIGJlbG93OlxuICB0aGlzLmFkZEludDE2KHZ0YWJsZWxvYyAtIHRoaXMub2JqZWN0X3N0YXJ0KTtcbiAgdmFyIGxlbiA9ICh0cmltbWVkX3NpemUgKyBzdGFuZGFyZF9maWVsZHMpICogZmxhdGJ1ZmZlcnMuU0laRU9GX1NIT1JUO1xuICB0aGlzLmFkZEludDE2KGxlbik7XG5cbiAgLy8gU2VhcmNoIGZvciBhbiBleGlzdGluZyB2dGFibGUgdGhhdCBtYXRjaGVzIHRoZSBjdXJyZW50IG9uZS5cbiAgdmFyIGV4aXN0aW5nX3Z0YWJsZSA9IDA7XG4gIHZhciB2dDEgPSB0aGlzLnNwYWNlO1xub3V0ZXJfbG9vcDpcbiAgZm9yIChpID0gMDsgaSA8IHRoaXMudnRhYmxlcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB2dDIgPSB0aGlzLmJiLmNhcGFjaXR5KCkgLSB0aGlzLnZ0YWJsZXNbaV07XG4gICAgaWYgKGxlbiA9PSB0aGlzLmJiLnJlYWRJbnQxNih2dDIpKSB7XG4gICAgICBmb3IgKHZhciBqID0gZmxhdGJ1ZmZlcnMuU0laRU9GX1NIT1JUOyBqIDwgbGVuOyBqICs9IGZsYXRidWZmZXJzLlNJWkVPRl9TSE9SVCkge1xuICAgICAgICBpZiAodGhpcy5iYi5yZWFkSW50MTYodnQxICsgaikgIT0gdGhpcy5iYi5yZWFkSW50MTYodnQyICsgaikpIHtcbiAgICAgICAgICBjb250aW51ZSBvdXRlcl9sb29wO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBleGlzdGluZ192dGFibGUgPSB0aGlzLnZ0YWJsZXNbaV07XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoZXhpc3RpbmdfdnRhYmxlKSB7XG4gICAgLy8gRm91bmQgYSBtYXRjaDpcbiAgICAvLyBSZW1vdmUgdGhlIGN1cnJlbnQgdnRhYmxlLlxuICAgIHRoaXMuc3BhY2UgPSB0aGlzLmJiLmNhcGFjaXR5KCkgLSB2dGFibGVsb2M7XG5cbiAgICAvLyBQb2ludCB0YWJsZSB0byBleGlzdGluZyB2dGFibGUuXG4gICAgdGhpcy5iYi53cml0ZUludDMyKHRoaXMuc3BhY2UsIGV4aXN0aW5nX3Z0YWJsZSAtIHZ0YWJsZWxvYyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gTm8gbWF0Y2g6XG4gICAgLy8gQWRkIHRoZSBsb2NhdGlvbiBvZiB0aGUgY3VycmVudCB2dGFibGUgdG8gdGhlIGxpc3Qgb2YgdnRhYmxlcy5cbiAgICB0aGlzLnZ0YWJsZXMucHVzaCh0aGlzLm9mZnNldCgpKTtcblxuICAgIC8vIFBvaW50IHRhYmxlIHRvIGN1cnJlbnQgdnRhYmxlLlxuICAgIHRoaXMuYmIud3JpdGVJbnQzMih0aGlzLmJiLmNhcGFjaXR5KCkgLSB2dGFibGVsb2MsIHRoaXMub2Zmc2V0KCkgLSB2dGFibGVsb2MpO1xuICB9XG5cbiAgdGhpcy5pc05lc3RlZCA9IGZhbHNlO1xuICByZXR1cm4gdnRhYmxlbG9jO1xufTtcbi8vLyBAZW5kY29uZFxuXG4vKipcbiAqIEZpbmFsaXplIGEgYnVmZmVyLCBwb2l0aW5nIHRvIHRoZSBnaXZlbiBgcm9vdF90YWJsZWAuXG4gKlxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5PZmZzZXR9IHJvb3RfdGFibGVcbiAqIEBwYXJhbSB7c3RyaW5nPX0gb3B0X2ZpbGVfaWRlbnRpZmllclxuICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3NpemVfcHJlZml4XG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uKHJvb3RfdGFibGUsIG9wdF9maWxlX2lkZW50aWZpZXIsIG9wdF9zaXplX3ByZWZpeCkge1xuICB2YXIgc2l6ZV9wcmVmaXggPSBvcHRfc2l6ZV9wcmVmaXggPyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEggOiAwO1xuICBpZiAob3B0X2ZpbGVfaWRlbnRpZmllcikge1xuICAgIHZhciBmaWxlX2lkZW50aWZpZXIgPSBvcHRfZmlsZV9pZGVudGlmaWVyO1xuICAgIHRoaXMucHJlcCh0aGlzLm1pbmFsaWduLCBmbGF0YnVmZmVycy5TSVpFT0ZfSU5UICtcbiAgICAgIGZsYXRidWZmZXJzLkZJTEVfSURFTlRJRklFUl9MRU5HVEggKyBzaXplX3ByZWZpeCk7XG4gICAgaWYgKGZpbGVfaWRlbnRpZmllci5sZW5ndGggIT0gZmxhdGJ1ZmZlcnMuRklMRV9JREVOVElGSUVSX0xFTkdUSCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogZmlsZSBpZGVudGlmaWVyIG11c3QgYmUgbGVuZ3RoICcgK1xuICAgICAgICBmbGF0YnVmZmVycy5GSUxFX0lERU5USUZJRVJfTEVOR1RIKTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IGZsYXRidWZmZXJzLkZJTEVfSURFTlRJRklFUl9MRU5HVEggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdGhpcy53cml0ZUludDgoZmlsZV9pZGVudGlmaWVyLmNoYXJDb2RlQXQoaSkpO1xuICAgIH1cbiAgfVxuICB0aGlzLnByZXAodGhpcy5taW5hbGlnbiwgZmxhdGJ1ZmZlcnMuU0laRU9GX0lOVCArIHNpemVfcHJlZml4KTtcbiAgdGhpcy5hZGRPZmZzZXQocm9vdF90YWJsZSk7XG4gIGlmIChzaXplX3ByZWZpeCkge1xuICAgIHRoaXMuYWRkSW50MzIodGhpcy5iYi5jYXBhY2l0eSgpIC0gdGhpcy5zcGFjZSk7XG4gIH1cbiAgdGhpcy5iYi5zZXRQb3NpdGlvbih0aGlzLnNwYWNlKTtcbn07XG5cbi8qKlxuICogRmluYWxpemUgYSBzaXplIHByZWZpeGVkIGJ1ZmZlciwgcG9pbnRpbmcgdG8gdGhlIGdpdmVuIGByb290X3RhYmxlYC5cbiAqXG4gKiBAcGFyYW0ge2ZsYXRidWZmZXJzLk9mZnNldH0gcm9vdF90YWJsZVxuICogQHBhcmFtIHtzdHJpbmc9fSBvcHRfZmlsZV9pZGVudGlmaWVyXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmZpbmlzaFNpemVQcmVmaXhlZCA9IGZ1bmN0aW9uIChyb290X3RhYmxlLCBvcHRfZmlsZV9pZGVudGlmaWVyKSB7XG4gIHRoaXMuZmluaXNoKHJvb3RfdGFibGUsIG9wdF9maWxlX2lkZW50aWZpZXIsIHRydWUpO1xufTtcblxuLy8vIEBjb25kIEZMQVRCVUZGRVJTX0lOVEVSTkFMXG4vKipcbiAqIFRoaXMgY2hlY2tzIGEgcmVxdWlyZWQgZmllbGQgaGFzIGJlZW4gc2V0IGluIGEgZ2l2ZW4gdGFibGUgdGhhdCBoYXNcbiAqIGp1c3QgYmVlbiBjb25zdHJ1Y3RlZC5cbiAqXG4gKiBAcGFyYW0ge2ZsYXRidWZmZXJzLk9mZnNldH0gdGFibGVcbiAqIEBwYXJhbSB7bnVtYmVyfSBmaWVsZFxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5yZXF1aXJlZEZpZWxkID0gZnVuY3Rpb24odGFibGUsIGZpZWxkKSB7XG4gIHZhciB0YWJsZV9zdGFydCA9IHRoaXMuYmIuY2FwYWNpdHkoKSAtIHRhYmxlO1xuICB2YXIgdnRhYmxlX3N0YXJ0ID0gdGFibGVfc3RhcnQgLSB0aGlzLmJiLnJlYWRJbnQzMih0YWJsZV9zdGFydCk7XG4gIHZhciBvayA9IHRoaXMuYmIucmVhZEludDE2KHZ0YWJsZV9zdGFydCArIGZpZWxkKSAhPSAwO1xuXG4gIC8vIElmIHRoaXMgZmFpbHMsIHRoZSBjYWxsZXIgd2lsbCBzaG93IHdoYXQgZmllbGQgbmVlZHMgdG8gYmUgc2V0LlxuICBpZiAoIW9rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogZmllbGQgJyArIGZpZWxkICsgJyBtdXN0IGJlIHNldCcpO1xuICB9XG59O1xuXG4vKipcbiAqIFN0YXJ0IGEgbmV3IGFycmF5L3ZlY3RvciBvZiBvYmplY3RzLiAgVXNlcnMgdXN1YWxseSB3aWxsIG5vdCBjYWxsXG4gKiB0aGlzIGRpcmVjdGx5LiBUaGUgRmxhdEJ1ZmZlcnMgY29tcGlsZXIgd2lsbCBjcmVhdGUgYSBzdGFydC9lbmRcbiAqIG1ldGhvZCBmb3IgdmVjdG9yIHR5cGVzIGluIGdlbmVyYXRlZCBjb2RlLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBlbGVtX3NpemUgVGhlIHNpemUgb2YgZWFjaCBlbGVtZW50IGluIHRoZSBhcnJheVxuICogQHBhcmFtIHtudW1iZXJ9IG51bV9lbGVtcyBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBhcnJheVxuICogQHBhcmFtIHtudW1iZXJ9IGFsaWdubWVudCBUaGUgYWxpZ25tZW50IG9mIHRoZSBhcnJheVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5zdGFydFZlY3RvciA9IGZ1bmN0aW9uKGVsZW1fc2l6ZSwgbnVtX2VsZW1zLCBhbGlnbm1lbnQpIHtcbiAgdGhpcy5ub3ROZXN0ZWQoKTtcbiAgdGhpcy52ZWN0b3JfbnVtX2VsZW1zID0gbnVtX2VsZW1zO1xuICB0aGlzLnByZXAoZmxhdGJ1ZmZlcnMuU0laRU9GX0lOVCwgZWxlbV9zaXplICogbnVtX2VsZW1zKTtcbiAgdGhpcy5wcmVwKGFsaWdubWVudCwgZWxlbV9zaXplICogbnVtX2VsZW1zKTsgLy8gSnVzdCBpbiBjYXNlIGFsaWdubWVudCA+IGludC5cbn07XG5cbi8qKlxuICogRmluaXNoIG9mZiB0aGUgY3JlYXRpb24gb2YgYW4gYXJyYXkgYW5kIGFsbCBpdHMgZWxlbWVudHMuIFRoZSBhcnJheSBtdXN0IGJlXG4gKiBjcmVhdGVkIHdpdGggYHN0YXJ0VmVjdG9yYC5cbiAqXG4gKiBAcmV0dXJucyB7ZmxhdGJ1ZmZlcnMuT2Zmc2V0fSBUaGUgb2Zmc2V0IGF0IHdoaWNoIHRoZSBuZXdseSBjcmVhdGVkIGFycmF5XG4gKiBzdGFydHMuXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmVuZFZlY3RvciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLndyaXRlSW50MzIodGhpcy52ZWN0b3JfbnVtX2VsZW1zKTtcbiAgcmV0dXJuIHRoaXMub2Zmc2V0KCk7XG59O1xuLy8vIEBlbmRjb25kXG5cbi8qKlxuICogRW5jb2RlIHRoZSBzdHJpbmcgYHNgIGluIHRoZSBidWZmZXIgdXNpbmcgVVRGLTguIElmIGEgVWludDhBcnJheSBpcyBwYXNzZWRcbiAqIGluc3RlYWQgb2YgYSBzdHJpbmcsIGl0IGlzIGFzc3VtZWQgdG8gY29udGFpbiB2YWxpZCBVVEYtOCBlbmNvZGVkIGRhdGEuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8VWludDhBcnJheX0gcyBUaGUgc3RyaW5nIHRvIGVuY29kZVxuICogQHJldHVybiB7ZmxhdGJ1ZmZlcnMuT2Zmc2V0fSBUaGUgb2Zmc2V0IGluIHRoZSBidWZmZXIgd2hlcmUgdGhlIGVuY29kZWQgc3RyaW5nIHN0YXJ0c1xuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5jcmVhdGVTdHJpbmcgPSBmdW5jdGlvbihzKSB7XG4gIGlmIChzIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgIHZhciB1dGY4ID0gcztcbiAgfSBlbHNlIHtcbiAgICB2YXIgdXRmOCA9IFtdO1xuICAgIHZhciBpID0gMDtcblxuICAgIHdoaWxlIChpIDwgcy5sZW5ndGgpIHtcbiAgICAgIHZhciBjb2RlUG9pbnQ7XG5cbiAgICAgIC8vIERlY29kZSBVVEYtMTZcbiAgICAgIHZhciBhID0gcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICBpZiAoYSA8IDB4RDgwMCB8fCBhID49IDB4REMwMCkge1xuICAgICAgICBjb2RlUG9pbnQgPSBhO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGIgPSBzLmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgICAgY29kZVBvaW50ID0gKGEgPDwgMTApICsgYiArICgweDEwMDAwIC0gKDB4RDgwMCA8PCAxMCkgLSAweERDMDApO1xuICAgICAgfVxuXG4gICAgICAvLyBFbmNvZGUgVVRGLThcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICAgIHV0ZjgucHVzaChjb2RlUG9pbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICAgICAgdXRmOC5wdXNoKCgoY29kZVBvaW50ID4+IDYpICYgMHgxRikgfCAweEMwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgICAgICAgdXRmOC5wdXNoKCgoY29kZVBvaW50ID4+IDEyKSAmIDB4MEYpIHwgMHhFMCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHV0ZjgucHVzaChcbiAgICAgICAgICAgICAgKChjb2RlUG9pbnQgPj4gMTgpICYgMHgwNykgfCAweEYwLFxuICAgICAgICAgICAgICAoKGNvZGVQb2ludCA+PiAxMikgJiAweDNGKSB8IDB4ODApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB1dGY4LnB1c2goKChjb2RlUG9pbnQgPj4gNikgJiAweDNGKSB8IDB4ODApO1xuICAgICAgICB9XG4gICAgICAgIHV0ZjgucHVzaCgoY29kZVBvaW50ICYgMHgzRikgfCAweDgwKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aGlzLmFkZEludDgoMCk7XG4gIHRoaXMuc3RhcnRWZWN0b3IoMSwgdXRmOC5sZW5ndGgsIDEpO1xuICB0aGlzLmJiLnNldFBvc2l0aW9uKHRoaXMuc3BhY2UgLT0gdXRmOC5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMCwgb2Zmc2V0ID0gdGhpcy5zcGFjZSwgYnl0ZXMgPSB0aGlzLmJiLmJ5dGVzKCk7IGkgPCB1dGY4Lmxlbmd0aDsgaSsrKSB7XG4gICAgYnl0ZXNbb2Zmc2V0KytdID0gdXRmOFtpXTtcbiAgfVxuICByZXR1cm4gdGhpcy5lbmRWZWN0b3IoKTtcbn07XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gYXZvaWQgZ2VuZXJhdGVkIGNvZGUgZGVwZW5kaW5nIG9uIHRoaXMgZmlsZSBkaXJlY3RseS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gbG93XG4gKiBAcGFyYW0ge251bWJlcn0gaGlnaFxuICogQHJldHVybnMgeyFmbGF0YnVmZmVycy5Mb25nfVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5jcmVhdGVMb25nID0gZnVuY3Rpb24obG93LCBoaWdoKSB7XG4gIHJldHVybiBmbGF0YnVmZmVycy5Mb25nLmNyZWF0ZShsb3csIGhpZ2gpO1xufTtcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLy8gQGNvbmQgRkxBVEJVRkZFUlNfSU5URVJOQUxcbi8qKlxuICogQ3JlYXRlIGEgbmV3IEJ5dGVCdWZmZXIgd2l0aCBhIGdpdmVuIGFycmF5IG9mIGJ5dGVzIChgVWludDhBcnJheWApLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBieXRlc1xuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgLyoqXG4gICAqIEB0eXBlIHtVaW50OEFycmF5fVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy5ieXRlc18gPSBieXRlcztcblxuICAvKipcbiAgICogQHR5cGUge251bWJlcn1cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHRoaXMucG9zaXRpb25fID0gMDtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGFuZCBhbGxvY2F0ZSBhIG5ldyBCeXRlQnVmZmVyIHdpdGggYSBnaXZlbiBzaXplLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBieXRlX3NpemVcbiAqIEByZXR1cm5zIHshZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5hbGxvY2F0ZSA9IGZ1bmN0aW9uKGJ5dGVfc2l6ZSkge1xuICByZXR1cm4gbmV3IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIobmV3IFVpbnQ4QXJyYXkoYnl0ZV9zaXplKSk7XG59O1xuXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLnBvc2l0aW9uXyA9IDA7XG59O1xuXG4vKipcbiAqIEdldCB0aGUgdW5kZXJseWluZyBgVWludDhBcnJheWAuXG4gKlxuICogQHJldHVybnMge1VpbnQ4QXJyYXl9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmJ5dGVzXztcbn07XG5cbi8qKlxuICogR2V0IHRoZSBidWZmZXIncyBwb3NpdGlvbi5cbiAqXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5wb3NpdGlvbiA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5wb3NpdGlvbl87XG59O1xuXG4vKipcbiAqIFNldCB0aGUgYnVmZmVyJ3MgcG9zaXRpb24uXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHBvc2l0aW9uXG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLnNldFBvc2l0aW9uID0gZnVuY3Rpb24ocG9zaXRpb24pIHtcbiAgdGhpcy5wb3NpdGlvbl8gPSBwb3NpdGlvbjtcbn07XG5cbi8qKlxuICogR2V0IHRoZSBidWZmZXIncyBjYXBhY2l0eS5cbiAqXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5jYXBhY2l0eSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5ieXRlc18ubGVuZ3RoO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICByZXR1cm4gdGhpcy5yZWFkVWludDgob2Zmc2V0KSA8PCAyNCA+PiAyNDtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUucmVhZFVpbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gIHJldHVybiB0aGlzLmJ5dGVzX1tvZmZzZXRdO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTYgPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgcmV0dXJuIHRoaXMucmVhZFVpbnQxNihvZmZzZXQpIDw8IDE2ID4+IDE2O1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5yZWFkVWludDE2ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gIHJldHVybiB0aGlzLmJ5dGVzX1tvZmZzZXRdIHwgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMV0gPDwgODtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gIHJldHVybiB0aGlzLmJ5dGVzX1tvZmZzZXRdIHwgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMV0gPDwgOCB8IHRoaXMuYnl0ZXNfW29mZnNldCArIDJdIDw8IDE2IHwgdGhpcy5ieXRlc19bb2Zmc2V0ICsgM10gPDwgMjQ7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLnJlYWRVaW50MzIgPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgcmV0dXJuIHRoaXMucmVhZEludDMyKG9mZnNldCkgPj4+IDA7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm5zIHshZmxhdGJ1ZmZlcnMuTG9uZ31cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUucmVhZEludDY0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gIHJldHVybiBuZXcgZmxhdGJ1ZmZlcnMuTG9uZyh0aGlzLnJlYWRJbnQzMihvZmZzZXQpLCB0aGlzLnJlYWRJbnQzMihvZmZzZXQgKyA0KSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm5zIHshZmxhdGJ1ZmZlcnMuTG9uZ31cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUucmVhZFVpbnQ2NCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICByZXR1cm4gbmV3IGZsYXRidWZmZXJzLkxvbmcodGhpcy5yZWFkVWludDMyKG9mZnNldCksIHRoaXMucmVhZFVpbnQzMihvZmZzZXQgKyA0KSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdDMyID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gIGZsYXRidWZmZXJzLmludDMyWzBdID0gdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgcmV0dXJuIGZsYXRidWZmZXJzLmZsb2F0MzJbMF07XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdDY0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gIGZsYXRidWZmZXJzLmludDMyW2ZsYXRidWZmZXJzLmlzTGl0dGxlRW5kaWFuID8gMCA6IDFdID0gdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgZmxhdGJ1ZmZlcnMuaW50MzJbZmxhdGJ1ZmZlcnMuaXNMaXR0bGVFbmRpYW4gPyAxIDogMF0gPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQgKyA0KTtcbiAgcmV0dXJuIGZsYXRidWZmZXJzLmZsb2F0NjRbMF07XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEBwYXJhbSB7bnVtYmVyfGJvb2xlYW59IHZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uKG9mZnNldCwgdmFsdWUpIHtcbiAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IC8qKiBAdHlwZSB7bnVtYmVyfSAqLyh2YWx1ZSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS53cml0ZVVpbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0LCB2YWx1ZSkge1xuICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2ID0gZnVuY3Rpb24ob2Zmc2V0LCB2YWx1ZSkge1xuICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gIHRoaXMuYnl0ZXNfW29mZnNldCArIDFdID0gdmFsdWUgPj4gODtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLndyaXRlVWludDE2ID0gZnVuY3Rpb24ob2Zmc2V0LCB2YWx1ZSkge1xuICAgIHRoaXMuYnl0ZXNfW29mZnNldF0gPSB2YWx1ZTtcbiAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAxXSA9IHZhbHVlID4+IDg7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyID0gZnVuY3Rpb24ob2Zmc2V0LCB2YWx1ZSkge1xuICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gIHRoaXMuYnl0ZXNfW29mZnNldCArIDFdID0gdmFsdWUgPj4gODtcbiAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMl0gPSB2YWx1ZSA+PiAxNjtcbiAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgM10gPSB2YWx1ZSA+PiAyNDtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLndyaXRlVWludDMyID0gZnVuY3Rpb24ob2Zmc2V0LCB2YWx1ZSkge1xuICAgIHRoaXMuYnl0ZXNfW29mZnNldF0gPSB2YWx1ZTtcbiAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAxXSA9IHZhbHVlID4+IDg7XG4gICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMl0gPSB2YWx1ZSA+PiAxNjtcbiAgICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAzXSA9IHZhbHVlID4+IDI0O1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcGFyYW0ge2ZsYXRidWZmZXJzLkxvbmd9IHZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLndyaXRlSW50NjQgPSBmdW5jdGlvbihvZmZzZXQsIHZhbHVlKSB7XG4gIHRoaXMud3JpdGVJbnQzMihvZmZzZXQsIHZhbHVlLmxvdyk7XG4gIHRoaXMud3JpdGVJbnQzMihvZmZzZXQgKyA0LCB2YWx1ZS5oaWdoKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5Mb25nfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS53cml0ZVVpbnQ2NCA9IGZ1bmN0aW9uKG9mZnNldCwgdmFsdWUpIHtcbiAgICB0aGlzLndyaXRlVWludDMyKG9mZnNldCwgdmFsdWUubG93KTtcbiAgICB0aGlzLndyaXRlVWludDMyKG9mZnNldCArIDQsIHZhbHVlLmhpZ2gpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdDMyID0gZnVuY3Rpb24ob2Zmc2V0LCB2YWx1ZSkge1xuICBmbGF0YnVmZmVycy5mbG9hdDMyWzBdID0gdmFsdWU7XG4gIHRoaXMud3JpdGVJbnQzMihvZmZzZXQsIGZsYXRidWZmZXJzLmludDMyWzBdKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXQ2NCA9IGZ1bmN0aW9uKG9mZnNldCwgdmFsdWUpIHtcbiAgZmxhdGJ1ZmZlcnMuZmxvYXQ2NFswXSA9IHZhbHVlO1xuICB0aGlzLndyaXRlSW50MzIob2Zmc2V0LCBmbGF0YnVmZmVycy5pbnQzMltmbGF0YnVmZmVycy5pc0xpdHRsZUVuZGlhbiA/IDAgOiAxXSk7XG4gIHRoaXMud3JpdGVJbnQzMihvZmZzZXQgKyA0LCBmbGF0YnVmZmVycy5pbnQzMltmbGF0YnVmZmVycy5pc0xpdHRsZUVuZGlhbiA/IDEgOiAwXSk7XG59O1xuXG4vKipcbiAqIFJldHVybiB0aGUgZmlsZSBpZGVudGlmaWVyLiAgIEJlaGF2aW9yIGlzIHVuZGVmaW5lZCBmb3IgRmxhdEJ1ZmZlcnMgd2hvc2VcbiAqIHNjaGVtYSBkb2VzIG5vdCBpbmNsdWRlIGEgZmlsZV9pZGVudGlmaWVyIChsaWtlbHkgcG9pbnRzIGF0IHBhZGRpbmcgb3IgdGhlXG4gKiBzdGFydCBvZiBhIHRoZSByb290IHZ0YWJsZSkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5nZXRCdWZmZXJJZGVudGlmaWVyID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLmJ5dGVzXy5sZW5ndGggPCB0aGlzLnBvc2l0aW9uXyArIGZsYXRidWZmZXJzLlNJWkVPRl9JTlQgK1xuICAgICAgZmxhdGJ1ZmZlcnMuRklMRV9JREVOVElGSUVSX0xFTkdUSCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0ZsYXRCdWZmZXJzOiBCeXRlQnVmZmVyIGlzIHRvbyBzaG9ydCB0byBjb250YWluIGFuIGlkZW50aWZpZXIuJyk7XG4gIH1cbiAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZmxhdGJ1ZmZlcnMuRklMRV9JREVOVElGSUVSX0xFTkdUSDsgaSsrKSB7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICAgIHRoaXMucmVhZEludDgodGhpcy5wb3NpdGlvbl8gKyBmbGF0YnVmZmVycy5TSVpFT0ZfSU5UICsgaSkpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIExvb2sgdXAgYSBmaWVsZCBpbiB0aGUgdnRhYmxlLCByZXR1cm4gYW4gb2Zmc2V0IGludG8gdGhlIG9iamVjdCwgb3IgMCBpZiB0aGVcbiAqIGZpZWxkIGlzIG5vdCBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBiYl9wb3NcbiAqIEBwYXJhbSB7bnVtYmVyfSB2dGFibGVfb2Zmc2V0XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5fX29mZnNldCA9IGZ1bmN0aW9uKGJiX3BvcywgdnRhYmxlX29mZnNldCkge1xuICB2YXIgdnRhYmxlID0gYmJfcG9zIC0gdGhpcy5yZWFkSW50MzIoYmJfcG9zKTtcbiAgcmV0dXJuIHZ0YWJsZV9vZmZzZXQgPCB0aGlzLnJlYWRJbnQxNih2dGFibGUpID8gdGhpcy5yZWFkSW50MTYodnRhYmxlICsgdnRhYmxlX29mZnNldCkgOiAwO1xufTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGFueSBUYWJsZS1kZXJpdmVkIHR5cGUgdG8gcG9pbnQgdG8gdGhlIHVuaW9uIGF0IHRoZSBnaXZlbiBvZmZzZXQuXG4gKlxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5UYWJsZX0gdFxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybnMge2ZsYXRidWZmZXJzLlRhYmxlfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5fX3VuaW9uID0gZnVuY3Rpb24odCwgb2Zmc2V0KSB7XG4gIHQuYmJfcG9zID0gb2Zmc2V0ICsgdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgdC5iYiA9IHRoaXM7XG4gIHJldHVybiB0O1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYSBKYXZhU2NyaXB0IHN0cmluZyBmcm9tIFVURi04IGRhdGEgc3RvcmVkIGluc2lkZSB0aGUgRmxhdEJ1ZmZlci5cbiAqIFRoaXMgYWxsb2NhdGVzIGEgbmV3IHN0cmluZyBhbmQgY29udmVydHMgdG8gd2lkZSBjaGFycyB1cG9uIGVhY2ggYWNjZXNzLlxuICpcbiAqIFRvIGF2b2lkIHRoZSBjb252ZXJzaW9uIHRvIFVURi0xNiwgcGFzcyBmbGF0YnVmZmVycy5FbmNvZGluZy5VVEY4X0JZVEVTIGFzXG4gKiB0aGUgXCJvcHRpb25hbEVuY29kaW5nXCIgYXJndW1lbnQuIFRoaXMgaXMgdXNlZnVsIGZvciBhdm9pZGluZyBjb252ZXJzaW9uIHRvXG4gKiBhbmQgZnJvbSBVVEYtMTYgd2hlbiB0aGUgZGF0YSB3aWxsIGp1c3QgYmUgcGFja2FnZWQgYmFjayB1cCBpbiBhbm90aGVyXG4gKiBGbGF0QnVmZmVyIGxhdGVyIG9uLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9fSBvcHRfZW5jb2RpbmcgRGVmYXVsdHMgdG8gVVRGMTZfU1RSSU5HXG4gKiBAcmV0dXJucyB7c3RyaW5nfCFVaW50OEFycmF5fVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5fX3N0cmluZyA9IGZ1bmN0aW9uKG9mZnNldCwgb3B0X2VuY29kaW5nKSB7XG4gIG9mZnNldCArPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuXG4gIHZhciBsZW5ndGggPSB0aGlzLnJlYWRJbnQzMihvZmZzZXQpO1xuICB2YXIgcmVzdWx0ID0gJyc7XG4gIHZhciBpID0gMDtcblxuICBvZmZzZXQgKz0gZmxhdGJ1ZmZlcnMuU0laRU9GX0lOVDtcblxuICBpZiAob3B0X2VuY29kaW5nID09PSBmbGF0YnVmZmVycy5FbmNvZGluZy5VVEY4X0JZVEVTKSB7XG4gICAgcmV0dXJuIHRoaXMuYnl0ZXNfLnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsgbGVuZ3RoKTtcbiAgfVxuXG4gIHdoaWxlIChpIDwgbGVuZ3RoKSB7XG4gICAgdmFyIGNvZGVQb2ludDtcblxuICAgIC8vIERlY29kZSBVVEYtOFxuICAgIHZhciBhID0gdGhpcy5yZWFkVWludDgob2Zmc2V0ICsgaSsrKTtcbiAgICBpZiAoYSA8IDB4QzApIHtcbiAgICAgIGNvZGVQb2ludCA9IGE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBiID0gdGhpcy5yZWFkVWludDgob2Zmc2V0ICsgaSsrKTtcbiAgICAgIGlmIChhIDwgMHhFMCkge1xuICAgICAgICBjb2RlUG9pbnQgPVxuICAgICAgICAgICgoYSAmIDB4MUYpIDw8IDYpIHxcbiAgICAgICAgICAoYiAmIDB4M0YpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGMgPSB0aGlzLnJlYWRVaW50OChvZmZzZXQgKyBpKyspO1xuICAgICAgICBpZiAoYSA8IDB4RjApIHtcbiAgICAgICAgICBjb2RlUG9pbnQgPVxuICAgICAgICAgICAgKChhICYgMHgwRikgPDwgMTIpIHxcbiAgICAgICAgICAgICgoYiAmIDB4M0YpIDw8IDYpIHxcbiAgICAgICAgICAgIChjICYgMHgzRik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIGQgPSB0aGlzLnJlYWRVaW50OChvZmZzZXQgKyBpKyspO1xuICAgICAgICAgIGNvZGVQb2ludCA9XG4gICAgICAgICAgICAoKGEgJiAweDA3KSA8PCAxOCkgfFxuICAgICAgICAgICAgKChiICYgMHgzRikgPDwgMTIpIHxcbiAgICAgICAgICAgICgoYyAmIDB4M0YpIDw8IDYpIHxcbiAgICAgICAgICAgIChkICYgMHgzRik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFbmNvZGUgVVRGLTE2XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGVQb2ludCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVQb2ludCAtPSAweDEwMDAwO1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICAgIChjb2RlUG9pbnQgPj4gMTApICsgMHhEODAwLFxuICAgICAgICAoY29kZVBvaW50ICYgKCgxIDw8IDEwKSAtIDEpKSArIDB4REMwMCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIHJlbGF0aXZlIG9mZnNldCBzdG9yZWQgYXQgXCJvZmZzZXRcIlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUuX19pbmRpcmVjdCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICByZXR1cm4gb2Zmc2V0ICsgdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbn07XG5cbi8qKlxuICogR2V0IHRoZSBzdGFydCBvZiBkYXRhIG9mIGEgdmVjdG9yIHdob3NlIG9mZnNldCBpcyBzdG9yZWQgYXQgXCJvZmZzZXRcIiBpbiB0aGlzIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5fX3ZlY3RvciA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICByZXR1cm4gb2Zmc2V0ICsgdGhpcy5yZWFkSW50MzIob2Zmc2V0KSArIGZsYXRidWZmZXJzLlNJWkVPRl9JTlQ7IC8vIGRhdGEgc3RhcnRzIGFmdGVyIHRoZSBsZW5ndGhcbn07XG5cbi8qKlxuICogR2V0IHRoZSBsZW5ndGggb2YgYSB2ZWN0b3Igd2hvc2Ugb2Zmc2V0IGlzIHN0b3JlZCBhdCBcIm9mZnNldFwiIGluIHRoaXMgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLl9fdmVjdG9yX2xlbiA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICByZXR1cm4gdGhpcy5yZWFkSW50MzIob2Zmc2V0ICsgdGhpcy5yZWFkSW50MzIob2Zmc2V0KSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZGVudFxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLl9faGFzX2lkZW50aWZpZXIgPSBmdW5jdGlvbihpZGVudCkge1xuICBpZiAoaWRlbnQubGVuZ3RoICE9IGZsYXRidWZmZXJzLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXRCdWZmZXJzOiBmaWxlIGlkZW50aWZpZXIgbXVzdCBiZSBsZW5ndGggJyArXG4gICAgICAgICAgICAgICAgICAgIGZsYXRidWZmZXJzLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpO1xuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZmxhdGJ1ZmZlcnMuRklMRV9JREVOVElGSUVSX0xFTkdUSDsgaSsrKSB7XG4gICAgaWYgKGlkZW50LmNoYXJDb2RlQXQoaSkgIT0gdGhpcy5yZWFkSW50OCh0aGlzLnBvc2l0aW9uXyArIGZsYXRidWZmZXJzLlNJWkVPRl9JTlQgKyBpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogQSBoZWxwZXIgZnVuY3Rpb24gdG8gYXZvaWQgZ2VuZXJhdGVkIGNvZGUgZGVwZW5kaW5nIG9uIHRoaXMgZmlsZSBkaXJlY3RseS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gbG93XG4gKiBAcGFyYW0ge251bWJlcn0gaGlnaFxuICogQHJldHVybnMgeyFmbGF0YnVmZmVycy5Mb25nfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5jcmVhdGVMb25nID0gZnVuY3Rpb24obG93LCBoaWdoKSB7XG4gIHJldHVybiBmbGF0YnVmZmVycy5Mb25nLmNyZWF0ZShsb3csIGhpZ2gpO1xufTtcblxuLy8gRXhwb3J0cyBmb3IgTm9kZS5qcyBhbmQgUmVxdWlyZUpTXG5leHBvcnQgeyBmbGF0YnVmZmVycyB9O1xuXG4vLy8gQGVuZGNvbmRcbi8vLyBAfVxuIiwgIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuLyogZXNsaW50LWRpc2FibGUgKi9cblxuaW1wb3J0IHtmbGF0YnVmZmVyc30gZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG4vKipcbiAqIEBlbnVtIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBlbnVtIEF0dHJpYnV0ZVR5cGUge1xuICAgIFVOREVGSU5FRCA9IDAsXG4gICAgRkxPQVQgPSAxLFxuICAgIElOVCA9IDIsXG4gICAgU1RSSU5HID0gMyxcbiAgICBURU5TT1IgPSA0LFxuICAgIEdSQVBIID0gNSxcbiAgICBGTE9BVFMgPSA2LFxuICAgIElOVFMgPSA3LFxuICAgIFNUUklOR1MgPSA4LFxuICAgIFRFTlNPUlMgPSA5LFxuICAgIEdSQVBIUyA9IDEwLFxuICAgIFNQQVJTRV9URU5TT1IgPSAxMSxcbiAgICBTUEFSU0VfVEVOU09SUyA9IDEyXG4gIH1cbn1cblxuLyoqXG4gKiBAZW51bSB7bnVtYmVyfVxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgZW51bSBEaW1lbnNpb25WYWx1ZVR5cGUge1VOS05PV04gPSAwLCBWQUxVRSA9IDEsIFBBUkFNID0gMn1cbn1cblxuLyoqXG4gKiBAZW51bSB7bnVtYmVyfVxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgZW51bSBUZW5zb3JEYXRhVHlwZSB7XG4gICAgVU5ERUZJTkVEID0gMCxcbiAgICBGTE9BVCA9IDEsXG4gICAgVUlOVDggPSAyLFxuICAgIElOVDggPSAzLFxuICAgIFVJTlQxNiA9IDQsXG4gICAgSU5UMTYgPSA1LFxuICAgIElOVDMyID0gNixcbiAgICBJTlQ2NCA9IDcsXG4gICAgU1RSSU5HID0gOCxcbiAgICBCT09MID0gOSxcbiAgICBGTE9BVDE2ID0gMTAsXG4gICAgRE9VQkxFID0gMTEsXG4gICAgVUlOVDMyID0gMTIsXG4gICAgVUlOVDY0ID0gMTMsXG4gICAgQ09NUExFWDY0ID0gMTQsXG4gICAgQ09NUExFWDEyOCA9IDE1LFxuICAgIEJGTE9BVDE2ID0gMTYsXG4gICAgRkxPQVQ4RTRNM0ZOID0gMTcsXG4gICAgRkxPQVQ4RTRNM0ZOVVogPSAxOCxcbiAgICBGTE9BVDhFNU0yID0gMTksXG4gICAgRkxPQVQ4RTVNMkZOVVogPSAyMCxcbiAgfVxufVxuXG4vKipcbiAqIEBlbnVtIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBlbnVtIE5vZGVUeXBlIHtQcmltaXRpdmUgPSAwLCBGdXNlZCA9IDF9XG59XG5cbi8qKlxuICogQGVudW0ge251bWJlcn1cbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGVudW0gVHlwZUluZm9WYWx1ZSB7Tk9ORSA9IDAsIHRlbnNvcl90eXBlID0gMSwgc2VxdWVuY2VfdHlwZSA9IDIsIG1hcF90eXBlID0gM31cbn1cblxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIFNoYXBlIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBTaGFwZVxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogU2hhcGUge1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gU2hhcGU9IG9ialxuICAgICAqIEByZXR1cm5zIFNoYXBlXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc1NoYXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTaGFwZSk6IFNoYXBlIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBTaGFwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIFNoYXBlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBTaGFwZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNTaGFwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU2hhcGUpOiBTaGFwZSB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBTaGFwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb249IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uXG4gICAgICovXG4gICAgZGltKGluZGV4OiBudW1iZXIsIG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb258bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgZGltTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRTaGFwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGRpbU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREaW0oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgZGltT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIEFycmF5LjxmbGF0YnVmZmVycy5PZmZzZXQ+IGRhdGFcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlRGltVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydERpbVZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZFNoYXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVTaGFwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBTaGFwZS5zdGFydFNoYXBlKGJ1aWxkZXIpO1xuICAgICAgU2hhcGUuYWRkRGltKGJ1aWxkZXIsIGRpbU9mZnNldCk7XG4gICAgICByZXR1cm4gU2hhcGUuZW5kU2hhcGUoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgRGltZW5zaW9uIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBEaW1lbnNpb25cbiAgICAgKi9cbiAgICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IERpbWVuc2lvbiB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBEaW1lbnNpb249IG9ialxuICAgICAqIEByZXR1cm5zIERpbWVuc2lvblxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSb290QXNEaW1lbnNpb24oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IERpbWVuc2lvbik6IERpbWVuc2lvbiB7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGltZW5zaW9uKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gRGltZW5zaW9uPSBvYmpcbiAgICAgKiBAcmV0dXJucyBEaW1lbnNpb25cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzRGltZW5zaW9uKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBEaW1lbnNpb24pOiBEaW1lbnNpb24ge1xuICAgICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGltZW5zaW9uKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uVmFsdWU9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uVmFsdWV8bnVsbFxuICAgICAqL1xuICAgIHZhbHVlKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uVmFsdWUpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkRpbWVuc2lvblZhbHVlfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkRpbWVuc2lvblZhbHVlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgZGVub3RhdGlvbigpOiBzdHJpbmd8bnVsbDtcbiAgICBkZW5vdGF0aW9uKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBkZW5vdGF0aW9uKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0RGltZW5zaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgdmFsdWVPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkVmFsdWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCB2YWx1ZU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZGVub3RhdGlvbk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREZW5vdGF0aW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRlbm90YXRpb25PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBkZW5vdGF0aW9uT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZERpbWVuc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGxldCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICB9XG5cbiAgICBzdGF0aWMgY3JlYXRlRGltZW5zaW9uKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBkZW5vdGF0aW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgRGltZW5zaW9uLnN0YXJ0RGltZW5zaW9uKGJ1aWxkZXIpO1xuICAgICAgRGltZW5zaW9uLmFkZFZhbHVlKGJ1aWxkZXIsIHZhbHVlT2Zmc2V0KTtcbiAgICAgIERpbWVuc2lvbi5hZGREZW5vdGF0aW9uKGJ1aWxkZXIsIGRlbm90YXRpb25PZmZzZXQpO1xuICAgICAgcmV0dXJuIERpbWVuc2lvbi5lbmREaW1lbnNpb24oYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgRGltZW5zaW9uVmFsdWUge1xuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyfG51bGwgPSBudWxsO1xuXG4gICAgYmJfcG9zID0gMDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGlcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIERpbWVuc2lvblZhbHVlXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEaW1lbnNpb25WYWx1ZSB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBEaW1lbnNpb25WYWx1ZT0gb2JqXG4gICAgICogQHJldHVybnMgRGltZW5zaW9uVmFsdWVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzRGltZW5zaW9uVmFsdWUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IERpbWVuc2lvblZhbHVlKTogRGltZW5zaW9uVmFsdWUge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IERpbWVuc2lvblZhbHVlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gRGltZW5zaW9uVmFsdWU9IG9ialxuICAgICAqIEByZXR1cm5zIERpbWVuc2lvblZhbHVlXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0RpbWVuc2lvblZhbHVlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBEaW1lbnNpb25WYWx1ZSk6IERpbWVuc2lvblZhbHVlIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IERpbWVuc2lvblZhbHVlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb25WYWx1ZVR5cGVcbiAgICAgKi9cbiAgICBkaW1UeXBlKCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uVmFsdWVUeXBlIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gLyoqICAqLyAodGhpcy5iYiEucmVhZEludDgodGhpcy5iYl9wb3MgKyBvZmZzZXQpKSA6XG4gICAgICAgICAgICAgICAgICAgICAgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb25WYWx1ZVR5cGUuVU5LTk9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5Mb25nXG4gICAgICovXG4gICAgZGltVmFsdWUoKTogZmxhdGJ1ZmZlcnMuTG9uZyB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiB0aGlzLmJiIS5jcmVhdGVMb25nKDAsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5fG51bGxcbiAgICAgKi9cbiAgICBkaW1QYXJhbSgpOiBzdHJpbmd8bnVsbDtcbiAgICBkaW1QYXJhbShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZGltUGFyYW0ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnREaW1lbnNpb25WYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb25WYWx1ZVR5cGUgZGltVHlwZVxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREaW1UeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbVR5cGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uVmFsdWVUeXBlKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50OCgwLCBkaW1UeXBlLCBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkRpbWVuc2lvblZhbHVlVHlwZS5VTktOT1dOKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkxvbmcgZGltVmFsdWVcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRGltVmFsdWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltVmFsdWU6IGZsYXRidWZmZXJzLkxvbmcpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCgxLCBkaW1WYWx1ZSwgYnVpbGRlci5jcmVhdGVMb25nKDAsIDApKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBkaW1QYXJhbU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREaW1QYXJhbShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1QYXJhbU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIGRpbVBhcmFtT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZERpbWVuc2lvblZhbHVlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVEaW1lbnNpb25WYWx1ZShcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltVHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb25WYWx1ZVR5cGUsXG4gICAgICAgIGRpbVZhbHVlOiBmbGF0YnVmZmVycy5Mb25nLCBkaW1QYXJhbU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIERpbWVuc2lvblZhbHVlLnN0YXJ0RGltZW5zaW9uVmFsdWUoYnVpbGRlcik7XG4gICAgICBEaW1lbnNpb25WYWx1ZS5hZGREaW1UeXBlKGJ1aWxkZXIsIGRpbVR5cGUpO1xuICAgICAgRGltZW5zaW9uVmFsdWUuYWRkRGltVmFsdWUoYnVpbGRlciwgZGltVmFsdWUpO1xuICAgICAgRGltZW5zaW9uVmFsdWUuYWRkRGltUGFyYW0oYnVpbGRlciwgZGltUGFyYW1PZmZzZXQpO1xuICAgICAgcmV0dXJuIERpbWVuc2lvblZhbHVlLmVuZERpbWVuc2lvblZhbHVlKGJ1aWxkZXIpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIFRlbnNvclR5cGVBbmRTaGFwZSB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgVGVuc29yVHlwZUFuZFNoYXBlXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBUZW5zb3JUeXBlQW5kU2hhcGUge1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gVGVuc29yVHlwZUFuZFNoYXBlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBUZW5zb3JUeXBlQW5kU2hhcGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzVGVuc29yVHlwZUFuZFNoYXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUZW5zb3JUeXBlQW5kU2hhcGUpOiBUZW5zb3JUeXBlQW5kU2hhcGUge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFRlbnNvclR5cGVBbmRTaGFwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIFRlbnNvclR5cGVBbmRTaGFwZT0gb2JqXG4gICAgICogQHJldHVybnMgVGVuc29yVHlwZUFuZFNoYXBlXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1RlbnNvclR5cGVBbmRTaGFwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVGVuc29yVHlwZUFuZFNoYXBlKTpcbiAgICAgICAgVGVuc29yVHlwZUFuZFNoYXBlIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFRlbnNvclR5cGVBbmRTaGFwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGVcbiAgICAgKi9cbiAgICBlbGVtVHlwZSgpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gLyoqICAqLyAodGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSkgOlxuICAgICAgICAgICAgICAgICAgICAgIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUuVU5ERUZJTkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNoYXBlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNoYXBlfG51bGxcbiAgICAgKi9cbiAgICBzaGFwZShvYmo/OiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNoYXBlKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TaGFwZXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TaGFwZSgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydFRlbnNvclR5cGVBbmRTaGFwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZSBlbGVtVHlwZVxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRFbGVtVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBlbGVtVHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZSkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDAsIGVsZW1UeXBlLCBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlLlVOREVGSU5FRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgc2hhcGVPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc2hhcGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBzaGFwZU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRUZW5zb3JUeXBlQW5kU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVRlbnNvclR5cGVBbmRTaGFwZShcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZWxlbVR5cGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUsXG4gICAgICAgIHNoYXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgVGVuc29yVHlwZUFuZFNoYXBlLnN0YXJ0VGVuc29yVHlwZUFuZFNoYXBlKGJ1aWxkZXIpO1xuICAgICAgVGVuc29yVHlwZUFuZFNoYXBlLmFkZEVsZW1UeXBlKGJ1aWxkZXIsIGVsZW1UeXBlKTtcbiAgICAgIFRlbnNvclR5cGVBbmRTaGFwZS5hZGRTaGFwZShidWlsZGVyLCBzaGFwZU9mZnNldCk7XG4gICAgICByZXR1cm4gVGVuc29yVHlwZUFuZFNoYXBlLmVuZFRlbnNvclR5cGVBbmRTaGFwZShidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBjbGFzcyBNYXBUeXBlIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBNYXBUeXBlXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBNYXBUeXBlIHtcbiAgICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICAgIHRoaXMuYmIgPSBiYjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIE1hcFR5cGU9IG9ialxuICAgICAqIEByZXR1cm5zIE1hcFR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzTWFwVHlwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTWFwVHlwZSk6IE1hcFR5cGUge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IE1hcFR5cGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBNYXBUeXBlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBNYXBUeXBlXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc01hcFR5cGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE1hcFR5cGUpOiBNYXBUeXBlIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IE1hcFR5cGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlXG4gICAgICovXG4gICAga2V5VHlwZSgpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gLyoqICAqLyAodGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSkgOlxuICAgICAgICAgICAgICAgICAgICAgIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUuVU5ERUZJTkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvPSBvYmpcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvfG51bGxcbiAgICAgKi9cbiAgICB2YWx1ZVR5cGUob2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mbyk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm98bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm8oKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDpcbiAgICAgICAgICAgICAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRNYXBUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlIGtleVR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkS2V5VHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXlUeXBlOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMCwga2V5VHlwZSwgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZS5VTkRFRklORUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHZhbHVlVHlwZU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRWYWx1ZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgdmFsdWVUeXBlT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZE1hcFR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZU1hcFR5cGUoXG4gICAgICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtleVR5cGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUsXG4gICAgICAgIHZhbHVlVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIE1hcFR5cGUuc3RhcnRNYXBUeXBlKGJ1aWxkZXIpO1xuICAgICAgTWFwVHlwZS5hZGRLZXlUeXBlKGJ1aWxkZXIsIGtleVR5cGUpO1xuICAgICAgTWFwVHlwZS5hZGRWYWx1ZVR5cGUoYnVpbGRlciwgdmFsdWVUeXBlT2Zmc2V0KTtcbiAgICAgIHJldHVybiBNYXBUeXBlLmVuZE1hcFR5cGUoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgU2VxdWVuY2VUeXBlIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBTZXF1ZW5jZVR5cGVcbiAgICAgKi9cbiAgICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFNlcXVlbmNlVHlwZSB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBTZXF1ZW5jZVR5cGU9IG9ialxuICAgICAqIEByZXR1cm5zIFNlcXVlbmNlVHlwZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSb290QXNTZXF1ZW5jZVR5cGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFNlcXVlbmNlVHlwZSk6IFNlcXVlbmNlVHlwZSB7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgU2VxdWVuY2VUeXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gU2VxdWVuY2VUeXBlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBTZXF1ZW5jZVR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzU2VxdWVuY2VUeXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTZXF1ZW5jZVR5cGUpOiBTZXF1ZW5jZVR5cGUge1xuICAgICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgU2VxdWVuY2VUeXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm89IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm98bnVsbFxuICAgICAqL1xuICAgIGVsZW1UeXBlKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm8pOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0U2VxdWVuY2VUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZWxlbVR5cGVPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRWxlbVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZWxlbVR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBlbGVtVHlwZU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRTZXF1ZW5jZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVNlcXVlbmNlVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBlbGVtVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIFNlcXVlbmNlVHlwZS5zdGFydFNlcXVlbmNlVHlwZShidWlsZGVyKTtcbiAgICAgIFNlcXVlbmNlVHlwZS5hZGRFbGVtVHlwZShidWlsZGVyLCBlbGVtVHlwZU9mZnNldCk7XG4gICAgICByZXR1cm4gU2VxdWVuY2VUeXBlLmVuZFNlcXVlbmNlVHlwZShidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBjbGFzcyBFZGdlRW5kIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBFZGdlRW5kXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBFZGdlRW5kIHtcbiAgICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICAgIHRoaXMuYmIgPSBiYjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIG5vZGVJbmRleCgpOiBudW1iZXIge1xuICAgICAgcmV0dXJuIHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIHNyY0FyZ0luZGV4KCk6IG51bWJlciB7XG4gICAgICByZXR1cm4gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgZHN0QXJnSW5kZXgoKTogbnVtYmVyIHtcbiAgICAgIHJldHVybiB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyA4KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBub2RlX2luZGV4XG4gICAgICogQHBhcmFtIG51bWJlciBzcmNfYXJnX2luZGV4XG4gICAgICogQHBhcmFtIG51bWJlciBkc3RfYXJnX2luZGV4XG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUVkZ2VFbmQoXG4gICAgICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVfaW5kZXg6IG51bWJlciwgc3JjX2FyZ19pbmRleDogbnVtYmVyLFxuICAgICAgICBkc3RfYXJnX2luZGV4OiBudW1iZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5wcmVwKDQsIDEyKTtcbiAgICAgIGJ1aWxkZXIud3JpdGVJbnQzMihkc3RfYXJnX2luZGV4KTtcbiAgICAgIGJ1aWxkZXIud3JpdGVJbnQzMihzcmNfYXJnX2luZGV4KTtcbiAgICAgIGJ1aWxkZXIud3JpdGVJbnQzMihub2RlX2luZGV4KTtcbiAgICAgIHJldHVybiBidWlsZGVyLm9mZnNldCgpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIE5vZGVFZGdlIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBOb2RlRWRnZVxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogTm9kZUVkZ2Uge1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gTm9kZUVkZ2U9IG9ialxuICAgICAqIEByZXR1cm5zIE5vZGVFZGdlXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc05vZGVFZGdlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBOb2RlRWRnZSk6IE5vZGVFZGdlIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlRWRnZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIE5vZGVFZGdlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBOb2RlRWRnZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNOb2RlRWRnZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTm9kZUVkZ2UpOiBOb2RlRWRnZSB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlRWRnZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIG5vZGVJbmRleCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkVkZ2VFbmQ9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRWRnZUVuZFxuICAgICAqL1xuICAgIGlucHV0RWRnZXMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5FZGdlRW5kKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5FZGdlRW5kfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkVkZ2VFbmQoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDEyLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW5wdXRFZGdlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRWRnZUVuZD0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5FZGdlRW5kXG4gICAgICovXG4gICAgb3V0cHV0RWRnZXMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5FZGdlRW5kKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5FZGdlRW5kfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkVkZ2VFbmQoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDEyLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgb3V0cHV0RWRnZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydE5vZGVFZGdlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbm9kZUluZGV4XG4gICAgICovXG4gICAgc3RhdGljIGFkZE5vZGVJbmRleChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBub2RlSW5kZXg6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDAsIG5vZGVJbmRleCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgaW5wdXRFZGdlc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRJbnB1dEVkZ2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlucHV0RWRnZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBpbnB1dEVkZ2VzT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydElucHV0RWRnZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3RvcigxMiwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG91dHB1dEVkZ2VzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE91dHB1dEVkZ2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG91dHB1dEVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgb3V0cHV0RWRnZXNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0T3V0cHV0RWRnZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3RvcigxMiwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kTm9kZUVkZ2UoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZU5vZGVFZGdlKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBub2RlSW5kZXg6IG51bWJlciwgaW5wdXRFZGdlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBvdXRwdXRFZGdlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIE5vZGVFZGdlLnN0YXJ0Tm9kZUVkZ2UoYnVpbGRlcik7XG4gICAgICBOb2RlRWRnZS5hZGROb2RlSW5kZXgoYnVpbGRlciwgbm9kZUluZGV4KTtcbiAgICAgIE5vZGVFZGdlLmFkZElucHV0RWRnZXMoYnVpbGRlciwgaW5wdXRFZGdlc09mZnNldCk7XG4gICAgICBOb2RlRWRnZS5hZGRPdXRwdXRFZGdlcyhidWlsZGVyLCBvdXRwdXRFZGdlc09mZnNldCk7XG4gICAgICByZXR1cm4gTm9kZUVkZ2UuZW5kTm9kZUVkZ2UoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgTm9kZSB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgTm9kZVxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogTm9kZSB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBOb2RlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBOb2RlXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc05vZGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE5vZGUpOiBOb2RlIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gTm9kZT0gb2JqXG4gICAgICogQHJldHVybnMgTm9kZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNOb2RlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBOb2RlKTogTm9kZSB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIG5hbWUoKTogc3RyaW5nfG51bGw7XG4gICAgbmFtZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRvY1N0cmluZygpOiBzdHJpbmd8bnVsbDtcbiAgICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRvbWFpbigpOiBzdHJpbmd8bnVsbDtcbiAgICBkb21haW4ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIGRvbWFpbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgc2luY2VWZXJzaW9uKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBpbmRleCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZFVpbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5fG51bGxcbiAgICAgKi9cbiAgICBvcFR5cGUoKTogc3RyaW5nfG51bGw7XG4gICAgb3BUeXBlKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBvcFR5cGUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGVUeXBlXG4gICAgICovXG4gICAgdHlwZSgpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGVUeXBlIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IC8qKiAgKi8gKHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkpIDpcbiAgICAgICAgICAgICAgICAgICAgICBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGVUeXBlLlByaW1pdGl2ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgZXhlY3V0aW9uUHJvdmlkZXJUeXBlKCk6IHN0cmluZ3xudWxsO1xuICAgIGV4ZWN1dGlvblByb3ZpZGVyVHlwZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZXhlY3V0aW9uUHJvdmlkZXJUeXBlKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5XG4gICAgICovXG4gICAgaW5wdXRzKGluZGV4OiBudW1iZXIpOiBzdHJpbmc7XG4gICAgaW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXk7XG4gICAgaW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIGlucHV0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5XG4gICAgICovXG4gICAgb3V0cHV0cyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICAgIG91dHB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheTtcbiAgICBvdXRwdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIG91dHB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5BdHRyaWJ1dGU9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuQXR0cmlidXRlXG4gICAgICovXG4gICAgYXR0cmlidXRlcyhpbmRleDogbnVtYmVyLCBvYmo/OiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkF0dHJpYnV0ZSk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuQXR0cmlidXRlXG4gICAgICAgIHxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuQXR0cmlidXRlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgYXR0cmlidXRlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIGlucHV0QXJnQ291bnRzKGluZGV4OiBudW1iZXIpOiBudW1iZXJ8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW5wdXRBcmdDb3VudHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIEludDMyQXJyYXlcbiAgICAgKi9cbiAgICBpbnB1dEFyZ0NvdW50c0FycmF5KCk6IEludDMyQXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgP1xuICAgICAgICAgIG5ldyBJbnQzMkFycmF5KFxuICAgICAgICAgICAgICB0aGlzLmJiIS5ieXRlcygpLmJ1ZmZlciwgdGhpcy5iYiEuYnl0ZXMoKS5ieXRlT2Zmc2V0ICsgdGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICAgICAgICB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpKSA6XG4gICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXlcbiAgICAgKi9cbiAgICBpbXBsaWNpdElucHV0cyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICAgIGltcGxpY2l0SW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXk7XG4gICAgaW1wbGljaXRJbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW1wbGljaXRJbnB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnROb2RlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMTMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG5hbWVPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgbmFtZU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZG9jU3RyaW5nT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBkb2NTdHJpbmdPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGRvbWFpbk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREb21haW4oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgZG9tYWluT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBzaW5jZVZlcnNpb25cbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkU2luY2VWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNpbmNlVmVyc2lvbjogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMywgc2luY2VWZXJzaW9uLCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRJbmRleChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbmRleDogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoNCwgaW5kZXgsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG9wVHlwZU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRPcFR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3BUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNSwgb3BUeXBlT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZVR5cGUgdHlwZVxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHR5cGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZVR5cGUpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMig2LCB0eXBlLCBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGVUeXBlLlByaW1pdGl2ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZXhlY3V0aW9uUHJvdmlkZXJUeXBlT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZEV4ZWN1dGlvblByb3ZpZGVyVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBleGVjdXRpb25Qcm92aWRlclR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg3LCBleGVjdXRpb25Qcm92aWRlclR5cGVPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGlucHV0c09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRJbnB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW5wdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOCwgaW5wdXRzT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIEFycmF5LjxmbGF0YnVmZmVycy5PZmZzZXQ+IGRhdGFcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlSW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydElucHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBvdXRwdXRzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE91dHB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3V0cHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDksIG91dHB1dHNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPGZsYXRidWZmZXJzLk9mZnNldD4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVPdXRwdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydE91dHB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgYXR0cmlidXRlc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRBdHRyaWJ1dGVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGF0dHJpYnV0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMCwgYXR0cmlidXRlc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUF0dHJpYnV0ZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0QXR0cmlidXRlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBpbnB1dEFyZ0NvdW50c09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRJbnB1dEFyZ0NvdW50cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnB1dEFyZ0NvdW50c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDExLCBpbnB1dEFyZ0NvdW50c09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48bnVtYmVyPiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUlucHV0QXJnQ291bnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdfFVpbnQ4QXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZEludDMyKGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRJbnB1dEFyZ0NvdW50c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBpbXBsaWNpdElucHV0c09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRJbXBsaWNpdElucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbXBsaWNpdElucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEyLCBpbXBsaWNpdElucHV0c09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUltcGxpY2l0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydEltcGxpY2l0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kTm9kZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGxldCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICB9XG5cbiAgICBzdGF0aWMgY3JlYXRlTm9kZShcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIHNpbmNlVmVyc2lvbjogbnVtYmVyLCBpbmRleDogbnVtYmVyLCBvcFR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgdHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlVHlwZSwgZXhlY3V0aW9uUHJvdmlkZXJUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIGlucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBvdXRwdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIGF0dHJpYnV0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgaW5wdXRBcmdDb3VudHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCwgaW1wbGljaXRJbnB1dHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBOb2RlLnN0YXJ0Tm9kZShidWlsZGVyKTtcbiAgICAgIE5vZGUuYWRkTmFtZShidWlsZGVyLCBuYW1lT2Zmc2V0KTtcbiAgICAgIE5vZGUuYWRkRG9jU3RyaW5nKGJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldCk7XG4gICAgICBOb2RlLmFkZERvbWFpbihidWlsZGVyLCBkb21haW5PZmZzZXQpO1xuICAgICAgTm9kZS5hZGRTaW5jZVZlcnNpb24oYnVpbGRlciwgc2luY2VWZXJzaW9uKTtcbiAgICAgIE5vZGUuYWRkSW5kZXgoYnVpbGRlciwgaW5kZXgpO1xuICAgICAgTm9kZS5hZGRPcFR5cGUoYnVpbGRlciwgb3BUeXBlT2Zmc2V0KTtcbiAgICAgIE5vZGUuYWRkVHlwZShidWlsZGVyLCB0eXBlKTtcbiAgICAgIE5vZGUuYWRkRXhlY3V0aW9uUHJvdmlkZXJUeXBlKGJ1aWxkZXIsIGV4ZWN1dGlvblByb3ZpZGVyVHlwZU9mZnNldCk7XG4gICAgICBOb2RlLmFkZElucHV0cyhidWlsZGVyLCBpbnB1dHNPZmZzZXQpO1xuICAgICAgTm9kZS5hZGRPdXRwdXRzKGJ1aWxkZXIsIG91dHB1dHNPZmZzZXQpO1xuICAgICAgTm9kZS5hZGRBdHRyaWJ1dGVzKGJ1aWxkZXIsIGF0dHJpYnV0ZXNPZmZzZXQpO1xuICAgICAgTm9kZS5hZGRJbnB1dEFyZ0NvdW50cyhidWlsZGVyLCBpbnB1dEFyZ0NvdW50c09mZnNldCk7XG4gICAgICBOb2RlLmFkZEltcGxpY2l0SW5wdXRzKGJ1aWxkZXIsIGltcGxpY2l0SW5wdXRzT2Zmc2V0KTtcbiAgICAgIHJldHVybiBOb2RlLmVuZE5vZGUoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgVmFsdWVJbmZvIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBWYWx1ZUluZm9cbiAgICAgKi9cbiAgICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFZhbHVlSW5mbyB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBWYWx1ZUluZm89IG9ialxuICAgICAqIEByZXR1cm5zIFZhbHVlSW5mb1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSb290QXNWYWx1ZUluZm8oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFZhbHVlSW5mbyk6IFZhbHVlSW5mbyB7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgVmFsdWVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gVmFsdWVJbmZvPSBvYmpcbiAgICAgKiBAcmV0dXJucyBWYWx1ZUluZm9cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzVmFsdWVJbmZvKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBWYWx1ZUluZm8pOiBWYWx1ZUluZm8ge1xuICAgICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgVmFsdWVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIG5hbWUoKTogc3RyaW5nfG51bGw7XG4gICAgbmFtZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRvY1N0cmluZygpOiBzdHJpbmd8bnVsbDtcbiAgICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm89IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm98bnVsbFxuICAgICAqL1xuICAgIHR5cGUob2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mbyk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm98bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm8oKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDpcbiAgICAgICAgICAgICAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRWYWx1ZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBuYW1lT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE5hbWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5hbWVPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGRvY1N0cmluZ09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCB0eXBlT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIHR5cGVPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kVmFsdWVJbmZvKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVWYWx1ZUluZm8oXG4gICAgICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIHR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBWYWx1ZUluZm8uc3RhcnRWYWx1ZUluZm8oYnVpbGRlcik7XG4gICAgICBWYWx1ZUluZm8uYWRkTmFtZShidWlsZGVyLCBuYW1lT2Zmc2V0KTtcbiAgICAgIFZhbHVlSW5mby5hZGREb2NTdHJpbmcoYnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0KTtcbiAgICAgIFZhbHVlSW5mby5hZGRUeXBlKGJ1aWxkZXIsIHR5cGVPZmZzZXQpO1xuICAgICAgcmV0dXJuIFZhbHVlSW5mby5lbmRWYWx1ZUluZm8oYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgVHlwZUluZm8ge1xuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyfG51bGwgPSBudWxsO1xuXG4gICAgYmJfcG9zID0gMDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGlcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIFR5cGVJbmZvXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBUeXBlSW5mbyB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBUeXBlSW5mbz0gb2JqXG4gICAgICogQHJldHVybnMgVHlwZUluZm9cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzVHlwZUluZm8oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFR5cGVJbmZvKTogVHlwZUluZm8ge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFR5cGVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gVHlwZUluZm89IG9ialxuICAgICAqIEByZXR1cm5zIFR5cGVJbmZvXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1R5cGVJbmZvKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUeXBlSW5mbyk6IFR5cGVJbmZvIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFR5cGVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRlbm90YXRpb24oKTogc3RyaW5nfG51bGw7XG4gICAgZGVub3RhdGlvbihvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZGVub3RhdGlvbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mb1ZhbHVlXG4gICAgICovXG4gICAgdmFsdWVUeXBlKCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm9WYWx1ZSB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IC8qKiAgKi8gKHRoaXMuYmIhLnJlYWRVaW50OCh0aGlzLmJiX3BvcyArIG9mZnNldCkpIDpcbiAgICAgICAgICAgICAgICAgICAgICBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvVmFsdWUuTk9ORTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuVGFibGUgb2JqXG4gICAgICogQHJldHVybnMgP2ZsYXRidWZmZXJzLlRhYmxlXG4gICAgICovXG4gICAgdmFsdWU8VCBleHRlbmRzIGZsYXRidWZmZXJzLlRhYmxlPihvYmo6IFQpOiBUfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3VuaW9uKG9iaiwgdGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0VHlwZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBkZW5vdGF0aW9uT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZERlbm90YXRpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGVub3RhdGlvbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGRlbm90YXRpb25PZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mb1ZhbHVlIHZhbHVlVHlwZVxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRWYWx1ZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVUeXBlOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvVmFsdWUpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ4KDEsIHZhbHVlVHlwZSwgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mb1ZhbHVlLk5PTkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHZhbHVlT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFZhbHVlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHZhbHVlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgdmFsdWVPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kVHlwZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVR5cGVJbmZvKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkZW5vdGF0aW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIHZhbHVlVHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mb1ZhbHVlLCB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIFR5cGVJbmZvLnN0YXJ0VHlwZUluZm8oYnVpbGRlcik7XG4gICAgICBUeXBlSW5mby5hZGREZW5vdGF0aW9uKGJ1aWxkZXIsIGRlbm90YXRpb25PZmZzZXQpO1xuICAgICAgVHlwZUluZm8uYWRkVmFsdWVUeXBlKGJ1aWxkZXIsIHZhbHVlVHlwZSk7XG4gICAgICBUeXBlSW5mby5hZGRWYWx1ZShidWlsZGVyLCB2YWx1ZU9mZnNldCk7XG4gICAgICByZXR1cm4gVHlwZUluZm8uZW5kVHlwZUluZm8oYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgT3BlcmF0b3JTZXRJZCB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgT3BlcmF0b3JTZXRJZFxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogT3BlcmF0b3JTZXRJZCB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBPcGVyYXRvclNldElkPSBvYmpcbiAgICAgKiBAcmV0dXJucyBPcGVyYXRvclNldElkXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc09wZXJhdG9yU2V0SWQoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE9wZXJhdG9yU2V0SWQpOiBPcGVyYXRvclNldElkIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBPcGVyYXRvclNldElkKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gT3BlcmF0b3JTZXRJZD0gb2JqXG4gICAgICogQHJldHVybnMgT3BlcmF0b3JTZXRJZFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNPcGVyYXRvclNldElkKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBPcGVyYXRvclNldElkKTogT3BlcmF0b3JTZXRJZCB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBPcGVyYXRvclNldElkKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRvbWFpbigpOiBzdHJpbmd8bnVsbDtcbiAgICBkb21haW4ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIGRvbWFpbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuTG9uZ1xuICAgICAqL1xuICAgIHZlcnNpb24oKTogZmxhdGJ1ZmZlcnMuTG9uZyB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiB0aGlzLmJiIS5jcmVhdGVMb25nKDAsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRPcGVyYXRvclNldElkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZG9tYWluT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZERvbWFpbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb21haW5PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBkb21haW5PZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuTG9uZyB2ZXJzaW9uXG4gICAgICovXG4gICAgc3RhdGljIGFkZFZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmVyc2lvbjogZmxhdGJ1ZmZlcnMuTG9uZykge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDEsIHZlcnNpb24sIGJ1aWxkZXIuY3JlYXRlTG9uZygwLCAwKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRPcGVyYXRvclNldElkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVPcGVyYXRvclNldElkKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb21haW5PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCwgdmVyc2lvbjogZmxhdGJ1ZmZlcnMuTG9uZyk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBPcGVyYXRvclNldElkLnN0YXJ0T3BlcmF0b3JTZXRJZChidWlsZGVyKTtcbiAgICAgIE9wZXJhdG9yU2V0SWQuYWRkRG9tYWluKGJ1aWxkZXIsIGRvbWFpbk9mZnNldCk7XG4gICAgICBPcGVyYXRvclNldElkLmFkZFZlcnNpb24oYnVpbGRlciwgdmVyc2lvbik7XG4gICAgICByZXR1cm4gT3BlcmF0b3JTZXRJZC5lbmRPcGVyYXRvclNldElkKGJ1aWxkZXIpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIFRlbnNvciB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgVGVuc29yXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBUZW5zb3Ige1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gVGVuc29yPSBvYmpcbiAgICAgKiBAcmV0dXJucyBUZW5zb3JcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzVGVuc29yKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUZW5zb3IpOiBUZW5zb3Ige1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFRlbnNvcigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIFRlbnNvcj0gb2JqXG4gICAgICogQHJldHVybnMgVGVuc29yXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1RlbnNvcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVGVuc29yKTogVGVuc29yIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFRlbnNvcigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5fG51bGxcbiAgICAgKi9cbiAgICBuYW1lKCk6IHN0cmluZ3xudWxsO1xuICAgIG5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIG5hbWUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5fG51bGxcbiAgICAgKi9cbiAgICBkb2NTdHJpbmcoKTogc3RyaW5nfG51bGw7XG4gICAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5Mb25nXG4gICAgICovXG4gICAgZGltcyhpbmRleDogbnVtYmVyKTogZmxhdGJ1ZmZlcnMuTG9uZ3xudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogOCkgOlxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYmIhLmNyZWF0ZUxvbmcoMCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgZGltc0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlXG4gICAgICovXG4gICAgZGF0YVR5cGUoKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZSB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAvKiogICovICh0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpKSA6XG4gICAgICAgICAgICAgICAgICAgICAgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZS5VTkRFRklORUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIHJhd0RhdGEoaW5kZXg6IG51bWJlcik6IG51bWJlcnxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50OCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIHJhd0RhdGFMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFVpbnQ4QXJyYXlcbiAgICAgKi9cbiAgICByYXdEYXRhQXJyYXkoKTogVWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/XG4gICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoXG4gICAgICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnVmZmVyLCB0aGlzLmJiIS5ieXRlcygpLmJ5dGVPZmZzZXQgKyB0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgICAgICAgIHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkpIDpcbiAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheVxuICAgICAqL1xuICAgIHN0cmluZ0RhdGEoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgICBzdHJpbmdEYXRhKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXk7XG4gICAgc3RyaW5nRGF0YShpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBzdHJpbmdEYXRhTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0VGVuc29yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoNik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgbmFtZU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGROYW1lKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBuYW1lT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBkb2NTdHJpbmdPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRG9jU3RyaW5nKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGRvY1N0cmluZ09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZGltc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREaW1zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgyLCBkaW1zT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIEFycmF5LjxmbGF0YnVmZmVycy5Mb25nPiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZURpbXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuTG9uZ1tdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgZGF0YS5sZW5ndGgsIDgpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRJbnQ2NChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0RGltc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIG51bUVsZW1zLCA4KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUgZGF0YVR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRGF0YVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YVR5cGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigzLCBkYXRhVHlwZSwgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZS5VTkRFRklORUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHJhd0RhdGFPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkUmF3RGF0YShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCByYXdEYXRhT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNCwgcmF3RGF0YU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48bnVtYmVyPiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZVJhd0RhdGFWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW118VWludDhBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDEsIGRhdGEubGVuZ3RoLCAxKTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkSW50OChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0UmF3RGF0YVZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDEsIG51bUVsZW1zLCAxKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBzdHJpbmdEYXRhT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFN0cmluZ0RhdGEoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc3RyaW5nRGF0YU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDUsIHN0cmluZ0RhdGFPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPGZsYXRidWZmZXJzLk9mZnNldD4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVTdHJpbmdEYXRhVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydFN0cmluZ0RhdGFWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRUZW5zb3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVRlbnNvcihcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgZGltc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBkYXRhVHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZSxcbiAgICAgICAgcmF3RGF0YU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBzdHJpbmdEYXRhT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgVGVuc29yLnN0YXJ0VGVuc29yKGJ1aWxkZXIpO1xuICAgICAgVGVuc29yLmFkZE5hbWUoYnVpbGRlciwgbmFtZU9mZnNldCk7XG4gICAgICBUZW5zb3IuYWRkRG9jU3RyaW5nKGJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldCk7XG4gICAgICBUZW5zb3IuYWRkRGltcyhidWlsZGVyLCBkaW1zT2Zmc2V0KTtcbiAgICAgIFRlbnNvci5hZGREYXRhVHlwZShidWlsZGVyLCBkYXRhVHlwZSk7XG4gICAgICBUZW5zb3IuYWRkUmF3RGF0YShidWlsZGVyLCByYXdEYXRhT2Zmc2V0KTtcbiAgICAgIFRlbnNvci5hZGRTdHJpbmdEYXRhKGJ1aWxkZXIsIHN0cmluZ0RhdGFPZmZzZXQpO1xuICAgICAgcmV0dXJuIFRlbnNvci5lbmRUZW5zb3IoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgU3BhcnNlVGVuc29yIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBTcGFyc2VUZW5zb3JcbiAgICAgKi9cbiAgICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFNwYXJzZVRlbnNvciB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBTcGFyc2VUZW5zb3I9IG9ialxuICAgICAqIEByZXR1cm5zIFNwYXJzZVRlbnNvclxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSb290QXNTcGFyc2VUZW5zb3IoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFNwYXJzZVRlbnNvcik6IFNwYXJzZVRlbnNvciB7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgU3BhcnNlVGVuc29yKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gU3BhcnNlVGVuc29yPSBvYmpcbiAgICAgKiBAcmV0dXJucyBTcGFyc2VUZW5zb3JcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzU3BhcnNlVGVuc29yKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTcGFyc2VUZW5zb3IpOiBTcGFyc2VUZW5zb3Ige1xuICAgICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgU3BhcnNlVGVuc29yKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yPSBvYmpcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvcnxudWxsXG4gICAgICovXG4gICAgdmFsdWVzKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3J8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3I9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yfG51bGxcbiAgICAgKi9cbiAgICBpbmRpY2VzKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3J8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuTG9uZ1xuICAgICAqL1xuICAgIGRpbXMoaW5kZXg6IG51bWJlcik6IGZsYXRidWZmZXJzLkxvbmd8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDgpIDpcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJiIS5jcmVhdGVMb25nKDAsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIGRpbXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydFNwYXJzZVRlbnNvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHZhbHVlc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRWYWx1ZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgdmFsdWVzT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBpbmRpY2VzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZEluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW5kaWNlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGluZGljZXNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGRpbXNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRGltcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1zT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgZGltc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuTG9uZz4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVEaW1zVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLkxvbmdbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIGRhdGEubGVuZ3RoLCA4KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkSW50NjQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydERpbXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig4LCBudW1FbGVtcywgOCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRTcGFyc2VUZW5zb3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVNwYXJzZVRlbnNvcihcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIGluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgZGltc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIFNwYXJzZVRlbnNvci5zdGFydFNwYXJzZVRlbnNvcihidWlsZGVyKTtcbiAgICAgIFNwYXJzZVRlbnNvci5hZGRWYWx1ZXMoYnVpbGRlciwgdmFsdWVzT2Zmc2V0KTtcbiAgICAgIFNwYXJzZVRlbnNvci5hZGRJbmRpY2VzKGJ1aWxkZXIsIGluZGljZXNPZmZzZXQpO1xuICAgICAgU3BhcnNlVGVuc29yLmFkZERpbXMoYnVpbGRlciwgZGltc09mZnNldCk7XG4gICAgICByZXR1cm4gU3BhcnNlVGVuc29yLmVuZFNwYXJzZVRlbnNvcihidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBjbGFzcyBBdHRyaWJ1dGUge1xuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyfG51bGwgPSBudWxsO1xuXG4gICAgYmJfcG9zID0gMDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGlcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIEF0dHJpYnV0ZVxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogQXR0cmlidXRlIHtcbiAgICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICAgIHRoaXMuYmIgPSBiYjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIEF0dHJpYnV0ZT0gb2JqXG4gICAgICogQHJldHVybnMgQXR0cmlidXRlXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc0F0dHJpYnV0ZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogQXR0cmlidXRlKTogQXR0cmlidXRlIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBBdHRyaWJ1dGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBBdHRyaWJ1dGU9IG9ialxuICAgICAqIEByZXR1cm5zIEF0dHJpYnV0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNBdHRyaWJ1dGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEF0dHJpYnV0ZSk6IEF0dHJpYnV0ZSB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBBdHRyaWJ1dGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgbmFtZSgpOiBzdHJpbmd8bnVsbDtcbiAgICBuYW1lKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBuYW1lKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgZG9jU3RyaW5nKCk6IHN0cmluZ3xudWxsO1xuICAgIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkF0dHJpYnV0ZVR5cGVcbiAgICAgKi9cbiAgICB0eXBlKCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuQXR0cmlidXRlVHlwZSB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IC8qKiAgKi8gKHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkpIDpcbiAgICAgICAgICAgICAgICAgICAgICBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkF0dHJpYnV0ZVR5cGUuVU5ERUZJTkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIGYoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRGbG9hdDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDAuMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5Mb25nXG4gICAgICovXG4gICAgaSgpOiBmbGF0YnVmZmVycy5Mb25nIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiB0aGlzLmJiIS5jcmVhdGVMb25nKDAsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5fG51bGxcbiAgICAgKi9cbiAgICBzKCk6IHN0cmluZ3xudWxsO1xuICAgIHMob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIHMob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3I9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yfG51bGxcbiAgICAgKi9cbiAgICB0KG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3J8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvcigpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGg9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGh8bnVsbFxuICAgICAqL1xuICAgIGcob2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5HcmFwaCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGh8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkdyYXBoKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgZmxvYXRzKGluZGV4OiBudW1iZXIpOiBudW1iZXJ8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIwKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkRmxvYXQzMih0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBmbG9hdHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIEZsb2F0MzJBcnJheVxuICAgICAqL1xuICAgIGZsb2F0c0FycmF5KCk6IEZsb2F0MzJBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/XG4gICAgICAgICAgbmV3IEZsb2F0MzJBcnJheShcbiAgICAgICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5idWZmZXIsIHRoaXMuYmIhLmJ5dGVzKCkuYnl0ZU9mZnNldCArIHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgICAgICAgdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSkgOlxuICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLkxvbmdcbiAgICAgKi9cbiAgICBpbnRzKGluZGV4OiBudW1iZXIpOiBmbGF0YnVmZmVycy5Mb25nfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogOCkgOlxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYmIhLmNyZWF0ZUxvbmcoMCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW50c0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5XG4gICAgICovXG4gICAgc3RyaW5ncyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICAgIHN0cmluZ3MoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheTtcbiAgICBzdHJpbmdzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIHN0cmluZ3NMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3I9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yXG4gICAgICovXG4gICAgdGVuc29ycyhpbmRleDogbnVtYmVyLCBvYmo/OiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvcik6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3IoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICB0ZW5zb3JzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGg9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGhcbiAgICAgKi9cbiAgICBncmFwaHMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5HcmFwaCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGh8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkdyYXBoKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgZ3JhcGhzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0QXR0cmlidXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMTMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG5hbWVPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgbmFtZU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZG9jU3RyaW5nT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBkb2NTdHJpbmdPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5BdHRyaWJ1dGVUeXBlIHR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB0eXBlOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkF0dHJpYnV0ZVR5cGUpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigyLCB0eXBlLCBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkF0dHJpYnV0ZVR5cGUuVU5ERUZJTkVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBmXG4gICAgICovXG4gICAgc3RhdGljIGFkZEYoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZjogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkRmxvYXQzMigzLCBmLCAwLjApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuTG9uZyBpXG4gICAgICovXG4gICAgc3RhdGljIGFkZEkoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaTogZmxhdGJ1ZmZlcnMuTG9uZykge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDQsIGksIGJ1aWxkZXIuY3JlYXRlTG9uZygwLCAwKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRTKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBzT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCB0T2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDYsIHRPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGdPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBnT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNywgZ09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZmxvYXRzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZEZsb2F0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBmbG9hdHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg4LCBmbG9hdHNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPG51bWJlcj4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVGbG9hdHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW118VWludDhBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkRmxvYXQzMihkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0RmxvYXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGludHNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkSW50cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOSwgaW50c09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuTG9uZz4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVJbnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLkxvbmdbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIGRhdGEubGVuZ3RoLCA4KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkSW50NjQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydEludHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig4LCBudW1FbGVtcywgOCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgc3RyaW5nc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRTdHJpbmdzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHN0cmluZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMCwgc3RyaW5nc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZVN0cmluZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0U3RyaW5nc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCB0ZW5zb3JzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFRlbnNvcnMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdGVuc29yc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDExLCB0ZW5zb3JzT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIEFycmF5LjxmbGF0YnVmZmVycy5PZmZzZXQ+IGRhdGFcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlVGVuc29yc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRUZW5zb3JzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGdyYXBoc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRHcmFwaHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZ3JhcGhzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMTIsIGdyYXBoc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUdyYXBoc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRHcmFwaHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRBdHRyaWJ1dGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZUF0dHJpYnV0ZShcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgdHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5BdHRyaWJ1dGVUeXBlLCBmOiBudW1iZXIsIGk6IGZsYXRidWZmZXJzLkxvbmcsIHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgdE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBnT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIGZsb2F0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBpbnRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIHN0cmluZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCwgdGVuc29yc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBncmFwaHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBBdHRyaWJ1dGUuc3RhcnRBdHRyaWJ1dGUoYnVpbGRlcik7XG4gICAgICBBdHRyaWJ1dGUuYWRkTmFtZShidWlsZGVyLCBuYW1lT2Zmc2V0KTtcbiAgICAgIEF0dHJpYnV0ZS5hZGREb2NTdHJpbmcoYnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0KTtcbiAgICAgIEF0dHJpYnV0ZS5hZGRUeXBlKGJ1aWxkZXIsIHR5cGUpO1xuICAgICAgQXR0cmlidXRlLmFkZEYoYnVpbGRlciwgZik7XG4gICAgICBBdHRyaWJ1dGUuYWRkSShidWlsZGVyLCBpKTtcbiAgICAgIEF0dHJpYnV0ZS5hZGRTKGJ1aWxkZXIsIHNPZmZzZXQpO1xuICAgICAgQXR0cmlidXRlLmFkZFQoYnVpbGRlciwgdE9mZnNldCk7XG4gICAgICBBdHRyaWJ1dGUuYWRkRyhidWlsZGVyLCBnT2Zmc2V0KTtcbiAgICAgIEF0dHJpYnV0ZS5hZGRGbG9hdHMoYnVpbGRlciwgZmxvYXRzT2Zmc2V0KTtcbiAgICAgIEF0dHJpYnV0ZS5hZGRJbnRzKGJ1aWxkZXIsIGludHNPZmZzZXQpO1xuICAgICAgQXR0cmlidXRlLmFkZFN0cmluZ3MoYnVpbGRlciwgc3RyaW5nc09mZnNldCk7XG4gICAgICBBdHRyaWJ1dGUuYWRkVGVuc29ycyhidWlsZGVyLCB0ZW5zb3JzT2Zmc2V0KTtcbiAgICAgIEF0dHJpYnV0ZS5hZGRHcmFwaHMoYnVpbGRlciwgZ3JhcGhzT2Zmc2V0KTtcbiAgICAgIHJldHVybiBBdHRyaWJ1dGUuZW5kQXR0cmlidXRlKGJ1aWxkZXIpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIEdyYXBoIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBHcmFwaFxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogR3JhcGgge1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gR3JhcGg9IG9ialxuICAgICAqIEByZXR1cm5zIEdyYXBoXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc0dyYXBoKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBHcmFwaCk6IEdyYXBoIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBHcmFwaCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIEdyYXBoPSBvYmpcbiAgICAgKiBAcmV0dXJucyBHcmFwaFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNHcmFwaChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogR3JhcGgpOiBHcmFwaCB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBHcmFwaCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3I9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZXJzKGluZGV4OiBudW1iZXIsIG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3J8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZXJzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5WYWx1ZUluZm89IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVmFsdWVJbmZvXG4gICAgICovXG4gICAgbm9kZUFyZ3MoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5WYWx1ZUluZm8pOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlZhbHVlSW5mb3xudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5WYWx1ZUluZm8oKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBub2RlQXJnc0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZT0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlXG4gICAgICovXG4gICAgbm9kZXMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGUoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBub2Rlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBtYXhOb2RlSW5kZXgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZUVkZ2U9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZUVkZ2VcbiAgICAgKi9cbiAgICBub2RlRWRnZXMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlRWRnZSk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZUVkZ2V8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGVFZGdlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgbm9kZUVkZ2VzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXlcbiAgICAgKi9cbiAgICBpbnB1dHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgICBpbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheTtcbiAgICBpbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW5wdXRzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXlcbiAgICAgKi9cbiAgICBvdXRwdXRzKGluZGV4OiBudW1iZXIpOiBzdHJpbmc7XG4gICAgb3V0cHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5O1xuICAgIG91dHB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgb3V0cHV0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNwYXJzZVRlbnNvcj0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TcGFyc2VUZW5zb3JcbiAgICAgKi9cbiAgICBzcGFyc2VJbml0aWFsaXplcnMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TcGFyc2VUZW5zb3IpOlxuICAgICAgICBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNwYXJzZVRlbnNvcnxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU3BhcnNlVGVuc29yKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgc3BhcnNlSW5pdGlhbGl6ZXJzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0R3JhcGgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgICAgYnVpbGRlci5zdGFydE9iamVjdCg4KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBpbml0aWFsaXplcnNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkSW5pdGlhbGl6ZXJzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGluaXRpYWxpemVyc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGluaXRpYWxpemVyc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUluaXRpYWxpemVyc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRJbml0aWFsaXplcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgbm9kZUFyZ3NPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTm9kZUFyZ3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUFyZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBub2RlQXJnc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZU5vZGVBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydE5vZGVBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG5vZGVzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE5vZGVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgbm9kZXNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPGZsYXRidWZmZXJzLk9mZnNldD4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVOb2Rlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnROb2Rlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBtYXhOb2RlSW5kZXhcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTWF4Tm9kZUluZGV4KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG1heE5vZGVJbmRleDogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMywgbWF4Tm9kZUluZGV4LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBub2RlRWRnZXNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTm9kZUVkZ2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVFZGdlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDQsIG5vZGVFZGdlc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZU5vZGVFZGdlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnROb2RlRWRnZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgaW5wdXRzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZElucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnB1dHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBpbnB1dHNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPGZsYXRidWZmZXJzLk9mZnNldD4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVJbnB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG91dHB1dHNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkT3V0cHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvdXRwdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNiwgb3V0cHV0c09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZU91dHB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0T3V0cHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBzcGFyc2VJbml0aWFsaXplcnNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkU3BhcnNlSW5pdGlhbGl6ZXJzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNwYXJzZUluaXRpYWxpemVyc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDcsIHNwYXJzZUluaXRpYWxpemVyc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZVNwYXJzZUluaXRpYWxpemVyc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6XG4gICAgICAgIGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRTcGFyc2VJbml0aWFsaXplcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRHcmFwaChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGxldCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICB9XG5cbiAgICBzdGF0aWMgY3JlYXRlR3JhcGgoXG4gICAgICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGluaXRpYWxpemVyc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBub2RlQXJnc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBub2Rlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBtYXhOb2RlSW5kZXg6IG51bWJlciwgbm9kZUVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIGlucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBvdXRwdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIHNwYXJzZUluaXRpYWxpemVyc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIEdyYXBoLnN0YXJ0R3JhcGgoYnVpbGRlcik7XG4gICAgICBHcmFwaC5hZGRJbml0aWFsaXplcnMoYnVpbGRlciwgaW5pdGlhbGl6ZXJzT2Zmc2V0KTtcbiAgICAgIEdyYXBoLmFkZE5vZGVBcmdzKGJ1aWxkZXIsIG5vZGVBcmdzT2Zmc2V0KTtcbiAgICAgIEdyYXBoLmFkZE5vZGVzKGJ1aWxkZXIsIG5vZGVzT2Zmc2V0KTtcbiAgICAgIEdyYXBoLmFkZE1heE5vZGVJbmRleChidWlsZGVyLCBtYXhOb2RlSW5kZXgpO1xuICAgICAgR3JhcGguYWRkTm9kZUVkZ2VzKGJ1aWxkZXIsIG5vZGVFZGdlc09mZnNldCk7XG4gICAgICBHcmFwaC5hZGRJbnB1dHMoYnVpbGRlciwgaW5wdXRzT2Zmc2V0KTtcbiAgICAgIEdyYXBoLmFkZE91dHB1dHMoYnVpbGRlciwgb3V0cHV0c09mZnNldCk7XG4gICAgICBHcmFwaC5hZGRTcGFyc2VJbml0aWFsaXplcnMoYnVpbGRlciwgc3BhcnNlSW5pdGlhbGl6ZXJzT2Zmc2V0KTtcbiAgICAgIHJldHVybiBHcmFwaC5lbmRHcmFwaChidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBjbGFzcyBNb2RlbCB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgTW9kZWxcbiAgICAgKi9cbiAgICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IE1vZGVsIHtcbiAgICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICAgIHRoaXMuYmIgPSBiYjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIE1vZGVsPSBvYmpcbiAgICAgKiBAcmV0dXJucyBNb2RlbFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSb290QXNNb2RlbChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTW9kZWwpOiBNb2RlbCB7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgTW9kZWwoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBNb2RlbD0gb2JqXG4gICAgICogQHJldHVybnMgTW9kZWxcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzTW9kZWwoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE1vZGVsKTogTW9kZWwge1xuICAgICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgTW9kZWwoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5Mb25nXG4gICAgICovXG4gICAgaXJWZXJzaW9uKCk6IGZsYXRidWZmZXJzLkxvbmcge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50NjQodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogdGhpcy5iYiEuY3JlYXRlTG9uZygwLCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuT3BlcmF0b3JTZXRJZD0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5PcGVyYXRvclNldElkXG4gICAgICovXG4gICAgb3BzZXRJbXBvcnQoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5PcGVyYXRvclNldElkKTpcbiAgICAgICAgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5PcGVyYXRvclNldElkfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk9wZXJhdG9yU2V0SWQoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBvcHNldEltcG9ydExlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgcHJvZHVjZXJOYW1lKCk6IHN0cmluZ3xudWxsO1xuICAgIHByb2R1Y2VyTmFtZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgcHJvZHVjZXJOYW1lKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgcHJvZHVjZXJWZXJzaW9uKCk6IHN0cmluZ3xudWxsO1xuICAgIHByb2R1Y2VyVmVyc2lvbihvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgcHJvZHVjZXJWZXJzaW9uKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRvbWFpbigpOiBzdHJpbmd8bnVsbDtcbiAgICBkb21haW4ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIGRvbWFpbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLkxvbmdcbiAgICAgKi9cbiAgICBtb2RlbFZlcnNpb24oKTogZmxhdGJ1ZmZlcnMuTG9uZyB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50NjQodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogdGhpcy5iYiEuY3JlYXRlTG9uZygwLCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgZG9jU3RyaW5nKCk6IHN0cmluZ3xudWxsO1xuICAgIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGg9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGh8bnVsbFxuICAgICAqL1xuICAgIGdyYXBoKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGgpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkdyYXBofG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5HcmFwaCgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGdyYXBoRG9jU3RyaW5nKCk6IHN0cmluZ3xudWxsO1xuICAgIGdyYXBoRG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBncmFwaERvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIwKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRNb2RlbChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuTG9uZyBpclZlcnNpb25cbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkSXJWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlyVmVyc2lvbjogZmxhdGJ1ZmZlcnMuTG9uZykge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDAsIGlyVmVyc2lvbiwgYnVpbGRlci5jcmVhdGVMb25nKDAsIDApKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBvcHNldEltcG9ydE9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRPcHNldEltcG9ydChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvcHNldEltcG9ydE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIG9wc2V0SW1wb3J0T2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIEFycmF5LjxmbGF0YnVmZmVycy5PZmZzZXQ+IGRhdGFcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlT3BzZXRJbXBvcnRWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0T3BzZXRJbXBvcnRWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgcHJvZHVjZXJOYW1lT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFByb2R1Y2VyTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBwcm9kdWNlck5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgyLCBwcm9kdWNlck5hbWVPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHByb2R1Y2VyVmVyc2lvbk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRQcm9kdWNlclZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgcHJvZHVjZXJWZXJzaW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMywgcHJvZHVjZXJWZXJzaW9uT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBkb21haW5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRG9tYWluKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRvbWFpbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDQsIGRvbWFpbk9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5Mb25nIG1vZGVsVmVyc2lvblxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRNb2RlbFZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbW9kZWxWZXJzaW9uOiBmbGF0YnVmZmVycy5Mb25nKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50NjQoNSwgbW9kZWxWZXJzaW9uLCBidWlsZGVyLmNyZWF0ZUxvbmcoMCwgMCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGRvY1N0cmluZ09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNiwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBncmFwaE9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRHcmFwaChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBncmFwaE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDcsIGdyYXBoT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBncmFwaERvY1N0cmluZ09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRHcmFwaERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBncmFwaERvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDgsIGdyYXBoRG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZE1vZGVsKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVNb2RlbChcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaXJWZXJzaW9uOiBmbGF0YnVmZmVycy5Mb25nLCBvcHNldEltcG9ydE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBwcm9kdWNlck5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCwgcHJvZHVjZXJWZXJzaW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIGRvbWFpbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBtb2RlbFZlcnNpb246IGZsYXRidWZmZXJzLkxvbmcsIGRvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBncmFwaE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBncmFwaERvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIE1vZGVsLnN0YXJ0TW9kZWwoYnVpbGRlcik7XG4gICAgICBNb2RlbC5hZGRJclZlcnNpb24oYnVpbGRlciwgaXJWZXJzaW9uKTtcbiAgICAgIE1vZGVsLmFkZE9wc2V0SW1wb3J0KGJ1aWxkZXIsIG9wc2V0SW1wb3J0T2Zmc2V0KTtcbiAgICAgIE1vZGVsLmFkZFByb2R1Y2VyTmFtZShidWlsZGVyLCBwcm9kdWNlck5hbWVPZmZzZXQpO1xuICAgICAgTW9kZWwuYWRkUHJvZHVjZXJWZXJzaW9uKGJ1aWxkZXIsIHByb2R1Y2VyVmVyc2lvbk9mZnNldCk7XG4gICAgICBNb2RlbC5hZGREb21haW4oYnVpbGRlciwgZG9tYWluT2Zmc2V0KTtcbiAgICAgIE1vZGVsLmFkZE1vZGVsVmVyc2lvbihidWlsZGVyLCBtb2RlbFZlcnNpb24pO1xuICAgICAgTW9kZWwuYWRkRG9jU3RyaW5nKGJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldCk7XG4gICAgICBNb2RlbC5hZGRHcmFwaChidWlsZGVyLCBncmFwaE9mZnNldCk7XG4gICAgICBNb2RlbC5hZGRHcmFwaERvY1N0cmluZyhidWlsZGVyLCBncmFwaERvY1N0cmluZ09mZnNldCk7XG4gICAgICByZXR1cm4gTW9kZWwuZW5kTW9kZWwoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgS2VybmVsQ3JlYXRlSW5mb3Mge1xuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyfG51bGwgPSBudWxsO1xuXG4gICAgYmJfcG9zID0gMDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGlcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIEtlcm5lbENyZWF0ZUluZm9zXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBLZXJuZWxDcmVhdGVJbmZvcyB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBLZXJuZWxDcmVhdGVJbmZvcz0gb2JqXG4gICAgICogQHJldHVybnMgS2VybmVsQ3JlYXRlSW5mb3NcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzS2VybmVsQ3JlYXRlSW5mb3MoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEtlcm5lbENyZWF0ZUluZm9zKTogS2VybmVsQ3JlYXRlSW5mb3Mge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IEtlcm5lbENyZWF0ZUluZm9zKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gS2VybmVsQ3JlYXRlSW5mb3M9IG9ialxuICAgICAqIEByZXR1cm5zIEtlcm5lbENyZWF0ZUluZm9zXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0tlcm5lbENyZWF0ZUluZm9zKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBLZXJuZWxDcmVhdGVJbmZvcyk6XG4gICAgICAgIEtlcm5lbENyZWF0ZUluZm9zIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IEtlcm5lbENyZWF0ZUluZm9zKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIG5vZGVJbmRpY2VzKGluZGV4OiBudW1iZXIpOiBudW1iZXJ8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgbm9kZUluZGljZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVWludDMyQXJyYXlcbiAgICAgKi9cbiAgICBub2RlSW5kaWNlc0FycmF5KCk6IFVpbnQzMkFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgP1xuICAgICAgICAgIG5ldyBVaW50MzJBcnJheShcbiAgICAgICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5idWZmZXIsIHRoaXMuYmIhLmJ5dGVzKCkuYnl0ZU9mZnNldCArIHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgICAgICAgdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSkgOlxuICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLkxvbmdcbiAgICAgKi9cbiAgICBrZXJuZWxEZWZIYXNoZXMoaW5kZXg6IG51bWJlcik6IGZsYXRidWZmZXJzLkxvbmd8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50NjQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA4KSA6XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5iYiEuY3JlYXRlTG9uZygwLCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBrZXJuZWxEZWZIYXNoZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydEtlcm5lbENyZWF0ZUluZm9zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgbm9kZUluZGljZXNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTm9kZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBub2RlSW5kaWNlc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48bnVtYmVyPiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZU5vZGVJbmRpY2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdfFVpbnQ4QXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZEludDMyKGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnROb2RlSW5kaWNlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBrZXJuZWxEZWZIYXNoZXNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkS2VybmVsRGVmSGFzaGVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbERlZkhhc2hlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGtlcm5lbERlZkhhc2hlc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuTG9uZz4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVLZXJuZWxEZWZIYXNoZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuTG9uZ1tdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgZGF0YS5sZW5ndGgsIDgpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRJbnQ2NChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0S2VybmVsRGVmSGFzaGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgbnVtRWxlbXMsIDgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZUtlcm5lbENyZWF0ZUluZm9zKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBub2RlSW5kaWNlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBrZXJuZWxEZWZIYXNoZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBLZXJuZWxDcmVhdGVJbmZvcy5zdGFydEtlcm5lbENyZWF0ZUluZm9zKGJ1aWxkZXIpO1xuICAgICAgS2VybmVsQ3JlYXRlSW5mb3MuYWRkTm9kZUluZGljZXMoYnVpbGRlciwgbm9kZUluZGljZXNPZmZzZXQpO1xuICAgICAgS2VybmVsQ3JlYXRlSW5mb3MuYWRkS2VybmVsRGVmSGFzaGVzKGJ1aWxkZXIsIGtlcm5lbERlZkhhc2hlc09mZnNldCk7XG4gICAgICByZXR1cm4gS2VybmVsQ3JlYXRlSW5mb3MuZW5kS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgU3ViR3JhcGhTZXNzaW9uU3RhdGUge1xuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyfG51bGwgPSBudWxsO1xuXG4gICAgYmJfcG9zID0gMDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGlcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIFN1YkdyYXBoU2Vzc2lvblN0YXRlXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBTdWJHcmFwaFNlc3Npb25TdGF0ZSB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBTdWJHcmFwaFNlc3Npb25TdGF0ZT0gb2JqXG4gICAgICogQHJldHVybnMgU3ViR3JhcGhTZXNzaW9uU3RhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzU3ViR3JhcGhTZXNzaW9uU3RhdGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFN1YkdyYXBoU2Vzc2lvblN0YXRlKTogU3ViR3JhcGhTZXNzaW9uU3RhdGUge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFN1YkdyYXBoU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gU3ViR3JhcGhTZXNzaW9uU3RhdGU9IG9ialxuICAgICAqIEByZXR1cm5zIFN1YkdyYXBoU2Vzc2lvblN0YXRlXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1N1YkdyYXBoU2Vzc2lvblN0YXRlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTdWJHcmFwaFNlc3Npb25TdGF0ZSk6XG4gICAgICAgIFN1YkdyYXBoU2Vzc2lvblN0YXRlIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFN1YkdyYXBoU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGdyYXBoSWQoKTogc3RyaW5nfG51bGw7XG4gICAgZ3JhcGhJZChvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZ3JhcGhJZChvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU2Vzc2lvblN0YXRlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNlc3Npb25TdGF0ZXxudWxsXG4gICAgICovXG4gICAgc2Vzc2lvblN0YXRlKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU2Vzc2lvblN0YXRlKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TZXNzaW9uU3RhdGV8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU2Vzc2lvblN0YXRlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0U3ViR3JhcGhTZXNzaW9uU3RhdGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBncmFwaElkT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZEdyYXBoSWQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZ3JhcGhJZE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGdyYXBoSWRPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHNlc3Npb25TdGF0ZU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRTZXNzaW9uU3RhdGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc2Vzc2lvblN0YXRlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgc2Vzc2lvblN0YXRlT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZFN1YkdyYXBoU2Vzc2lvblN0YXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICBidWlsZGVyLnJlcXVpcmVkRmllbGQob2Zmc2V0LCA0KTsgIC8vIGdyYXBoX2lkXG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVTdWJHcmFwaFNlc3Npb25TdGF0ZShcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZ3JhcGhJZE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBzZXNzaW9uU3RhdGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBTdWJHcmFwaFNlc3Npb25TdGF0ZS5zdGFydFN1YkdyYXBoU2Vzc2lvblN0YXRlKGJ1aWxkZXIpO1xuICAgICAgU3ViR3JhcGhTZXNzaW9uU3RhdGUuYWRkR3JhcGhJZChidWlsZGVyLCBncmFwaElkT2Zmc2V0KTtcbiAgICAgIFN1YkdyYXBoU2Vzc2lvblN0YXRlLmFkZFNlc3Npb25TdGF0ZShidWlsZGVyLCBzZXNzaW9uU3RhdGVPZmZzZXQpO1xuICAgICAgcmV0dXJuIFN1YkdyYXBoU2Vzc2lvblN0YXRlLmVuZFN1YkdyYXBoU2Vzc2lvblN0YXRlKGJ1aWxkZXIpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIFNlc3Npb25TdGF0ZSB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgU2Vzc2lvblN0YXRlXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBTZXNzaW9uU3RhdGUge1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gU2Vzc2lvblN0YXRlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBTZXNzaW9uU3RhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzU2Vzc2lvblN0YXRlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTZXNzaW9uU3RhdGUpOiBTZXNzaW9uU3RhdGUge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFNlc3Npb25TdGF0ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIFNlc3Npb25TdGF0ZT0gb2JqXG4gICAgICogQHJldHVybnMgU2Vzc2lvblN0YXRlXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1Nlc3Npb25TdGF0ZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU2Vzc2lvblN0YXRlKTogU2Vzc2lvblN0YXRlIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFNlc3Npb25TdGF0ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLktlcm5lbENyZWF0ZUluZm9zPSBvYmpcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLktlcm5lbENyZWF0ZUluZm9zfG51bGxcbiAgICAgKi9cbiAgICBrZXJuZWxzKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuS2VybmVsQ3JlYXRlSW5mb3MpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLktlcm5lbENyZWF0ZUluZm9zfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLktlcm5lbENyZWF0ZUluZm9zKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU3ViR3JhcGhTZXNzaW9uU3RhdGU9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU3ViR3JhcGhTZXNzaW9uU3RhdGVcbiAgICAgKi9cbiAgICBzdWJHcmFwaFNlc3Npb25TdGF0ZXMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TdWJHcmFwaFNlc3Npb25TdGF0ZSk6XG4gICAgICAgIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU3ViR3JhcGhTZXNzaW9uU3RhdGV8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU3ViR3JhcGhTZXNzaW9uU3RhdGUoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBzdWJHcmFwaFNlc3Npb25TdGF0ZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydFNlc3Npb25TdGF0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGtlcm5lbHNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkS2VybmVscyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXJuZWxzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwga2VybmVsc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgc3ViR3JhcGhTZXNzaW9uU3RhdGVzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFN1YkdyYXBoU2Vzc2lvblN0YXRlcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzdWJHcmFwaFNlc3Npb25TdGF0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBzdWJHcmFwaFNlc3Npb25TdGF0ZXNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPGZsYXRidWZmZXJzLk9mZnNldD4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVTdWJHcmFwaFNlc3Npb25TdGF0ZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOlxuICAgICAgICBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0U3ViR3JhcGhTZXNzaW9uU3RhdGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kU2Vzc2lvblN0YXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVTZXNzaW9uU3RhdGUoXG4gICAgICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgc3ViR3JhcGhTZXNzaW9uU3RhdGVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgU2Vzc2lvblN0YXRlLnN0YXJ0U2Vzc2lvblN0YXRlKGJ1aWxkZXIpO1xuICAgICAgU2Vzc2lvblN0YXRlLmFkZEtlcm5lbHMoYnVpbGRlciwga2VybmVsc09mZnNldCk7XG4gICAgICBTZXNzaW9uU3RhdGUuYWRkU3ViR3JhcGhTZXNzaW9uU3RhdGVzKGJ1aWxkZXIsIHN1YkdyYXBoU2Vzc2lvblN0YXRlc09mZnNldCk7XG4gICAgICByZXR1cm4gU2Vzc2lvblN0YXRlLmVuZFNlc3Npb25TdGF0ZShidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBjbGFzcyBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBJbmZlcmVuY2VTZXNzaW9uXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICAgIHRoaXMuYmIgPSBiYjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIEluZmVyZW5jZVNlc3Npb249IG9ialxuICAgICAqIEByZXR1cm5zIEluZmVyZW5jZVNlc3Npb25cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzSW5mZXJlbmNlU2Vzc2lvbihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogSW5mZXJlbmNlU2Vzc2lvbik6IEluZmVyZW5jZVNlc3Npb24ge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IEluZmVyZW5jZVNlc3Npb24oKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBJbmZlcmVuY2VTZXNzaW9uPSBvYmpcbiAgICAgKiBAcmV0dXJucyBJbmZlcmVuY2VTZXNzaW9uXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0luZmVyZW5jZVNlc3Npb24oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEluZmVyZW5jZVNlc3Npb24pOiBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IEluZmVyZW5jZVNlc3Npb24oKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIGJvb2xlYW5cbiAgICAgKi9cbiAgICBzdGF0aWMgYnVmZmVySGFzSWRlbnRpZmllcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIGJiLl9faGFzX2lkZW50aWZpZXIoJ09SVE0nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgb3J0VmVyc2lvbigpOiBzdHJpbmd8bnVsbDtcbiAgICBvcnRWZXJzaW9uKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBvcnRWZXJzaW9uKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Nb2RlbD0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Nb2RlbHxudWxsXG4gICAgICovXG4gICAgbW9kZWwob2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Nb2RlbCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTW9kZWx8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTW9kZWwoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDpcbiAgICAgICAgICAgICAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNlc3Npb25TdGF0ZT0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TZXNzaW9uU3RhdGV8bnVsbFxuICAgICAqL1xuICAgIHNlc3Npb25TdGF0ZShvYmo/OiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNlc3Npb25TdGF0ZSk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU2Vzc2lvblN0YXRlfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNlc3Npb25TdGF0ZSgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydEluZmVyZW5jZVNlc3Npb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBvcnRWZXJzaW9uT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE9ydFZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3J0VmVyc2lvbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG9ydFZlcnNpb25PZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG1vZGVsT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE1vZGVsKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG1vZGVsT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgbW9kZWxPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHNlc3Npb25TdGF0ZU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRTZXNzaW9uU3RhdGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc2Vzc2lvblN0YXRlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgc2Vzc2lvblN0YXRlT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZEluZmVyZW5jZVNlc3Npb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgb2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGZpbmlzaEluZmVyZW5jZVNlc3Npb25CdWZmZXIoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuZmluaXNoKG9mZnNldCwgJ09SVE0nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBvZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZmluaXNoU2l6ZVByZWZpeGVkSW5mZXJlbmNlU2Vzc2lvbkJ1ZmZlcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5maW5pc2gob2Zmc2V0LCAnT1JUTScsIHRydWUpO1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVJbmZlcmVuY2VTZXNzaW9uKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvcnRWZXJzaW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIG1vZGVsT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIHNlc3Npb25TdGF0ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIEluZmVyZW5jZVNlc3Npb24uc3RhcnRJbmZlcmVuY2VTZXNzaW9uKGJ1aWxkZXIpO1xuICAgICAgSW5mZXJlbmNlU2Vzc2lvbi5hZGRPcnRWZXJzaW9uKGJ1aWxkZXIsIG9ydFZlcnNpb25PZmZzZXQpO1xuICAgICAgSW5mZXJlbmNlU2Vzc2lvbi5hZGRNb2RlbChidWlsZGVyLCBtb2RlbE9mZnNldCk7XG4gICAgICBJbmZlcmVuY2VTZXNzaW9uLmFkZFNlc3Npb25TdGF0ZShidWlsZGVyLCBzZXNzaW9uU3RhdGVPZmZzZXQpO1xuICAgICAgcmV0dXJuIEluZmVyZW5jZVNlc3Npb24uZW5kSW5mZXJlbmNlU2Vzc2lvbihidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbiIsICJcInVzZSBzdHJpY3RcIjtcclxubW9kdWxlLmV4cG9ydHMgPSBhc1Byb21pc2U7XHJcblxyXG4vKipcclxuICogQ2FsbGJhY2sgYXMgdXNlZCBieSB7QGxpbmsgdXRpbC5hc1Byb21pc2V9LlxyXG4gKiBAdHlwZWRlZiBhc1Byb21pc2VDYWxsYmFja1xyXG4gKiBAdHlwZSB7ZnVuY3Rpb259XHJcbiAqIEBwYXJhbSB7RXJyb3J8bnVsbH0gZXJyb3IgRXJyb3IsIGlmIGFueVxyXG4gKiBAcGFyYW0gey4uLip9IHBhcmFtcyBBZGRpdGlvbmFsIGFyZ3VtZW50c1xyXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgcHJvbWlzZSBmcm9tIGEgbm9kZS1zdHlsZSBjYWxsYmFjayBmdW5jdGlvbi5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQHBhcmFtIHthc1Byb21pc2VDYWxsYmFja30gZm4gRnVuY3Rpb24gdG8gY2FsbFxyXG4gKiBAcGFyYW0geyp9IGN0eCBGdW5jdGlvbiBjb250ZXh0XHJcbiAqIEBwYXJhbSB7Li4uKn0gcGFyYW1zIEZ1bmN0aW9uIGFyZ3VtZW50c1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTwqPn0gUHJvbWlzaWZpZWQgZnVuY3Rpb25cclxuICovXHJcbmZ1bmN0aW9uIGFzUHJvbWlzZShmbiwgY3R4LyosIHZhcmFyZ3MgKi8pIHtcclxuICAgIHZhciBwYXJhbXMgID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKSxcclxuICAgICAgICBvZmZzZXQgID0gMCxcclxuICAgICAgICBpbmRleCAgID0gMixcclxuICAgICAgICBwZW5kaW5nID0gdHJ1ZTtcclxuICAgIHdoaWxlIChpbmRleCA8IGFyZ3VtZW50cy5sZW5ndGgpXHJcbiAgICAgICAgcGFyYW1zW29mZnNldCsrXSA9IGFyZ3VtZW50c1tpbmRleCsrXTtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiBleGVjdXRvcihyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBwYXJhbXNbb2Zmc2V0XSA9IGZ1bmN0aW9uIGNhbGxiYWNrKGVyci8qLCB2YXJhcmdzICovKSB7XHJcbiAgICAgICAgICAgIGlmIChwZW5kaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBwZW5kaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyKVxyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG9mZnNldCA8IHBhcmFtcy5sZW5ndGgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtc1tvZmZzZXQrK10gPSBhcmd1bWVudHNbb2Zmc2V0XTtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlLmFwcGx5KG51bGwsIHBhcmFtcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGZuLmFwcGx5KGN0eCB8fCBudWxsLCBwYXJhbXMpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICBpZiAocGVuZGluZykge1xyXG4gICAgICAgICAgICAgICAgcGVuZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9KTtcclxufVxyXG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vKipcclxuICogQSBtaW5pbWFsIGJhc2U2NCBpbXBsZW1lbnRhdGlvbiBmb3IgbnVtYmVyIGFycmF5cy5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQG5hbWVzcGFjZVxyXG4gKi9cclxudmFyIGJhc2U2NCA9IGV4cG9ydHM7XHJcblxyXG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgYnl0ZSBsZW5ndGggb2YgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgQmFzZTY0IGVuY29kZWQgc3RyaW5nXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IEJ5dGUgbGVuZ3RoXHJcbiAqL1xyXG5iYXNlNjQubGVuZ3RoID0gZnVuY3Rpb24gbGVuZ3RoKHN0cmluZykge1xyXG4gICAgdmFyIHAgPSBzdHJpbmcubGVuZ3RoO1xyXG4gICAgaWYgKCFwKVxyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgdmFyIG4gPSAwO1xyXG4gICAgd2hpbGUgKC0tcCAlIDQgPiAxICYmIHN0cmluZy5jaGFyQXQocCkgPT09IFwiPVwiKVxyXG4gICAgICAgICsrbjtcclxuICAgIHJldHVybiBNYXRoLmNlaWwoc3RyaW5nLmxlbmd0aCAqIDMpIC8gNCAtIG47XHJcbn07XHJcblxyXG4vLyBCYXNlNjQgZW5jb2RpbmcgdGFibGVcclxudmFyIGI2NCA9IG5ldyBBcnJheSg2NCk7XHJcblxyXG4vLyBCYXNlNjQgZGVjb2RpbmcgdGFibGVcclxudmFyIHM2NCA9IG5ldyBBcnJheSgxMjMpO1xyXG5cclxuLy8gNjUuLjkwLCA5Ny4uMTIyLCA0OC4uNTcsIDQzLCA0N1xyXG5mb3IgKHZhciBpID0gMDsgaSA8IDY0OylcclxuICAgIHM2NFtiNjRbaV0gPSBpIDwgMjYgPyBpICsgNjUgOiBpIDwgNTIgPyBpICsgNzEgOiBpIDwgNjIgPyBpIC0gNCA6IGkgLSA1OSB8IDQzXSA9IGkrKztcclxuXHJcbi8qKlxyXG4gKiBFbmNvZGVzIGEgYnVmZmVyIHRvIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nLlxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZmZlciBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBTb3VyY2Ugc3RhcnRcclxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBTb3VyY2UgZW5kXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9IEJhc2U2NCBlbmNvZGVkIHN0cmluZ1xyXG4gKi9cclxuYmFzZTY0LmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShidWZmZXIsIHN0YXJ0LCBlbmQpIHtcclxuICAgIHZhciBwYXJ0cyA9IG51bGwsXHJcbiAgICAgICAgY2h1bmsgPSBbXTtcclxuICAgIHZhciBpID0gMCwgLy8gb3V0cHV0IGluZGV4XHJcbiAgICAgICAgaiA9IDAsIC8vIGdvdG8gaW5kZXhcclxuICAgICAgICB0OyAgICAgLy8gdGVtcG9yYXJ5XHJcbiAgICB3aGlsZSAoc3RhcnQgPCBlbmQpIHtcclxuICAgICAgICB2YXIgYiA9IGJ1ZmZlcltzdGFydCsrXTtcclxuICAgICAgICBzd2l0Y2ggKGopIHtcclxuICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgICAgY2h1bmtbaSsrXSA9IGI2NFtiID4+IDJdO1xyXG4gICAgICAgICAgICAgICAgdCA9IChiICYgMykgPDwgNDtcclxuICAgICAgICAgICAgICAgIGogPSAxO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgIGNodW5rW2krK10gPSBiNjRbdCB8IGIgPj4gNF07XHJcbiAgICAgICAgICAgICAgICB0ID0gKGIgJiAxNSkgPDwgMjtcclxuICAgICAgICAgICAgICAgIGogPSAyO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgIGNodW5rW2krK10gPSBiNjRbdCB8IGIgPj4gNl07XHJcbiAgICAgICAgICAgICAgICBjaHVua1tpKytdID0gYjY0W2IgJiA2M107XHJcbiAgICAgICAgICAgICAgICBqID0gMDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaSA+IDgxOTEpIHtcclxuICAgICAgICAgICAgKHBhcnRzIHx8IChwYXJ0cyA9IFtdKSkucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2h1bmspKTtcclxuICAgICAgICAgICAgaSA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGopIHtcclxuICAgICAgICBjaHVua1tpKytdID0gYjY0W3RdO1xyXG4gICAgICAgIGNodW5rW2krK10gPSA2MTtcclxuICAgICAgICBpZiAoaiA9PT0gMSlcclxuICAgICAgICAgICAgY2h1bmtbaSsrXSA9IDYxO1xyXG4gICAgfVxyXG4gICAgaWYgKHBhcnRzKSB7XHJcbiAgICAgICAgaWYgKGkpXHJcbiAgICAgICAgICAgIHBhcnRzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNodW5rLnNsaWNlKDAsIGkpKSk7XHJcbiAgICAgICAgcmV0dXJuIHBhcnRzLmpvaW4oXCJcIik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNodW5rLnNsaWNlKDAsIGkpKTtcclxufTtcclxuXHJcbnZhciBpbnZhbGlkRW5jb2RpbmcgPSBcImludmFsaWQgZW5jb2RpbmdcIjtcclxuXHJcbi8qKlxyXG4gKiBEZWNvZGVzIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nIHRvIGEgYnVmZmVyLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFNvdXJjZSBzdHJpbmdcclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgRGVzdGluYXRpb24gYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgRGVzdGluYXRpb24gb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBieXRlcyB3cml0dGVuXHJcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBlbmNvZGluZyBpcyBpbnZhbGlkXHJcbiAqL1xyXG5iYXNlNjQuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHN0cmluZywgYnVmZmVyLCBvZmZzZXQpIHtcclxuICAgIHZhciBzdGFydCA9IG9mZnNldDtcclxuICAgIHZhciBqID0gMCwgLy8gZ290byBpbmRleFxyXG4gICAgICAgIHQ7ICAgICAvLyB0ZW1wb3JhcnlcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDspIHtcclxuICAgICAgICB2YXIgYyA9IHN0cmluZy5jaGFyQ29kZUF0KGkrKyk7XHJcbiAgICAgICAgaWYgKGMgPT09IDYxICYmIGogPiAxKVxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBpZiAoKGMgPSBzNjRbY10pID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgIHRocm93IEVycm9yKGludmFsaWRFbmNvZGluZyk7XHJcbiAgICAgICAgc3dpdGNoIChqKSB7XHJcbiAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgIHQgPSBjO1xyXG4gICAgICAgICAgICAgICAgaiA9IDE7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IHQgPDwgMiB8IChjICYgNDgpID4+IDQ7XHJcbiAgICAgICAgICAgICAgICB0ID0gYztcclxuICAgICAgICAgICAgICAgIGogPSAyO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMjpcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSAodCAmIDE1KSA8PCA0IHwgKGMgJiA2MCkgPj4gMjtcclxuICAgICAgICAgICAgICAgIHQgPSBjO1xyXG4gICAgICAgICAgICAgICAgaiA9IDM7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAzOlxyXG4gICAgICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9ICh0ICYgMykgPDwgNiB8IGM7XHJcbiAgICAgICAgICAgICAgICBqID0gMDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChqID09PSAxKVxyXG4gICAgICAgIHRocm93IEVycm9yKGludmFsaWRFbmNvZGluZyk7XHJcbiAgICByZXR1cm4gb2Zmc2V0IC0gc3RhcnQ7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCBzdHJpbmcgYXBwZWFycyB0byBiZSBiYXNlNjQgZW5jb2RlZC5cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTdHJpbmcgdG8gdGVzdFxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHByb2JhYmx5IGJhc2U2NCBlbmNvZGVkLCBvdGhlcndpc2UgZmFsc2VcclxuICovXHJcbmJhc2U2NC50ZXN0ID0gZnVuY3Rpb24gdGVzdChzdHJpbmcpIHtcclxuICAgIHJldHVybiAvXig/OltBLVphLXowLTkrL117NH0pKig/OltBLVphLXowLTkrL117Mn09PXxbQS1aYS16MC05Ky9dezN9PSk/JC8udGVzdChzdHJpbmcpO1xyXG59O1xyXG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xyXG5cclxuLyoqXHJcbiAqIENvbnN0cnVjdHMgYSBuZXcgZXZlbnQgZW1pdHRlciBpbnN0YW5jZS5cclxuICogQGNsYXNzZGVzYyBBIG1pbmltYWwgZXZlbnQgZW1pdHRlci5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqL1xyXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWdpc3RlcmVkIGxpc3RlbmVycy5cclxuICAgICAqIEB0eXBlIHtPYmplY3QuPHN0cmluZywqPn1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xyXG59XHJcblxyXG4vKipcclxuICogUmVnaXN0ZXJzIGFuIGV2ZW50IGxpc3RlbmVyLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZ0IEV2ZW50IG5hbWVcclxuICogQHBhcmFtIHtmdW5jdGlvbn0gZm4gTGlzdGVuZXJcclxuICogQHBhcmFtIHsqfSBbY3R4XSBMaXN0ZW5lciBjb250ZXh0XHJcbiAqIEByZXR1cm5zIHt1dGlsLkV2ZW50RW1pdHRlcn0gYHRoaXNgXHJcbiAqL1xyXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gb24oZXZ0LCBmbiwgY3R4KSB7XHJcbiAgICAodGhpcy5fbGlzdGVuZXJzW2V2dF0gfHwgKHRoaXMuX2xpc3RlbmVyc1tldnRdID0gW10pKS5wdXNoKHtcclxuICAgICAgICBmbiAgOiBmbixcclxuICAgICAgICBjdHggOiBjdHggfHwgdGhpc1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZW1vdmVzIGFuIGV2ZW50IGxpc3RlbmVyIG9yIGFueSBtYXRjaGluZyBsaXN0ZW5lcnMgaWYgYXJndW1lbnRzIGFyZSBvbWl0dGVkLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gW2V2dF0gRXZlbnQgbmFtZS4gUmVtb3ZlcyBhbGwgbGlzdGVuZXJzIGlmIG9taXR0ZWQuXHJcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IFtmbl0gTGlzdGVuZXIgdG8gcmVtb3ZlLiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgb2YgYGV2dGAgaWYgb21pdHRlZC5cclxuICogQHJldHVybnMge3V0aWwuRXZlbnRFbWl0dGVyfSBgdGhpc2BcclxuICovXHJcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24gb2ZmKGV2dCwgZm4pIHtcclxuICAgIGlmIChldnQgPT09IHVuZGVmaW5lZClcclxuICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSB7fTtcclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGlmIChmbiA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lcnNbZXZ0XSA9IFtdO1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzW2V2dF07XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDspXHJcbiAgICAgICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmZuID09PSBmbilcclxuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICsraTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBFbWl0cyBhbiBldmVudCBieSBjYWxsaW5nIGl0cyBsaXN0ZW5lcnMgd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cy5cclxuICogQHBhcmFtIHtzdHJpbmd9IGV2dCBFdmVudCBuYW1lXHJcbiAqIEBwYXJhbSB7Li4uKn0gYXJncyBBcmd1bWVudHNcclxuICogQHJldHVybnMge3V0aWwuRXZlbnRFbWl0dGVyfSBgdGhpc2BcclxuICovXHJcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZ0KSB7XHJcbiAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzW2V2dF07XHJcbiAgICBpZiAobGlzdGVuZXJzKSB7XHJcbiAgICAgICAgdmFyIGFyZ3MgPSBbXSxcclxuICAgICAgICAgICAgaSA9IDE7XHJcbiAgICAgICAgZm9yICg7IGkgPCBhcmd1bWVudHMubGVuZ3RoOylcclxuICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpKytdKTtcclxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDspXHJcbiAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5mbi5hcHBseShsaXN0ZW5lcnNbaSsrXS5jdHgsIGFyZ3MpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbn07XHJcbiIsICJcInVzZSBzdHJpY3RcIjtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShmYWN0b3J5KTtcclxuXHJcbi8qKlxyXG4gKiBSZWFkcyAvIHdyaXRlcyBmbG9hdHMgLyBkb3VibGVzIGZyb20gLyB0byBidWZmZXJzLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0XHJcbiAqIEBuYW1lc3BhY2VcclxuICovXHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgMzIgYml0IGZsb2F0IHRvIGEgYnVmZmVyIHVzaW5nIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC53cml0ZUZsb2F0TEVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgVGFyZ2V0IGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFRhcmdldCBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFdyaXRlcyBhIDMyIGJpdCBmbG9hdCB0byBhIGJ1ZmZlciB1c2luZyBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQud3JpdGVGbG9hdEJFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsIFZhbHVlIHRvIHdyaXRlXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFRhcmdldCBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBUYXJnZXQgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBSZWFkcyBhIDMyIGJpdCBmbG9hdCBmcm9tIGEgYnVmZmVyIHVzaW5nIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC5yZWFkRmxvYXRMRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFNvdXJjZSBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICovXHJcblxyXG4vKipcclxuICogUmVhZHMgYSAzMiBiaXQgZmxvYXQgZnJvbSBhIGJ1ZmZlciB1c2luZyBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQucmVhZEZsb2F0QkVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFNvdXJjZSBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBTb3VyY2UgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFdyaXRlcyBhIDY0IGJpdCBkb3VibGUgdG8gYSBidWZmZXIgdXNpbmcgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LndyaXRlRG91YmxlTEVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgVGFyZ2V0IGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFRhcmdldCBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFdyaXRlcyBhIDY0IGJpdCBkb3VibGUgdG8gYSBidWZmZXIgdXNpbmcgYmlnIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LndyaXRlRG91YmxlQkVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgVGFyZ2V0IGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFRhcmdldCBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIGEgNjQgYml0IGRvdWJsZSBmcm9tIGEgYnVmZmVyIHVzaW5nIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC5yZWFkRG91YmxlTEVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFNvdXJjZSBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBTb3VyY2UgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIGEgNjQgYml0IGRvdWJsZSBmcm9tIGEgYnVmZmVyIHVzaW5nIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC5yZWFkRG91YmxlQkVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmIFNvdXJjZSBidWZmZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IHBvcyBTb3VyY2UgYnVmZmVyIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAqL1xyXG5cclxuLy8gRmFjdG9yeSBmdW5jdGlvbiBmb3IgdGhlIHB1cnBvc2Ugb2Ygbm9kZS1iYXNlZCB0ZXN0aW5nIGluIG1vZGlmaWVkIGdsb2JhbCBlbnZpcm9ubWVudHNcclxuZnVuY3Rpb24gZmFjdG9yeShleHBvcnRzKSB7XHJcblxyXG4gICAgLy8gZmxvYXQ6IHR5cGVkIGFycmF5XHJcbiAgICBpZiAodHlwZW9mIEZsb2F0MzJBcnJheSAhPT0gXCJ1bmRlZmluZWRcIikgKGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgZjMyID0gbmV3IEZsb2F0MzJBcnJheShbIC0wIF0pLFxyXG4gICAgICAgICAgICBmOGIgPSBuZXcgVWludDhBcnJheShmMzIuYnVmZmVyKSxcclxuICAgICAgICAgICAgbGUgID0gZjhiWzNdID09PSAxMjg7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRmxvYXRfZjMyX2NweSh2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGYzMlswXSA9IHZhbDtcclxuICAgICAgICAgICAgYnVmW3BvcyAgICBdID0gZjhiWzBdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMV0gPSBmOGJbMV07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAyXSA9IGY4YlsyXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDNdID0gZjhiWzNdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gd3JpdGVGbG9hdF9mMzJfcmV2KHZhbCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjMyWzBdID0gdmFsO1xyXG4gICAgICAgICAgICBidWZbcG9zICAgIF0gPSBmOGJbM107XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAxXSA9IGY4YlsyXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDJdID0gZjhiWzFdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgM10gPSBmOGJbMF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMud3JpdGVGbG9hdExFID0gbGUgPyB3cml0ZUZsb2F0X2YzMl9jcHkgOiB3cml0ZUZsb2F0X2YzMl9yZXY7XHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLndyaXRlRmxvYXRCRSA9IGxlID8gd3JpdGVGbG9hdF9mMzJfcmV2IDogd3JpdGVGbG9hdF9mMzJfY3B5O1xyXG5cclxuICAgICAgICBmdW5jdGlvbiByZWFkRmxvYXRfZjMyX2NweShidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmOGJbMF0gPSBidWZbcG9zICAgIF07XHJcbiAgICAgICAgICAgIGY4YlsxXSA9IGJ1Zltwb3MgKyAxXTtcclxuICAgICAgICAgICAgZjhiWzJdID0gYnVmW3BvcyArIDJdO1xyXG4gICAgICAgICAgICBmOGJbM10gPSBidWZbcG9zICsgM107XHJcbiAgICAgICAgICAgIHJldHVybiBmMzJbMF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiByZWFkRmxvYXRfZjMyX3JldihidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmOGJbM10gPSBidWZbcG9zICAgIF07XHJcbiAgICAgICAgICAgIGY4YlsyXSA9IGJ1Zltwb3MgKyAxXTtcclxuICAgICAgICAgICAgZjhiWzFdID0gYnVmW3BvcyArIDJdO1xyXG4gICAgICAgICAgICBmOGJbMF0gPSBidWZbcG9zICsgM107XHJcbiAgICAgICAgICAgIHJldHVybiBmMzJbMF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMucmVhZEZsb2F0TEUgPSBsZSA/IHJlYWRGbG9hdF9mMzJfY3B5IDogcmVhZEZsb2F0X2YzMl9yZXY7XHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLnJlYWRGbG9hdEJFID0gbGUgPyByZWFkRmxvYXRfZjMyX3JldiA6IHJlYWRGbG9hdF9mMzJfY3B5O1xyXG5cclxuICAgIC8vIGZsb2F0OiBpZWVlNzU0XHJcbiAgICB9KSgpOyBlbHNlIChmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gd3JpdGVGbG9hdF9pZWVlNzU0KHdyaXRlVWludCwgdmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICB2YXIgc2lnbiA9IHZhbCA8IDAgPyAxIDogMDtcclxuICAgICAgICAgICAgaWYgKHNpZ24pXHJcbiAgICAgICAgICAgICAgICB2YWwgPSAtdmFsO1xyXG4gICAgICAgICAgICBpZiAodmFsID09PSAwKVxyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KDEgLyB2YWwgPiAwID8gLyogcG9zaXRpdmUgKi8gMCA6IC8qIG5lZ2F0aXZlIDAgKi8gMjE0NzQ4MzY0OCwgYnVmLCBwb3MpO1xyXG4gICAgICAgICAgICBlbHNlIGlmIChpc05hTih2YWwpKVxyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KDIxNDMyODkzNDQsIGJ1ZiwgcG9zKTtcclxuICAgICAgICAgICAgZWxzZSBpZiAodmFsID4gMy40MDI4MjM0NjYzODUyODg2ZSszOCkgLy8gKy1JbmZpbml0eVxyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KChzaWduIDw8IDMxIHwgMjEzOTA5NTA0MCkgPj4+IDAsIGJ1ZiwgcG9zKTtcclxuICAgICAgICAgICAgZWxzZSBpZiAodmFsIDwgMS4xNzU0OTQzNTA4MjIyODc1ZS0zOCkgLy8gZGVub3JtYWxcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IE1hdGgucm91bmQodmFsIC8gMS40MDEyOTg0NjQzMjQ4MTdlLTQ1KSkgPj4+IDAsIGJ1ZiwgcG9zKTtcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZXhwb25lbnQgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbCkgLyBNYXRoLkxOMiksXHJcbiAgICAgICAgICAgICAgICAgICAgbWFudGlzc2EgPSBNYXRoLnJvdW5kKHZhbCAqIE1hdGgucG93KDIsIC1leHBvbmVudCkgKiA4Mzg4NjA4KSAmIDgzODg2MDc7XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoKHNpZ24gPDwgMzEgfCBleHBvbmVudCArIDEyNyA8PCAyMyB8IG1hbnRpc3NhKSA+Pj4gMCwgYnVmLCBwb3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBleHBvcnRzLndyaXRlRmxvYXRMRSA9IHdyaXRlRmxvYXRfaWVlZTc1NC5iaW5kKG51bGwsIHdyaXRlVWludExFKTtcclxuICAgICAgICBleHBvcnRzLndyaXRlRmxvYXRCRSA9IHdyaXRlRmxvYXRfaWVlZTc1NC5iaW5kKG51bGwsIHdyaXRlVWludEJFKTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcmVhZEZsb2F0X2llZWU3NTQocmVhZFVpbnQsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIHZhciB1aW50ID0gcmVhZFVpbnQoYnVmLCBwb3MpLFxyXG4gICAgICAgICAgICAgICAgc2lnbiA9ICh1aW50ID4+IDMxKSAqIDIgKyAxLFxyXG4gICAgICAgICAgICAgICAgZXhwb25lbnQgPSB1aW50ID4+PiAyMyAmIDI1NSxcclxuICAgICAgICAgICAgICAgIG1hbnRpc3NhID0gdWludCAmIDgzODg2MDc7XHJcbiAgICAgICAgICAgIHJldHVybiBleHBvbmVudCA9PT0gMjU1XHJcbiAgICAgICAgICAgICAgICA/IG1hbnRpc3NhXHJcbiAgICAgICAgICAgICAgICA/IE5hTlxyXG4gICAgICAgICAgICAgICAgOiBzaWduICogSW5maW5pdHlcclxuICAgICAgICAgICAgICAgIDogZXhwb25lbnQgPT09IDAgLy8gZGVub3JtYWxcclxuICAgICAgICAgICAgICAgID8gc2lnbiAqIDEuNDAxMjk4NDY0MzI0ODE3ZS00NSAqIG1hbnRpc3NhXHJcbiAgICAgICAgICAgICAgICA6IHNpZ24gKiBNYXRoLnBvdygyLCBleHBvbmVudCAtIDE1MCkgKiAobWFudGlzc2EgKyA4Mzg4NjA4KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGV4cG9ydHMucmVhZEZsb2F0TEUgPSByZWFkRmxvYXRfaWVlZTc1NC5iaW5kKG51bGwsIHJlYWRVaW50TEUpO1xyXG4gICAgICAgIGV4cG9ydHMucmVhZEZsb2F0QkUgPSByZWFkRmxvYXRfaWVlZTc1NC5iaW5kKG51bGwsIHJlYWRVaW50QkUpO1xyXG5cclxuICAgIH0pKCk7XHJcblxyXG4gICAgLy8gZG91YmxlOiB0eXBlZCBhcnJheVxyXG4gICAgaWYgKHR5cGVvZiBGbG9hdDY0QXJyYXkgIT09IFwidW5kZWZpbmVkXCIpIChmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIGY2NCA9IG5ldyBGbG9hdDY0QXJyYXkoWy0wXSksXHJcbiAgICAgICAgICAgIGY4YiA9IG5ldyBVaW50OEFycmF5KGY2NC5idWZmZXIpLFxyXG4gICAgICAgICAgICBsZSAgPSBmOGJbN10gPT09IDEyODtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gd3JpdGVEb3VibGVfZjY0X2NweSh2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY2NFswXSA9IHZhbDtcclxuICAgICAgICAgICAgYnVmW3BvcyAgICBdID0gZjhiWzBdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMV0gPSBmOGJbMV07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAyXSA9IGY4YlsyXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDNdID0gZjhiWzNdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgNF0gPSBmOGJbNF07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA1XSA9IGY4Yls1XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDZdID0gZjhiWzZdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgN10gPSBmOGJbN107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZURvdWJsZV9mNjRfcmV2KHZhbCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjY0WzBdID0gdmFsO1xyXG4gICAgICAgICAgICBidWZbcG9zICAgIF0gPSBmOGJbN107XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAxXSA9IGY4Yls2XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDJdID0gZjhiWzVdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgM10gPSBmOGJbNF07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA0XSA9IGY4YlszXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDVdID0gZjhiWzJdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgNl0gPSBmOGJbMV07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA3XSA9IGY4YlswXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZURvdWJsZUxFID0gbGUgPyB3cml0ZURvdWJsZV9mNjRfY3B5IDogd3JpdGVEb3VibGVfZjY0X3JldjtcclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMud3JpdGVEb3VibGVCRSA9IGxlID8gd3JpdGVEb3VibGVfZjY0X3JldiA6IHdyaXRlRG91YmxlX2Y2NF9jcHk7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWREb3VibGVfZjY0X2NweShidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmOGJbMF0gPSBidWZbcG9zICAgIF07XHJcbiAgICAgICAgICAgIGY4YlsxXSA9IGJ1Zltwb3MgKyAxXTtcclxuICAgICAgICAgICAgZjhiWzJdID0gYnVmW3BvcyArIDJdO1xyXG4gICAgICAgICAgICBmOGJbM10gPSBidWZbcG9zICsgM107XHJcbiAgICAgICAgICAgIGY4Yls0XSA9IGJ1Zltwb3MgKyA0XTtcclxuICAgICAgICAgICAgZjhiWzVdID0gYnVmW3BvcyArIDVdO1xyXG4gICAgICAgICAgICBmOGJbNl0gPSBidWZbcG9zICsgNl07XHJcbiAgICAgICAgICAgIGY4Yls3XSA9IGJ1Zltwb3MgKyA3XTtcclxuICAgICAgICAgICAgcmV0dXJuIGY2NFswXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWREb3VibGVfZjY0X3JldihidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmOGJbN10gPSBidWZbcG9zICAgIF07XHJcbiAgICAgICAgICAgIGY4Yls2XSA9IGJ1Zltwb3MgKyAxXTtcclxuICAgICAgICAgICAgZjhiWzVdID0gYnVmW3BvcyArIDJdO1xyXG4gICAgICAgICAgICBmOGJbNF0gPSBidWZbcG9zICsgM107XHJcbiAgICAgICAgICAgIGY4YlszXSA9IGJ1Zltwb3MgKyA0XTtcclxuICAgICAgICAgICAgZjhiWzJdID0gYnVmW3BvcyArIDVdO1xyXG4gICAgICAgICAgICBmOGJbMV0gPSBidWZbcG9zICsgNl07XHJcbiAgICAgICAgICAgIGY4YlswXSA9IGJ1Zltwb3MgKyA3XTtcclxuICAgICAgICAgICAgcmV0dXJuIGY2NFswXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRG91YmxlTEUgPSBsZSA/IHJlYWREb3VibGVfZjY0X2NweSA6IHJlYWREb3VibGVfZjY0X3JldjtcclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMucmVhZERvdWJsZUJFID0gbGUgPyByZWFkRG91YmxlX2Y2NF9yZXYgOiByZWFkRG91YmxlX2Y2NF9jcHk7XHJcblxyXG4gICAgLy8gZG91YmxlOiBpZWVlNzU0XHJcbiAgICB9KSgpOyBlbHNlIChmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gd3JpdGVEb3VibGVfaWVlZTc1NCh3cml0ZVVpbnQsIG9mZjAsIG9mZjEsIHZhbCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgdmFyIHNpZ24gPSB2YWwgPCAwID8gMSA6IDA7XHJcbiAgICAgICAgICAgIGlmIChzaWduKVxyXG4gICAgICAgICAgICAgICAgdmFsID0gLXZhbDtcclxuICAgICAgICAgICAgaWYgKHZhbCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KDAsIGJ1ZiwgcG9zICsgb2ZmMCk7XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMSAvIHZhbCA+IDAgPyAvKiBwb3NpdGl2ZSAqLyAwIDogLyogbmVnYXRpdmUgMCAqLyAyMTQ3NDgzNjQ4LCBidWYsIHBvcyArIG9mZjEpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzTmFOKHZhbCkpIHtcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgwLCBidWYsIHBvcyArIG9mZjApO1xyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KDIxNDY5NTkzNjAsIGJ1ZiwgcG9zICsgb2ZmMSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsID4gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDgpIHsgLy8gKy1JbmZpbml0eVxyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KDAsIGJ1ZiwgcG9zICsgb2ZmMCk7XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoKHNpZ24gPDwgMzEgfCAyMTQ2NDM1MDcyKSA+Pj4gMCwgYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHZhciBtYW50aXNzYTtcclxuICAgICAgICAgICAgICAgIGlmICh2YWwgPCAyLjIyNTA3Mzg1ODUwNzIwMTRlLTMwOCkgeyAvLyBkZW5vcm1hbFxyXG4gICAgICAgICAgICAgICAgICAgIG1hbnRpc3NhID0gdmFsIC8gNWUtMzI0O1xyXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlVWludChtYW50aXNzYSA+Pj4gMCwgYnVmLCBwb3MgKyBvZmYwKTtcclxuICAgICAgICAgICAgICAgICAgICB3cml0ZVVpbnQoKHNpZ24gPDwgMzEgfCBtYW50aXNzYSAvIDQyOTQ5NjcyOTYpID4+PiAwLCBidWYsIHBvcyArIG9mZjEpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXhwb25lbnQgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbCkgLyBNYXRoLkxOMik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4cG9uZW50ID09PSAxMDI0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHBvbmVudCA9IDEwMjM7XHJcbiAgICAgICAgICAgICAgICAgICAgbWFudGlzc2EgPSB2YWwgKiBNYXRoLnBvdygyLCAtZXhwb25lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlVWludChtYW50aXNzYSAqIDQ1MDM1OTk2MjczNzA0OTYgPj4+IDAsIGJ1ZiwgcG9zICsgb2ZmMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVVaW50KChzaWduIDw8IDMxIHwgZXhwb25lbnQgKyAxMDIzIDw8IDIwIHwgbWFudGlzc2EgKiAxMDQ4NTc2ICYgMTA0ODU3NSkgPj4+IDAsIGJ1ZiwgcG9zICsgb2ZmMSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGV4cG9ydHMud3JpdGVEb3VibGVMRSA9IHdyaXRlRG91YmxlX2llZWU3NTQuYmluZChudWxsLCB3cml0ZVVpbnRMRSwgMCwgNCk7XHJcbiAgICAgICAgZXhwb3J0cy53cml0ZURvdWJsZUJFID0gd3JpdGVEb3VibGVfaWVlZTc1NC5iaW5kKG51bGwsIHdyaXRlVWludEJFLCA0LCAwKTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcmVhZERvdWJsZV9pZWVlNzU0KHJlYWRVaW50LCBvZmYwLCBvZmYxLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICB2YXIgbG8gPSByZWFkVWludChidWYsIHBvcyArIG9mZjApLFxyXG4gICAgICAgICAgICAgICAgaGkgPSByZWFkVWludChidWYsIHBvcyArIG9mZjEpO1xyXG4gICAgICAgICAgICB2YXIgc2lnbiA9IChoaSA+PiAzMSkgKiAyICsgMSxcclxuICAgICAgICAgICAgICAgIGV4cG9uZW50ID0gaGkgPj4+IDIwICYgMjA0NyxcclxuICAgICAgICAgICAgICAgIG1hbnRpc3NhID0gNDI5NDk2NzI5NiAqIChoaSAmIDEwNDg1NzUpICsgbG87XHJcbiAgICAgICAgICAgIHJldHVybiBleHBvbmVudCA9PT0gMjA0N1xyXG4gICAgICAgICAgICAgICAgPyBtYW50aXNzYVxyXG4gICAgICAgICAgICAgICAgPyBOYU5cclxuICAgICAgICAgICAgICAgIDogc2lnbiAqIEluZmluaXR5XHJcbiAgICAgICAgICAgICAgICA6IGV4cG9uZW50ID09PSAwIC8vIGRlbm9ybWFsXHJcbiAgICAgICAgICAgICAgICA/IHNpZ24gKiA1ZS0zMjQgKiBtYW50aXNzYVxyXG4gICAgICAgICAgICAgICAgOiBzaWduICogTWF0aC5wb3coMiwgZXhwb25lbnQgLSAxMDc1KSAqIChtYW50aXNzYSArIDQ1MDM1OTk2MjczNzA0OTYpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRG91YmxlTEUgPSByZWFkRG91YmxlX2llZWU3NTQuYmluZChudWxsLCByZWFkVWludExFLCAwLCA0KTtcclxuICAgICAgICBleHBvcnRzLnJlYWREb3VibGVCRSA9IHJlYWREb3VibGVfaWVlZTc1NC5iaW5kKG51bGwsIHJlYWRVaW50QkUsIDQsIDApO1xyXG5cclxuICAgIH0pKCk7XHJcblxyXG4gICAgcmV0dXJuIGV4cG9ydHM7XHJcbn1cclxuXHJcbi8vIHVpbnQgaGVscGVyc1xyXG5cclxuZnVuY3Rpb24gd3JpdGVVaW50TEUodmFsLCBidWYsIHBvcykge1xyXG4gICAgYnVmW3BvcyAgICBdID0gIHZhbCAgICAgICAgJiAyNTU7XHJcbiAgICBidWZbcG9zICsgMV0gPSAgdmFsID4+PiA4ICAmIDI1NTtcclxuICAgIGJ1Zltwb3MgKyAyXSA9ICB2YWwgPj4+IDE2ICYgMjU1O1xyXG4gICAgYnVmW3BvcyArIDNdID0gIHZhbCA+Pj4gMjQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHdyaXRlVWludEJFKHZhbCwgYnVmLCBwb3MpIHtcclxuICAgIGJ1Zltwb3MgICAgXSA9ICB2YWwgPj4+IDI0O1xyXG4gICAgYnVmW3BvcyArIDFdID0gIHZhbCA+Pj4gMTYgJiAyNTU7XHJcbiAgICBidWZbcG9zICsgMl0gPSAgdmFsID4+PiA4ICAmIDI1NTtcclxuICAgIGJ1Zltwb3MgKyAzXSA9ICB2YWwgICAgICAgICYgMjU1O1xyXG59XHJcblxyXG5mdW5jdGlvbiByZWFkVWludExFKGJ1ZiwgcG9zKSB7XHJcbiAgICByZXR1cm4gKGJ1Zltwb3MgICAgXVxyXG4gICAgICAgICAgfCBidWZbcG9zICsgMV0gPDwgOFxyXG4gICAgICAgICAgfCBidWZbcG9zICsgMl0gPDwgMTZcclxuICAgICAgICAgIHwgYnVmW3BvcyArIDNdIDw8IDI0KSA+Pj4gMDtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVhZFVpbnRCRShidWYsIHBvcykge1xyXG4gICAgcmV0dXJuIChidWZbcG9zICAgIF0gPDwgMjRcclxuICAgICAgICAgIHwgYnVmW3BvcyArIDFdIDw8IDE2XHJcbiAgICAgICAgICB8IGJ1Zltwb3MgKyAyXSA8PCA4XHJcbiAgICAgICAgICB8IGJ1Zltwb3MgKyAzXSkgPj4+IDA7XHJcbn1cclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGlucXVpcmU7XHJcblxyXG4vKipcclxuICogUmVxdWlyZXMgYSBtb2R1bGUgb25seSBpZiBhdmFpbGFibGUuXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBtb2R1bGVOYW1lIE1vZHVsZSB0byByZXF1aXJlXHJcbiAqIEByZXR1cm5zIHs/T2JqZWN0fSBSZXF1aXJlZCBtb2R1bGUgaWYgYXZhaWxhYmxlIGFuZCBub3QgZW1wdHksIG90aGVyd2lzZSBgbnVsbGBcclxuICovXHJcbmZ1bmN0aW9uIGlucXVpcmUobW9kdWxlTmFtZSkge1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB2YXIgbW9kID0gZXZhbChcInF1aXJlXCIucmVwbGFjZSgvXi8sXCJyZVwiKSkobW9kdWxlTmFtZSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZXZhbFxyXG4gICAgICAgIGlmIChtb2QgJiYgKG1vZC5sZW5ndGggfHwgT2JqZWN0LmtleXMobW9kKS5sZW5ndGgpKVxyXG4gICAgICAgICAgICByZXR1cm4gbW9kO1xyXG4gICAgfSBjYXRjaCAoZSkge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1lbXB0eVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbn1cclxuIiwgIlwidXNlIHN0cmljdFwiO1xyXG5cclxuLyoqXHJcbiAqIEEgbWluaW1hbCBVVEY4IGltcGxlbWVudGF0aW9uIGZvciBudW1iZXIgYXJyYXlzLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAbmFtZXNwYWNlXHJcbiAqL1xyXG52YXIgdXRmOCA9IGV4cG9ydHM7XHJcblxyXG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgVVRGOCBieXRlIGxlbmd0aCBvZiBhIHN0cmluZy5cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTdHJpbmdcclxuICogQHJldHVybnMge251bWJlcn0gQnl0ZSBsZW5ndGhcclxuICovXHJcbnV0ZjgubGVuZ3RoID0gZnVuY3Rpb24gdXRmOF9sZW5ndGgoc3RyaW5nKSB7XHJcbiAgICB2YXIgbGVuID0gMCxcclxuICAgICAgICBjID0gMDtcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgKytpKSB7XHJcbiAgICAgICAgYyA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xyXG4gICAgICAgIGlmIChjIDwgMTI4KVxyXG4gICAgICAgICAgICBsZW4gKz0gMTtcclxuICAgICAgICBlbHNlIGlmIChjIDwgMjA0OClcclxuICAgICAgICAgICAgbGVuICs9IDI7XHJcbiAgICAgICAgZWxzZSBpZiAoKGMgJiAweEZDMDApID09PSAweEQ4MDAgJiYgKHN0cmluZy5jaGFyQ29kZUF0KGkgKyAxKSAmIDB4RkMwMCkgPT09IDB4REMwMCkge1xyXG4gICAgICAgICAgICArK2k7XHJcbiAgICAgICAgICAgIGxlbiArPSA0O1xyXG4gICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICBsZW4gKz0gMztcclxuICAgIH1cclxuICAgIHJldHVybiBsZW47XHJcbn07XHJcblxyXG4vKipcclxuICogUmVhZHMgVVRGOCBieXRlcyBhcyBhIHN0cmluZy5cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgU291cmNlIHN0YXJ0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgU291cmNlIGVuZFxyXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBTdHJpbmcgcmVhZFxyXG4gKi9cclxudXRmOC5yZWFkID0gZnVuY3Rpb24gdXRmOF9yZWFkKGJ1ZmZlciwgc3RhcnQsIGVuZCkge1xyXG4gICAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0O1xyXG4gICAgaWYgKGxlbiA8IDEpXHJcbiAgICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB2YXIgcGFydHMgPSBudWxsLFxyXG4gICAgICAgIGNodW5rID0gW10sXHJcbiAgICAgICAgaSA9IDAsIC8vIGNoYXIgb2Zmc2V0XHJcbiAgICAgICAgdDsgICAgIC8vIHRlbXBvcmFyeVxyXG4gICAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7XHJcbiAgICAgICAgdCA9IGJ1ZmZlcltzdGFydCsrXTtcclxuICAgICAgICBpZiAodCA8IDEyOClcclxuICAgICAgICAgICAgY2h1bmtbaSsrXSA9IHQ7XHJcbiAgICAgICAgZWxzZSBpZiAodCA+IDE5MSAmJiB0IDwgMjI0KVxyXG4gICAgICAgICAgICBjaHVua1tpKytdID0gKHQgJiAzMSkgPDwgNiB8IGJ1ZmZlcltzdGFydCsrXSAmIDYzO1xyXG4gICAgICAgIGVsc2UgaWYgKHQgPiAyMzkgJiYgdCA8IDM2NSkge1xyXG4gICAgICAgICAgICB0ID0gKCh0ICYgNykgPDwgMTggfCAoYnVmZmVyW3N0YXJ0KytdICYgNjMpIDw8IDEyIHwgKGJ1ZmZlcltzdGFydCsrXSAmIDYzKSA8PCA2IHwgYnVmZmVyW3N0YXJ0KytdICYgNjMpIC0gMHgxMDAwMDtcclxuICAgICAgICAgICAgY2h1bmtbaSsrXSA9IDB4RDgwMCArICh0ID4+IDEwKTtcclxuICAgICAgICAgICAgY2h1bmtbaSsrXSA9IDB4REMwMCArICh0ICYgMTAyMyk7XHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSAodCAmIDE1KSA8PCAxMiB8IChidWZmZXJbc3RhcnQrK10gJiA2MykgPDwgNiB8IGJ1ZmZlcltzdGFydCsrXSAmIDYzO1xyXG4gICAgICAgIGlmIChpID4gODE5MSkge1xyXG4gICAgICAgICAgICAocGFydHMgfHwgKHBhcnRzID0gW10pKS5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuaykpO1xyXG4gICAgICAgICAgICBpID0gMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAocGFydHMpIHtcclxuICAgICAgICBpZiAoaSlcclxuICAgICAgICAgICAgcGFydHMucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2h1bmsuc2xpY2UoMCwgaSkpKTtcclxuICAgICAgICByZXR1cm4gcGFydHMuam9pbihcIlwiKTtcclxuICAgIH1cclxuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2h1bmsuc2xpY2UoMCwgaSkpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFdyaXRlcyBhIHN0cmluZyBhcyBVVEY4IGJ5dGVzLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFNvdXJjZSBzdHJpbmdcclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgRGVzdGluYXRpb24gYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgRGVzdGluYXRpb24gb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IEJ5dGVzIHdyaXR0ZW5cclxuICovXHJcbnV0Zjgud3JpdGUgPSBmdW5jdGlvbiB1dGY4X3dyaXRlKHN0cmluZywgYnVmZmVyLCBvZmZzZXQpIHtcclxuICAgIHZhciBzdGFydCA9IG9mZnNldCxcclxuICAgICAgICBjMSwgLy8gY2hhcmFjdGVyIDFcclxuICAgICAgICBjMjsgLy8gY2hhcmFjdGVyIDJcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgKytpKSB7XHJcbiAgICAgICAgYzEgPSBzdHJpbmcuY2hhckNvZGVBdChpKTtcclxuICAgICAgICBpZiAoYzEgPCAxMjgpIHtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoYzEgPCAyMDQ4KSB7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSA+PiA2ICAgICAgIHwgMTkyO1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgICAgICAgJiA2MyB8IDEyODtcclxuICAgICAgICB9IGVsc2UgaWYgKChjMSAmIDB4RkMwMCkgPT09IDB4RDgwMCAmJiAoKGMyID0gc3RyaW5nLmNoYXJDb2RlQXQoaSArIDEpKSAmIDB4RkMwMCkgPT09IDB4REMwMCkge1xyXG4gICAgICAgICAgICBjMSA9IDB4MTAwMDAgKyAoKGMxICYgMHgwM0ZGKSA8PCAxMCkgKyAoYzIgJiAweDAzRkYpO1xyXG4gICAgICAgICAgICArK2k7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSA+PiAxOCAgICAgIHwgMjQwO1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gMTIgJiA2MyB8IDEyODtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxID4+IDYgICYgNjMgfCAxMjg7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSAgICAgICAmIDYzIHwgMTI4O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSA+PiAxMiAgICAgIHwgMjI0O1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gNiAgJiA2MyB8IDEyODtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxICAgICAgICYgNjMgfCAxMjg7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG59O1xyXG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XHJcbm1vZHVsZS5leHBvcnRzID0gcG9vbDtcclxuXHJcbi8qKlxyXG4gKiBBbiBhbGxvY2F0b3IgYXMgdXNlZCBieSB7QGxpbmsgdXRpbC5wb29sfS5cclxuICogQHR5cGVkZWYgUG9vbEFsbG9jYXRvclxyXG4gKiBAdHlwZSB7ZnVuY3Rpb259XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIEJ1ZmZlciBzaXplXHJcbiAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBCdWZmZXJcclxuICovXHJcblxyXG4vKipcclxuICogQSBzbGljZXIgYXMgdXNlZCBieSB7QGxpbmsgdXRpbC5wb29sfS5cclxuICogQHR5cGVkZWYgUG9vbFNsaWNlclxyXG4gKiBAdHlwZSB7ZnVuY3Rpb259XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBTdGFydCBvZmZzZXRcclxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBCdWZmZXIgc2xpY2VcclxuICogQHRoaXMge1VpbnQ4QXJyYXl9XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEEgZ2VuZXJhbCBwdXJwb3NlIGJ1ZmZlciBwb29sLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtQb29sQWxsb2NhdG9yfSBhbGxvYyBBbGxvY2F0b3JcclxuICogQHBhcmFtIHtQb29sU2xpY2VyfSBzbGljZSBTbGljZXJcclxuICogQHBhcmFtIHtudW1iZXJ9IFtzaXplPTgxOTJdIFNsYWIgc2l6ZVxyXG4gKiBAcmV0dXJucyB7UG9vbEFsbG9jYXRvcn0gUG9vbGVkIGFsbG9jYXRvclxyXG4gKi9cclxuZnVuY3Rpb24gcG9vbChhbGxvYywgc2xpY2UsIHNpemUpIHtcclxuICAgIHZhciBTSVpFICAgPSBzaXplIHx8IDgxOTI7XHJcbiAgICB2YXIgTUFYICAgID0gU0laRSA+Pj4gMTtcclxuICAgIHZhciBzbGFiICAgPSBudWxsO1xyXG4gICAgdmFyIG9mZnNldCA9IFNJWkU7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gcG9vbF9hbGxvYyhzaXplKSB7XHJcbiAgICAgICAgaWYgKHNpemUgPCAxIHx8IHNpemUgPiBNQVgpXHJcbiAgICAgICAgICAgIHJldHVybiBhbGxvYyhzaXplKTtcclxuICAgICAgICBpZiAob2Zmc2V0ICsgc2l6ZSA+IFNJWkUpIHtcclxuICAgICAgICAgICAgc2xhYiA9IGFsbG9jKFNJWkUpO1xyXG4gICAgICAgICAgICBvZmZzZXQgPSAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgYnVmID0gc2xpY2UuY2FsbChzbGFiLCBvZmZzZXQsIG9mZnNldCArPSBzaXplKTtcclxuICAgICAgICBpZiAob2Zmc2V0ICYgNykgLy8gYWxpZ24gdG8gMzIgYml0XHJcbiAgICAgICAgICAgIG9mZnNldCA9IChvZmZzZXQgfCA3KSArIDE7XHJcbiAgICAgICAgcmV0dXJuIGJ1ZjtcclxuICAgIH07XHJcbn1cclxuIiwgIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBMb25nQml0cztcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiLi4vdXRpbC9taW5pbWFsXCIpO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgbmV3IGxvbmcgYml0cy5cbiAqIEBjbGFzc2Rlc2MgSGVscGVyIGNsYXNzIGZvciB3b3JraW5nIHdpdGggdGhlIGxvdyBhbmQgaGlnaCBiaXRzIG9mIGEgNjQgYml0IHZhbHVlLlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtudW1iZXJ9IGxvIExvdyAzMiBiaXRzLCB1bnNpZ25lZFxuICogQHBhcmFtIHtudW1iZXJ9IGhpIEhpZ2ggMzIgYml0cywgdW5zaWduZWRcbiAqL1xuZnVuY3Rpb24gTG9uZ0JpdHMobG8sIGhpKSB7XG5cbiAgICAvLyBub3RlIHRoYXQgdGhlIGNhc3RzIGJlbG93IGFyZSB0aGVvcmV0aWNhbGx5IHVubmVjZXNzYXJ5IGFzIG9mIHRvZGF5LCBidXQgb2xkZXIgc3RhdGljYWxseVxuICAgIC8vIGdlbmVyYXRlZCBjb252ZXJ0ZXIgY29kZSBtaWdodCBzdGlsbCBjYWxsIHRoZSBjdG9yIHdpdGggc2lnbmVkIDMyYml0cy4ga2VwdCBmb3IgY29tcGF0LlxuXG4gICAgLyoqXG4gICAgICogTG93IGJpdHMuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmxvID0gbG8gPj4+IDA7XG5cbiAgICAvKipcbiAgICAgKiBIaWdoIGJpdHMuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmhpID0gaGkgPj4+IDA7XG59XG5cbi8qKlxuICogWmVybyBiaXRzLlxuICogQG1lbWJlcm9mIHV0aWwuTG9uZ0JpdHNcbiAqIEB0eXBlIHt1dGlsLkxvbmdCaXRzfVxuICovXG52YXIgemVybyA9IExvbmdCaXRzLnplcm8gPSBuZXcgTG9uZ0JpdHMoMCwgMCk7XG5cbnplcm8udG9OdW1iZXIgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG56ZXJvLnp6RW5jb2RlID0gemVyby56ekRlY29kZSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfTtcbnplcm8ubGVuZ3RoID0gZnVuY3Rpb24oKSB7IHJldHVybiAxOyB9O1xuXG4vKipcbiAqIFplcm8gaGFzaC5cbiAqIEBtZW1iZXJvZiB1dGlsLkxvbmdCaXRzXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG52YXIgemVyb0hhc2ggPSBMb25nQml0cy56ZXJvSGFzaCA9IFwiXFwwXFwwXFwwXFwwXFwwXFwwXFwwXFwwXCI7XG5cbi8qKlxuICogQ29uc3RydWN0cyBuZXcgbG9uZyBiaXRzIGZyb20gdGhlIHNwZWNpZmllZCBudW1iZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWVcbiAqIEByZXR1cm5zIHt1dGlsLkxvbmdCaXRzfSBJbnN0YW5jZVxuICovXG5Mb25nQml0cy5mcm9tTnVtYmVyID0gZnVuY3Rpb24gZnJvbU51bWJlcih2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gMClcbiAgICAgICAgcmV0dXJuIHplcm87XG4gICAgdmFyIHNpZ24gPSB2YWx1ZSA8IDA7XG4gICAgaWYgKHNpZ24pXG4gICAgICAgIHZhbHVlID0gLXZhbHVlO1xuICAgIHZhciBsbyA9IHZhbHVlID4+PiAwLFxuICAgICAgICBoaSA9ICh2YWx1ZSAtIGxvKSAvIDQyOTQ5NjcyOTYgPj4+IDA7XG4gICAgaWYgKHNpZ24pIHtcbiAgICAgICAgaGkgPSB+aGkgPj4+IDA7XG4gICAgICAgIGxvID0gfmxvID4+PiAwO1xuICAgICAgICBpZiAoKytsbyA+IDQyOTQ5NjcyOTUpIHtcbiAgICAgICAgICAgIGxvID0gMDtcbiAgICAgICAgICAgIGlmICgrK2hpID4gNDI5NDk2NzI5NSlcbiAgICAgICAgICAgICAgICBoaSA9IDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBMb25nQml0cyhsbywgaGkpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIG5ldyBsb25nIGJpdHMgZnJvbSBhIG51bWJlciwgbG9uZyBvciBzdHJpbmcuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfHN0cmluZ30gdmFsdWUgVmFsdWVcbiAqIEByZXR1cm5zIHt1dGlsLkxvbmdCaXRzfSBJbnN0YW5jZVxuICovXG5Mb25nQml0cy5mcm9tID0gZnVuY3Rpb24gZnJvbSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIpXG4gICAgICAgIHJldHVybiBMb25nQml0cy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICBpZiAodXRpbC5pc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgICAgaWYgKHV0aWwuTG9uZylcbiAgICAgICAgICAgIHZhbHVlID0gdXRpbC5Mb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gTG9uZ0JpdHMuZnJvbU51bWJlcihwYXJzZUludCh2YWx1ZSwgMTApKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlLmxvdyB8fCB2YWx1ZS5oaWdoID8gbmV3IExvbmdCaXRzKHZhbHVlLmxvdyA+Pj4gMCwgdmFsdWUuaGlnaCA+Pj4gMCkgOiB6ZXJvO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIGxvbmcgYml0cyB0byBhIHBvc3NpYmx5IHVuc2FmZSBKYXZhU2NyaXB0IG51bWJlci5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Vuc2lnbmVkPWZhbHNlXSBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdFxuICogQHJldHVybnMge251bWJlcn0gUG9zc2libHkgdW5zYWZlIG51bWJlclxuICovXG5Mb25nQml0cy5wcm90b3R5cGUudG9OdW1iZXIgPSBmdW5jdGlvbiB0b051bWJlcih1bnNpZ25lZCkge1xuICAgIGlmICghdW5zaWduZWQgJiYgdGhpcy5oaSA+Pj4gMzEpIHtcbiAgICAgICAgdmFyIGxvID0gfnRoaXMubG8gKyAxID4+PiAwLFxuICAgICAgICAgICAgaGkgPSB+dGhpcy5oaSAgICAgPj4+IDA7XG4gICAgICAgIGlmICghbG8pXG4gICAgICAgICAgICBoaSA9IGhpICsgMSA+Pj4gMDtcbiAgICAgICAgcmV0dXJuIC0obG8gKyBoaSAqIDQyOTQ5NjcyOTYpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5sbyArIHRoaXMuaGkgKiA0Mjk0OTY3Mjk2O1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIGxvbmcgYml0cyB0byBhIGxvbmcuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1bnNpZ25lZD1mYWxzZV0gV2hldGhlciB1bnNpZ25lZCBvciBub3RcbiAqIEByZXR1cm5zIHtMb25nfSBMb25nXG4gKi9cbkxvbmdCaXRzLnByb3RvdHlwZS50b0xvbmcgPSBmdW5jdGlvbiB0b0xvbmcodW5zaWduZWQpIHtcbiAgICByZXR1cm4gdXRpbC5Mb25nXG4gICAgICAgID8gbmV3IHV0aWwuTG9uZyh0aGlzLmxvIHwgMCwgdGhpcy5oaSB8IDAsIEJvb2xlYW4odW5zaWduZWQpKVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICA6IHsgbG93OiB0aGlzLmxvIHwgMCwgaGlnaDogdGhpcy5oaSB8IDAsIHVuc2lnbmVkOiBCb29sZWFuKHVuc2lnbmVkKSB9O1xufTtcblxudmFyIGNoYXJDb2RlQXQgPSBTdHJpbmcucHJvdG90eXBlLmNoYXJDb2RlQXQ7XG5cbi8qKlxuICogQ29uc3RydWN0cyBuZXcgbG9uZyBiaXRzIGZyb20gdGhlIHNwZWNpZmllZCA4IGNoYXJhY3RlcnMgbG9uZyBoYXNoLlxuICogQHBhcmFtIHtzdHJpbmd9IGhhc2ggSGFzaFxuICogQHJldHVybnMge3V0aWwuTG9uZ0JpdHN9IEJpdHNcbiAqL1xuTG9uZ0JpdHMuZnJvbUhhc2ggPSBmdW5jdGlvbiBmcm9tSGFzaChoYXNoKSB7XG4gICAgaWYgKGhhc2ggPT09IHplcm9IYXNoKVxuICAgICAgICByZXR1cm4gemVybztcbiAgICByZXR1cm4gbmV3IExvbmdCaXRzKFxuICAgICAgICAoIGNoYXJDb2RlQXQuY2FsbChoYXNoLCAwKVxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCAxKSA8PCA4XG4gICAgICAgIHwgY2hhckNvZGVBdC5jYWxsKGhhc2gsIDIpIDw8IDE2XG4gICAgICAgIHwgY2hhckNvZGVBdC5jYWxsKGhhc2gsIDMpIDw8IDI0KSA+Pj4gMFxuICAgICxcbiAgICAgICAgKCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgNClcbiAgICAgICAgfCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgNSkgPDwgOFxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCA2KSA8PCAxNlxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCA3KSA8PCAyNCkgPj4+IDBcbiAgICApO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIGxvbmcgYml0cyB0byBhIDggY2hhcmFjdGVycyBsb25nIGhhc2guXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBIYXNoXG4gKi9cbkxvbmdCaXRzLnByb3RvdHlwZS50b0hhc2ggPSBmdW5jdGlvbiB0b0hhc2goKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICAgIHRoaXMubG8gICAgICAgICYgMjU1LFxuICAgICAgICB0aGlzLmxvID4+PiA4ICAmIDI1NSxcbiAgICAgICAgdGhpcy5sbyA+Pj4gMTYgJiAyNTUsXG4gICAgICAgIHRoaXMubG8gPj4+IDI0ICAgICAgLFxuICAgICAgICB0aGlzLmhpICAgICAgICAmIDI1NSxcbiAgICAgICAgdGhpcy5oaSA+Pj4gOCAgJiAyNTUsXG4gICAgICAgIHRoaXMuaGkgPj4+IDE2ICYgMjU1LFxuICAgICAgICB0aGlzLmhpID4+PiAyNFxuICAgICk7XG59O1xuXG4vKipcbiAqIFppZy16YWcgZW5jb2RlcyB0aGlzIGxvbmcgYml0cy5cbiAqIEByZXR1cm5zIHt1dGlsLkxvbmdCaXRzfSBgdGhpc2BcbiAqL1xuTG9uZ0JpdHMucHJvdG90eXBlLnp6RW5jb2RlID0gZnVuY3Rpb24genpFbmNvZGUoKSB7XG4gICAgdmFyIG1hc2sgPSAgIHRoaXMuaGkgPj4gMzE7XG4gICAgdGhpcy5oaSAgPSAoKHRoaXMuaGkgPDwgMSB8IHRoaXMubG8gPj4+IDMxKSBeIG1hc2spID4+PiAwO1xuICAgIHRoaXMubG8gID0gKCB0aGlzLmxvIDw8IDEgICAgICAgICAgICAgICAgICAgXiBtYXNrKSA+Pj4gMDtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogWmlnLXphZyBkZWNvZGVzIHRoaXMgbG9uZyBiaXRzLlxuICogQHJldHVybnMge3V0aWwuTG9uZ0JpdHN9IGB0aGlzYFxuICovXG5Mb25nQml0cy5wcm90b3R5cGUuenpEZWNvZGUgPSBmdW5jdGlvbiB6ekRlY29kZSgpIHtcbiAgICB2YXIgbWFzayA9IC0odGhpcy5sbyAmIDEpO1xuICAgIHRoaXMubG8gID0gKCh0aGlzLmxvID4+PiAxIHwgdGhpcy5oaSA8PCAzMSkgXiBtYXNrKSA+Pj4gMDtcbiAgICB0aGlzLmhpICA9ICggdGhpcy5oaSA+Pj4gMSAgICAgICAgICAgICAgICAgIF4gbWFzaykgPj4+IDA7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGxlbmd0aCBvZiB0aGlzIGxvbmdiaXRzIHdoZW4gZW5jb2RlZCBhcyBhIHZhcmludC5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IExlbmd0aFxuICovXG5Mb25nQml0cy5wcm90b3R5cGUubGVuZ3RoID0gZnVuY3Rpb24gbGVuZ3RoKCkge1xuICAgIHZhciBwYXJ0MCA9ICB0aGlzLmxvLFxuICAgICAgICBwYXJ0MSA9ICh0aGlzLmxvID4+PiAyOCB8IHRoaXMuaGkgPDwgNCkgPj4+IDAsXG4gICAgICAgIHBhcnQyID0gIHRoaXMuaGkgPj4+IDI0O1xuICAgIHJldHVybiBwYXJ0MiA9PT0gMFxuICAgICAgICAgPyBwYXJ0MSA9PT0gMFxuICAgICAgICAgICA/IHBhcnQwIDwgMTYzODRcbiAgICAgICAgICAgICA/IHBhcnQwIDwgMTI4ID8gMSA6IDJcbiAgICAgICAgICAgICA6IHBhcnQwIDwgMjA5NzE1MiA/IDMgOiA0XG4gICAgICAgICAgIDogcGFydDEgPCAxNjM4NFxuICAgICAgICAgICAgID8gcGFydDEgPCAxMjggPyA1IDogNlxuICAgICAgICAgICAgIDogcGFydDEgPCAyMDk3MTUyID8gNyA6IDhcbiAgICAgICAgIDogcGFydDIgPCAxMjggPyA5IDogMTA7XG59O1xuIiwgIlwidXNlIHN0cmljdFwiO1xudmFyIHV0aWwgPSBleHBvcnRzO1xuXG4vLyB1c2VkIHRvIHJldHVybiBhIFByb21pc2Ugd2hlcmUgY2FsbGJhY2sgaXMgb21pdHRlZFxudXRpbC5hc1Byb21pc2UgPSByZXF1aXJlKFwiQHByb3RvYnVmanMvYXNwcm9taXNlXCIpO1xuXG4vLyBjb252ZXJ0cyB0byAvIGZyb20gYmFzZTY0IGVuY29kZWQgc3RyaW5nc1xudXRpbC5iYXNlNjQgPSByZXF1aXJlKFwiQHByb3RvYnVmanMvYmFzZTY0XCIpO1xuXG4vLyBiYXNlIGNsYXNzIG9mIHJwYy5TZXJ2aWNlXG51dGlsLkV2ZW50RW1pdHRlciA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9ldmVudGVtaXR0ZXJcIik7XG5cbi8vIGZsb2F0IGhhbmRsaW5nIGFjY3Jvc3MgYnJvd3NlcnNcbnV0aWwuZmxvYXQgPSByZXF1aXJlKFwiQHByb3RvYnVmanMvZmxvYXRcIik7XG5cbi8vIHJlcXVpcmVzIG1vZHVsZXMgb3B0aW9uYWxseSBhbmQgaGlkZXMgdGhlIGNhbGwgZnJvbSBidW5kbGVyc1xudXRpbC5pbnF1aXJlID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2lucXVpcmVcIik7XG5cbi8vIGNvbnZlcnRzIHRvIC8gZnJvbSB1dGY4IGVuY29kZWQgc3RyaW5nc1xudXRpbC51dGY4ID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL3V0ZjhcIik7XG5cbi8vIHByb3ZpZGVzIGEgbm9kZS1saWtlIGJ1ZmZlciBwb29sIGluIHRoZSBicm93c2VyXG51dGlsLnBvb2wgPSByZXF1aXJlKFwiQHByb3RvYnVmanMvcG9vbFwiKTtcblxuLy8gdXRpbGl0eSB0byB3b3JrIHdpdGggdGhlIGxvdyBhbmQgaGlnaCBiaXRzIG9mIGEgNjQgYml0IHZhbHVlXG51dGlsLkxvbmdCaXRzID0gcmVxdWlyZShcIi4vbG9uZ2JpdHNcIik7XG5cbi8qKlxuICogV2hldGhlciBydW5uaW5nIHdpdGhpbiBub2RlIG9yIG5vdC5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAdHlwZSB7Ym9vbGVhbn1cbiAqL1xudXRpbC5pc05vZGUgPSBCb29sZWFuKHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCJcbiAgICAgICAgICAgICAgICAgICAmJiBnbG9iYWxcbiAgICAgICAgICAgICAgICAgICAmJiBnbG9iYWwucHJvY2Vzc1xuICAgICAgICAgICAgICAgICAgICYmIGdsb2JhbC5wcm9jZXNzLnZlcnNpb25zXG4gICAgICAgICAgICAgICAgICAgJiYgZ2xvYmFsLnByb2Nlc3MudmVyc2lvbnMubm9kZSk7XG5cbi8qKlxuICogR2xvYmFsIG9iamVjdCByZWZlcmVuY2UuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHR5cGUge09iamVjdH1cbiAqL1xudXRpbC5nbG9iYWwgPSB1dGlsLmlzTm9kZSAmJiBnbG9iYWxcbiAgICAgICAgICAgfHwgdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3dcbiAgICAgICAgICAgfHwgdHlwZW9mIHNlbGYgICAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzZWxmXG4gICAgICAgICAgIHx8IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8taW52YWxpZC10aGlzXG5cbi8qKlxuICogQW4gaW1tdWFibGUgZW1wdHkgYXJyYXkuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHR5cGUge0FycmF5LjwqPn1cbiAqIEBjb25zdFxuICovXG51dGlsLmVtcHR5QXJyYXkgPSBPYmplY3QuZnJlZXplID8gT2JqZWN0LmZyZWV6ZShbXSkgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBbXTsgLy8gdXNlZCBvbiBwcm90b3R5cGVzXG5cbi8qKlxuICogQW4gaW1tdXRhYmxlIGVtcHR5IG9iamVjdC5cbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAY29uc3RcbiAqL1xudXRpbC5lbXB0eU9iamVjdCA9IE9iamVjdC5mcmVlemUgPyBPYmplY3QuZnJlZXplKHt9KSA6IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIHt9OyAvLyB1c2VkIG9uIHByb3RvdHlwZXNcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIGFuIGludGVnZXIuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgdmFsdWUgaXMgYW4gaW50ZWdlclxuICovXG51dGlsLmlzSW50ZWdlciA9IE51bWJlci5pc0ludGVnZXIgfHwgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gZnVuY3Rpb24gaXNJbnRlZ2VyKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIiAmJiBpc0Zpbml0ZSh2YWx1ZSkgJiYgTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIGEgc3RyaW5nLlxuICogQHBhcmFtIHsqfSB2YWx1ZSBWYWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSB2YWx1ZSBpcyBhIHN0cmluZ1xuICovXG51dGlsLmlzU3RyaW5nID0gZnVuY3Rpb24gaXNTdHJpbmcodmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiIHx8IHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nO1xufTtcblxuLyoqXG4gKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIHZhbHVlIGlzIGEgbm9uLW51bGwgb2JqZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBWYWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSB2YWx1ZSBpcyBhIG5vbi1udWxsIG9iamVjdFxuICovXG51dGlsLmlzT2JqZWN0ID0gZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiO1xufTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBwcm9wZXJ0eSBvbiBhIG1lc3NhZ2UgaXMgY29uc2lkZXJlZCB0byBiZSBwcmVzZW50LlxuICogVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgdXRpbC5pc1NldH0uXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogUGxhaW4gb2JqZWN0IG9yIG1lc3NhZ2UgaW5zdGFuY2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wIFByb3BlcnR5IG5hbWVcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgY29uc2lkZXJlZCB0byBiZSBwcmVzZW50LCBvdGhlcndpc2UgYGZhbHNlYFxuICovXG51dGlsLmlzc2V0ID1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSBwcm9wZXJ0eSBvbiBhIG1lc3NhZ2UgaXMgY29uc2lkZXJlZCB0byBiZSBwcmVzZW50LlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBQbGFpbiBvYmplY3Qgb3IgbWVzc2FnZSBpbnN0YW5jZVxuICogQHBhcmFtIHtzdHJpbmd9IHByb3AgUHJvcGVydHkgbmFtZVxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBjb25zaWRlcmVkIHRvIGJlIHByZXNlbnQsIG90aGVyd2lzZSBgZmFsc2VgXG4gKi9cbnV0aWwuaXNTZXQgPSBmdW5jdGlvbiBpc1NldChvYmosIHByb3ApIHtcbiAgICB2YXIgdmFsdWUgPSBvYmpbcHJvcF07XG4gICAgaWYgKHZhbHVlICE9IG51bGwgJiYgb2JqLmhhc093blByb3BlcnR5KHByb3ApKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcSwgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgfHwgKEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUubGVuZ3RoIDogT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCkgPiAwO1xuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogQW55IGNvbXBhdGlibGUgQnVmZmVyIGluc3RhbmNlLlxuICogVGhpcyBpcyBhIG1pbmltYWwgc3RhbmQtYWxvbmUgZGVmaW5pdGlvbiBvZiBhIEJ1ZmZlciBpbnN0YW5jZS4gVGhlIGFjdHVhbCB0eXBlIGlzIHRoYXQgZXhwb3J0ZWQgYnkgbm9kZSdzIHR5cGluZ3MuXG4gKiBAaW50ZXJmYWNlIEJ1ZmZlclxuICogQGV4dGVuZHMgVWludDhBcnJheVxuICovXG5cbi8qKlxuICogTm9kZSdzIEJ1ZmZlciBjbGFzcyBpZiBhdmFpbGFibGUuXG4gKiBAdHlwZSB7Q29uc3RydWN0b3I8QnVmZmVyPn1cbiAqL1xudXRpbC5CdWZmZXIgPSAoZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgdmFyIEJ1ZmZlciA9IHV0aWwuaW5xdWlyZShcImJ1ZmZlclwiKS5CdWZmZXI7XG4gICAgICAgIC8vIHJlZnVzZSB0byB1c2Ugbm9uLW5vZGUgYnVmZmVycyBpZiBub3QgZXhwbGljaXRseSBhc3NpZ25lZCAocGVyZiByZWFzb25zKTpcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5wcm90b3R5cGUudXRmOFdyaXRlID8gQnVmZmVyIDogLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gbnVsbDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbn0pKCk7XG5cbi8vIEludGVybmFsIGFsaWFzIG9mIG9yIHBvbHlmdWxsIGZvciBCdWZmZXIuZnJvbS5cbnV0aWwuX0J1ZmZlcl9mcm9tID0gbnVsbDtcblxuLy8gSW50ZXJuYWwgYWxpYXMgb2Ygb3IgcG9seWZpbGwgZm9yIEJ1ZmZlci5hbGxvY1Vuc2FmZS5cbnV0aWwuX0J1ZmZlcl9hbGxvY1Vuc2FmZSA9IG51bGw7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBidWZmZXIgb2Ygd2hhdGV2ZXIgdHlwZSBzdXBwb3J0ZWQgYnkgdGhlIGVudmlyb25tZW50LlxuICogQHBhcmFtIHtudW1iZXJ8bnVtYmVyW119IFtzaXplT3JBcnJheT0wXSBCdWZmZXIgc2l6ZSBvciBudW1iZXIgYXJyYXlcbiAqIEByZXR1cm5zIHtVaW50OEFycmF5fEJ1ZmZlcn0gQnVmZmVyXG4gKi9cbnV0aWwubmV3QnVmZmVyID0gZnVuY3Rpb24gbmV3QnVmZmVyKHNpemVPckFycmF5KSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICByZXR1cm4gdHlwZW9mIHNpemVPckFycmF5ID09PSBcIm51bWJlclwiXG4gICAgICAgID8gdXRpbC5CdWZmZXJcbiAgICAgICAgICAgID8gdXRpbC5fQnVmZmVyX2FsbG9jVW5zYWZlKHNpemVPckFycmF5KVxuICAgICAgICAgICAgOiBuZXcgdXRpbC5BcnJheShzaXplT3JBcnJheSlcbiAgICAgICAgOiB1dGlsLkJ1ZmZlclxuICAgICAgICAgICAgPyB1dGlsLl9CdWZmZXJfZnJvbShzaXplT3JBcnJheSlcbiAgICAgICAgICAgIDogdHlwZW9mIFVpbnQ4QXJyYXkgPT09IFwidW5kZWZpbmVkXCJcbiAgICAgICAgICAgICAgICA/IHNpemVPckFycmF5XG4gICAgICAgICAgICAgICAgOiBuZXcgVWludDhBcnJheShzaXplT3JBcnJheSk7XG59O1xuXG4vKipcbiAqIEFycmF5IGltcGxlbWVudGF0aW9uIHVzZWQgaW4gdGhlIGJyb3dzZXIuIGBVaW50OEFycmF5YCBpZiBzdXBwb3J0ZWQsIG90aGVyd2lzZSBgQXJyYXlgLlxuICogQHR5cGUge0NvbnN0cnVjdG9yPFVpbnQ4QXJyYXk+fVxuICovXG51dGlsLkFycmF5ID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09IFwidW5kZWZpbmVkXCIgPyBVaW50OEFycmF5IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIDogQXJyYXk7XG5cbi8qKlxuICogQW55IGNvbXBhdGlibGUgTG9uZyBpbnN0YW5jZS5cbiAqIFRoaXMgaXMgYSBtaW5pbWFsIHN0YW5kLWFsb25lIGRlZmluaXRpb24gb2YgYSBMb25nIGluc3RhbmNlLiBUaGUgYWN0dWFsIHR5cGUgaXMgdGhhdCBleHBvcnRlZCBieSBsb25nLmpzLlxuICogQGludGVyZmFjZSBMb25nXG4gKiBAcHJvcGVydHkge251bWJlcn0gbG93IExvdyBiaXRzXG4gKiBAcHJvcGVydHkge251bWJlcn0gaGlnaCBIaWdoIGJpdHNcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3RcbiAqL1xuXG4vKipcbiAqIExvbmcuanMncyBMb25nIGNsYXNzIGlmIGF2YWlsYWJsZS5cbiAqIEB0eXBlIHtDb25zdHJ1Y3RvcjxMb25nPn1cbiAqL1xudXRpbC5Mb25nID0gLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gdXRpbC5nbG9iYWwuZGNvZGVJTyAmJiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyB1dGlsLmdsb2JhbC5kY29kZUlPLkxvbmdcbiAgICAgICAgIHx8IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIHV0aWwuZ2xvYmFsLkxvbmdcbiAgICAgICAgIHx8IHV0aWwuaW5xdWlyZShcImxvbmdcIik7XG5cbi8qKlxuICogUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gdmVyaWZ5IDIgYml0IChgYm9vbGApIG1hcCBrZXlzLlxuICogQHR5cGUge1JlZ0V4cH1cbiAqIEBjb25zdFxuICovXG51dGlsLmtleTJSZSA9IC9edHJ1ZXxmYWxzZXwwfDEkLztcblxuLyoqXG4gKiBSZWd1bGFyIGV4cHJlc3Npb24gdXNlZCB0byB2ZXJpZnkgMzIgYml0IChgaW50MzJgIGV0Yy4pIG1hcCBrZXlzLlxuICogQHR5cGUge1JlZ0V4cH1cbiAqIEBjb25zdFxuICovXG51dGlsLmtleTMyUmUgPSAvXi0/KD86MHxbMS05XVswLTldKikkLztcblxuLyoqXG4gKiBSZWd1bGFyIGV4cHJlc3Npb24gdXNlZCB0byB2ZXJpZnkgNjQgYml0IChgaW50NjRgIGV0Yy4pIG1hcCBrZXlzLlxuICogQHR5cGUge1JlZ0V4cH1cbiAqIEBjb25zdFxuICovXG51dGlsLmtleTY0UmUgPSAvXig/OltcXFxceDAwLVxcXFx4ZmZdezh9fC0/KD86MHxbMS05XVswLTldKikpJC87XG5cbi8qKlxuICogQ29udmVydHMgYSBudW1iZXIgb3IgbG9uZyB0byBhbiA4IGNoYXJhY3RlcnMgbG9uZyBoYXNoIHN0cmluZy5cbiAqIEBwYXJhbSB7TG9uZ3xudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHtzdHJpbmd9IEhhc2hcbiAqL1xudXRpbC5sb25nVG9IYXNoID0gZnVuY3Rpb24gbG9uZ1RvSGFzaCh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZVxuICAgICAgICA/IHV0aWwuTG9uZ0JpdHMuZnJvbSh2YWx1ZSkudG9IYXNoKClcbiAgICAgICAgOiB1dGlsLkxvbmdCaXRzLnplcm9IYXNoO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyBhbiA4IGNoYXJhY3RlcnMgbG9uZyBoYXNoIHN0cmluZyB0byBhIGxvbmcgb3IgbnVtYmVyLlxuICogQHBhcmFtIHtzdHJpbmd9IGhhc2ggSGFzaFxuICogQHBhcmFtIHtib29sZWFufSBbdW5zaWduZWQ9ZmFsc2VdIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90XG4gKiBAcmV0dXJucyB7TG9uZ3xudW1iZXJ9IE9yaWdpbmFsIHZhbHVlXG4gKi9cbnV0aWwubG9uZ0Zyb21IYXNoID0gZnVuY3Rpb24gbG9uZ0Zyb21IYXNoKGhhc2gsIHVuc2lnbmVkKSB7XG4gICAgdmFyIGJpdHMgPSB1dGlsLkxvbmdCaXRzLmZyb21IYXNoKGhhc2gpO1xuICAgIGlmICh1dGlsLkxvbmcpXG4gICAgICAgIHJldHVybiB1dGlsLkxvbmcuZnJvbUJpdHMoYml0cy5sbywgYml0cy5oaSwgdW5zaWduZWQpO1xuICAgIHJldHVybiBiaXRzLnRvTnVtYmVyKEJvb2xlYW4odW5zaWduZWQpKTtcbn07XG5cbi8qKlxuICogTWVyZ2VzIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBzb3VyY2Ugb2JqZWN0IGludG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBkc3QgRGVzdGluYXRpb24gb2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBzcmMgU291cmNlIG9iamVjdFxuICogQHBhcmFtIHtib29sZWFufSBbaWZOb3RTZXQ9ZmFsc2VdIE1lcmdlcyBvbmx5IGlmIHRoZSBrZXkgaXMgbm90IGFscmVhZHkgc2V0XG4gKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IERlc3RpbmF0aW9uIG9iamVjdFxuICovXG5mdW5jdGlvbiBtZXJnZShkc3QsIHNyYywgaWZOb3RTZXQpIHsgLy8gdXNlZCBieSBjb252ZXJ0ZXJzXG4gICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHNyYyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgaWYgKGRzdFtrZXlzW2ldXSA9PT0gdW5kZWZpbmVkIHx8ICFpZk5vdFNldClcbiAgICAgICAgICAgIGRzdFtrZXlzW2ldXSA9IHNyY1trZXlzW2ldXTtcbiAgICByZXR1cm4gZHN0O1xufVxuXG51dGlsLm1lcmdlID0gbWVyZ2U7XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBhIHN0cmluZyB0byBsb3dlciBjYXNlLlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gY29udmVydFxuICogQHJldHVybnMge3N0cmluZ30gQ29udmVydGVkIHN0cmluZ1xuICovXG51dGlsLmxjRmlyc3QgPSBmdW5jdGlvbiBsY0ZpcnN0KHN0cikge1xuICAgIHJldHVybiBzdHIuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBzdHIuc3Vic3RyaW5nKDEpO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY3VzdG9tIGVycm9yIGNvbnN0cnVjdG9yLlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIEVycm9yIG5hbWVcbiAqIEByZXR1cm5zIHtDb25zdHJ1Y3RvcjxFcnJvcj59IEN1c3RvbSBlcnJvciBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBuZXdFcnJvcihuYW1lKSB7XG5cbiAgICBmdW5jdGlvbiBDdXN0b21FcnJvcihtZXNzYWdlLCBwcm9wZXJ0aWVzKSB7XG5cbiAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEN1c3RvbUVycm9yKSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ3VzdG9tRXJyb3IobWVzc2FnZSwgcHJvcGVydGllcyk7XG5cbiAgICAgICAgLy8gRXJyb3IuY2FsbCh0aGlzLCBtZXNzYWdlKTtcbiAgICAgICAgLy8gXiBqdXN0IHJldHVybnMgYSBuZXcgZXJyb3IgaW5zdGFuY2UgYmVjYXVzZSB0aGUgY3RvciBjYW4gYmUgY2FsbGVkIGFzIGEgZnVuY3Rpb25cblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJtZXNzYWdlXCIsIHsgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1lc3NhZ2U7IH0gfSk7XG5cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSAvLyBub2RlXG4gICAgICAgICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBDdXN0b21FcnJvcik7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcInN0YWNrXCIsIHsgdmFsdWU6IG5ldyBFcnJvcigpLnN0YWNrIHx8IFwiXCIgfSk7XG5cbiAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICBtZXJnZSh0aGlzLCBwcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBDdXN0b21FcnJvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgICAgdmFsdWU6IEN1c3RvbUVycm9yLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgbmFtZToge1xuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7IHJldHVybiBuYW1lOyB9LFxuICAgICAgICAgICAgc2V0OiB1bmRlZmluZWQsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIC8vIGNvbmZpZ3VyYWJsZTogZmFsc2Ugd291bGQgYWNjdXJhdGVseSBwcmVzZXJ2ZSB0aGUgYmVoYXZpb3Igb2ZcbiAgICAgICAgICAgIC8vIHRoZSBvcmlnaW5hbCwgYnV0IEknbSBndWVzc2luZyB0aGF0IHdhcyBub3QgaW50ZW50aW9uYWwuXG4gICAgICAgICAgICAvLyBGb3IgYW4gYWN0dWFsIGVycm9yIHN1YmNsYXNzLCB0aGlzIHByb3BlcnR5IHdvdWxkXG4gICAgICAgICAgICAvLyBiZSBjb25maWd1cmFibGUuXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIHRvU3RyaW5nOiB7XG4gICAgICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUoKSB7IHJldHVybiB0aGlzLm5hbWUgKyBcIjogXCIgKyB0aGlzLm1lc3NhZ2U7IH0sXG4gICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB9LFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIEN1c3RvbUVycm9yO1xufVxuXG51dGlsLm5ld0Vycm9yID0gbmV3RXJyb3I7XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyBwcm90b2NvbCBlcnJvci5cbiAqIEBjbGFzc2Rlc2MgRXJyb3Igc3ViY2xhc3MgaW5kaWNhdGluZyBhIHByb3RvY29sIHNwZWNpZmMgZXJyb3IuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQGV4dGVuZHMgRXJyb3JcbiAqIEB0ZW1wbGF0ZSBUIGV4dGVuZHMgTWVzc2FnZTxUPlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBFcnJvciBtZXNzYWdlXG4gKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBbcHJvcGVydGllc10gQWRkaXRpb25hbCBwcm9wZXJ0aWVzXG4gKiBAZXhhbXBsZVxuICogdHJ5IHtcbiAqICAgICBNeU1lc3NhZ2UuZGVjb2RlKHNvbWVCdWZmZXIpOyAvLyB0aHJvd3MgaWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gKiB9IGNhdGNoIChlKSB7XG4gKiAgICAgaWYgKGUgaW5zdGFuY2VvZiBQcm90b2NvbEVycm9yICYmIGUuaW5zdGFuY2UpXG4gKiAgICAgICAgIGNvbnNvbGUubG9nKFwiZGVjb2RlZCBzbyBmYXI6IFwiICsgSlNPTi5zdHJpbmdpZnkoZS5pbnN0YW5jZSkpO1xuICogfVxuICovXG51dGlsLlByb3RvY29sRXJyb3IgPSBuZXdFcnJvcihcIlByb3RvY29sRXJyb3JcIik7XG5cbi8qKlxuICogU28gZmFyIGRlY29kZWQgbWVzc2FnZSBpbnN0YW5jZS5cbiAqIEBuYW1lIHV0aWwuUHJvdG9jb2xFcnJvciNpbnN0YW5jZVxuICogQHR5cGUge01lc3NhZ2U8VD59XG4gKi9cblxuLyoqXG4gKiBBIE9uZU9mIGdldHRlciBhcyByZXR1cm5lZCBieSB7QGxpbmsgdXRpbC5vbmVPZkdldHRlcn0uXG4gKiBAdHlwZWRlZiBPbmVPZkdldHRlclxuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHJldHVybnMge3N0cmluZ3x1bmRlZmluZWR9IFNldCBmaWVsZCBuYW1lLCBpZiBhbnlcbiAqL1xuXG4vKipcbiAqIEJ1aWxkcyBhIGdldHRlciBmb3IgYSBvbmVvZidzIHByZXNlbnQgZmllbGQgbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nW119IGZpZWxkTmFtZXMgRmllbGQgbmFtZXNcbiAqIEByZXR1cm5zIHtPbmVPZkdldHRlcn0gVW5ib3VuZCBnZXR0ZXJcbiAqL1xudXRpbC5vbmVPZkdldHRlciA9IGZ1bmN0aW9uIGdldE9uZU9mKGZpZWxkTmFtZXMpIHtcbiAgICB2YXIgZmllbGRNYXAgPSB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpZWxkTmFtZXMubGVuZ3RoOyArK2kpXG4gICAgICAgIGZpZWxkTWFwW2ZpZWxkTmFtZXNbaV1dID0gMTtcblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8dW5kZWZpbmVkfSBTZXQgZmllbGQgbmFtZSwgaWYgYW55XG4gICAgICogQHRoaXMgT2JqZWN0XG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgIHJldHVybiBmdW5jdGlvbigpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXModGhpcyksIGkgPSBrZXlzLmxlbmd0aCAtIDE7IGkgPiAtMTsgLS1pKVxuICAgICAgICAgICAgaWYgKGZpZWxkTWFwW2tleXNbaV1dID09PSAxICYmIHRoaXNba2V5c1tpXV0gIT09IHVuZGVmaW5lZCAmJiB0aGlzW2tleXNbaV1dICE9PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBrZXlzW2ldO1xuICAgIH07XG59O1xuXG4vKipcbiAqIEEgT25lT2Ygc2V0dGVyIGFzIHJldHVybmVkIGJ5IHtAbGluayB1dGlsLm9uZU9mU2V0dGVyfS5cbiAqIEB0eXBlZGVmIE9uZU9mU2V0dGVyXG4gKiBAdHlwZSB7ZnVuY3Rpb259XG4gKiBAcGFyYW0ge3N0cmluZ3x1bmRlZmluZWR9IHZhbHVlIEZpZWxkIG5hbWVcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKi9cblxuLyoqXG4gKiBCdWlsZHMgYSBzZXR0ZXIgZm9yIGEgb25lb2YncyBwcmVzZW50IGZpZWxkIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBmaWVsZE5hbWVzIEZpZWxkIG5hbWVzXG4gKiBAcmV0dXJucyB7T25lT2ZTZXR0ZXJ9IFVuYm91bmQgc2V0dGVyXG4gKi9cbnV0aWwub25lT2ZTZXR0ZXIgPSBmdW5jdGlvbiBzZXRPbmVPZihmaWVsZE5hbWVzKSB7XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBGaWVsZCBuYW1lXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAgICAgKiBAdGhpcyBPYmplY3RcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWVsZE5hbWVzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgaWYgKGZpZWxkTmFtZXNbaV0gIT09IG5hbWUpXG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXNbZmllbGROYW1lc1tpXV07XG4gICAgfTtcbn07XG5cbi8qKlxuICogRGVmYXVsdCBjb252ZXJzaW9uIG9wdGlvbnMgdXNlZCBmb3Ige0BsaW5rIE1lc3NhZ2UjdG9KU09OfSBpbXBsZW1lbnRhdGlvbnMuXG4gKlxuICogVGhlc2Ugb3B0aW9ucyBhcmUgY2xvc2UgdG8gcHJvdG8zJ3MgSlNPTiBtYXBwaW5nIHdpdGggdGhlIGV4Y2VwdGlvbiB0aGF0IGludGVybmFsIHR5cGVzIGxpa2UgQW55IGFyZSBoYW5kbGVkIGp1c3QgbGlrZSBtZXNzYWdlcy4gTW9yZSBwcmVjaXNlbHk6XG4gKlxuICogLSBMb25ncyBiZWNvbWUgc3RyaW5nc1xuICogLSBFbnVtcyBiZWNvbWUgc3RyaW5nIGtleXNcbiAqIC0gQnl0ZXMgYmVjb21lIGJhc2U2NCBlbmNvZGVkIHN0cmluZ3NcbiAqIC0gKFN1Yi0pTWVzc2FnZXMgYmVjb21lIHBsYWluIG9iamVjdHNcbiAqIC0gTWFwcyBiZWNvbWUgcGxhaW4gb2JqZWN0cyB3aXRoIGFsbCBzdHJpbmcga2V5c1xuICogLSBSZXBlYXRlZCBmaWVsZHMgYmVjb21lIGFycmF5c1xuICogLSBOYU4gYW5kIEluZmluaXR5IGZvciBmbG9hdCBhbmQgZG91YmxlIGZpZWxkcyBiZWNvbWUgc3RyaW5nc1xuICpcbiAqIEB0eXBlIHtJQ29udmVyc2lvbk9wdGlvbnN9XG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvZG9jcy9wcm90bzM/aGw9ZW4janNvblxuICovXG51dGlsLnRvSlNPTk9wdGlvbnMgPSB7XG4gICAgbG9uZ3M6IFN0cmluZyxcbiAgICBlbnVtczogU3RyaW5nLFxuICAgIGJ5dGVzOiBTdHJpbmcsXG4gICAganNvbjogdHJ1ZVxufTtcblxuLy8gU2V0cyB1cCBidWZmZXIgdXRpbGl0eSBhY2NvcmRpbmcgdG8gdGhlIGVudmlyb25tZW50IChjYWxsZWQgaW4gaW5kZXgtbWluaW1hbClcbnV0aWwuX2NvbmZpZ3VyZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBCdWZmZXIgPSB1dGlsLkJ1ZmZlcjtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoIUJ1ZmZlcikge1xuICAgICAgICB1dGlsLl9CdWZmZXJfZnJvbSA9IHV0aWwuX0J1ZmZlcl9hbGxvY1Vuc2FmZSA9IG51bGw7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gYmVjYXVzZSBub2RlIDQueCBidWZmZXJzIGFyZSBpbmNvbXBhdGlibGUgJiBpbW11dGFibGVcbiAgICAvLyBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL3Byb3RvYnVmLmpzL3B1bGwvNjY1XG4gICAgdXRpbC5fQnVmZmVyX2Zyb20gPSBCdWZmZXIuZnJvbSAhPT0gVWludDhBcnJheS5mcm9tICYmIEJ1ZmZlci5mcm9tIHx8XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGZ1bmN0aW9uIEJ1ZmZlcl9mcm9tKHZhbHVlLCBlbmNvZGluZykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXIodmFsdWUsIGVuY29kaW5nKTtcbiAgICAgICAgfTtcbiAgICB1dGlsLl9CdWZmZXJfYWxsb2NVbnNhZmUgPSBCdWZmZXIuYWxsb2NVbnNhZmUgfHxcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgZnVuY3Rpb24gQnVmZmVyX2FsbG9jVW5zYWZlKHNpemUpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQnVmZmVyKHNpemUpO1xuICAgICAgICB9O1xufTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gV3JpdGVyO1xuXG52YXIgdXRpbCAgICAgID0gcmVxdWlyZShcIi4vdXRpbC9taW5pbWFsXCIpO1xuXG52YXIgQnVmZmVyV3JpdGVyOyAvLyBjeWNsaWNcblxudmFyIExvbmdCaXRzICA9IHV0aWwuTG9uZ0JpdHMsXG4gICAgYmFzZTY0ICAgID0gdXRpbC5iYXNlNjQsXG4gICAgdXRmOCAgICAgID0gdXRpbC51dGY4O1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgd3JpdGVyIG9wZXJhdGlvbiBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgU2NoZWR1bGVkIHdyaXRlciBvcGVyYXRpb24uXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKiwgVWludDhBcnJheSwgbnVtYmVyKX0gZm4gRnVuY3Rpb24gdG8gY2FsbFxuICogQHBhcmFtIHtudW1iZXJ9IGxlbiBWYWx1ZSBieXRlIGxlbmd0aFxuICogQHBhcmFtIHsqfSB2YWwgVmFsdWUgdG8gd3JpdGVcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gT3AoZm4sIGxlbiwgdmFsKSB7XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB0byBjYWxsLlxuICAgICAqIEB0eXBlIHtmdW5jdGlvbihVaW50OEFycmF5LCBudW1iZXIsICopfVxuICAgICAqL1xuICAgIHRoaXMuZm4gPSBmbjtcblxuICAgIC8qKlxuICAgICAqIFZhbHVlIGJ5dGUgbGVuZ3RoLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sZW4gPSBsZW47XG5cbiAgICAvKipcbiAgICAgKiBOZXh0IG9wZXJhdGlvbi5cbiAgICAgKiBAdHlwZSB7V3JpdGVyLk9wfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICB0aGlzLm5leHQgPSB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSB0byB3cml0ZS5cbiAgICAgKiBAdHlwZSB7Kn1cbiAgICAgKi9cbiAgICB0aGlzLnZhbCA9IHZhbDsgLy8gdHlwZSB2YXJpZXNcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIG5vb3AoKSB7fSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWVtcHR5LWZ1bmN0aW9uXG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyB3cml0ZXIgc3RhdGUgaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIENvcGllZCB3cml0ZXIgc3RhdGUuXG4gKiBAbWVtYmVyb2YgV3JpdGVyXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7V3JpdGVyfSB3cml0ZXIgV3JpdGVyIHRvIGNvcHkgc3RhdGUgZnJvbVxuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBTdGF0ZSh3cml0ZXIpIHtcblxuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgaGVhZC5cbiAgICAgKiBAdHlwZSB7V3JpdGVyLk9wfVxuICAgICAqL1xuICAgIHRoaXMuaGVhZCA9IHdyaXRlci5oZWFkO1xuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCB0YWlsLlxuICAgICAqIEB0eXBlIHtXcml0ZXIuT3B9XG4gICAgICovXG4gICAgdGhpcy50YWlsID0gd3JpdGVyLnRhaWw7XG5cbiAgICAvKipcbiAgICAgKiBDdXJyZW50IGJ1ZmZlciBsZW5ndGguXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmxlbiA9IHdyaXRlci5sZW47XG5cbiAgICAvKipcbiAgICAgKiBOZXh0IHN0YXRlLlxuICAgICAqIEB0eXBlIHtTdGF0ZXxudWxsfVxuICAgICAqL1xuICAgIHRoaXMubmV4dCA9IHdyaXRlci5zdGF0ZXM7XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyB3cml0ZXIgaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFdpcmUgZm9ybWF0IHdyaXRlciB1c2luZyBgVWludDhBcnJheWAgaWYgYXZhaWxhYmxlLCBvdGhlcndpc2UgYEFycmF5YC5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBXcml0ZXIoKSB7XG5cbiAgICAvKipcbiAgICAgKiBDdXJyZW50IGxlbmd0aC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMubGVuID0gMDtcblxuICAgIC8qKlxuICAgICAqIE9wZXJhdGlvbnMgaGVhZC5cbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqL1xuICAgIHRoaXMuaGVhZCA9IG5ldyBPcChub29wLCAwLCAwKTtcblxuICAgIC8qKlxuICAgICAqIE9wZXJhdGlvbnMgdGFpbFxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICovXG4gICAgdGhpcy50YWlsID0gdGhpcy5oZWFkO1xuXG4gICAgLyoqXG4gICAgICogTGlua2VkIGZvcmtlZCBzdGF0ZXMuXG4gICAgICogQHR5cGUge09iamVjdHxudWxsfVxuICAgICAqL1xuICAgIHRoaXMuc3RhdGVzID0gbnVsbDtcblxuICAgIC8vIFdoZW4gYSB2YWx1ZSBpcyB3cml0dGVuLCB0aGUgd3JpdGVyIGNhbGN1bGF0ZXMgaXRzIGJ5dGUgbGVuZ3RoIGFuZCBwdXRzIGl0IGludG8gYSBsaW5rZWRcbiAgICAvLyBsaXN0IG9mIG9wZXJhdGlvbnMgdG8gcGVyZm9ybSB3aGVuIGZpbmlzaCgpIGlzIGNhbGxlZC4gVGhpcyBib3RoIGFsbG93cyB1cyB0byBhbGxvY2F0ZVxuICAgIC8vIGJ1ZmZlcnMgb2YgdGhlIGV4YWN0IHJlcXVpcmVkIHNpemUgYW5kIHJlZHVjZXMgdGhlIGFtb3VudCBvZiB3b3JrIHdlIGhhdmUgdG8gZG8gY29tcGFyZWRcbiAgICAvLyB0byBmaXJzdCBjYWxjdWxhdGluZyBvdmVyIG9iamVjdHMgYW5kIHRoZW4gZW5jb2Rpbmcgb3ZlciBvYmplY3RzLiBJbiBvdXIgY2FzZSwgdGhlIGVuY29kaW5nXG4gICAgLy8gcGFydCBpcyBqdXN0IGEgbGlua2VkIGxpc3Qgd2FsayBjYWxsaW5nIG9wZXJhdGlvbnMgd2l0aCBhbHJlYWR5IHByZXBhcmVkIHZhbHVlcy5cbn1cblxudmFyIGNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICByZXR1cm4gdXRpbC5CdWZmZXJcbiAgICAgICAgPyBmdW5jdGlvbiBjcmVhdGVfYnVmZmVyX3NldHVwKCkge1xuICAgICAgICAgICAgcmV0dXJuIChXcml0ZXIuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlX2J1ZmZlcigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcldyaXRlcigpO1xuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgfVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICA6IGZ1bmN0aW9uIGNyZWF0ZV9hcnJheSgpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgV3JpdGVyKCk7XG4gICAgICAgIH07XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgd3JpdGVyLlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7QnVmZmVyV3JpdGVyfFdyaXRlcn0gQSB7QGxpbmsgQnVmZmVyV3JpdGVyfSB3aGVuIEJ1ZmZlcnMgYXJlIHN1cHBvcnRlZCwgb3RoZXJ3aXNlIGEge0BsaW5rIFdyaXRlcn1cbiAqL1xuV3JpdGVyLmNyZWF0ZSA9IGNyZWF0ZSgpO1xuXG4vKipcbiAqIEFsbG9jYXRlcyBhIGJ1ZmZlciBvZiB0aGUgc3BlY2lmaWVkIHNpemUuXG4gKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBCdWZmZXIgc2l6ZVxuICogQHJldHVybnMge1VpbnQ4QXJyYXl9IEJ1ZmZlclxuICovXG5Xcml0ZXIuYWxsb2MgPSBmdW5jdGlvbiBhbGxvYyhzaXplKSB7XG4gICAgcmV0dXJuIG5ldyB1dGlsLkFycmF5KHNpemUpO1xufTtcblxuLy8gVXNlIFVpbnQ4QXJyYXkgYnVmZmVyIHBvb2wgaW4gdGhlIGJyb3dzZXIsIGp1c3QgbGlrZSBub2RlIGRvZXMgd2l0aCBidWZmZXJzXG4vKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuaWYgKHV0aWwuQXJyYXkgIT09IEFycmF5KVxuICAgIFdyaXRlci5hbGxvYyA9IHV0aWwucG9vbChXcml0ZXIuYWxsb2MsIHV0aWwuQXJyYXkucHJvdG90eXBlLnN1YmFycmF5KTtcblxuLyoqXG4gKiBQdXNoZXMgYSBuZXcgb3BlcmF0aW9uIHRvIHRoZSBxdWV1ZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oVWludDhBcnJheSwgbnVtYmVyLCAqKX0gZm4gRnVuY3Rpb24gdG8gY2FsbFxuICogQHBhcmFtIHtudW1iZXJ9IGxlbiBWYWx1ZSBieXRlIGxlbmd0aFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKiBAcHJpdmF0ZVxuICovXG5Xcml0ZXIucHJvdG90eXBlLl9wdXNoID0gZnVuY3Rpb24gcHVzaChmbiwgbGVuLCB2YWwpIHtcbiAgICB0aGlzLnRhaWwgPSB0aGlzLnRhaWwubmV4dCA9IG5ldyBPcChmbiwgbGVuLCB2YWwpO1xuICAgIHRoaXMubGVuICs9IGxlbjtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHdyaXRlQnl0ZSh2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgYnVmW3Bvc10gPSB2YWwgJiAyNTU7XG59XG5cbmZ1bmN0aW9uIHdyaXRlVmFyaW50MzIodmFsLCBidWYsIHBvcykge1xuICAgIHdoaWxlICh2YWwgPiAxMjcpIHtcbiAgICAgICAgYnVmW3BvcysrXSA9IHZhbCAmIDEyNyB8IDEyODtcbiAgICAgICAgdmFsID4+Pj0gNztcbiAgICB9XG4gICAgYnVmW3Bvc10gPSB2YWw7XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyB2YXJpbnQgd3JpdGVyIG9wZXJhdGlvbiBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgU2NoZWR1bGVkIHZhcmludCB3cml0ZXIgb3BlcmF0aW9uLlxuICogQGV4dGVuZHMgT3BcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtudW1iZXJ9IGxlbiBWYWx1ZSBieXRlIGxlbmd0aFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxuICogQGlnbm9yZVxuICovXG5mdW5jdGlvbiBWYXJpbnRPcChsZW4sIHZhbCkge1xuICAgIHRoaXMubGVuID0gbGVuO1xuICAgIHRoaXMubmV4dCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnZhbCA9IHZhbDtcbn1cblxuVmFyaW50T3AucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShPcC5wcm90b3R5cGUpO1xuVmFyaW50T3AucHJvdG90eXBlLmZuID0gd3JpdGVWYXJpbnQzMjtcblxuLyoqXG4gKiBXcml0ZXMgYW4gdW5zaWduZWQgMzIgYml0IHZhbHVlIGFzIGEgdmFyaW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS51aW50MzIgPSBmdW5jdGlvbiB3cml0ZV91aW50MzIodmFsdWUpIHtcbiAgICAvLyBoZXJlLCB0aGUgY2FsbCB0byB0aGlzLnB1c2ggaGFzIGJlZW4gaW5saW5lZCBhbmQgYSB2YXJpbnQgc3BlY2lmaWMgT3Agc3ViY2xhc3MgaXMgdXNlZC5cbiAgICAvLyB1aW50MzIgaXMgYnkgZmFyIHRoZSBtb3N0IGZyZXF1ZW50bHkgdXNlZCBvcGVyYXRpb24gYW5kIGJlbmVmaXRzIHNpZ25pZmljYW50bHkgZnJvbSB0aGlzLlxuICAgIHRoaXMubGVuICs9ICh0aGlzLnRhaWwgPSB0aGlzLnRhaWwubmV4dCA9IG5ldyBWYXJpbnRPcChcbiAgICAgICAgKHZhbHVlID0gdmFsdWUgPj4+IDApXG4gICAgICAgICAgICAgICAgPCAxMjggICAgICAgPyAxXG4gICAgICAgIDogdmFsdWUgPCAxNjM4NCAgICAgPyAyXG4gICAgICAgIDogdmFsdWUgPCAyMDk3MTUyICAgPyAzXG4gICAgICAgIDogdmFsdWUgPCAyNjg0MzU0NTYgPyA0XG4gICAgICAgIDogICAgICAgICAgICAgICAgICAgICA1LFxuICAgIHZhbHVlKSkubGVuO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzaWduZWQgMzIgYml0IHZhbHVlIGFzIGEgdmFyaW50LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmludDMyID0gZnVuY3Rpb24gd3JpdGVfaW50MzIodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPCAwXG4gICAgICAgID8gdGhpcy5fcHVzaCh3cml0ZVZhcmludDY0LCAxMCwgTG9uZ0JpdHMuZnJvbU51bWJlcih2YWx1ZSkpIC8vIDEwIGJ5dGVzIHBlciBzcGVjXG4gICAgICAgIDogdGhpcy51aW50MzIodmFsdWUpO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSAzMiBiaXQgdmFsdWUgYXMgYSB2YXJpbnQsIHppZy16YWcgZW5jb2RlZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuc2ludDMyID0gZnVuY3Rpb24gd3JpdGVfc2ludDMyKHZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMudWludDMyKCh2YWx1ZSA8PCAxIF4gdmFsdWUgPj4gMzEpID4+PiAwKTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlVmFyaW50NjQodmFsLCBidWYsIHBvcykge1xuICAgIHdoaWxlICh2YWwuaGkpIHtcbiAgICAgICAgYnVmW3BvcysrXSA9IHZhbC5sbyAmIDEyNyB8IDEyODtcbiAgICAgICAgdmFsLmxvID0gKHZhbC5sbyA+Pj4gNyB8IHZhbC5oaSA8PCAyNSkgPj4+IDA7XG4gICAgICAgIHZhbC5oaSA+Pj49IDc7XG4gICAgfVxuICAgIHdoaWxlICh2YWwubG8gPiAxMjcpIHtcbiAgICAgICAgYnVmW3BvcysrXSA9IHZhbC5sbyAmIDEyNyB8IDEyODtcbiAgICAgICAgdmFsLmxvID0gdmFsLmxvID4+PiA3O1xuICAgIH1cbiAgICBidWZbcG9zKytdID0gdmFsLmxvO1xufVxuXG4vKipcbiAqIFdyaXRlcyBhbiB1bnNpZ25lZCA2NCBiaXQgdmFsdWUgYXMgYSB2YXJpbnQuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfHN0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgdmFsdWVgIGlzIGEgc3RyaW5nIGFuZCBubyBsb25nIGxpYnJhcnkgaXMgcHJlc2VudC5cbiAqL1xuV3JpdGVyLnByb3RvdHlwZS51aW50NjQgPSBmdW5jdGlvbiB3cml0ZV91aW50NjQodmFsdWUpIHtcbiAgICB2YXIgYml0cyA9IExvbmdCaXRzLmZyb20odmFsdWUpO1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHdyaXRlVmFyaW50NjQsIGJpdHMubGVuZ3RoKCksIGJpdHMpO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzaWduZWQgNjQgYml0IHZhbHVlIGFzIGEgdmFyaW50LlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfHN0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgdmFsdWVgIGlzIGEgc3RyaW5nIGFuZCBubyBsb25nIGxpYnJhcnkgaXMgcHJlc2VudC5cbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5pbnQ2NCA9IFdyaXRlci5wcm90b3R5cGUudWludDY0O1xuXG4vKipcbiAqIFdyaXRlcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUgYXMgYSB2YXJpbnQsIHppZy16YWcgZW5jb2RlZC5cbiAqIEBwYXJhbSB7TG9uZ3xudW1iZXJ8c3RyaW5nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGB2YWx1ZWAgaXMgYSBzdHJpbmcgYW5kIG5vIGxvbmcgbGlicmFyeSBpcyBwcmVzZW50LlxuICovXG5Xcml0ZXIucHJvdG90eXBlLnNpbnQ2NCA9IGZ1bmN0aW9uIHdyaXRlX3NpbnQ2NCh2YWx1ZSkge1xuICAgIHZhciBiaXRzID0gTG9uZ0JpdHMuZnJvbSh2YWx1ZSkuenpFbmNvZGUoKTtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZVZhcmludDY0LCBiaXRzLmxlbmd0aCgpLCBiaXRzKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgYm9vbGlzaCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmJvb2wgPSBmdW5jdGlvbiB3cml0ZV9ib29sKHZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMuX3B1c2god3JpdGVCeXRlLCAxLCB2YWx1ZSA/IDEgOiAwKTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlRml4ZWQzMih2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgYnVmW3BvcyAgICBdID0gIHZhbCAgICAgICAgICYgMjU1O1xuICAgIGJ1Zltwb3MgKyAxXSA9ICB2YWwgPj4+IDggICAmIDI1NTtcbiAgICBidWZbcG9zICsgMl0gPSAgdmFsID4+PiAxNiAgJiAyNTU7XG4gICAgYnVmW3BvcyArIDNdID0gIHZhbCA+Pj4gMjQ7XG59XG5cbi8qKlxuICogV3JpdGVzIGFuIHVuc2lnbmVkIDMyIGJpdCB2YWx1ZSBhcyBmaXhlZCAzMiBiaXRzLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5maXhlZDMyID0gZnVuY3Rpb24gd3JpdGVfZml4ZWQzMih2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHdyaXRlRml4ZWQzMiwgNCwgdmFsdWUgPj4+IDApO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzaWduZWQgMzIgYml0IHZhbHVlIGFzIGZpeGVkIDMyIGJpdHMuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuc2ZpeGVkMzIgPSBXcml0ZXIucHJvdG90eXBlLmZpeGVkMzI7XG5cbi8qKlxuICogV3JpdGVzIGFuIHVuc2lnbmVkIDY0IGJpdCB2YWx1ZSBhcyBmaXhlZCA2NCBiaXRzLlxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZml4ZWQ2NCA9IGZ1bmN0aW9uIHdyaXRlX2ZpeGVkNjQodmFsdWUpIHtcbiAgICB2YXIgYml0cyA9IExvbmdCaXRzLmZyb20odmFsdWUpO1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHdyaXRlRml4ZWQzMiwgNCwgYml0cy5sbykuX3B1c2god3JpdGVGaXhlZDMyLCA0LCBiaXRzLmhpKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDY0IGJpdCB2YWx1ZSBhcyBmaXhlZCA2NCBiaXRzLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfHN0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgdmFsdWVgIGlzIGEgc3RyaW5nIGFuZCBubyBsb25nIGxpYnJhcnkgaXMgcHJlc2VudC5cbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5zZml4ZWQ2NCA9IFdyaXRlci5wcm90b3R5cGUuZml4ZWQ2NDtcblxuLyoqXG4gKiBXcml0ZXMgYSBmbG9hdCAoMzIgYml0KS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5mbG9hdCA9IGZ1bmN0aW9uIHdyaXRlX2Zsb2F0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMuX3B1c2godXRpbC5mbG9hdC53cml0ZUZsb2F0TEUsIDQsIHZhbHVlKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgZG91YmxlICg2NCBiaXQgZmxvYXQpLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmRvdWJsZSA9IGZ1bmN0aW9uIHdyaXRlX2RvdWJsZSh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHV0aWwuZmxvYXQud3JpdGVEb3VibGVMRSwgOCwgdmFsdWUpO1xufTtcblxudmFyIHdyaXRlQnl0ZXMgPSB1dGlsLkFycmF5LnByb3RvdHlwZS5zZXRcbiAgICA/IGZ1bmN0aW9uIHdyaXRlQnl0ZXNfc2V0KHZhbCwgYnVmLCBwb3MpIHtcbiAgICAgICAgYnVmLnNldCh2YWwsIHBvcyk7IC8vIGFsc28gd29ya3MgZm9yIHBsYWluIGFycmF5IHZhbHVlc1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIDogZnVuY3Rpb24gd3JpdGVCeXRlc19mb3IodmFsLCBidWYsIHBvcykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgIGJ1Zltwb3MgKyBpXSA9IHZhbFtpXTtcbiAgICB9O1xuXG4vKipcbiAqIFdyaXRlcyBhIHNlcXVlbmNlIG9mIGJ5dGVzLlxuICogQHBhcmFtIHtVaW50OEFycmF5fHN0cmluZ30gdmFsdWUgQnVmZmVyIG9yIGJhc2U2NCBlbmNvZGVkIHN0cmluZyB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuYnl0ZXMgPSBmdW5jdGlvbiB3cml0ZV9ieXRlcyh2YWx1ZSkge1xuICAgIHZhciBsZW4gPSB2YWx1ZS5sZW5ndGggPj4+IDA7XG4gICAgaWYgKCFsZW4pXG4gICAgICAgIHJldHVybiB0aGlzLl9wdXNoKHdyaXRlQnl0ZSwgMSwgMCk7XG4gICAgaWYgKHV0aWwuaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICAgIHZhciBidWYgPSBXcml0ZXIuYWxsb2MobGVuID0gYmFzZTY0Lmxlbmd0aCh2YWx1ZSkpO1xuICAgICAgICBiYXNlNjQuZGVjb2RlKHZhbHVlLCBidWYsIDApO1xuICAgICAgICB2YWx1ZSA9IGJ1ZjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudWludDMyKGxlbikuX3B1c2god3JpdGVCeXRlcywgbGVuLCB2YWx1ZSk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHN0cmluZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuc3RyaW5nID0gZnVuY3Rpb24gd3JpdGVfc3RyaW5nKHZhbHVlKSB7XG4gICAgdmFyIGxlbiA9IHV0ZjgubGVuZ3RoKHZhbHVlKTtcbiAgICByZXR1cm4gbGVuXG4gICAgICAgID8gdGhpcy51aW50MzIobGVuKS5fcHVzaCh1dGY4LndyaXRlLCBsZW4sIHZhbHVlKVxuICAgICAgICA6IHRoaXMuX3B1c2god3JpdGVCeXRlLCAxLCAwKTtcbn07XG5cbi8qKlxuICogRm9ya3MgdGhpcyB3cml0ZXIncyBzdGF0ZSBieSBwdXNoaW5nIGl0IHRvIGEgc3RhY2suXG4gKiBDYWxsaW5nIHtAbGluayBXcml0ZXIjcmVzZXR8cmVzZXR9IG9yIHtAbGluayBXcml0ZXIjbGRlbGltfGxkZWxpbX0gcmVzZXRzIHRoZSB3cml0ZXIgdG8gdGhlIHByZXZpb3VzIHN0YXRlLlxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZm9yayA9IGZ1bmN0aW9uIGZvcmsoKSB7XG4gICAgdGhpcy5zdGF0ZXMgPSBuZXcgU3RhdGUodGhpcyk7XG4gICAgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbmV3IE9wKG5vb3AsIDAsIDApO1xuICAgIHRoaXMubGVuID0gMDtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVzZXRzIHRoaXMgaW5zdGFuY2UgdG8gdGhlIGxhc3Qgc3RhdGUuXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgIGlmICh0aGlzLnN0YXRlcykge1xuICAgICAgICB0aGlzLmhlYWQgICA9IHRoaXMuc3RhdGVzLmhlYWQ7XG4gICAgICAgIHRoaXMudGFpbCAgID0gdGhpcy5zdGF0ZXMudGFpbDtcbiAgICAgICAgdGhpcy5sZW4gICAgPSB0aGlzLnN0YXRlcy5sZW47XG4gICAgICAgIHRoaXMuc3RhdGVzID0gdGhpcy5zdGF0ZXMubmV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBuZXcgT3Aobm9vcCwgMCwgMCk7XG4gICAgICAgIHRoaXMubGVuICA9IDA7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXNldHMgdG8gdGhlIGxhc3Qgc3RhdGUgYW5kIGFwcGVuZHMgdGhlIGZvcmsgc3RhdGUncyBjdXJyZW50IHdyaXRlIGxlbmd0aCBhcyBhIHZhcmludCBmb2xsb3dlZCBieSBpdHMgb3BlcmF0aW9ucy5cbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmxkZWxpbSA9IGZ1bmN0aW9uIGxkZWxpbSgpIHtcbiAgICB2YXIgaGVhZCA9IHRoaXMuaGVhZCxcbiAgICAgICAgdGFpbCA9IHRoaXMudGFpbCxcbiAgICAgICAgbGVuICA9IHRoaXMubGVuO1xuICAgIHRoaXMucmVzZXQoKS51aW50MzIobGVuKTtcbiAgICBpZiAobGVuKSB7XG4gICAgICAgIHRoaXMudGFpbC5uZXh0ID0gaGVhZC5uZXh0OyAvLyBza2lwIG5vb3BcbiAgICAgICAgdGhpcy50YWlsID0gdGFpbDtcbiAgICAgICAgdGhpcy5sZW4gKz0gbGVuO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRmluaXNoZXMgdGhlIHdyaXRlIG9wZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBGaW5pc2hlZCBidWZmZXJcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbiBmaW5pc2goKSB7XG4gICAgdmFyIGhlYWQgPSB0aGlzLmhlYWQubmV4dCwgLy8gc2tpcCBub29wXG4gICAgICAgIGJ1ZiAgPSB0aGlzLmNvbnN0cnVjdG9yLmFsbG9jKHRoaXMubGVuKSxcbiAgICAgICAgcG9zICA9IDA7XG4gICAgd2hpbGUgKGhlYWQpIHtcbiAgICAgICAgaGVhZC5mbihoZWFkLnZhbCwgYnVmLCBwb3MpO1xuICAgICAgICBwb3MgKz0gaGVhZC5sZW47XG4gICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgfVxuICAgIC8vIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7XG4gICAgcmV0dXJuIGJ1Zjtcbn07XG5cbldyaXRlci5fY29uZmlndXJlID0gZnVuY3Rpb24oQnVmZmVyV3JpdGVyXykge1xuICAgIEJ1ZmZlcldyaXRlciA9IEJ1ZmZlcldyaXRlcl87XG4gICAgV3JpdGVyLmNyZWF0ZSA9IGNyZWF0ZSgpO1xuICAgIEJ1ZmZlcldyaXRlci5fY29uZmlndXJlKCk7XG59O1xuIiwgIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBCdWZmZXJXcml0ZXI7XG5cbi8vIGV4dGVuZHMgV3JpdGVyXG52YXIgV3JpdGVyID0gcmVxdWlyZShcIi4vd3JpdGVyXCIpO1xuKEJ1ZmZlcldyaXRlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFdyaXRlci5wcm90b3R5cGUpKS5jb25zdHJ1Y3RvciA9IEJ1ZmZlcldyaXRlcjtcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiLi91dGlsL21pbmltYWxcIik7XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyBidWZmZXIgd3JpdGVyIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBXaXJlIGZvcm1hdCB3cml0ZXIgdXNpbmcgbm9kZSBidWZmZXJzLlxuICogQGV4dGVuZHMgV3JpdGVyXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gQnVmZmVyV3JpdGVyKCkge1xuICAgIFdyaXRlci5jYWxsKHRoaXMpO1xufVxuXG5CdWZmZXJXcml0ZXIuX2NvbmZpZ3VyZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBBbGxvY2F0ZXMgYSBidWZmZXIgb2YgdGhlIHNwZWNpZmllZCBzaXplLlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIEJ1ZmZlciBzaXplXG4gICAgICogQHJldHVybnMge0J1ZmZlcn0gQnVmZmVyXG4gICAgICovXG4gICAgQnVmZmVyV3JpdGVyLmFsbG9jID0gdXRpbC5fQnVmZmVyX2FsbG9jVW5zYWZlO1xuXG4gICAgQnVmZmVyV3JpdGVyLndyaXRlQnl0ZXNCdWZmZXIgPSB1dGlsLkJ1ZmZlciAmJiB1dGlsLkJ1ZmZlci5wcm90b3R5cGUgaW5zdGFuY2VvZiBVaW50OEFycmF5ICYmIHV0aWwuQnVmZmVyLnByb3RvdHlwZS5zZXQubmFtZSA9PT0gXCJzZXRcIlxuICAgICAgICA/IGZ1bmN0aW9uIHdyaXRlQnl0ZXNCdWZmZXJfc2V0KHZhbCwgYnVmLCBwb3MpIHtcbiAgICAgICAgICBidWYuc2V0KHZhbCwgcG9zKTsgLy8gZmFzdGVyIHRoYW4gY29weSAocmVxdWlyZXMgbm9kZSA+PSA0IHdoZXJlIEJ1ZmZlcnMgZXh0ZW5kIFVpbnQ4QXJyYXkgYW5kIHNldCBpcyBwcm9wZXJseSBpbmhlcml0ZWQpXG4gICAgICAgICAgLy8gYWxzbyB3b3JrcyBmb3IgcGxhaW4gYXJyYXkgdmFsdWVzXG4gICAgICAgIH1cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgOiBmdW5jdGlvbiB3cml0ZUJ5dGVzQnVmZmVyX2NvcHkodmFsLCBidWYsIHBvcykge1xuICAgICAgICAgIGlmICh2YWwuY29weSkgLy8gQnVmZmVyIHZhbHVlc1xuICAgICAgICAgICAgdmFsLmNvcHkoYnVmLCBwb3MsIDAsIHZhbC5sZW5ndGgpO1xuICAgICAgICAgIGVsc2UgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWwubGVuZ3RoOykgLy8gcGxhaW4gYXJyYXkgdmFsdWVzXG4gICAgICAgICAgICBidWZbcG9zKytdID0gdmFsW2krK107XG4gICAgICAgIH07XG59O1xuXG5cbi8qKlxuICogQG92ZXJyaWRlXG4gKi9cbkJ1ZmZlcldyaXRlci5wcm90b3R5cGUuYnl0ZXMgPSBmdW5jdGlvbiB3cml0ZV9ieXRlc19idWZmZXIodmFsdWUpIHtcbiAgICBpZiAodXRpbC5pc1N0cmluZyh2YWx1ZSkpXG4gICAgICAgIHZhbHVlID0gdXRpbC5fQnVmZmVyX2Zyb20odmFsdWUsIFwiYmFzZTY0XCIpO1xuICAgIHZhciBsZW4gPSB2YWx1ZS5sZW5ndGggPj4+IDA7XG4gICAgdGhpcy51aW50MzIobGVuKTtcbiAgICBpZiAobGVuKVxuICAgICAgICB0aGlzLl9wdXNoKEJ1ZmZlcldyaXRlci53cml0ZUJ5dGVzQnVmZmVyLCBsZW4sIHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHdyaXRlU3RyaW5nQnVmZmVyKHZhbCwgYnVmLCBwb3MpIHtcbiAgICBpZiAodmFsLmxlbmd0aCA8IDQwKSAvLyBwbGFpbiBqcyBpcyBmYXN0ZXIgZm9yIHNob3J0IHN0cmluZ3MgKHByb2JhYmx5IGR1ZSB0byByZWR1bmRhbnQgYXNzZXJ0aW9ucylcbiAgICAgICAgdXRpbC51dGY4LndyaXRlKHZhbCwgYnVmLCBwb3MpO1xuICAgIGVsc2UgaWYgKGJ1Zi51dGY4V3JpdGUpXG4gICAgICAgIGJ1Zi51dGY4V3JpdGUodmFsLCBwb3MpO1xuICAgIGVsc2VcbiAgICAgICAgYnVmLndyaXRlKHZhbCwgcG9zKTtcbn1cblxuLyoqXG4gKiBAb3ZlcnJpZGVcbiAqL1xuQnVmZmVyV3JpdGVyLnByb3RvdHlwZS5zdHJpbmcgPSBmdW5jdGlvbiB3cml0ZV9zdHJpbmdfYnVmZmVyKHZhbHVlKSB7XG4gICAgdmFyIGxlbiA9IHV0aWwuQnVmZmVyLmJ5dGVMZW5ndGgodmFsdWUpO1xuICAgIHRoaXMudWludDMyKGxlbik7XG4gICAgaWYgKGxlbilcbiAgICAgICAgdGhpcy5fcHVzaCh3cml0ZVN0cmluZ0J1ZmZlciwgbGVuLCB2YWx1ZSk7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5cbi8qKlxuICogRmluaXNoZXMgdGhlIHdyaXRlIG9wZXJhdGlvbi5cbiAqIEBuYW1lIEJ1ZmZlcldyaXRlciNmaW5pc2hcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0J1ZmZlcn0gRmluaXNoZWQgYnVmZmVyXG4gKi9cblxuQnVmZmVyV3JpdGVyLl9jb25maWd1cmUoKTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gUmVhZGVyO1xuXG52YXIgdXRpbCAgICAgID0gcmVxdWlyZShcIi4vdXRpbC9taW5pbWFsXCIpO1xuXG52YXIgQnVmZmVyUmVhZGVyOyAvLyBjeWNsaWNcblxudmFyIExvbmdCaXRzICA9IHV0aWwuTG9uZ0JpdHMsXG4gICAgdXRmOCAgICAgID0gdXRpbC51dGY4O1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gaW5kZXhPdXRPZlJhbmdlKHJlYWRlciwgd3JpdGVMZW5ndGgpIHtcbiAgICByZXR1cm4gUmFuZ2VFcnJvcihcImluZGV4IG91dCBvZiByYW5nZTogXCIgKyByZWFkZXIucG9zICsgXCIgKyBcIiArICh3cml0ZUxlbmd0aCB8fCAxKSArIFwiID4gXCIgKyByZWFkZXIubGVuKTtcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IHJlYWRlciBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIGJ1ZmZlci5cbiAqIEBjbGFzc2Rlc2MgV2lyZSBmb3JtYXQgcmVhZGVyIHVzaW5nIGBVaW50OEFycmF5YCBpZiBhdmFpbGFibGUsIG90aGVyd2lzZSBgQXJyYXlgLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZmZlciBCdWZmZXIgdG8gcmVhZCBmcm9tXG4gKi9cbmZ1bmN0aW9uIFJlYWRlcihidWZmZXIpIHtcblxuICAgIC8qKlxuICAgICAqIFJlYWQgYnVmZmVyLlxuICAgICAqIEB0eXBlIHtVaW50OEFycmF5fVxuICAgICAqL1xuICAgIHRoaXMuYnVmID0gYnVmZmVyO1xuXG4gICAgLyoqXG4gICAgICogUmVhZCBidWZmZXIgcG9zaXRpb24uXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLnBvcyA9IDA7XG5cbiAgICAvKipcbiAgICAgKiBSZWFkIGJ1ZmZlciBsZW5ndGguXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmxlbiA9IGJ1ZmZlci5sZW5ndGg7XG59XG5cbnZhciBjcmVhdGVfYXJyYXkgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gXCJ1bmRlZmluZWRcIlxuICAgID8gZnVuY3Rpb24gY3JlYXRlX3R5cGVkX2FycmF5KGJ1ZmZlcikge1xuICAgICAgICBpZiAoYnVmZmVyIGluc3RhbmNlb2YgVWludDhBcnJheSB8fCBBcnJheS5pc0FycmF5KGJ1ZmZlcikpXG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlYWRlcihidWZmZXIpO1xuICAgICAgICB0aHJvdyBFcnJvcihcImlsbGVnYWwgYnVmZmVyXCIpO1xuICAgIH1cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIDogZnVuY3Rpb24gY3JlYXRlX2FycmF5KGJ1ZmZlcikge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShidWZmZXIpKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWFkZXIoYnVmZmVyKTtcbiAgICAgICAgdGhyb3cgRXJyb3IoXCJpbGxlZ2FsIGJ1ZmZlclwiKTtcbiAgICB9O1xuXG52YXIgY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgIHJldHVybiB1dGlsLkJ1ZmZlclxuICAgICAgICA/IGZ1bmN0aW9uIGNyZWF0ZV9idWZmZXJfc2V0dXAoYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gKFJlYWRlci5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGVfYnVmZmVyKGJ1ZmZlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiB1dGlsLkJ1ZmZlci5pc0J1ZmZlcihidWZmZXIpXG4gICAgICAgICAgICAgICAgICAgID8gbmV3IEJ1ZmZlclJlYWRlcihidWZmZXIpXG4gICAgICAgICAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgICAgICAgICAgIDogY3JlYXRlX2FycmF5KGJ1ZmZlcik7XG4gICAgICAgICAgICB9KShidWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIDogY3JlYXRlX2FycmF5O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHJlYWRlciB1c2luZyB0aGUgc3BlY2lmaWVkIGJ1ZmZlci5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtVaW50OEFycmF5fEJ1ZmZlcn0gYnVmZmVyIEJ1ZmZlciB0byByZWFkIGZyb21cbiAqIEByZXR1cm5zIHtSZWFkZXJ8QnVmZmVyUmVhZGVyfSBBIHtAbGluayBCdWZmZXJSZWFkZXJ9IGlmIGBidWZmZXJgIGlzIGEgQnVmZmVyLCBvdGhlcndpc2UgYSB7QGxpbmsgUmVhZGVyfVxuICogQHRocm93cyB7RXJyb3J9IElmIGBidWZmZXJgIGlzIG5vdCBhIHZhbGlkIGJ1ZmZlclxuICovXG5SZWFkZXIuY3JlYXRlID0gY3JlYXRlKCk7XG5cblJlYWRlci5wcm90b3R5cGUuX3NsaWNlID0gdXRpbC5BcnJheS5wcm90b3R5cGUuc3ViYXJyYXkgfHwgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gdXRpbC5BcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbi8qKlxuICogUmVhZHMgYSB2YXJpbnQgYXMgYW4gdW5zaWduZWQgMzIgYml0IHZhbHVlLlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUudWludDMyID0gKGZ1bmN0aW9uIHJlYWRfdWludDMyX3NldHVwKCkge1xuICAgIHZhciB2YWx1ZSA9IDQyOTQ5NjcyOTU7IC8vIG9wdGltaXplciB0eXBlLWhpbnQsIHRlbmRzIHRvIGRlb3B0IG90aGVyd2lzZSAoPyEpXG4gICAgcmV0dXJuIGZ1bmN0aW9uIHJlYWRfdWludDMyKCkge1xuICAgICAgICB2YWx1ZSA9ICggICAgICAgICB0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcgICAgICAgKSA+Pj4gMDsgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KSByZXR1cm4gdmFsdWU7XG4gICAgICAgIHZhbHVlID0gKHZhbHVlIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgIDcpID4+PiAwOyBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpIHJldHVybiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSAodmFsdWUgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCAxNCkgPj4+IDA7IGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOCkgcmV0dXJuIHZhbHVlO1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IDIxKSA+Pj4gMDsgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KSByZXR1cm4gdmFsdWU7XG4gICAgICAgIHZhbHVlID0gKHZhbHVlIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmICAxNSkgPDwgMjgpID4+PiAwOyBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpIHJldHVybiB2YWx1ZTtcblxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgaWYgKCh0aGlzLnBvcyArPSA1KSA+IHRoaXMubGVuKSB7XG4gICAgICAgICAgICB0aGlzLnBvcyA9IHRoaXMubGVuO1xuICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMsIDEwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfTtcbn0pKCk7XG5cbi8qKlxuICogUmVhZHMgYSB2YXJpbnQgYXMgYSBzaWduZWQgMzIgYml0IHZhbHVlLlxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLmludDMyID0gZnVuY3Rpb24gcmVhZF9pbnQzMigpIHtcbiAgICByZXR1cm4gdGhpcy51aW50MzIoKSB8IDA7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgemlnLXphZyBlbmNvZGVkIHZhcmludCBhcyBhIHNpZ25lZCAzMiBiaXQgdmFsdWUuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuc2ludDMyID0gZnVuY3Rpb24gcmVhZF9zaW50MzIoKSB7XG4gICAgdmFyIHZhbHVlID0gdGhpcy51aW50MzIoKTtcbiAgICByZXR1cm4gdmFsdWUgPj4+IDEgXiAtKHZhbHVlICYgMSkgfCAwO1xufTtcblxuLyogZXNsaW50LWRpc2FibGUgbm8taW52YWxpZC10aGlzICovXG5cbmZ1bmN0aW9uIHJlYWRMb25nVmFyaW50KCkge1xuICAgIC8vIHRlbmRzIHRvIGRlb3B0IHdpdGggbG9jYWwgdmFycyBmb3Igb2N0ZXQgZXRjLlxuICAgIHZhciBiaXRzID0gbmV3IExvbmdCaXRzKDAsIDApO1xuICAgIHZhciBpID0gMDtcbiAgICBpZiAodGhpcy5sZW4gLSB0aGlzLnBvcyA+IDQpIHsgLy8gZmFzdCByb3V0ZSAobG8pXG4gICAgICAgIGZvciAoOyBpIDwgNDsgKytpKSB7XG4gICAgICAgICAgICAvLyAxc3QuLjR0aFxuICAgICAgICAgICAgYml0cy5sbyA9IChiaXRzLmxvIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgaSAqIDcpID4+PiAwO1xuICAgICAgICAgICAgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KVxuICAgICAgICAgICAgICAgIHJldHVybiBiaXRzO1xuICAgICAgICB9XG4gICAgICAgIC8vIDV0aFxuICAgICAgICBiaXRzLmxvID0gKGJpdHMubG8gfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCAyOCkgPj4+IDA7XG4gICAgICAgIGJpdHMuaGkgPSAoYml0cy5oaSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpID4+ICA0KSA+Pj4gMDtcbiAgICAgICAgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KVxuICAgICAgICAgICAgcmV0dXJuIGJpdHM7XG4gICAgICAgIGkgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoOyBpIDwgMzsgKytpKSB7XG4gICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLnBvcyA+PSB0aGlzLmxlbilcbiAgICAgICAgICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcyk7XG4gICAgICAgICAgICAvLyAxc3QuLjN0aFxuICAgICAgICAgICAgYml0cy5sbyA9IChiaXRzLmxvIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgaSAqIDcpID4+PiAwO1xuICAgICAgICAgICAgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KVxuICAgICAgICAgICAgICAgIHJldHVybiBiaXRzO1xuICAgICAgICB9XG4gICAgICAgIC8vIDR0aFxuICAgICAgICBiaXRzLmxvID0gKGJpdHMubG8gfCAodGhpcy5idWZbdGhpcy5wb3MrK10gJiAxMjcpIDw8IGkgKiA3KSA+Pj4gMDtcbiAgICAgICAgcmV0dXJuIGJpdHM7XG4gICAgfVxuICAgIGlmICh0aGlzLmxlbiAtIHRoaXMucG9zID4gNCkgeyAvLyBmYXN0IHJvdXRlIChoaSlcbiAgICAgICAgZm9yICg7IGkgPCA1OyArK2kpIHtcbiAgICAgICAgICAgIC8vIDZ0aC4uMTB0aFxuICAgICAgICAgICAgYml0cy5oaSA9IChiaXRzLmhpIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgaSAqIDcgKyAzKSA+Pj4gMDtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgICAgICByZXR1cm4gYml0cztcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoOyBpIDwgNTsgKytpKSB7XG4gICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLnBvcyA+PSB0aGlzLmxlbilcbiAgICAgICAgICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcyk7XG4gICAgICAgICAgICAvLyA2dGguLjEwdGhcbiAgICAgICAgICAgIGJpdHMuaGkgPSAoYml0cy5oaSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IGkgKiA3ICsgMykgPj4+IDA7XG4gICAgICAgICAgICBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpdHM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICB0aHJvdyBFcnJvcihcImludmFsaWQgdmFyaW50IGVuY29kaW5nXCIpO1xufVxuXG4vKiBlc2xpbnQtZW5hYmxlIG5vLWludmFsaWQtdGhpcyAqL1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGEgc2lnbmVkIDY0IGJpdCB2YWx1ZS5cbiAqIEBuYW1lIFJlYWRlciNpbnQ2NFxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7TG9uZ30gVmFsdWUgcmVhZFxuICovXG5cbi8qKlxuICogUmVhZHMgYSB2YXJpbnQgYXMgYW4gdW5zaWduZWQgNjQgYml0IHZhbHVlLlxuICogQG5hbWUgUmVhZGVyI3VpbnQ2NFxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7TG9uZ30gVmFsdWUgcmVhZFxuICovXG5cbi8qKlxuICogUmVhZHMgYSB6aWctemFnIGVuY29kZWQgdmFyaW50IGFzIGEgc2lnbmVkIDY0IGJpdCB2YWx1ZS5cbiAqIEBuYW1lIFJlYWRlciNzaW50NjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGEgYm9vbGVhbi5cbiAqIEByZXR1cm5zIHtib29sZWFufSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuYm9vbCA9IGZ1bmN0aW9uIHJlYWRfYm9vbCgpIHtcbiAgICByZXR1cm4gdGhpcy51aW50MzIoKSAhPT0gMDtcbn07XG5cbmZ1bmN0aW9uIHJlYWRGaXhlZDMyX2VuZChidWYsIGVuZCkgeyAvLyBub3RlIHRoYXQgdGhpcyB1c2VzIGBlbmRgLCBub3QgYHBvc2BcbiAgICByZXR1cm4gKGJ1ZltlbmQgLSA0XVxuICAgICAgICAgIHwgYnVmW2VuZCAtIDNdIDw8IDhcbiAgICAgICAgICB8IGJ1ZltlbmQgLSAyXSA8PCAxNlxuICAgICAgICAgIHwgYnVmW2VuZCAtIDFdIDw8IDI0KSA+Pj4gMDtcbn1cblxuLyoqXG4gKiBSZWFkcyBmaXhlZCAzMiBiaXRzIGFzIGFuIHVuc2lnbmVkIDMyIGJpdCBpbnRlZ2VyLlxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLmZpeGVkMzIgPSBmdW5jdGlvbiByZWFkX2ZpeGVkMzIoKSB7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodGhpcy5wb3MgKyA0ID4gdGhpcy5sZW4pXG4gICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCA0KTtcblxuICAgIHJldHVybiByZWFkRml4ZWQzMl9lbmQodGhpcy5idWYsIHRoaXMucG9zICs9IDQpO1xufTtcblxuLyoqXG4gKiBSZWFkcyBmaXhlZCAzMiBiaXRzIGFzIGEgc2lnbmVkIDMyIGJpdCBpbnRlZ2VyLlxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLnNmaXhlZDMyID0gZnVuY3Rpb24gcmVhZF9zZml4ZWQzMigpIHtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICh0aGlzLnBvcyArIDQgPiB0aGlzLmxlbilcbiAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMsIDQpO1xuXG4gICAgcmV0dXJuIHJlYWRGaXhlZDMyX2VuZCh0aGlzLmJ1ZiwgdGhpcy5wb3MgKz0gNCkgfCAwO1xufTtcblxuLyogZXNsaW50LWRpc2FibGUgbm8taW52YWxpZC10aGlzICovXG5cbmZ1bmN0aW9uIHJlYWRGaXhlZDY0KC8qIHRoaXM6IFJlYWRlciAqLykge1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHRoaXMucG9zICsgOCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgOCk7XG5cbiAgICByZXR1cm4gbmV3IExvbmdCaXRzKHJlYWRGaXhlZDMyX2VuZCh0aGlzLmJ1ZiwgdGhpcy5wb3MgKz0gNCksIHJlYWRGaXhlZDMyX2VuZCh0aGlzLmJ1ZiwgdGhpcy5wb3MgKz0gNCkpO1xufVxuXG4vKiBlc2xpbnQtZW5hYmxlIG5vLWludmFsaWQtdGhpcyAqL1xuXG4vKipcbiAqIFJlYWRzIGZpeGVkIDY0IGJpdHMuXG4gKiBAbmFtZSBSZWFkZXIjZml4ZWQ2NFxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7TG9uZ30gVmFsdWUgcmVhZFxuICovXG5cbi8qKlxuICogUmVhZHMgemlnLXphZyBlbmNvZGVkIGZpeGVkIDY0IGJpdHMuXG4gKiBAbmFtZSBSZWFkZXIjc2ZpeGVkNjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIGEgZmxvYXQgKDMyIGJpdCkgYXMgYSBudW1iZXIuXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5mbG9hdCA9IGZ1bmN0aW9uIHJlYWRfZmxvYXQoKSB7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodGhpcy5wb3MgKyA0ID4gdGhpcy5sZW4pXG4gICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCA0KTtcblxuICAgIHZhciB2YWx1ZSA9IHV0aWwuZmxvYXQucmVhZEZsb2F0TEUodGhpcy5idWYsIHRoaXMucG9zKTtcbiAgICB0aGlzLnBvcyArPSA0O1xuICAgIHJldHVybiB2YWx1ZTtcbn07XG5cbi8qKlxuICogUmVhZHMgYSBkb3VibGUgKDY0IGJpdCBmbG9hdCkgYXMgYSBudW1iZXIuXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5kb3VibGUgPSBmdW5jdGlvbiByZWFkX2RvdWJsZSgpIHtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICh0aGlzLnBvcyArIDggPiB0aGlzLmxlbilcbiAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMsIDQpO1xuXG4gICAgdmFyIHZhbHVlID0gdXRpbC5mbG9hdC5yZWFkRG91YmxlTEUodGhpcy5idWYsIHRoaXMucG9zKTtcbiAgICB0aGlzLnBvcyArPSA4O1xuICAgIHJldHVybiB2YWx1ZTtcbn07XG5cbi8qKlxuICogUmVhZHMgYSBzZXF1ZW5jZSBvZiBieXRlcyBwcmVjZWVkZWQgYnkgaXRzIGxlbmd0aCBhcyBhIHZhcmludC5cbiAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuYnl0ZXMgPSBmdW5jdGlvbiByZWFkX2J5dGVzKCkge1xuICAgIHZhciBsZW5ndGggPSB0aGlzLnVpbnQzMigpLFxuICAgICAgICBzdGFydCAgPSB0aGlzLnBvcyxcbiAgICAgICAgZW5kICAgID0gdGhpcy5wb3MgKyBsZW5ndGg7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoZW5kID4gdGhpcy5sZW4pXG4gICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCBsZW5ndGgpO1xuXG4gICAgdGhpcy5wb3MgKz0gbGVuZ3RoO1xuICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMuYnVmKSkgLy8gcGxhaW4gYXJyYXlcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVmLnNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgaWYgKHN0YXJ0ID09PSBlbmQpIHsgLy8gZml4IGZvciBJRSAxMC9XaW44IGFuZCBvdGhlcnMnIHN1YmFycmF5IHJldHVybmluZyBhcnJheSBvZiBzaXplIDFcbiAgICAgICAgdmFyIG5hdGl2ZUJ1ZmZlciA9IHV0aWwuQnVmZmVyO1xuICAgICAgICByZXR1cm4gbmF0aXZlQnVmZmVyXG4gICAgICAgICAgICA/IG5hdGl2ZUJ1ZmZlci5hbGxvYygwKVxuICAgICAgICAgICAgOiBuZXcgdGhpcy5idWYuY29uc3RydWN0b3IoMCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9zbGljZS5jYWxsKHRoaXMuYnVmLCBzdGFydCwgZW5kKTtcbn07XG5cbi8qKlxuICogUmVhZHMgYSBzdHJpbmcgcHJlY2VlZGVkIGJ5IGl0cyBieXRlIGxlbmd0aCBhcyBhIHZhcmludC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5zdHJpbmcgPSBmdW5jdGlvbiByZWFkX3N0cmluZygpIHtcbiAgICB2YXIgYnl0ZXMgPSB0aGlzLmJ5dGVzKCk7XG4gICAgcmV0dXJuIHV0ZjgucmVhZChieXRlcywgMCwgYnl0ZXMubGVuZ3RoKTtcbn07XG5cbi8qKlxuICogU2tpcHMgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgYnl0ZXMgaWYgc3BlY2lmaWVkLCBvdGhlcndpc2Ugc2tpcHMgYSB2YXJpbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTGVuZ3RoIGlmIGtub3duLCBvdGhlcndpc2UgYSB2YXJpbnQgaXMgYXNzdW1lZFxuICogQHJldHVybnMge1JlYWRlcn0gYHRoaXNgXG4gKi9cblJlYWRlci5wcm90b3R5cGUuc2tpcCA9IGZ1bmN0aW9uIHNraXAobGVuZ3RoKSB7XG4gICAgaWYgKHR5cGVvZiBsZW5ndGggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgIGlmICh0aGlzLnBvcyArIGxlbmd0aCA+IHRoaXMubGVuKVxuICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIHRoaXMucG9zICs9IGxlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLnBvcyA+PSB0aGlzLmxlbilcbiAgICAgICAgICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcyk7XG4gICAgICAgIH0gd2hpbGUgKHRoaXMuYnVmW3RoaXMucG9zKytdICYgMTI4KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNraXBzIHRoZSBuZXh0IGVsZW1lbnQgb2YgdGhlIHNwZWNpZmllZCB3aXJlIHR5cGUuXG4gKiBAcGFyYW0ge251bWJlcn0gd2lyZVR5cGUgV2lyZSB0eXBlIHJlY2VpdmVkXG4gKiBAcmV0dXJucyB7UmVhZGVyfSBgdGhpc2BcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5za2lwVHlwZSA9IGZ1bmN0aW9uKHdpcmVUeXBlKSB7XG4gICAgc3dpdGNoICh3aXJlVHlwZSkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICB0aGlzLnNraXAoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICB0aGlzLnNraXAoOCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgdGhpcy5za2lwKHRoaXMudWludDMyKCkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgIHdoaWxlICgod2lyZVR5cGUgPSB0aGlzLnVpbnQzMigpICYgNykgIT09IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNraXBUeXBlKHdpcmVUeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICB0aGlzLnNraXAoNCk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJpbnZhbGlkIHdpcmUgdHlwZSBcIiArIHdpcmVUeXBlICsgXCIgYXQgb2Zmc2V0IFwiICsgdGhpcy5wb3MpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbn07XG5cblJlYWRlci5fY29uZmlndXJlID0gZnVuY3Rpb24oQnVmZmVyUmVhZGVyXykge1xuICAgIEJ1ZmZlclJlYWRlciA9IEJ1ZmZlclJlYWRlcl87XG4gICAgUmVhZGVyLmNyZWF0ZSA9IGNyZWF0ZSgpO1xuICAgIEJ1ZmZlclJlYWRlci5fY29uZmlndXJlKCk7XG5cbiAgICB2YXIgZm4gPSB1dGlsLkxvbmcgPyBcInRvTG9uZ1wiIDogLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gXCJ0b051bWJlclwiO1xuICAgIHV0aWwubWVyZ2UoUmVhZGVyLnByb3RvdHlwZSwge1xuXG4gICAgICAgIGludDY0OiBmdW5jdGlvbiByZWFkX2ludDY0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlYWRMb25nVmFyaW50LmNhbGwodGhpcylbZm5dKGZhbHNlKTtcbiAgICAgICAgfSxcblxuICAgICAgICB1aW50NjQ6IGZ1bmN0aW9uIHJlYWRfdWludDY0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlYWRMb25nVmFyaW50LmNhbGwodGhpcylbZm5dKHRydWUpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHNpbnQ2NDogZnVuY3Rpb24gcmVhZF9zaW50NjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZExvbmdWYXJpbnQuY2FsbCh0aGlzKS56ekRlY29kZSgpW2ZuXShmYWxzZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZml4ZWQ2NDogZnVuY3Rpb24gcmVhZF9maXhlZDY0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlYWRGaXhlZDY0LmNhbGwodGhpcylbZm5dKHRydWUpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHNmaXhlZDY0OiBmdW5jdGlvbiByZWFkX3NmaXhlZDY0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlYWRGaXhlZDY0LmNhbGwodGhpcylbZm5dKGZhbHNlKTtcbiAgICAgICAgfVxuXG4gICAgfSk7XG59O1xuIiwgIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBCdWZmZXJSZWFkZXI7XG5cbi8vIGV4dGVuZHMgUmVhZGVyXG52YXIgUmVhZGVyID0gcmVxdWlyZShcIi4vcmVhZGVyXCIpO1xuKEJ1ZmZlclJlYWRlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFJlYWRlci5wcm90b3R5cGUpKS5jb25zdHJ1Y3RvciA9IEJ1ZmZlclJlYWRlcjtcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiLi91dGlsL21pbmltYWxcIik7XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyBidWZmZXIgcmVhZGVyIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBXaXJlIGZvcm1hdCByZWFkZXIgdXNpbmcgbm9kZSBidWZmZXJzLlxuICogQGV4dGVuZHMgUmVhZGVyXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7QnVmZmVyfSBidWZmZXIgQnVmZmVyIHRvIHJlYWQgZnJvbVxuICovXG5mdW5jdGlvbiBCdWZmZXJSZWFkZXIoYnVmZmVyKSB7XG4gICAgUmVhZGVyLmNhbGwodGhpcywgYnVmZmVyKTtcblxuICAgIC8qKlxuICAgICAqIFJlYWQgYnVmZmVyLlxuICAgICAqIEBuYW1lIEJ1ZmZlclJlYWRlciNidWZcbiAgICAgKiBAdHlwZSB7QnVmZmVyfVxuICAgICAqL1xufVxuXG5CdWZmZXJSZWFkZXIuX2NvbmZpZ3VyZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgIGlmICh1dGlsLkJ1ZmZlcilcbiAgICAgICAgQnVmZmVyUmVhZGVyLnByb3RvdHlwZS5fc2xpY2UgPSB1dGlsLkJ1ZmZlci5wcm90b3R5cGUuc2xpY2U7XG59O1xuXG5cbi8qKlxuICogQG92ZXJyaWRlXG4gKi9cbkJ1ZmZlclJlYWRlci5wcm90b3R5cGUuc3RyaW5nID0gZnVuY3Rpb24gcmVhZF9zdHJpbmdfYnVmZmVyKCkge1xuICAgIHZhciBsZW4gPSB0aGlzLnVpbnQzMigpOyAvLyBtb2RpZmllcyBwb3NcbiAgICByZXR1cm4gdGhpcy5idWYudXRmOFNsaWNlXG4gICAgICAgID8gdGhpcy5idWYudXRmOFNsaWNlKHRoaXMucG9zLCB0aGlzLnBvcyA9IE1hdGgubWluKHRoaXMucG9zICsgbGVuLCB0aGlzLmxlbikpXG4gICAgICAgIDogdGhpcy5idWYudG9TdHJpbmcoXCJ1dGYtOFwiLCB0aGlzLnBvcywgdGhpcy5wb3MgPSBNYXRoLm1pbih0aGlzLnBvcyArIGxlbiwgdGhpcy5sZW4pKTtcbn07XG5cbi8qKlxuICogUmVhZHMgYSBzZXF1ZW5jZSBvZiBieXRlcyBwcmVjZWVkZWQgYnkgaXRzIGxlbmd0aCBhcyBhIHZhcmludC5cbiAqIEBuYW1lIEJ1ZmZlclJlYWRlciNieXRlc1xuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7QnVmZmVyfSBWYWx1ZSByZWFkXG4gKi9cblxuQnVmZmVyUmVhZGVyLl9jb25maWd1cmUoKTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gU2VydmljZTtcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiLi4vdXRpbC9taW5pbWFsXCIpO1xuXG4vLyBFeHRlbmRzIEV2ZW50RW1pdHRlclxuKFNlcnZpY2UucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSh1dGlsLkV2ZW50RW1pdHRlci5wcm90b3R5cGUpKS5jb25zdHJ1Y3RvciA9IFNlcnZpY2U7XG5cbi8qKlxuICogQSBzZXJ2aWNlIG1ldGhvZCBjYWxsYmFjayBhcyB1c2VkIGJ5IHtAbGluayBycGMuU2VydmljZU1ldGhvZHxTZXJ2aWNlTWV0aG9kfS5cbiAqXG4gKiBEaWZmZXJzIGZyb20ge0BsaW5rIFJQQ0ltcGxDYWxsYmFja30gaW4gdGhhdCBpdCBpcyBhbiBhY3R1YWwgY2FsbGJhY2sgb2YgYSBzZXJ2aWNlIG1ldGhvZCB3aGljaCBtYXkgbm90IHJldHVybiBgcmVzcG9uc2UgPSBudWxsYC5cbiAqIEB0eXBlZGVmIHJwYy5TZXJ2aWNlTWV0aG9kQ2FsbGJhY2tcbiAqIEB0ZW1wbGF0ZSBUUmVzIGV4dGVuZHMgTWVzc2FnZTxUUmVzPlxuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtFcnJvcnxudWxsfSBlcnJvciBFcnJvciwgaWYgYW55XG4gKiBAcGFyYW0ge1RSZXN9IFtyZXNwb25zZV0gUmVzcG9uc2UgbWVzc2FnZVxuICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAqL1xuXG4vKipcbiAqIEEgc2VydmljZSBtZXRob2QgcGFydCBvZiBhIHtAbGluayBycGMuU2VydmljZX0gYXMgY3JlYXRlZCBieSB7QGxpbmsgU2VydmljZS5jcmVhdGV9LlxuICogQHR5cGVkZWYgcnBjLlNlcnZpY2VNZXRob2RcbiAqIEB0ZW1wbGF0ZSBUUmVxIGV4dGVuZHMgTWVzc2FnZTxUUmVxPlxuICogQHRlbXBsYXRlIFRSZXMgZXh0ZW5kcyBNZXNzYWdlPFRSZXM+XG4gKiBAdHlwZSB7ZnVuY3Rpb259XG4gKiBAcGFyYW0ge1RSZXF8UHJvcGVydGllczxUUmVxPn0gcmVxdWVzdCBSZXF1ZXN0IG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0XG4gKiBAcGFyYW0ge3JwYy5TZXJ2aWNlTWV0aG9kQ2FsbGJhY2s8VFJlcz59IFtjYWxsYmFja10gTm9kZS1zdHlsZSBjYWxsYmFjayBjYWxsZWQgd2l0aCB0aGUgZXJyb3IsIGlmIGFueSwgYW5kIHRoZSByZXNwb25zZSBtZXNzYWdlXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxNZXNzYWdlPFRSZXM+Pn0gUHJvbWlzZSBpZiBgY2FsbGJhY2tgIGhhcyBiZWVuIG9taXR0ZWQsIG90aGVyd2lzZSBgdW5kZWZpbmVkYFxuICovXG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyBSUEMgc2VydmljZSBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgQW4gUlBDIHNlcnZpY2UgYXMgcmV0dXJuZWQgYnkge0BsaW5rIFNlcnZpY2UjY3JlYXRlfS5cbiAqIEBleHBvcnRzIHJwYy5TZXJ2aWNlXG4gKiBAZXh0ZW5kcyB1dGlsLkV2ZW50RW1pdHRlclxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge1JQQ0ltcGx9IHJwY0ltcGwgUlBDIGltcGxlbWVudGF0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXF1ZXN0RGVsaW1pdGVkPWZhbHNlXSBXaGV0aGVyIHJlcXVlc3RzIGFyZSBsZW5ndGgtZGVsaW1pdGVkXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXNwb25zZURlbGltaXRlZD1mYWxzZV0gV2hldGhlciByZXNwb25zZXMgYXJlIGxlbmd0aC1kZWxpbWl0ZWRcbiAqL1xuZnVuY3Rpb24gU2VydmljZShycGNJbXBsLCByZXF1ZXN0RGVsaW1pdGVkLCByZXNwb25zZURlbGltaXRlZCkge1xuXG4gICAgaWYgKHR5cGVvZiBycGNJbXBsICE9PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgIHRocm93IFR5cGVFcnJvcihcInJwY0ltcGwgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpO1xuXG4gICAgdXRpbC5FdmVudEVtaXR0ZXIuY2FsbCh0aGlzKTtcblxuICAgIC8qKlxuICAgICAqIFJQQyBpbXBsZW1lbnRhdGlvbi4gQmVjb21lcyBgbnVsbGAgb25jZSB0aGUgc2VydmljZSBpcyBlbmRlZC5cbiAgICAgKiBAdHlwZSB7UlBDSW1wbHxudWxsfVxuICAgICAqL1xuICAgIHRoaXMucnBjSW1wbCA9IHJwY0ltcGw7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHJlcXVlc3RzIGFyZSBsZW5ndGgtZGVsaW1pdGVkLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMucmVxdWVzdERlbGltaXRlZCA9IEJvb2xlYW4ocmVxdWVzdERlbGltaXRlZCk7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHJlc3BvbnNlcyBhcmUgbGVuZ3RoLWRlbGltaXRlZC5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLnJlc3BvbnNlRGVsaW1pdGVkID0gQm9vbGVhbihyZXNwb25zZURlbGltaXRlZCk7XG59XG5cbi8qKlxuICogQ2FsbHMgYSBzZXJ2aWNlIG1ldGhvZCB0aHJvdWdoIHtAbGluayBycGMuU2VydmljZSNycGNJbXBsfHJwY0ltcGx9LlxuICogQHBhcmFtIHtNZXRob2R8cnBjLlNlcnZpY2VNZXRob2Q8VFJlcSxUUmVzPn0gbWV0aG9kIFJlZmxlY3RlZCBvciBzdGF0aWMgbWV0aG9kXG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yPFRSZXE+fSByZXF1ZXN0Q3RvciBSZXF1ZXN0IGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yPFRSZXM+fSByZXNwb25zZUN0b3IgUmVzcG9uc2UgY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7VFJlcXxQcm9wZXJ0aWVzPFRSZXE+fSByZXF1ZXN0IFJlcXVlc3QgbWVzc2FnZSBvciBwbGFpbiBvYmplY3RcbiAqIEBwYXJhbSB7cnBjLlNlcnZpY2VNZXRob2RDYWxsYmFjazxUUmVzPn0gY2FsbGJhY2sgU2VydmljZSBjYWxsYmFja1xuICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAqIEB0ZW1wbGF0ZSBUUmVxIGV4dGVuZHMgTWVzc2FnZTxUUmVxPlxuICogQHRlbXBsYXRlIFRSZXMgZXh0ZW5kcyBNZXNzYWdlPFRSZXM+XG4gKi9cblNlcnZpY2UucHJvdG90eXBlLnJwY0NhbGwgPSBmdW5jdGlvbiBycGNDYWxsKG1ldGhvZCwgcmVxdWVzdEN0b3IsIHJlc3BvbnNlQ3RvciwgcmVxdWVzdCwgY2FsbGJhY2spIHtcblxuICAgIGlmICghcmVxdWVzdClcbiAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwicmVxdWVzdCBtdXN0IGJlIHNwZWNpZmllZFwiKTtcblxuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBpZiAoIWNhbGxiYWNrKVxuICAgICAgICByZXR1cm4gdXRpbC5hc1Byb21pc2UocnBjQ2FsbCwgc2VsZiwgbWV0aG9kLCByZXF1ZXN0Q3RvciwgcmVzcG9uc2VDdG9yLCByZXF1ZXN0KTtcblxuICAgIGlmICghc2VsZi5ycGNJbXBsKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNhbGxiYWNrKEVycm9yKFwiYWxyZWFkeSBlbmRlZFwiKSk7IH0sIDApO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBzZWxmLnJwY0ltcGwoXG4gICAgICAgICAgICBtZXRob2QsXG4gICAgICAgICAgICByZXF1ZXN0Q3RvcltzZWxmLnJlcXVlc3REZWxpbWl0ZWQgPyBcImVuY29kZURlbGltaXRlZFwiIDogXCJlbmNvZGVcIl0ocmVxdWVzdCkuZmluaXNoKCksXG4gICAgICAgICAgICBmdW5jdGlvbiBycGNDYWxsYmFjayhlcnIsIHJlc3BvbnNlKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdChcImVycm9yXCIsIGVyciwgbWV0aG9kKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZW5kKC8qIGVuZGVkQnlSUEMgKi8gdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCEocmVzcG9uc2UgaW5zdGFuY2VvZiByZXNwb25zZUN0b3IpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IHJlc3BvbnNlQ3RvcltzZWxmLnJlc3BvbnNlRGVsaW1pdGVkID8gXCJkZWNvZGVEZWxpbWl0ZWRcIiA6IFwiZGVjb2RlXCJdKHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmVtaXQoXCJlcnJvclwiLCBlcnIsIG1ldGhvZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHNlbGYuZW1pdChcImRhdGFcIiwgcmVzcG9uc2UsIG1ldGhvZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgc2VsZi5lbWl0KFwiZXJyb3JcIiwgZXJyLCBtZXRob2QpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBjYWxsYmFjayhlcnIpOyB9LCAwKTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG59O1xuXG4vKipcbiAqIEVuZHMgdGhpcyBzZXJ2aWNlIGFuZCBlbWl0cyB0aGUgYGVuZGAgZXZlbnQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtlbmRlZEJ5UlBDPWZhbHNlXSBXaGV0aGVyIHRoZSBzZXJ2aWNlIGhhcyBiZWVuIGVuZGVkIGJ5IHRoZSBSUEMgaW1wbGVtZW50YXRpb24uXG4gKiBAcmV0dXJucyB7cnBjLlNlcnZpY2V9IGB0aGlzYFxuICovXG5TZXJ2aWNlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiBlbmQoZW5kZWRCeVJQQykge1xuICAgIGlmICh0aGlzLnJwY0ltcGwpIHtcbiAgICAgICAgaWYgKCFlbmRlZEJ5UlBDKSAvLyBzaWduYWwgZW5kIHRvIHJwY0ltcGxcbiAgICAgICAgICAgIHRoaXMucnBjSW1wbChudWxsLCBudWxsLCBudWxsKTtcbiAgICAgICAgdGhpcy5ycGNJbXBsID0gbnVsbDtcbiAgICAgICAgdGhpcy5lbWl0KFwiZW5kXCIpLm9mZigpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbn07XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qKlxuICogU3RyZWFtaW5nIFJQQyBoZWxwZXJzLlxuICogQG5hbWVzcGFjZVxuICovXG52YXIgcnBjID0gZXhwb3J0cztcblxuLyoqXG4gKiBSUEMgaW1wbGVtZW50YXRpb24gcGFzc2VkIHRvIHtAbGluayBTZXJ2aWNlI2NyZWF0ZX0gcGVyZm9ybWluZyBhIHNlcnZpY2UgcmVxdWVzdCBvbiBuZXR3b3JrIGxldmVsLCBpLmUuIGJ5IHV0aWxpemluZyBodHRwIHJlcXVlc3RzIG9yIHdlYnNvY2tldHMuXG4gKiBAdHlwZWRlZiBSUENJbXBsXG4gKiBAdHlwZSB7ZnVuY3Rpb259XG4gKiBAcGFyYW0ge01ldGhvZHxycGMuU2VydmljZU1ldGhvZDxNZXNzYWdlPHt9PixNZXNzYWdlPHt9Pj59IG1ldGhvZCBSZWZsZWN0ZWQgb3Igc3RhdGljIG1ldGhvZCBiZWluZyBjYWxsZWRcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gcmVxdWVzdERhdGEgUmVxdWVzdCBkYXRhXG4gKiBAcGFyYW0ge1JQQ0ltcGxDYWxsYmFja30gY2FsbGJhY2sgQ2FsbGJhY2sgZnVuY3Rpb25cbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKiBAZXhhbXBsZVxuICogZnVuY3Rpb24gcnBjSW1wbChtZXRob2QsIHJlcXVlc3REYXRhLCBjYWxsYmFjaykge1xuICogICAgIGlmIChwcm90b2J1Zi51dGlsLmxjRmlyc3QobWV0aG9kLm5hbWUpICE9PSBcIm15TWV0aG9kXCIpIC8vIGNvbXBhdGlibGUgd2l0aCBzdGF0aWMgY29kZVxuICogICAgICAgICB0aHJvdyBFcnJvcihcIm5vIHN1Y2ggbWV0aG9kXCIpO1xuICogICAgIGFzeW5jaHJvbm91c2x5T2J0YWluQVJlc3BvbnNlKHJlcXVlc3REYXRhLCBmdW5jdGlvbihlcnIsIHJlc3BvbnNlRGF0YSkge1xuICogICAgICAgICBjYWxsYmFjayhlcnIsIHJlc3BvbnNlRGF0YSk7XG4gKiAgICAgfSk7XG4gKiB9XG4gKi9cblxuLyoqXG4gKiBOb2RlLXN0eWxlIGNhbGxiYWNrIGFzIHVzZWQgYnkge0BsaW5rIFJQQ0ltcGx9LlxuICogQHR5cGVkZWYgUlBDSW1wbENhbGxiYWNrXG4gKiBAdHlwZSB7ZnVuY3Rpb259XG4gKiBAcGFyYW0ge0Vycm9yfG51bGx9IGVycm9yIEVycm9yLCBpZiBhbnksIG90aGVyd2lzZSBgbnVsbGBcbiAqIEBwYXJhbSB7VWludDhBcnJheXxudWxsfSBbcmVzcG9uc2VdIFJlc3BvbnNlIGRhdGEgb3IgYG51bGxgIHRvIHNpZ25hbCBlbmQgb2Ygc3RyZWFtLCBpZiB0aGVyZSBoYXNuJ3QgYmVlbiBhbiBlcnJvclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAqL1xuXG5ycGMuU2VydmljZSA9IHJlcXVpcmUoXCIuL3JwYy9zZXJ2aWNlXCIpO1xuIiwgIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLyoqXG4gKiBOYW1lZCByb290cy5cbiAqIFRoaXMgaXMgd2hlcmUgcGJqcyBzdG9yZXMgZ2VuZXJhdGVkIHN0cnVjdHVyZXMgKHRoZSBvcHRpb24gYC1yLCAtLXJvb3RgIHNwZWNpZmllcyBhIG5hbWUpLlxuICogQ2FuIGFsc28gYmUgdXNlZCBtYW51YWxseSB0byBtYWtlIHJvb3RzIGF2YWlsYWJsZSBhY3Jvc3MgbW9kdWxlcy5cbiAqIEBuYW1lIHJvb3RzXG4gKiBAdHlwZSB7T2JqZWN0LjxzdHJpbmcsUm9vdD59XG4gKiBAZXhhbXBsZVxuICogLy8gcGJqcyAtciBteXJvb3QgLW8gY29tcGlsZWQuanMgLi4uXG4gKlxuICogLy8gaW4gYW5vdGhlciBtb2R1bGU6XG4gKiByZXF1aXJlKFwiLi9jb21waWxlZC5qc1wiKTtcbiAqXG4gKiAvLyBpbiBhbnkgc3Vic2VxdWVudCBtb2R1bGU6XG4gKiB2YXIgcm9vdCA9IHByb3RvYnVmLnJvb3RzW1wibXlyb290XCJdO1xuICovXG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgcHJvdG9idWYgPSBleHBvcnRzO1xuXG4vKipcbiAqIEJ1aWxkIHR5cGUsIG9uZSBvZiBgXCJmdWxsXCJgLCBgXCJsaWdodFwiYCBvciBgXCJtaW5pbWFsXCJgLlxuICogQG5hbWUgYnVpbGRcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKiBAY29uc3RcbiAqL1xucHJvdG9idWYuYnVpbGQgPSBcIm1pbmltYWxcIjtcblxuLy8gU2VyaWFsaXphdGlvblxucHJvdG9idWYuV3JpdGVyICAgICAgID0gcmVxdWlyZShcIi4vd3JpdGVyXCIpO1xucHJvdG9idWYuQnVmZmVyV3JpdGVyID0gcmVxdWlyZShcIi4vd3JpdGVyX2J1ZmZlclwiKTtcbnByb3RvYnVmLlJlYWRlciAgICAgICA9IHJlcXVpcmUoXCIuL3JlYWRlclwiKTtcbnByb3RvYnVmLkJ1ZmZlclJlYWRlciA9IHJlcXVpcmUoXCIuL3JlYWRlcl9idWZmZXJcIik7XG5cbi8vIFV0aWxpdHlcbnByb3RvYnVmLnV0aWwgICAgICAgICA9IHJlcXVpcmUoXCIuL3V0aWwvbWluaW1hbFwiKTtcbnByb3RvYnVmLnJwYyAgICAgICAgICA9IHJlcXVpcmUoXCIuL3JwY1wiKTtcbnByb3RvYnVmLnJvb3RzICAgICAgICA9IHJlcXVpcmUoXCIuL3Jvb3RzXCIpO1xucHJvdG9idWYuY29uZmlndXJlICAgID0gY29uZmlndXJlO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuLyoqXG4gKiBSZWNvbmZpZ3VyZXMgdGhlIGxpYnJhcnkgYWNjb3JkaW5nIHRvIHRoZSBlbnZpcm9ubWVudC5cbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKi9cbmZ1bmN0aW9uIGNvbmZpZ3VyZSgpIHtcbiAgICBwcm90b2J1Zi51dGlsLl9jb25maWd1cmUoKTtcbiAgICBwcm90b2J1Zi5Xcml0ZXIuX2NvbmZpZ3VyZShwcm90b2J1Zi5CdWZmZXJXcml0ZXIpO1xuICAgIHByb3RvYnVmLlJlYWRlci5fY29uZmlndXJlKHByb3RvYnVmLkJ1ZmZlclJlYWRlcik7XG59XG5cbi8vIFNldCB1cCBidWZmZXIgdXRpbGl0eSBhY2NvcmRpbmcgdG8gdGhlIGVudmlyb25tZW50XG5jb25maWd1cmUoKTtcbiIsICIvLyBtaW5pbWFsIGxpYnJhcnkgZW50cnkgcG9pbnQuXG5cblwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9zcmMvaW5kZXgtbWluaW1hbFwiKTtcbiIsICIvKmVzbGludC1kaXNhYmxlIGJsb2NrLXNjb3BlZC12YXIsIGlkLWxlbmd0aCwgbm8tY29udHJvbC1yZWdleCwgbm8tbWFnaWMtbnVtYmVycywgbm8tcHJvdG90eXBlLWJ1aWx0aW5zLCBuby1yZWRlY2xhcmUsIG5vLXNoYWRvdywgbm8tdmFyLCBzb3J0LXZhcnMqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciAkcHJvdG9idWYgPSByZXF1aXJlKFwicHJvdG9idWZqcy9taW5pbWFsXCIpO1xuXG4vLyBDb21tb24gYWxpYXNlc1xudmFyICRSZWFkZXIgPSAkcHJvdG9idWYuUmVhZGVyLCAkV3JpdGVyID0gJHByb3RvYnVmLldyaXRlciwgJHV0aWwgPSAkcHJvdG9idWYudXRpbDtcblxuLy8gRXhwb3J0ZWQgcm9vdCBuYW1lc3BhY2VcbnZhciAkcm9vdCA9ICRwcm90b2J1Zi5yb290c1tcImRlZmF1bHRcIl0gfHwgKCRwcm90b2J1Zi5yb290c1tcImRlZmF1bHRcIl0gPSB7fSk7XG5cbiRyb290Lm9ubnggPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAvKipcbiAgICAgKiBOYW1lc3BhY2Ugb25ueC5cbiAgICAgKiBAZXhwb3J0cyBvbm54XG4gICAgICogQG5hbWVzcGFjZVxuICAgICAqL1xuICAgIHZhciBvbm54ID0ge307XG5cbiAgICAvKipcbiAgICAgKiBWZXJzaW9uIGVudW0uXG4gICAgICogQG5hbWUgb25ueC5WZXJzaW9uXG4gICAgICogQGVudW0ge251bWJlcn1cbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gX1NUQVJUX1ZFUlNJT049MCBfU1RBUlRfVkVSU0lPTiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMTdfMTBfMTA9MSBJUl9WRVJTSU9OXzIwMTdfMTBfMTAgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTl8yMDE3XzEwXzMwPTIgSVJfVkVSU0lPTl8yMDE3XzEwXzMwIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxN18xMV8zPTMgSVJfVkVSU0lPTl8yMDE3XzExXzMgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTl8yMDE5XzFfMjI9NCBJUl9WRVJTSU9OXzIwMTlfMV8yMiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMTlfM18xOD01IElSX1ZFUlNJT05fMjAxOV8zXzE4IHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxOV85XzE5PTYgSVJfVkVSU0lPTl8yMDE5XzlfMTkgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTl8yMDIwXzVfOD03IElSX1ZFUlNJT05fMjAyMF81XzggdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTl8yMDIxXzdfMzA9OCBJUl9WRVJTSU9OXzIwMjFfN18zMCB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OPTkgSVJfVkVSU0lPTiB2YWx1ZVxuICAgICAqL1xuICAgIG9ubnguVmVyc2lvbiA9IChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHZhbHVlc0J5SWQgPSB7fSwgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMF0gPSBcIl9TVEFSVF9WRVJTSU9OXCJdID0gMDtcbiAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMV0gPSBcIklSX1ZFUlNJT05fMjAxN18xMF8xMFwiXSA9IDE7XG4gICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzJdID0gXCJJUl9WRVJTSU9OXzIwMTdfMTBfMzBcIl0gPSAyO1xuICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFszXSA9IFwiSVJfVkVSU0lPTl8yMDE3XzExXzNcIl0gPSAzO1xuICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs0XSA9IFwiSVJfVkVSU0lPTl8yMDE5XzFfMjJcIl0gPSA0O1xuICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs1XSA9IFwiSVJfVkVSU0lPTl8yMDE5XzNfMThcIl0gPSA1O1xuICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs2XSA9IFwiSVJfVkVSU0lPTl8yMDE5XzlfMTlcIl0gPSA2O1xuICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs3XSA9IFwiSVJfVkVSU0lPTl8yMDIwXzVfOFwiXSA9IDc7XG4gICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzhdID0gXCJJUl9WRVJTSU9OXzIwMjFfN18zMFwiXSA9IDg7XG4gICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzldID0gXCJJUl9WRVJTSU9OXCJdID0gOTtcbiAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5BdHRyaWJ1dGVQcm90byA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJvcGVydGllcyBvZiBhbiBBdHRyaWJ1dGVQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGludGVyZmFjZSBJQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW25hbWVdIEF0dHJpYnV0ZVByb3RvIG5hbWVcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW3JlZkF0dHJOYW1lXSBBdHRyaWJ1dGVQcm90byByZWZBdHRyTmFtZVxuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBBdHRyaWJ1dGVQcm90byBkb2NTdHJpbmdcbiAgICAgICAgICogQHByb3BlcnR5IHtvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGV8bnVsbH0gW3R5cGVdIEF0dHJpYnV0ZVByb3RvIHR5cGVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8bnVsbH0gW2ZdIEF0dHJpYnV0ZVByb3RvIGZcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbaV0gQXR0cmlidXRlUHJvdG8gaVxuICAgICAgICAgKiBAcHJvcGVydHkge1VpbnQ4QXJyYXl8bnVsbH0gW3NdIEF0dHJpYnV0ZVByb3RvIHNcbiAgICAgICAgICogQHByb3BlcnR5IHtvbm54LklUZW5zb3JQcm90b3xudWxsfSBbdF0gQXR0cmlidXRlUHJvdG8gdFxuICAgICAgICAgKiBAcHJvcGVydHkge29ubnguSUdyYXBoUHJvdG98bnVsbH0gW2ddIEF0dHJpYnV0ZVByb3RvIGdcbiAgICAgICAgICogQHByb3BlcnR5IHtvbm54LklTcGFyc2VUZW5zb3JQcm90b3xudWxsfSBbc3BhcnNlVGVuc29yXSBBdHRyaWJ1dGVQcm90byBzcGFyc2VUZW5zb3JcbiAgICAgICAgICogQHByb3BlcnR5IHtvbm54LklUeXBlUHJvdG98bnVsbH0gW3RwXSBBdHRyaWJ1dGVQcm90byB0cFxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXI+fG51bGx9IFtmbG9hdHNdIEF0dHJpYnV0ZVByb3RvIGZsb2F0c1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXJ8TG9uZz58bnVsbH0gW2ludHNdIEF0dHJpYnV0ZVByb3RvIGludHNcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48VWludDhBcnJheT58bnVsbH0gW3N0cmluZ3NdIEF0dHJpYnV0ZVByb3RvIHN0cmluZ3NcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JVGVuc29yUHJvdG8+fG51bGx9IFt0ZW5zb3JzXSBBdHRyaWJ1dGVQcm90byB0ZW5zb3JzXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSUdyYXBoUHJvdG8+fG51bGx9IFtncmFwaHNdIEF0dHJpYnV0ZVByb3RvIGdyYXBoc1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklTcGFyc2VUZW5zb3JQcm90bz58bnVsbH0gW3NwYXJzZVRlbnNvcnNdIEF0dHJpYnV0ZVByb3RvIHNwYXJzZVRlbnNvcnNcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JVHlwZVByb3RvPnxudWxsfSBbdHlwZVByb3Rvc10gQXR0cmlidXRlUHJvdG8gdHlwZVByb3Rvc1xuICAgICAgICAgKi9cblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBBdHRyaWJ1dGVQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGFuIEF0dHJpYnV0ZVByb3RvLlxuICAgICAgICAgKiBAaW1wbGVtZW50cyBJQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JQXR0cmlidXRlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIEF0dHJpYnV0ZVByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHRoaXMuZmxvYXRzID0gW107XG4gICAgICAgICAgICB0aGlzLmludHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuc3RyaW5ncyA9IFtdO1xuICAgICAgICAgICAgdGhpcy50ZW5zb3JzID0gW107XG4gICAgICAgICAgICB0aGlzLmdyYXBocyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5zcGFyc2VUZW5zb3JzID0gW107XG4gICAgICAgICAgICB0aGlzLnR5cGVQcm90b3MgPSBbXTtcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlUHJvdG8gbmFtZS5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBuYW1lXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLm5hbWUgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byByZWZBdHRyTmFtZS5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSByZWZBdHRyTmFtZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5yZWZBdHRyTmFtZSA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIGRvY1N0cmluZy5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZG9jU3RyaW5nID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlUHJvdG8gdHlwZS5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlfSB0eXBlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnR5cGUgPSAwO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byBmLlxuICAgICAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGZcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZiA9IDA7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIGkuXG4gICAgICAgICAqIEBtZW1iZXIge251bWJlcnxMb25nfSBpXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLmkgPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLDAsZmFsc2UpIDogMDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlUHJvdG8gcy5cbiAgICAgICAgICogQG1lbWJlciB7VWludDhBcnJheX0gc1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5zID0gJHV0aWwubmV3QnVmZmVyKFtdKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlUHJvdG8gdC5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5JVGVuc29yUHJvdG98bnVsbHx1bmRlZmluZWR9IHRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUudCA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIGcuXG4gICAgICAgICAqIEBtZW1iZXIge29ubnguSUdyYXBoUHJvdG98bnVsbHx1bmRlZmluZWR9IGdcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZyA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIHNwYXJzZVRlbnNvci5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5JU3BhcnNlVGVuc29yUHJvdG98bnVsbHx1bmRlZmluZWR9IHNwYXJzZVRlbnNvclxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5zcGFyc2VUZW5zb3IgPSBudWxsO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byB0cC5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5JVHlwZVByb3RvfG51bGx8dW5kZWZpbmVkfSB0cFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS50cCA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIGZsb2F0cy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcj59IGZsb2F0c1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5mbG9hdHMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byBpbnRzLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyfExvbmc+fSBpbnRzXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLmludHMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byBzdHJpbmdzLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48VWludDhBcnJheT59IHN0cmluZ3NcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuc3RyaW5ncyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIHRlbnNvcnMuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklUZW5zb3JQcm90bz59IHRlbnNvcnNcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUudGVuc29ycyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIGdyYXBocy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSUdyYXBoUHJvdG8+fSBncmFwaHNcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZ3JhcGhzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlUHJvdG8gc3BhcnNlVGVuc29ycy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVNwYXJzZVRlbnNvclByb3RvPn0gc3BhcnNlVGVuc29yc1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5zcGFyc2VUZW5zb3JzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlUHJvdG8gdHlwZVByb3Rvcy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVR5cGVQcm90bz59IHR5cGVQcm90b3NcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUudHlwZVByb3RvcyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgQXR0cmlidXRlUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklBdHRyaWJ1dGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5BdHRyaWJ1dGVQcm90b30gQXR0cmlidXRlUHJvdG8gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZVByb3RvKHByb3BlcnRpZXMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgQXR0cmlidXRlUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5BdHRyaWJ1dGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JQXR0cmlidXRlUHJvdG99IG1lc3NhZ2UgQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovMTApLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiZlwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDUgPSovMjEpLmZsb2F0KG1lc3NhZ2UuZik7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJpXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMCA9Ki8yNCkuaW50NjQobWVzc2FnZS5pKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnMgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcInNcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLzM0KS5ieXRlcyhtZXNzYWdlLnMpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudCAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwidFwiKSlcbiAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclByb3RvLmVuY29kZShtZXNzYWdlLnQsIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki80MikuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmcgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcImdcIikpXG4gICAgICAgICAgICAgICAgJHJvb3Qub25ueC5HcmFwaFByb3RvLmVuY29kZShtZXNzYWdlLmcsIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki81MCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmZsb2F0cyAhPSBudWxsICYmIG1lc3NhZ2UuZmxvYXRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNywgd2lyZVR5cGUgMiA9Ki81OCkuZm9yaygpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mbG9hdHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci5mbG9hdChtZXNzYWdlLmZsb2F0c1tpXSk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW50cyAhPSBudWxsICYmIG1lc3NhZ2UuaW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDgsIHdpcmVUeXBlIDIgPSovNjYpLmZvcmsoKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmludDY0KG1lc3NhZ2UuaW50c1tpXSk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5ncyAhPSBudWxsICYmIG1lc3NhZ2Uuc3RyaW5ncy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgOSwgd2lyZVR5cGUgMiA9Ki83NCkuYnl0ZXMobWVzc2FnZS5zdHJpbmdzW2ldKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRlbnNvcnMgIT0gbnVsbCAmJiBtZXNzYWdlLnRlbnNvcnMubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclByb3RvLmVuY29kZShtZXNzYWdlLnRlbnNvcnNbaV0sIHdyaXRlci51aW50MzIoLyogaWQgMTAsIHdpcmVUeXBlIDIgPSovODIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5ncmFwaHMgIT0gbnVsbCAmJiBtZXNzYWdlLmdyYXBocy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmdyYXBocy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5HcmFwaFByb3RvLmVuY29kZShtZXNzYWdlLmdyYXBoc1tpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxMSwgd2lyZVR5cGUgMiA9Ki85MCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTMsIHdpcmVUeXBlIDIgPSovMTA2KS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudHAgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcInRwXCIpKVxuICAgICAgICAgICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLmVuY29kZShtZXNzYWdlLnRwLCB3cml0ZXIudWludDMyKC8qIGlkIDE0LCB3aXJlVHlwZSAyID0qLzExNCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnR5cGVQcm90b3MgIT0gbnVsbCAmJiBtZXNzYWdlLnR5cGVQcm90b3MubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50eXBlUHJvdG9zLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5lbmNvZGUobWVzc2FnZS50eXBlUHJvdG9zW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDE1LCB3aXJlVHlwZSAyID0qLzEyMikuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcInR5cGVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyMCwgd2lyZVR5cGUgMCA9Ki8xNjApLmludDMyKG1lc3NhZ2UudHlwZSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5yZWZBdHRyTmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwicmVmQXR0ck5hbWVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyMSwgd2lyZVR5cGUgMiA9Ki8xNzApLnN0cmluZyhtZXNzYWdlLnJlZkF0dHJOYW1lKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvciAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwic3BhcnNlVGVuc29yXCIpKVxuICAgICAgICAgICAgICAgICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZW5jb2RlKG1lc3NhZ2Uuc3BhcnNlVGVuc29yLCB3cml0ZXIudWludDMyKC8qIGlkIDIyLCB3aXJlVHlwZSAyID0qLzE3OCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvcnMgIT0gbnVsbCAmJiBtZXNzYWdlLnNwYXJzZVRlbnNvcnMubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmVuY29kZShtZXNzYWdlLnNwYXJzZVRlbnNvcnNbaV0sIHdyaXRlci51aW50MzIoLyogaWQgMjMsIHdpcmVUeXBlIDIgPSovMTg2KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguQXR0cmlidXRlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSUF0dHJpYnV0ZVByb3RvfSBtZXNzYWdlIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYW4gQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5BdHRyaWJ1dGVQcm90b30gQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvKCk7XG4gICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAyMToge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5yZWZBdHRyTmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAxMzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgMjA6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZiA9IHJlYWRlci5mbG9hdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaSA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucyA9IHJlYWRlci5ieXRlcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSA2OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmcgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAyMjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3IgPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgMTQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudHAgPSAkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZmxvYXRzICYmIG1lc3NhZ2UuZmxvYXRzLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5mbG9hdHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmZsb2F0cy5wdXNoKHJlYWRlci5mbG9hdCgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZmxvYXRzLnB1c2gocmVhZGVyLmZsb2F0KCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDg6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuaW50cyAmJiBtZXNzYWdlLmludHMubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludHMucHVzaChyZWFkZXIuaW50NjQoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludHMucHVzaChyZWFkZXIuaW50NjQoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgOToge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5zdHJpbmdzICYmIG1lc3NhZ2Uuc3RyaW5ncy5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc3RyaW5ncyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zdHJpbmdzLnB1c2gocmVhZGVyLmJ5dGVzKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDEwOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLnRlbnNvcnMgJiYgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS50ZW5zb3JzID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnRlbnNvcnMucHVzaCgkcm9vdC5vbm54LlRlbnNvclByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDExOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmdyYXBocyAmJiBtZXNzYWdlLmdyYXBocy5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZ3JhcGhzID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmdyYXBocy5wdXNoKCRyb290Lm9ubnguR3JhcGhQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAyMzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5zcGFyc2VUZW5zb3JzICYmIG1lc3NhZ2Uuc3BhcnNlVGVuc29ycy5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3JzLnB1c2goJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAxNToge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS50eXBlUHJvdG9zICYmIG1lc3NhZ2UudHlwZVByb3Rvcy5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZVByb3RvcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlUHJvdG9zLnB1c2goJHJvb3Qub25ueC5UeXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYW4gQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5BdHRyaWJ1dGVQcm90b30gQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVmVyaWZpZXMgYW4gQXR0cmlidXRlUHJvdG8gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJuYW1lXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5uYW1lKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibmFtZTogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5yZWZBdHRyTmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJyZWZBdHRyTmFtZVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UucmVmQXR0ck5hbWUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJyZWZBdHRyTmFtZTogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJ0eXBlXCIpKVxuICAgICAgICAgICAgICAgIHN3aXRjaCAobWVzc2FnZS50eXBlKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidHlwZTogZW51bSB2YWx1ZSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIGNhc2UgMTE6XG4gICAgICAgICAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgICAgY2FzZSAxMDpcbiAgICAgICAgICAgICAgICBjYXNlIDEyOlxuICAgICAgICAgICAgICAgIGNhc2UgMTQ6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmYgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZlwiKSlcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZiAhPT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZjogbnVtYmVyIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImlcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pKSAmJiAhKG1lc3NhZ2UuaSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaS5oaWdoKSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImk6IGludGVnZXJ8TG9uZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzXCIpKVxuICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UucyAmJiB0eXBlb2YgbWVzc2FnZS5zLmxlbmd0aCA9PT0gXCJudW1iZXJcIiB8fCAkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnMpKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiczogYnVmZmVyIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInRcIikpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnZlcmlmeShtZXNzYWdlLnQpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidC5cIiArIGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJnXCIpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnZlcmlmeShtZXNzYWdlLmcpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZy5cIiArIGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29yICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInNwYXJzZVRlbnNvclwiKSkge1xuICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2Uuc3BhcnNlVGVuc29yKTtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInNwYXJzZVRlbnNvci5cIiArIGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudHAgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidHBcIikpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by52ZXJpZnkobWVzc2FnZS50cCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0cC5cIiArIGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZmxvYXRzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImZsb2F0c1wiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmZsb2F0cykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImZsb2F0czogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZmxvYXRzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZmxvYXRzW2ldICE9PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZmxvYXRzOiBudW1iZXJbXSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW50cyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJpbnRzXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW50cykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImludHM6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmludHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50c1tpXSkgJiYgIShtZXNzYWdlLmludHNbaV0gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50c1tpXS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludHNbaV0uaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW50czogaW50ZWdlcnxMb25nW10gZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnN0cmluZ3MgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwic3RyaW5nc1wiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnN0cmluZ3MpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJzdHJpbmdzOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5zdHJpbmdzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLnN0cmluZ3NbaV0gJiYgdHlwZW9mIG1lc3NhZ2Uuc3RyaW5nc1tpXS5sZW5ndGggPT09IFwibnVtYmVyXCIgfHwgJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5zdHJpbmdzW2ldKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJzdHJpbmdzOiBidWZmZXJbXSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudGVuc29ycyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJ0ZW5zb3JzXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudGVuc29ycykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInRlbnNvcnM6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnRlbnNvcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS50ZW5zb3JzW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidGVuc29ycy5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmdyYXBocyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJncmFwaHNcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5ncmFwaHMpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJncmFwaHM6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmdyYXBocy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udmVyaWZ5KG1lc3NhZ2UuZ3JhcGhzW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZ3JhcGhzLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzcGFyc2VUZW5zb3JzXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uuc3BhcnNlVGVuc29ycykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInNwYXJzZVRlbnNvcnM6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnNwYXJzZVRlbnNvcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS5zcGFyc2VUZW5zb3JzW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwic3BhcnNlVGVuc29ycy5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnR5cGVQcm90b3MgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidHlwZVByb3Rvc1wiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnR5cGVQcm90b3MpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0eXBlUHJvdG9zOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50eXBlUHJvdG9zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLnR5cGVQcm90b3NbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0eXBlUHJvdG9zLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYW4gQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguQXR0cmlidXRlUHJvdG99IEF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvKCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5yZWZBdHRyTmFtZSAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UucmVmQXR0ck5hbWUgPSBTdHJpbmcob2JqZWN0LnJlZkF0dHJOYW1lKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QuZG9jU3RyaW5nICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICAgICAgICBzd2l0Y2ggKG9iamVjdC50eXBlKSB7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnR5cGUgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gb2JqZWN0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJVTkRFRklORURcIjpcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAwO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIkZMT0FUXCI6XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJJTlRcIjpcbiAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAyO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIlNUUklOR1wiOlxuICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDM7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiVEVOU09SXCI6XG4gICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gNDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJHUkFQSFwiOlxuICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiU1BBUlNFX1RFTlNPUlwiOlxuICAgICAgICAgICAgY2FzZSAxMTpcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAxMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJUWVBFX1BST1RPXCI6XG4gICAgICAgICAgICBjYXNlIDEzOlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDEzO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIkZMT0FUU1wiOlxuICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDY7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiSU5UU1wiOlxuICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiU1RSSU5HU1wiOlxuICAgICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDg7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiVEVOU09SU1wiOlxuICAgICAgICAgICAgY2FzZSA5OlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiR1JBUEhTXCI6XG4gICAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDEwO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIlNQQVJTRV9URU5TT1JTXCI6XG4gICAgICAgICAgICBjYXNlIDEyOlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDEyO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIlRZUEVfUFJPVE9TXCI6XG4gICAgICAgICAgICBjYXNlIDE0OlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDE0O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5mICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5mID0gTnVtYmVyKG9iamVjdC5mKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QuaSAhPSBudWxsKVxuICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKVxuICAgICAgICAgICAgICAgICAgICAobWVzc2FnZS5pID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmkpKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pID0gcGFyc2VJbnQob2JqZWN0LmksIDEwKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmkgPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaSA9IG9iamVjdC5pO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaSA9PT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5pLmxvdyA+Pj4gMCwgb2JqZWN0LmkuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QucyAhPSBudWxsKVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnMgPT09IFwic3RyaW5nXCIpXG4gICAgICAgICAgICAgICAgICAgICR1dGlsLmJhc2U2NC5kZWNvZGUob2JqZWN0LnMsIG1lc3NhZ2UucyA9ICR1dGlsLm5ld0J1ZmZlcigkdXRpbC5iYXNlNjQubGVuZ3RoKG9iamVjdC5zKSksIDApO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG9iamVjdC5zLmxlbmd0aCA+PSAwKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnMgPSBvYmplY3QucztcbiAgICAgICAgICAgIGlmIChvYmplY3QudCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudCAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguQXR0cmlidXRlUHJvdG8udDogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3QudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmcgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmcgIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkF0dHJpYnV0ZVByb3RvLmc6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmcgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LnNwYXJzZVRlbnNvciAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3BhcnNlVGVuc29yICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5BdHRyaWJ1dGVQcm90by5zcGFyc2VUZW5zb3I6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvciA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3Quc3BhcnNlVGVuc29yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QudHAgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnRwICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5BdHRyaWJ1dGVQcm90by50cDogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHAgPSAkcm9vdC5vbm54LlR5cGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC50cCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmZsb2F0cykge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZmxvYXRzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguQXR0cmlidXRlUHJvdG8uZmxvYXRzOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmZsb2F0cyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmZsb2F0cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5mbG9hdHNbaV0gPSBOdW1iZXIob2JqZWN0LmZsb2F0c1tpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmludHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmludHMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5BdHRyaWJ1dGVQcm90by5pbnRzOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmludHMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbnRzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLmludHNbaV0gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuaW50c1tpXSkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaW50c1tpXSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50c1tpXSA9IHBhcnNlSW50KG9iamVjdC5pbnRzW2ldLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaW50c1tpXSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50c1tpXSA9IG9iamVjdC5pbnRzW2ldO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmludHNbaV0gPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludHNbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmludHNbaV0ubG93ID4+PiAwLCBvYmplY3QuaW50c1tpXS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5zdHJpbmdzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5zdHJpbmdzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguQXR0cmlidXRlUHJvdG8uc3RyaW5nczogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5zdHJpbmdzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Quc3RyaW5ncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3RyaW5nc1tpXSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICR1dGlsLmJhc2U2NC5kZWNvZGUob2JqZWN0LnN0cmluZ3NbaV0sIG1lc3NhZ2Uuc3RyaW5nc1tpXSA9ICR1dGlsLm5ld0J1ZmZlcigkdXRpbC5iYXNlNjQubGVuZ3RoKG9iamVjdC5zdHJpbmdzW2ldKSksIDApO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChvYmplY3Quc3RyaW5nc1tpXS5sZW5ndGggPj0gMClcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc3RyaW5nc1tpXSA9IG9iamVjdC5zdHJpbmdzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC50ZW5zb3JzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC50ZW5zb3JzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguQXR0cmlidXRlUHJvdG8udGVuc29yczogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50ZW5zb3JzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QudGVuc29ycy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50ZW5zb3JzW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguQXR0cmlidXRlUHJvdG8udGVuc29yczogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnRlbnNvcnNbaV0gPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLmZyb21PYmplY3Qob2JqZWN0LnRlbnNvcnNbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QuZ3JhcGhzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5ncmFwaHMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5BdHRyaWJ1dGVQcm90by5ncmFwaHM6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZ3JhcGhzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZ3JhcGhzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmdyYXBoc1tpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkF0dHJpYnV0ZVByb3RvLmdyYXBoczogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmdyYXBoc1tpXSA9ICRyb290Lm9ubnguR3JhcGhQcm90by5mcm9tT2JqZWN0KG9iamVjdC5ncmFwaHNbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3Quc3BhcnNlVGVuc29ycykge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Quc3BhcnNlVGVuc29ycykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkF0dHJpYnV0ZVByb3RvLnNwYXJzZVRlbnNvcnM6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnNwYXJzZVRlbnNvcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3BhcnNlVGVuc29yc1tpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkF0dHJpYnV0ZVByb3RvLnNwYXJzZVRlbnNvcnM6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zcGFyc2VUZW5zb3JzW2ldID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC5zcGFyc2VUZW5zb3JzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LnR5cGVQcm90b3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnR5cGVQcm90b3MpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5BdHRyaWJ1dGVQcm90by50eXBlUHJvdG9zOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnR5cGVQcm90b3MgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC50eXBlUHJvdG9zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnR5cGVQcm90b3NbaV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5BdHRyaWJ1dGVQcm90by50eXBlUHJvdG9zOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZVByb3Rvc1tpXSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnR5cGVQcm90b3NbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYW4gQXR0cmlidXRlUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguQXR0cmlidXRlUHJvdG99IG1lc3NhZ2UgQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgIG9iamVjdC5mbG9hdHMgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QuaW50cyA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC5zdHJpbmdzID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LnRlbnNvcnMgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QuZ3JhcGhzID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LnR5cGVQcm90b3MgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3Quc3BhcnNlVGVuc29ycyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmYgPSAwO1xuICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsb25nID0gbmV3ICR1dGlsLkxvbmcoMCwgMCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuaSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5pID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gXCIwXCIgOiAwO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmJ5dGVzID09PSBTdHJpbmcpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5zID0gXCJcIjtcbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuYnl0ZXMgIT09IEFycmF5KVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnMgPSAkdXRpbC5uZXdCdWZmZXIob2JqZWN0LnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvYmplY3QudCA9IG51bGw7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmcgPSBudWxsO1xuICAgICAgICAgICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSBcIlwiO1xuICAgICAgICAgICAgICAgIG9iamVjdC50cCA9IG51bGw7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnR5cGUgPSBvcHRpb25zLmVudW1zID09PSBTdHJpbmcgPyBcIlVOREVGSU5FRFwiIDogMDtcbiAgICAgICAgICAgICAgICBvYmplY3QucmVmQXR0ck5hbWUgPSBcIlwiO1xuICAgICAgICAgICAgICAgIG9iamVjdC5zcGFyc2VUZW5zb3IgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJuYW1lXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5uYW1lID0gbWVzc2FnZS5uYW1lO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJmXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5mID0gb3B0aW9ucy5qc29uICYmICFpc0Zpbml0ZShtZXNzYWdlLmYpID8gU3RyaW5nKG1lc3NhZ2UuZikgOiBtZXNzYWdlLmY7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImlcIikpXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmkgPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5pID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuaSkgOiBtZXNzYWdlLmk7XG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuaSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5pKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmkubG93ID4+PiAwLCBtZXNzYWdlLmkuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKSA6IG1lc3NhZ2UuaTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwic1wiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QucyA9IG9wdGlvbnMuYnl0ZXMgPT09IFN0cmluZyA/ICR1dGlsLmJhc2U2NC5lbmNvZGUobWVzc2FnZS5zLCAwLCBtZXNzYWdlLnMubGVuZ3RoKSA6IG9wdGlvbnMuYnl0ZXMgPT09IEFycmF5ID8gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwobWVzc2FnZS5zKSA6IG1lc3NhZ2UucztcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidFwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS50LCBvcHRpb25zKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZ1wiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QuZyA9ICRyb290Lm9ubnguR3JhcGhQcm90by50b09iamVjdChtZXNzYWdlLmcsIG9wdGlvbnMpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZmxvYXRzICYmIG1lc3NhZ2UuZmxvYXRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5mbG9hdHMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZmxvYXRzLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZmxvYXRzW2pdID0gb3B0aW9ucy5qc29uICYmICFpc0Zpbml0ZShtZXNzYWdlLmZsb2F0c1tqXSkgPyBTdHJpbmcobWVzc2FnZS5mbG9hdHNbal0pIDogbWVzc2FnZS5mbG9hdHNbal07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbnRzICYmIG1lc3NhZ2UuaW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuaW50cyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbnRzLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuaW50c1tqXSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbnRzW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuaW50c1tqXSkgOiBtZXNzYWdlLmludHNbal07XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbnRzW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLmludHNbal0pIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuaW50c1tqXS5sb3cgPj4+IDAsIG1lc3NhZ2UuaW50c1tqXS5oaWdoID4+PiAwKS50b051bWJlcigpIDogbWVzc2FnZS5pbnRzW2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5ncyAmJiBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnN0cmluZ3MgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uuc3RyaW5ncy5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnN0cmluZ3Nbal0gPSBvcHRpb25zLmJ5dGVzID09PSBTdHJpbmcgPyAkdXRpbC5iYXNlNjQuZW5jb2RlKG1lc3NhZ2Uuc3RyaW5nc1tqXSwgMCwgbWVzc2FnZS5zdHJpbmdzW2pdLmxlbmd0aCkgOiBvcHRpb25zLmJ5dGVzID09PSBBcnJheSA/IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG1lc3NhZ2Uuc3RyaW5nc1tqXSkgOiBtZXNzYWdlLnN0cmluZ3Nbal07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50ZW5zb3JzICYmIG1lc3NhZ2UudGVuc29ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QudGVuc29ycyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QudGVuc29yc1tqXSA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS50ZW5zb3JzW2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmdyYXBocyAmJiBtZXNzYWdlLmdyYXBocy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZ3JhcGhzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmdyYXBocy5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmdyYXBoc1tqXSA9ICRyb290Lm9ubnguR3JhcGhQcm90by50b09iamVjdChtZXNzYWdlLmdyYXBoc1tqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSBtZXNzYWdlLmRvY1N0cmluZztcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRwICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInRwXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC50cCA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudHAsIG9wdGlvbnMpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudHlwZVByb3RvcyAmJiBtZXNzYWdlLnR5cGVQcm90b3MubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnR5cGVQcm90b3MgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UudHlwZVByb3Rvcy5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnR5cGVQcm90b3Nbal0gPSAkcm9vdC5vbm54LlR5cGVQcm90by50b09iamVjdChtZXNzYWdlLnR5cGVQcm90b3Nbal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJ0eXBlXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC50eXBlID0gb3B0aW9ucy5lbnVtcyA9PT0gU3RyaW5nID8gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlW21lc3NhZ2UudHlwZV0gPT09IHVuZGVmaW5lZCA/IG1lc3NhZ2UudHlwZSA6ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZVttZXNzYWdlLnR5cGVdIDogbWVzc2FnZS50eXBlO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucmVmQXR0ck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwicmVmQXR0ck5hbWVcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnJlZkF0dHJOYW1lID0gbWVzc2FnZS5yZWZBdHRyTmFtZTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvciAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzcGFyc2VUZW5zb3JcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnNwYXJzZVRlbnNvciA9ICRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8udG9PYmplY3QobWVzc2FnZS5zcGFyc2VUZW5zb3IsIG9wdGlvbnMpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29ycyAmJiBtZXNzYWdlLnNwYXJzZVRlbnNvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnNwYXJzZVRlbnNvcnMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uuc3BhcnNlVGVuc29ycy5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnNwYXJzZVRlbnNvcnNbal0gPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc3BhcnNlVGVuc29yc1tqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIEF0dHJpYnV0ZVByb3RvIHRvIEpTT04uXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArIFwiL29ubnguQXR0cmlidXRlUHJvdG9cIjtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlVHlwZSBlbnVtLlxuICAgICAgICAgKiBAbmFtZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVcbiAgICAgICAgICogQGVudW0ge251bWJlcn1cbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVOREVGSU5FRD0wIFVOREVGSU5FRCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ9MSBGTE9BVCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UPTIgSU5UIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBTVFJJTkc9MyBTVFJJTkcgdmFsdWVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFRFTlNPUj00IFRFTlNPUiB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gR1JBUEg9NSBHUkFQSCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gU1BBUlNFX1RFTlNPUj0xMSBTUEFSU0VfVEVOU09SIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBUWVBFX1BST1RPPTEzIFRZUEVfUFJPVE8gdmFsdWVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEZMT0FUUz02IEZMT0FUUyB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UUz03IElOVFMgdmFsdWVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFNUUklOR1M9OCBTVFJJTkdTIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBURU5TT1JTPTkgVEVOU09SUyB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gR1JBUEhTPTEwIEdSQVBIUyB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gU1BBUlNFX1RFTlNPUlM9MTIgU1BBUlNFX1RFTlNPUlMgdmFsdWVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFRZUEVfUFJPVE9TPTE0IFRZUEVfUFJPVE9TIHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlID0gKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIHZhbHVlc0J5SWQgPSB7fSwgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzBdID0gXCJVTkRFRklORURcIl0gPSAwO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMV0gPSBcIkZMT0FUXCJdID0gMTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzJdID0gXCJJTlRcIl0gPSAyO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbM10gPSBcIlNUUklOR1wiXSA9IDM7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs0XSA9IFwiVEVOU09SXCJdID0gNDtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzVdID0gXCJHUkFQSFwiXSA9IDU7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFsxMV0gPSBcIlNQQVJTRV9URU5TT1JcIl0gPSAxMTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzEzXSA9IFwiVFlQRV9QUk9UT1wiXSA9IDEzO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbNl0gPSBcIkZMT0FUU1wiXSA9IDY7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs3XSA9IFwiSU5UU1wiXSA9IDc7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs4XSA9IFwiU1RSSU5HU1wiXSA9IDg7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs5XSA9IFwiVEVOU09SU1wiXSA9IDk7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFsxMF0gPSBcIkdSQVBIU1wiXSA9IDEwO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMTJdID0gXCJTUEFSU0VfVEVOU09SU1wiXSA9IDEyO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMTRdID0gXCJUWVBFX1BST1RPU1wiXSA9IDE0O1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICAgICAgfSkoKTtcblxuICAgICAgICByZXR1cm4gQXR0cmlidXRlUHJvdG87XG4gICAgfSkoKTtcblxuICAgIG9ubnguVmFsdWVJbmZvUHJvdG8gPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBWYWx1ZUluZm9Qcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGludGVyZmFjZSBJVmFsdWVJbmZvUHJvdG9cbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW25hbWVdIFZhbHVlSW5mb1Byb3RvIG5hbWVcbiAgICAgICAgICogQHByb3BlcnR5IHtvbm54LklUeXBlUHJvdG98bnVsbH0gW3R5cGVdIFZhbHVlSW5mb1Byb3RvIHR5cGVcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gVmFsdWVJbmZvUHJvdG8gZG9jU3RyaW5nXG4gICAgICAgICAqL1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFZhbHVlSW5mb1Byb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBWYWx1ZUluZm9Qcm90by5cbiAgICAgICAgICogQGltcGxlbWVudHMgSVZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVZhbHVlSW5mb1Byb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBWYWx1ZUluZm9Qcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZhbHVlSW5mb1Byb3RvIG5hbWUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFZhbHVlSW5mb1Byb3RvLnByb3RvdHlwZS5uYW1lID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVmFsdWVJbmZvUHJvdG8gdHlwZS5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5JVHlwZVByb3RvfG51bGx8dW5kZWZpbmVkfSB0eXBlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8ucHJvdG90eXBlLnR5cGUgPSBudWxsO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBWYWx1ZUluZm9Qcm90byBkb2NTdHJpbmcuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9jU3RyaW5nXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8ucHJvdG90eXBlLmRvY1N0cmluZyA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgVmFsdWVJbmZvUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklWYWx1ZUluZm9Qcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5WYWx1ZUluZm9Qcm90b30gVmFsdWVJbmZvUHJvdG8gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFZhbHVlSW5mb1Byb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFZhbHVlSW5mb1Byb3RvKHByb3BlcnRpZXMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5WYWx1ZUluZm9Qcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVmFsdWVJbmZvUHJvdG99IG1lc3NhZ2UgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBWYWx1ZUluZm9Qcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovMTApLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwidHlwZVwiKSlcbiAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5lbmNvZGUobWVzc2FnZS50eXBlLCB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovMTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovMjYpLnN0cmluZyhtZXNzYWdlLmRvY1N0cmluZyk7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5WYWx1ZUluZm9Qcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVmFsdWVJbmZvUHJvdG99IG1lc3NhZ2UgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBWYWx1ZUluZm9Qcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICogQHJldHVybnMge29ubnguVmFsdWVJbmZvUHJvdG99IFZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90bygpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguVmFsdWVJbmZvUHJvdG99IFZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGEgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJuYW1lXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5uYW1lKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibmFtZTogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50eXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInR5cGVcIikpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by52ZXJpZnkobWVzc2FnZS50eXBlKTtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInR5cGUuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvY1N0cmluZykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRvY1N0cmluZzogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlZhbHVlSW5mb1Byb3RvfSBWYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90bylcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90bygpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5uYW1lICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gU3RyaW5nKG9iamVjdC5uYW1lKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QudHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudHlwZSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVmFsdWVJbmZvUHJvdG8udHlwZTogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5WYWx1ZUluZm9Qcm90b30gbWVzc2FnZSBWYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIFZhbHVlSW5mb1Byb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm5hbWUgPSBcIlwiO1xuICAgICAgICAgICAgICAgIG9iamVjdC50eXBlID0gbnVsbDtcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gXCJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IG1lc3NhZ2UubmFtZTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidHlwZVwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QudHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudHlwZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSBtZXNzYWdlLmRvY1N0cmluZztcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnZlcnRzIHRoaXMgVmFsdWVJbmZvUHJvdG8gdG8gSlNPTi5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBWYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgXCIvb25ueC5WYWx1ZUluZm9Qcm90b1wiO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBWYWx1ZUluZm9Qcm90bztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5Ob2RlUHJvdG8gPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBOb2RlUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBpbnRlcmZhY2UgSU5vZGVQcm90b1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxzdHJpbmc+fG51bGx9IFtpbnB1dF0gTm9kZVByb3RvIGlucHV0XG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz58bnVsbH0gW291dHB1dF0gTm9kZVByb3RvIG91dHB1dFxuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbbmFtZV0gTm9kZVByb3RvIG5hbWVcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW29wVHlwZV0gTm9kZVByb3RvIG9wVHlwZVxuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9tYWluXSBOb2RlUHJvdG8gZG9tYWluXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSUF0dHJpYnV0ZVByb3RvPnxudWxsfSBbYXR0cmlidXRlXSBOb2RlUHJvdG8gYXR0cmlidXRlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIE5vZGVQcm90byBkb2NTdHJpbmdcbiAgICAgICAgICovXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgTm9kZVByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBOb2RlUHJvdG8uXG4gICAgICAgICAqIEBpbXBsZW1lbnRzIElOb2RlUHJvdG9cbiAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JTm9kZVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBOb2RlUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgICAgICAgdGhpcy5pbnB1dCA9IFtdO1xuICAgICAgICAgICAgdGhpcy5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlID0gW107XG4gICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE5vZGVQcm90byBpbnB1dC5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPHN0cmluZz59IGlucHV0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5wcm90b3R5cGUuaW5wdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBOb2RlUHJvdG8gb3V0cHV0LlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48c3RyaW5nPn0gb3V0cHV0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5wcm90b3R5cGUub3V0cHV0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTm9kZVByb3RvIG5hbWUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8ucHJvdG90eXBlLm5hbWUgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBOb2RlUHJvdG8gb3BUeXBlLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IG9wVHlwZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8ucHJvdG90eXBlLm9wVHlwZSA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE5vZGVQcm90byBkb21haW4uXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9tYWluXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5wcm90b3R5cGUuZG9tYWluID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTm9kZVByb3RvIGF0dHJpYnV0ZS5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSUF0dHJpYnV0ZVByb3RvPn0gYXR0cmlidXRlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5wcm90b3R5cGUuYXR0cmlidXRlID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTm9kZVByb3RvIGRvY1N0cmluZy5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTm9kZVByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IE5vZGVQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklOb2RlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICogQHJldHVybnMge29ubnguTm9kZVByb3RvfSBOb2RlUHJvdG8gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBOb2RlUHJvdG8ocHJvcGVydGllcyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBOb2RlUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5Ob2RlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklOb2RlUHJvdG99IG1lc3NhZ2UgTm9kZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgTm9kZVByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIGlmICghd3JpdGVyKVxuICAgICAgICAgICAgICAgIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLzEwKS5zdHJpbmcobWVzc2FnZS5pbnB1dFtpXSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vdXRwdXQgIT0gbnVsbCAmJiBtZXNzYWdlLm91dHB1dC5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLzE4KS5zdHJpbmcobWVzc2FnZS5vdXRwdXRbaV0pO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovMjYpLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3BUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJvcFR5cGVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLzM0KS5zdHJpbmcobWVzc2FnZS5vcFR5cGUpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlICE9IG51bGwgJiYgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZW5jb2RlKG1lc3NhZ2UuYXR0cmlidXRlW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovNDIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDYsIHdpcmVUeXBlIDIgPSovNTApLnN0cmluZyhtZXNzYWdlLmRvY1N0cmluZyk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcImRvbWFpblwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDcsIHdpcmVUeXBlIDIgPSovNTgpLnN0cmluZyhtZXNzYWdlLmRvbWFpbik7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgTm9kZVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguTm9kZVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JTm9kZVByb3RvfSBtZXNzYWdlIE5vZGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIE5vZGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5Ob2RlUHJvdG99IE5vZGVQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk5vZGVQcm90bygpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmlucHV0ICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmlucHV0LnB1c2gocmVhZGVyLnN0cmluZygpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLm91dHB1dCAmJiBtZXNzYWdlLm91dHB1dC5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0ID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm91dHB1dC5wdXNoKHJlYWRlci5zdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgMzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3BUeXBlID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuYXR0cmlidXRlICYmIG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXR0cmlidXRlLnB1c2goJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSA2OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIE5vZGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5Ob2RlUHJvdG99IE5vZGVQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVmVyaWZpZXMgYSBOb2RlUHJvdG8gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJpbnB1dFwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmlucHV0KSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW5wdXQ6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuaW5wdXRbaV0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW5wdXQ6IHN0cmluZ1tdIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vdXRwdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwib3V0cHV0XCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uub3V0cHV0KSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib3V0cHV0OiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5vdXRwdXRbaV0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib3V0cHV0OiBzdHJpbmdbXSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJuYW1lXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5uYW1lKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibmFtZTogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vcFR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwib3BUeXBlXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5vcFR5cGUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJvcFR5cGU6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvbWFpblwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9tYWluKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZG9tYWluOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmF0dHJpYnV0ZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJhdHRyaWJ1dGVcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5hdHRyaWJ1dGUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhdHRyaWJ1dGU6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLnZlcmlmeShtZXNzYWdlLmF0dHJpYnV0ZVtpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImF0dHJpYnV0ZS5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvY1N0cmluZykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRvY1N0cmluZzogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIE5vZGVQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguTm9kZVByb3RvfSBOb2RlUHJvdG9cbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54Lk5vZGVQcm90bylcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5Ob2RlUHJvdG8oKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QuaW5wdXQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmlucHV0KSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguTm9kZVByb3RvLmlucHV0OiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW5wdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXRbaV0gPSBTdHJpbmcob2JqZWN0LmlucHV0W2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3Qub3V0cHV0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5vdXRwdXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5Ob2RlUHJvdG8ub3V0cHV0OiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm91dHB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5vdXRwdXRbaV0gPSBTdHJpbmcob2JqZWN0Lm91dHB1dFtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5vcFR5cGUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLm9wVHlwZSA9IFN0cmluZyhvYmplY3Qub3BUeXBlKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QuZG9tYWluICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5kb21haW4gPSBTdHJpbmcob2JqZWN0LmRvbWFpbik7XG4gICAgICAgICAgICBpZiAob2JqZWN0LmF0dHJpYnV0ZSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuYXR0cmlidXRlKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguTm9kZVByb3RvLmF0dHJpYnV0ZTogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuYXR0cmlidXRlW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguTm9kZVByb3RvLmF0dHJpYnV0ZTogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZVtpXSA9ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZnJvbU9iamVjdChvYmplY3QuYXR0cmlidXRlW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIE5vZGVQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguTm9kZVByb3RvfSBtZXNzYWdlIE5vZGVQcm90b1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgIG9iamVjdC5pbnB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QuYXR0cmlidXRlID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgIG9iamVjdC5uYW1lID0gXCJcIjtcbiAgICAgICAgICAgICAgICBvYmplY3Qub3BUeXBlID0gXCJcIjtcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gXCJcIjtcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9tYWluID0gXCJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmlucHV0ICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuaW5wdXRbal0gPSBtZXNzYWdlLmlucHV0W2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3Qub3V0cHV0W2pdID0gbWVzc2FnZS5vdXRwdXRbal07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm5hbWVcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vcFR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwib3BUeXBlXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5vcFR5cGUgPSBtZXNzYWdlLm9wVHlwZTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmF0dHJpYnV0ZSAmJiBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuYXR0cmlidXRlID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZVtqXSA9ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8udG9PYmplY3QobWVzc2FnZS5hdHRyaWJ1dGVbal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gbWVzc2FnZS5kb2NTdHJpbmc7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9tYWluXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5kb21haW4gPSBtZXNzYWdlLmRvbWFpbjtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnZlcnRzIHRoaXMgTm9kZVByb3RvIHRvIEpTT04uXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBOb2RlUHJvdG9cbiAgICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgXCIvb25ueC5Ob2RlUHJvdG9cIjtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gTm9kZVByb3RvO1xuICAgIH0pKCk7XG5cbiAgICBvbm54LlRyYWluaW5nSW5mb1Byb3RvID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVHJhaW5pbmdJbmZvUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBpbnRlcmZhY2UgSVRyYWluaW5nSW5mb1Byb3RvXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JR3JhcGhQcm90b3xudWxsfSBbaW5pdGlhbGl6YXRpb25dIFRyYWluaW5nSW5mb1Byb3RvIGluaXRpYWxpemF0aW9uXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JR3JhcGhQcm90b3xudWxsfSBbYWxnb3JpdGhtXSBUcmFpbmluZ0luZm9Qcm90byBhbGdvcml0aG1cbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz58bnVsbH0gW2luaXRpYWxpemF0aW9uQmluZGluZ10gVHJhaW5pbmdJbmZvUHJvdG8gaW5pdGlhbGl6YXRpb25CaW5kaW5nXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFt1cGRhdGVCaW5kaW5nXSBUcmFpbmluZ0luZm9Qcm90byB1cGRhdGVCaW5kaW5nXG4gICAgICAgICAqL1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFRyYWluaW5nSW5mb1Byb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBUcmFpbmluZ0luZm9Qcm90by5cbiAgICAgICAgICogQGltcGxlbWVudHMgSVRyYWluaW5nSW5mb1Byb3RvXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVRyYWluaW5nSW5mb1Byb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBUcmFpbmluZ0luZm9Qcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemF0aW9uQmluZGluZyA9IFtdO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVCaW5kaW5nID0gW107XG4gICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRyYWluaW5nSW5mb1Byb3RvIGluaXRpYWxpemF0aW9uLlxuICAgICAgICAgKiBAbWVtYmVyIHtvbm54LklHcmFwaFByb3RvfG51bGx8dW5kZWZpbmVkfSBpbml0aWFsaXphdGlvblxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRyYWluaW5nSW5mb1Byb3RvLnByb3RvdHlwZS5pbml0aWFsaXphdGlvbiA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRyYWluaW5nSW5mb1Byb3RvIGFsZ29yaXRobS5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5JR3JhcGhQcm90b3xudWxsfHVuZGVmaW5lZH0gYWxnb3JpdGhtXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVHJhaW5pbmdJbmZvUHJvdG8ucHJvdG90eXBlLmFsZ29yaXRobSA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRyYWluaW5nSW5mb1Byb3RvIGluaXRpYWxpemF0aW9uQmluZGluZy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSBpbml0aWFsaXphdGlvbkJpbmRpbmdcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUcmFpbmluZ0luZm9Qcm90by5wcm90b3R5cGUuaW5pdGlhbGl6YXRpb25CaW5kaW5nID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVHJhaW5pbmdJbmZvUHJvdG8gdXBkYXRlQmluZGluZy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSB1cGRhdGVCaW5kaW5nXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVHJhaW5pbmdJbmZvUHJvdG8ucHJvdG90eXBlLnVwZGF0ZUJpbmRpbmcgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IFRyYWluaW5nSW5mb1Byb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVHJhaW5pbmdJbmZvUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICogQHJldHVybnMge29ubnguVHJhaW5pbmdJbmZvUHJvdG99IFRyYWluaW5nSW5mb1Byb3RvIGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUcmFpbmluZ0luZm9Qcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBUcmFpbmluZ0luZm9Qcm90byhwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRyYWluaW5nSW5mb1Byb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHJhaW5pbmdJbmZvUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVRyYWluaW5nSW5mb1Byb3RvfSBtZXNzYWdlIFRyYWluaW5nSW5mb1Byb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgVHJhaW5pbmdJbmZvUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJpbml0aWFsaXphdGlvblwiKSlcbiAgICAgICAgICAgICAgICAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZW5jb2RlKG1lc3NhZ2UuaW5pdGlhbGl6YXRpb24sIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8xMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmFsZ29yaXRobSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiYWxnb3JpdGhtXCIpKVxuICAgICAgICAgICAgICAgICRyb290Lm9ubnguR3JhcGhQcm90by5lbmNvZGUobWVzc2FnZS5hbGdvcml0aG0sIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8xOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZyAhPSBudWxsICYmIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlKG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovMjYpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS51cGRhdGVCaW5kaW5nICE9IG51bGwgJiYgbWVzc2FnZS51cGRhdGVCaW5kaW5nLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZShtZXNzYWdlLnVwZGF0ZUJpbmRpbmdbaV0sIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8zNCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRyYWluaW5nSW5mb1Byb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUcmFpbmluZ0luZm9Qcm90b30gbWVzc2FnZSBUcmFpbmluZ0luZm9Qcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFRyYWluaW5nSW5mb1Byb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UcmFpbmluZ0luZm9Qcm90b30gVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBUcmFpbmluZ0luZm9Qcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRyYWluaW5nSW5mb1Byb3RvKCk7XG4gICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb24gPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmFsZ29yaXRobSA9ICRyb290Lm9ubnguR3JhcGhQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nICYmIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLnB1c2goJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UudXBkYXRlQmluZGluZyAmJiBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudXBkYXRlQmluZGluZy5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFRyYWluaW5nSW5mb1Byb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguVHJhaW5pbmdJbmZvUHJvdG99IFRyYWluaW5nSW5mb1Byb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgVHJhaW5pbmdJbmZvUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGEgVHJhaW5pbmdJbmZvUHJvdG8gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgKi9cbiAgICAgICAgVHJhaW5pbmdJbmZvUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5pdGlhbGl6YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiaW5pdGlhbGl6YXRpb25cIikpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udmVyaWZ5KG1lc3NhZ2UuaW5pdGlhbGl6YXRpb24pO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW5pdGlhbGl6YXRpb24uXCIgKyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmFsZ29yaXRobSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJhbGdvcml0aG1cIikpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udmVyaWZ5KG1lc3NhZ2UuYWxnb3JpdGhtKTtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImFsZ29yaXRobS5cIiArIGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImluaXRpYWxpemF0aW9uQmluZGluZ1wiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmluaXRpYWxpemF0aW9uQmluZGluZykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImluaXRpYWxpemF0aW9uQmluZGluZzogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnkobWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmdbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJpbml0aWFsaXphdGlvbkJpbmRpbmcuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS51cGRhdGVCaW5kaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInVwZGF0ZUJpbmRpbmdcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS51cGRhdGVCaW5kaW5nKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidXBkYXRlQmluZGluZzogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UudXBkYXRlQmluZGluZ1tpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcInVwZGF0ZUJpbmRpbmcuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIFRyYWluaW5nSW5mb1Byb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHJhaW5pbmdJbmZvUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRyYWluaW5nSW5mb1Byb3RvfSBUcmFpbmluZ0luZm9Qcm90b1xuICAgICAgICAgKi9cbiAgICAgICAgVHJhaW5pbmdJbmZvUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90bylcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90bygpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5pbml0aWFsaXphdGlvbiAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5pdGlhbGl6YXRpb24gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmluaXRpYWxpemF0aW9uOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbiA9ICRyb290Lm9ubnguR3JhcGhQcm90by5mcm9tT2JqZWN0KG9iamVjdC5pbml0aWFsaXphdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmFsZ29yaXRobSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuYWxnb3JpdGhtICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UcmFpbmluZ0luZm9Qcm90by5hbGdvcml0aG06IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmFsZ29yaXRobSA9ICRyb290Lm9ubnguR3JhcGhQcm90by5mcm9tT2JqZWN0KG9iamVjdC5hbGdvcml0aG0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmcpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmluaXRpYWxpemF0aW9uQmluZGluZzogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmcubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5pdGlhbGl6YXRpb25CaW5kaW5nW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVHJhaW5pbmdJbmZvUHJvdG8uaW5pdGlhbGl6YXRpb25CaW5kaW5nOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6YXRpb25CaW5kaW5nW2ldID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmZyb21PYmplY3Qob2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZ1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC51cGRhdGVCaW5kaW5nKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC51cGRhdGVCaW5kaW5nKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVHJhaW5pbmdJbmZvUHJvdG8udXBkYXRlQmluZGluZzogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS51cGRhdGVCaW5kaW5nID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QudXBkYXRlQmluZGluZy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC51cGRhdGVCaW5kaW5nW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVHJhaW5pbmdJbmZvUHJvdG8udXBkYXRlQmluZGluZzogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnVwZGF0ZUJpbmRpbmdbaV0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdChvYmplY3QudXBkYXRlQmluZGluZ1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFRyYWluaW5nSW5mb1Byb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRyYWluaW5nSW5mb1Byb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LlRyYWluaW5nSW5mb1Byb3RvfSBtZXNzYWdlIFRyYWluaW5nSW5mb1Byb3RvXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgVHJhaW5pbmdJbmZvUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuaW5pdGlhbGl6YXRpb25CaW5kaW5nID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LnVwZGF0ZUJpbmRpbmcgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmluaXRpYWxpemF0aW9uID0gbnVsbDtcbiAgICAgICAgICAgICAgICBvYmplY3QuYWxnb3JpdGhtID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImluaXRpYWxpemF0aW9uXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbiA9ICRyb290Lm9ubnguR3JhcGhQcm90by50b09iamVjdChtZXNzYWdlLmluaXRpYWxpemF0aW9uLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmFsZ29yaXRobSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJhbGdvcml0aG1cIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmFsZ29yaXRobSA9ICRyb290Lm9ubnguR3JhcGhQcm90by50b09iamVjdChtZXNzYWdlLmFsZ29yaXRobSwgb3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcgJiYgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmluaXRpYWxpemF0aW9uQmluZGluZyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmcubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbml0aWFsaXphdGlvbkJpbmRpbmdbal0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udG9PYmplY3QobWVzc2FnZS5pbml0aWFsaXphdGlvbkJpbmRpbmdbal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudXBkYXRlQmluZGluZyAmJiBtZXNzYWdlLnVwZGF0ZUJpbmRpbmcubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnVwZGF0ZUJpbmRpbmcgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UudXBkYXRlQmluZGluZy5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnVwZGF0ZUJpbmRpbmdbal0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udG9PYmplY3QobWVzc2FnZS51cGRhdGVCaW5kaW5nW2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnZlcnRzIHRoaXMgVHJhaW5pbmdJbmZvUHJvdG8gdG8gSlNPTi5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgVHJhaW5pbmdJbmZvUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBUcmFpbmluZ0luZm9Qcm90b1xuICAgICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UcmFpbmluZ0luZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICAgKi9cbiAgICAgICAgVHJhaW5pbmdJbmZvUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgXCIvb25ueC5UcmFpbmluZ0luZm9Qcm90b1wiO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBUcmFpbmluZ0luZm9Qcm90bztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5Nb2RlbFByb3RvID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgTW9kZWxQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGludGVyZmFjZSBJTW9kZWxQcm90b1xuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcnxMb25nfG51bGx9IFtpclZlcnNpb25dIE1vZGVsUHJvdG8gaXJWZXJzaW9uXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSU9wZXJhdG9yU2V0SWRQcm90bz58bnVsbH0gW29wc2V0SW1wb3J0XSBNb2RlbFByb3RvIG9wc2V0SW1wb3J0XG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtwcm9kdWNlck5hbWVdIE1vZGVsUHJvdG8gcHJvZHVjZXJOYW1lXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtwcm9kdWNlclZlcnNpb25dIE1vZGVsUHJvdG8gcHJvZHVjZXJWZXJzaW9uXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb21haW5dIE1vZGVsUHJvdG8gZG9tYWluXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW21vZGVsVmVyc2lvbl0gTW9kZWxQcm90byBtb2RlbFZlcnNpb25cbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gTW9kZWxQcm90byBkb2NTdHJpbmdcbiAgICAgICAgICogQHByb3BlcnR5IHtvbm54LklHcmFwaFByb3RvfG51bGx9IFtncmFwaF0gTW9kZWxQcm90byBncmFwaFxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPnxudWxsfSBbbWV0YWRhdGFQcm9wc10gTW9kZWxQcm90byBtZXRhZGF0YVByb3BzXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVRyYWluaW5nSW5mb1Byb3RvPnxudWxsfSBbdHJhaW5pbmdJbmZvXSBNb2RlbFByb3RvIHRyYWluaW5nSW5mb1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklGdW5jdGlvblByb3RvPnxudWxsfSBbZnVuY3Rpb25zXSBNb2RlbFByb3RvIGZ1bmN0aW9uc1xuICAgICAgICAgKi9cblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBNb2RlbFByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBNb2RlbFByb3RvLlxuICAgICAgICAgKiBAaW1wbGVtZW50cyBJTW9kZWxQcm90b1xuICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklNb2RlbFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBNb2RlbFByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHRoaXMub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgICAgIHRoaXMubWV0YWRhdGFQcm9wcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy50cmFpbmluZ0luZm8gPSBbXTtcbiAgICAgICAgICAgIHRoaXMuZnVuY3Rpb25zID0gW107XG4gICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1vZGVsUHJvdG8gaXJWZXJzaW9uLlxuICAgICAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gaXJWZXJzaW9uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5pclZlcnNpb24gPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLDAsZmFsc2UpIDogMDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTW9kZWxQcm90byBvcHNldEltcG9ydC5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSU9wZXJhdG9yU2V0SWRQcm90bz59IG9wc2V0SW1wb3J0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5vcHNldEltcG9ydCA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1vZGVsUHJvdG8gcHJvZHVjZXJOYW1lLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IHByb2R1Y2VyTmFtZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTW9kZWxQcm90by5wcm90b3R5cGUucHJvZHVjZXJOYW1lID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTW9kZWxQcm90byBwcm9kdWNlclZlcnNpb24uXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gcHJvZHVjZXJWZXJzaW9uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5wcm9kdWNlclZlcnNpb24gPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2RlbFByb3RvIGRvbWFpbi5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBkb21haW5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLmRvbWFpbiA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1vZGVsUHJvdG8gbW9kZWxWZXJzaW9uLlxuICAgICAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gbW9kZWxWZXJzaW9uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5tb2RlbFZlcnNpb24gPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLDAsZmFsc2UpIDogMDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTW9kZWxQcm90byBkb2NTdHJpbmcuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9jU3RyaW5nXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2RlbFByb3RvIGdyYXBoLlxuICAgICAgICAgKiBAbWVtYmVyIHtvbm54LklHcmFwaFByb3RvfG51bGx8dW5kZWZpbmVkfSBncmFwaFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTW9kZWxQcm90by5wcm90b3R5cGUuZ3JhcGggPSBudWxsO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2RlbFByb3RvIG1ldGFkYXRhUHJvcHMuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPn0gbWV0YWRhdGFQcm9wc1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTW9kZWxQcm90by5wcm90b3R5cGUubWV0YWRhdGFQcm9wcyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1vZGVsUHJvdG8gdHJhaW5pbmdJbmZvLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVHJhaW5pbmdJbmZvUHJvdG8+fSB0cmFpbmluZ0luZm9cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLnRyYWluaW5nSW5mbyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1vZGVsUHJvdG8gZnVuY3Rpb25zLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JRnVuY3Rpb25Qcm90bz59IGZ1bmN0aW9uc1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTW9kZWxQcm90by5wcm90b3R5cGUuZnVuY3Rpb25zID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBNb2RlbFByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklNb2RlbFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54Lk1vZGVsUHJvdG99IE1vZGVsUHJvdG8gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgTW9kZWxQcm90byhwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1vZGVsUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5Nb2RlbFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSU1vZGVsUHJvdG99IG1lc3NhZ2UgTW9kZWxQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmlyVmVyc2lvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiaXJWZXJzaW9uXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki84KS5pbnQ2NChtZXNzYWdlLmlyVmVyc2lvbik7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5wcm9kdWNlck5hbWUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcInByb2R1Y2VyTmFtZVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovMTgpLnN0cmluZyhtZXNzYWdlLnByb2R1Y2VyTmFtZSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5wcm9kdWNlclZlcnNpb24gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcInByb2R1Y2VyVmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovMjYpLnN0cmluZyhtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbik7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcImRvbWFpblwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDQsIHdpcmVUeXBlIDIgPSovMzQpLnN0cmluZyhtZXNzYWdlLmRvbWFpbik7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5tb2RlbFZlcnNpb24gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcIm1vZGVsVmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDAgPSovNDApLmludDY0KG1lc3NhZ2UubW9kZWxWZXJzaW9uKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki81MCkuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmdyYXBoICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJncmFwaFwiKSlcbiAgICAgICAgICAgICAgICAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZW5jb2RlKG1lc3NhZ2UuZ3JhcGgsIHdyaXRlci51aW50MzIoLyogaWQgNywgd2lyZVR5cGUgMiA9Ki81OCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm9wc2V0SW1wb3J0ICE9IG51bGwgJiYgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by5lbmNvZGUobWVzc2FnZS5vcHNldEltcG9ydFtpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLzY2KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubWV0YWRhdGFQcm9wcyAhPSBudWxsICYmIG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm1ldGFkYXRhUHJvcHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5lbmNvZGUobWVzc2FnZS5tZXRhZGF0YVByb3BzW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDE0LCB3aXJlVHlwZSAyID0qLzExNCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRyYWluaW5nSW5mbyAhPSBudWxsICYmIG1lc3NhZ2UudHJhaW5pbmdJbmZvLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudHJhaW5pbmdJbmZvLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlRyYWluaW5nSW5mb1Byb3RvLmVuY29kZShtZXNzYWdlLnRyYWluaW5nSW5mb1tpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyMCwgd2lyZVR5cGUgMiA9Ki8xNjIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5mdW5jdGlvbnMgIT0gbnVsbCAmJiBtZXNzYWdlLmZ1bmN0aW9ucy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmZ1bmN0aW9ucy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5GdW5jdGlvblByb3RvLmVuY29kZShtZXNzYWdlLmZ1bmN0aW9uc1tpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyNSwgd2lyZVR5cGUgMiA9Ki8yMDIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgTW9kZWxQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54Lk1vZGVsUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JTW9kZWxQcm90b30gbWVzc2FnZSBNb2RlbFByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgTW9kZWxQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIE1vZGVsUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54Lk1vZGVsUHJvdG99IE1vZGVsUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLCBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguTW9kZWxQcm90bygpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmlyVmVyc2lvbiA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDg6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uub3BzZXRJbXBvcnQgJiYgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnQucHVzaCgkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnByb2R1Y2VyTmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSA0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRvbWFpbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSA1OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm1vZGVsVmVyc2lvbiA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDY6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZ3JhcGggPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAxNDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5tZXRhZGF0YVByb3BzICYmIG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubWV0YWRhdGFQcm9wcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5tZXRhZGF0YVByb3BzLnB1c2goJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDIwOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLnRyYWluaW5nSW5mbyAmJiBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudHJhaW5pbmdJbmZvID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnRyYWluaW5nSW5mby5wdXNoKCRyb290Lm9ubnguVHJhaW5pbmdJbmZvUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgMjU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZnVuY3Rpb25zICYmIG1lc3NhZ2UuZnVuY3Rpb25zLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5mdW5jdGlvbnMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZnVuY3Rpb25zLnB1c2goJHJvb3Qub25ueC5GdW5jdGlvblByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgTW9kZWxQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguTW9kZWxQcm90b30gTW9kZWxQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGEgTW9kZWxQcm90byBtZXNzYWdlLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImlyVmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmlyVmVyc2lvbikgJiYgIShtZXNzYWdlLmlyVmVyc2lvbiAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pclZlcnNpb24ubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pclZlcnNpb24uaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJpclZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwib3BzZXRJbXBvcnRcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5vcHNldEltcG9ydCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm9wc2V0SW1wb3J0OiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by52ZXJpZnkobWVzc2FnZS5vcHNldEltcG9ydFtpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm9wc2V0SW1wb3J0LlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucHJvZHVjZXJOYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInByb2R1Y2VyTmFtZVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UucHJvZHVjZXJOYW1lKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwicHJvZHVjZXJOYW1lOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJwcm9kdWNlclZlcnNpb25cIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInByb2R1Y2VyVmVyc2lvbjogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9tYWluXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb21haW4pKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkb21haW46IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubW9kZWxWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm1vZGVsVmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLm1vZGVsVmVyc2lvbikgJiYgIShtZXNzYWdlLm1vZGVsVmVyc2lvbiAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5tb2RlbFZlcnNpb24ubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5tb2RlbFZlcnNpb24uaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJtb2RlbFZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmdyYXBoICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImdyYXBoXCIpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnZlcmlmeShtZXNzYWdlLmdyYXBoKTtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImdyYXBoLlwiICsgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5tZXRhZGF0YVByb3BzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm1ldGFkYXRhUHJvcHNcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5tZXRhZGF0YVByb3BzKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibWV0YWRhdGFQcm9wczogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UubWV0YWRhdGFQcm9wc1tpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm1ldGFkYXRhUHJvcHMuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50cmFpbmluZ0luZm8gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidHJhaW5pbmdJbmZvXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudHJhaW5pbmdJbmZvKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidHJhaW5pbmdJbmZvOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50cmFpbmluZ0luZm8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90by52ZXJpZnkobWVzc2FnZS50cmFpbmluZ0luZm9baV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0cmFpbmluZ0luZm8uXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5mdW5jdGlvbnMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZnVuY3Rpb25zXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuZnVuY3Rpb25zKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZnVuY3Rpb25zOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mdW5jdGlvbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5GdW5jdGlvblByb3RvLnZlcmlmeShtZXNzYWdlLmZ1bmN0aW9uc1tpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImZ1bmN0aW9ucy5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgTW9kZWxQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54Lk1vZGVsUHJvdG99IE1vZGVsUHJvdG9cbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5Nb2RlbFByb3RvKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk1vZGVsUHJvdG8oKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QuaXJWZXJzaW9uICE9IG51bGwpXG4gICAgICAgICAgICAgICAgaWYgKCR1dGlsLkxvbmcpXG4gICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLmlyVmVyc2lvbiA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5pclZlcnNpb24pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaXJWZXJzaW9uID09PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmlyVmVyc2lvbiA9IHBhcnNlSW50KG9iamVjdC5pclZlcnNpb24sIDEwKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmlyVmVyc2lvbiA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pclZlcnNpb24gPSBvYmplY3QuaXJWZXJzaW9uO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaXJWZXJzaW9uID09PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmlyVmVyc2lvbiA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuaXJWZXJzaW9uLmxvdyA+Pj4gMCwgb2JqZWN0LmlyVmVyc2lvbi5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5vcHNldEltcG9ydCkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qub3BzZXRJbXBvcnQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5Nb2RlbFByb3RvLm9wc2V0SW1wb3J0OiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qub3BzZXRJbXBvcnQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Qub3BzZXRJbXBvcnRbaV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5Nb2RlbFByb3RvLm9wc2V0SW1wb3J0OiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnRbaV0gPSAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by5mcm9tT2JqZWN0KG9iamVjdC5vcHNldEltcG9ydFtpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5wcm9kdWNlck5hbWUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnByb2R1Y2VyTmFtZSA9IFN0cmluZyhvYmplY3QucHJvZHVjZXJOYW1lKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QucHJvZHVjZXJWZXJzaW9uICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5wcm9kdWNlclZlcnNpb24gPSBTdHJpbmcob2JqZWN0LnByb2R1Y2VyVmVyc2lvbik7XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRvbWFpbiAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gU3RyaW5nKG9iamVjdC5kb21haW4pO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5tb2RlbFZlcnNpb24gIT0gbnVsbClcbiAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgKG1lc3NhZ2UubW9kZWxWZXJzaW9uID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0Lm1vZGVsVmVyc2lvbikpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5tb2RlbFZlcnNpb24gPT09IFwic3RyaW5nXCIpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubW9kZWxWZXJzaW9uID0gcGFyc2VJbnQob2JqZWN0Lm1vZGVsVmVyc2lvbiwgMTApO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QubW9kZWxWZXJzaW9uID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm1vZGVsVmVyc2lvbiA9IG9iamVjdC5tb2RlbFZlcnNpb247XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5tb2RlbFZlcnNpb24gPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubW9kZWxWZXJzaW9uID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5tb2RlbFZlcnNpb24ubG93ID4+PiAwLCBvYmplY3QubW9kZWxWZXJzaW9uLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5ncmFwaCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZ3JhcGggIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54Lk1vZGVsUHJvdG8uZ3JhcGg6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmdyYXBoID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLmZyb21PYmplY3Qob2JqZWN0LmdyYXBoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QubWV0YWRhdGFQcm9wcykge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QubWV0YWRhdGFQcm9wcykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54Lk1vZGVsUHJvdG8ubWV0YWRhdGFQcm9wczogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5tZXRhZGF0YVByb3BzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QubWV0YWRhdGFQcm9wcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5tZXRhZGF0YVByb3BzW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguTW9kZWxQcm90by5tZXRhZGF0YVByb3BzOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubWV0YWRhdGFQcm9wc1tpXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5mcm9tT2JqZWN0KG9iamVjdC5tZXRhZGF0YVByb3BzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LnRyYWluaW5nSW5mbykge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QudHJhaW5pbmdJbmZvKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguTW9kZWxQcm90by50cmFpbmluZ0luZm86IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHJhaW5pbmdJbmZvID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QudHJhaW5pbmdJbmZvLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnRyYWluaW5nSW5mb1tpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54Lk1vZGVsUHJvdG8udHJhaW5pbmdJbmZvOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudHJhaW5pbmdJbmZvW2ldID0gJHJvb3Qub25ueC5UcmFpbmluZ0luZm9Qcm90by5mcm9tT2JqZWN0KG9iamVjdC50cmFpbmluZ0luZm9baV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QuZnVuY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5mdW5jdGlvbnMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5Nb2RlbFByb3RvLmZ1bmN0aW9uczogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5mdW5jdGlvbnMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5mdW5jdGlvbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZnVuY3Rpb25zW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguTW9kZWxQcm90by5mdW5jdGlvbnM6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5mdW5jdGlvbnNbaV0gPSAkcm9vdC5vbm54LkZ1bmN0aW9uUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZnVuY3Rpb25zW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgTW9kZWxQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54Lk1vZGVsUHJvdG99IG1lc3NhZ2UgTW9kZWxQcm90b1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3Qub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QubWV0YWRhdGFQcm9wcyA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC50cmFpbmluZ0luZm8gPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QuZnVuY3Rpb25zID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsb25nID0gbmV3ICR1dGlsLkxvbmcoMCwgMCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuaXJWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gbG9uZy50b1N0cmluZygpIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbG9uZy50b051bWJlcigpIDogbG9uZztcbiAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmlyVmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFwiMFwiIDogMDtcbiAgICAgICAgICAgICAgICBvYmplY3QucHJvZHVjZXJOYW1lID0gXCJcIjtcbiAgICAgICAgICAgICAgICBvYmplY3QucHJvZHVjZXJWZXJzaW9uID0gXCJcIjtcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9tYWluID0gXCJcIjtcbiAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Lm1vZGVsVmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5tb2RlbFZlcnNpb24gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBcIjBcIiA6IDA7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmdyYXBoID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmlyVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJpclZlcnNpb25cIikpXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmlyVmVyc2lvbiA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmlyVmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmlyVmVyc2lvbikgOiBtZXNzYWdlLmlyVmVyc2lvbjtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5pclZlcnNpb24gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuaXJWZXJzaW9uKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmlyVmVyc2lvbi5sb3cgPj4+IDAsIG1lc3NhZ2UuaXJWZXJzaW9uLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCkgOiBtZXNzYWdlLmlyVmVyc2lvbjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyTmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJwcm9kdWNlck5hbWVcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnByb2R1Y2VyTmFtZSA9IG1lc3NhZ2UucHJvZHVjZXJOYW1lO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInByb2R1Y2VyVmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QucHJvZHVjZXJWZXJzaW9uID0gbWVzc2FnZS5wcm9kdWNlclZlcnNpb247XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9tYWluXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5kb21haW4gPSBtZXNzYWdlLmRvbWFpbjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm1vZGVsVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJtb2RlbFZlcnNpb25cIikpXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLm1vZGVsVmVyc2lvbiA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Lm1vZGVsVmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLm1vZGVsVmVyc2lvbikgOiBtZXNzYWdlLm1vZGVsVmVyc2lvbjtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5tb2RlbFZlcnNpb24gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UubW9kZWxWZXJzaW9uKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLm1vZGVsVmVyc2lvbi5sb3cgPj4+IDAsIG1lc3NhZ2UubW9kZWxWZXJzaW9uLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCkgOiBtZXNzYWdlLm1vZGVsVmVyc2lvbjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZ3JhcGggIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZ3JhcGhcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmdyYXBoID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZ3JhcGgsIG9wdGlvbnMpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgJiYgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3Qub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5vcHNldEltcG9ydFtqXSA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uub3BzZXRJbXBvcnRbal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubWV0YWRhdGFQcm9wcyAmJiBtZXNzYWdlLm1ldGFkYXRhUHJvcHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm1ldGFkYXRhUHJvcHMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Lm1ldGFkYXRhUHJvcHNbal0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udG9PYmplY3QobWVzc2FnZS5tZXRhZGF0YVByb3BzW2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRyYWluaW5nSW5mbyAmJiBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QudHJhaW5pbmdJbmZvID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnRyYWluaW5nSW5mby5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnRyYWluaW5nSW5mb1tqXSA9ICRyb290Lm9ubnguVHJhaW5pbmdJbmZvUHJvdG8udG9PYmplY3QobWVzc2FnZS50cmFpbmluZ0luZm9bal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZnVuY3Rpb25zICYmIG1lc3NhZ2UuZnVuY3Rpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5mdW5jdGlvbnMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZnVuY3Rpb25zLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZnVuY3Rpb25zW2pdID0gJHJvb3Qub25ueC5GdW5jdGlvblByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZnVuY3Rpb25zW2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnZlcnRzIHRoaXMgTW9kZWxQcm90byB0byBKU09OLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBNb2RlbFByb3RvXG4gICAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgXCIvb25ueC5Nb2RlbFByb3RvXCI7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIE1vZGVsUHJvdG87XG4gICAgfSkoKTtcblxuICAgIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90byA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJvcGVydGllcyBvZiBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBpbnRlcmZhY2UgSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2tleV0gU3RyaW5nU3RyaW5nRW50cnlQcm90byBrZXlcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW3ZhbHVlXSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIHZhbHVlXG4gICAgICAgICAqL1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uXG4gICAgICAgICAqIEBpbXBsZW1lbnRzIElTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ocHJvcGVydGllcykge1xuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIGtleS5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBrZXlcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLmtleSA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gdmFsdWUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gdmFsdWVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLnZhbHVlID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nU3RyaW5nRW50cnlQcm90byhwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IG1lc3NhZ2UgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmtleSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwia2V5XCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8xMCkuc3RyaW5nKG1lc3NhZ2Uua2V5KTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnZhbHVlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJ2YWx1ZVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovMTgpLnN0cmluZyhtZXNzYWdlLnZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvfSBtZXNzYWdlIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICogQHJldHVybnMge29ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b30gU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvKCk7XG4gICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uua2V5ID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudmFsdWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvfSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVmVyaWZpZXMgYSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2UuXG4gICAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgKi9cbiAgICAgICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5rZXkgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwia2V5XCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5rZXkpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJrZXk6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidmFsdWVcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnZhbHVlKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidmFsdWU6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b30gU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKi9cbiAgICAgICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8pXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90bygpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5rZXkgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmtleSA9IFN0cmluZyhvYmplY3Qua2V5KTtcbiAgICAgICAgICAgIGlmIChvYmplY3QudmFsdWUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnZhbHVlID0gU3RyaW5nKG9iamVjdC52YWx1ZSk7XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IG1lc3NhZ2UgU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3Qua2V5ID0gXCJcIjtcbiAgICAgICAgICAgICAgICBvYmplY3QudmFsdWUgPSBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uua2V5ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImtleVwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3Qua2V5ID0gbWVzc2FnZS5rZXk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS52YWx1ZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJ2YWx1ZVwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QudmFsdWUgPSBtZXNzYWdlLnZhbHVlO1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydHMgdGhpcyBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIHRvIEpTT04uXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICAgKi9cbiAgICAgICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdHlwZVVybFByZWZpeCA9IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyBcIi9vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cIjtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gU3RyaW5nU3RyaW5nRW50cnlQcm90bztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5UZW5zb3JBbm5vdGF0aW9uID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVGVuc29yQW5ub3RhdGlvbi5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGludGVyZmFjZSBJVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbdGVuc29yTmFtZV0gVGVuc29yQW5ub3RhdGlvbiB0ZW5zb3JOYW1lXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFtxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzXSBUZW5zb3JBbm5vdGF0aW9uIHF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNcbiAgICAgICAgICovXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVGVuc29yQW5ub3RhdGlvbi5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVGVuc29yQW5ub3RhdGlvbi5cbiAgICAgICAgICogQGltcGxlbWVudHMgSVRlbnNvckFubm90YXRpb25cbiAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yQW5ub3RhdGlvbj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gVGVuc29yQW5ub3RhdGlvbihwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICB0aGlzLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgPSBbXTtcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogVGVuc29yQW5ub3RhdGlvbiB0ZW5zb3JOYW1lLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IHRlbnNvck5hbWVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvckFubm90YXRpb24ucHJvdG90eXBlLnRlbnNvck5hbWUgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JBbm5vdGF0aW9uIHF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPn0gcXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yQW5ub3RhdGlvbi5wcm90b3R5cGUucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgVGVuc29yQW5ub3RhdGlvbiBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yQW5ub3RhdGlvbj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JBbm5vdGF0aW9ufSBUZW5zb3JBbm5vdGF0aW9uIGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JBbm5vdGF0aW9uLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFRlbnNvckFubm90YXRpb24ocHJvcGVydGllcyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yQW5ub3RhdGlvbi52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JBbm5vdGF0aW9ufSBtZXNzYWdlIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JBbm5vdGF0aW9uLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIGlmICghd3JpdGVyKVxuICAgICAgICAgICAgICAgIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50ZW5zb3JOYW1lICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJ0ZW5zb3JOYW1lXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8xMCkuc3RyaW5nKG1lc3NhZ2UudGVuc29yTmFtZSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzICE9IG51bGwgJiYgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZShtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbaV0sIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8xOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yQW5ub3RhdGlvbi52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JBbm5vdGF0aW9ufSBtZXNzYWdlIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JBbm5vdGF0aW9uLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yQW5ub3RhdGlvbn0gVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvckFubm90YXRpb24uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uKCk7XG4gICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudGVuc29yTmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgJiYgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMucHVzaCgkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYSBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JBbm5vdGF0aW9ufSBUZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yQW5ub3RhdGlvbi5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVmVyaWZpZXMgYSBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2UuXG4gICAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yQW5ub3RhdGlvbi52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50ZW5zb3JOYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInRlbnNvck5hbWVcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnRlbnNvck5hbWUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0ZW5zb3JOYW1lOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwicXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1wiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnkobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwicXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvckFubm90YXRpb259IFRlbnNvckFubm90YXRpb25cbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvckFubm90YXRpb24uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24oKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QudGVuc29yTmFtZSAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudGVuc29yTmFtZSA9IFN0cmluZyhvYmplY3QudGVuc29yTmFtZSk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UZW5zb3JBbm5vdGF0aW9uLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXM6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRlbnNvckFubm90YXRpb24ucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lczogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbaV0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdChvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JBbm5vdGF0aW9ufSBtZXNzYWdlIFRlbnNvckFubm90YXRpb25cbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JBbm5vdGF0aW9uLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKVxuICAgICAgICAgICAgICAgIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cylcbiAgICAgICAgICAgICAgICBvYmplY3QudGVuc29yTmFtZSA9IFwiXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50ZW5zb3JOYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInRlbnNvck5hbWVcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnRlbnNvck5hbWUgPSBtZXNzYWdlLnRlbnNvck5hbWU7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzICYmIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tqXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by50b09iamVjdChtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydHMgdGhpcyBUZW5zb3JBbm5vdGF0aW9uIHRvIEpTT04uXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yQW5ub3RhdGlvbi5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFRlbnNvckFubm90YXRpb25cbiAgICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yQW5ub3RhdGlvbi5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdHlwZVVybFByZWZpeCA9IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyBcIi9vbm54LlRlbnNvckFubm90YXRpb25cIjtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gVGVuc29yQW5ub3RhdGlvbjtcbiAgICB9KSgpO1xuXG4gICAgb25ueC5HcmFwaFByb3RvID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgR3JhcGhQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGludGVyZmFjZSBJR3JhcGhQcm90b1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklOb2RlUHJvdG8+fG51bGx9IFtub2RlXSBHcmFwaFByb3RvIG5vZGVcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW25hbWVdIEdyYXBoUHJvdG8gbmFtZVxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUZW5zb3JQcm90bz58bnVsbH0gW2luaXRpYWxpemVyXSBHcmFwaFByb3RvIGluaXRpYWxpemVyXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVNwYXJzZVRlbnNvclByb3RvPnxudWxsfSBbc3BhcnNlSW5pdGlhbGl6ZXJdIEdyYXBoUHJvdG8gc3BhcnNlSW5pdGlhbGl6ZXJcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gR3JhcGhQcm90byBkb2NTdHJpbmdcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JVmFsdWVJbmZvUHJvdG8+fG51bGx9IFtpbnB1dF0gR3JhcGhQcm90byBpbnB1dFxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklWYWx1ZUluZm9Qcm90bz58bnVsbH0gW291dHB1dF0gR3JhcGhQcm90byBvdXRwdXRcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JVmFsdWVJbmZvUHJvdG8+fG51bGx9IFt2YWx1ZUluZm9dIEdyYXBoUHJvdG8gdmFsdWVJbmZvXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVRlbnNvckFubm90YXRpb24+fG51bGx9IFtxdWFudGl6YXRpb25Bbm5vdGF0aW9uXSBHcmFwaFByb3RvIHF1YW50aXphdGlvbkFubm90YXRpb25cbiAgICAgICAgICovXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgR3JhcGhQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgR3JhcGhQcm90by5cbiAgICAgICAgICogQGltcGxlbWVudHMgSUdyYXBoUHJvdG9cbiAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JR3JhcGhQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gR3JhcGhQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICB0aGlzLm5vZGUgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuc3BhcnNlSW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQgPSBbXTtcbiAgICAgICAgICAgIHRoaXMub3V0cHV0ID0gW107XG4gICAgICAgICAgICB0aGlzLnZhbHVlSW5mbyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5xdWFudGl6YXRpb25Bbm5vdGF0aW9uID0gW107XG4gICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdyYXBoUHJvdG8gbm9kZS5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSU5vZGVQcm90bz59IG5vZGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLm5vZGUgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHcmFwaFByb3RvIG5hbWUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5wcm90b3R5cGUubmFtZSA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdyYXBoUHJvdG8gaW5pdGlhbGl6ZXIuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklUZW5zb3JQcm90bz59IGluaXRpYWxpemVyXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5pbml0aWFsaXplciA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdyYXBoUHJvdG8gc3BhcnNlSW5pdGlhbGl6ZXIuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklTcGFyc2VUZW5zb3JQcm90bz59IHNwYXJzZUluaXRpYWxpemVyXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5zcGFyc2VJbml0aWFsaXplciA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdyYXBoUHJvdG8gZG9jU3RyaW5nLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5wcm90b3R5cGUuZG9jU3RyaW5nID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogR3JhcGhQcm90byBpbnB1dC5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPn0gaW5wdXRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLmlucHV0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogR3JhcGhQcm90byBvdXRwdXQuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklWYWx1ZUluZm9Qcm90bz59IG91dHB1dFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5wcm90b3R5cGUub3V0cHV0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogR3JhcGhQcm90byB2YWx1ZUluZm8uXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklWYWx1ZUluZm9Qcm90bz59IHZhbHVlSW5mb1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5wcm90b3R5cGUudmFsdWVJbmZvID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogR3JhcGhQcm90byBxdWFudGl6YXRpb25Bbm5vdGF0aW9uLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVGVuc29yQW5ub3RhdGlvbj59IHF1YW50aXphdGlvbkFubm90YXRpb25cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLnF1YW50aXphdGlvbkFubm90YXRpb24gPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IEdyYXBoUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSUdyYXBoUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICogQHJldHVybnMge29ubnguR3JhcGhQcm90b30gR3JhcGhQcm90byBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBHcmFwaFByb3RvKHByb3BlcnRpZXMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgR3JhcGhQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LkdyYXBoUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JR3JhcGhQcm90b30gbWVzc2FnZSBHcmFwaFByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uubm9kZSAhPSBudWxsICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm5vZGUubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguTm9kZVByb3RvLmVuY29kZShtZXNzYWdlLm5vZGVbaV0sIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8xMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcIm5hbWVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLzE4KS5zdHJpbmcobWVzc2FnZS5uYW1lKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemVyICE9IG51bGwgJiYgbWVzc2FnZS5pbml0aWFsaXplci5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclByb3RvLmVuY29kZShtZXNzYWdlLmluaXRpYWxpemVyW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovNDIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEwLCB3aXJlVHlwZSAyID0qLzgyKS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZW5jb2RlKG1lc3NhZ2UuaW5wdXRbaV0sIHdyaXRlci51aW50MzIoLyogaWQgMTEsIHdpcmVUeXBlIDIgPSovOTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vdXRwdXQgIT0gbnVsbCAmJiBtZXNzYWdlLm91dHB1dC5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5lbmNvZGUobWVzc2FnZS5vdXRwdXRbaV0sIHdyaXRlci51aW50MzIoLyogaWQgMTIsIHdpcmVUeXBlIDIgPSovOTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS52YWx1ZUluZm8gIT0gbnVsbCAmJiBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5lbmNvZGUobWVzc2FnZS52YWx1ZUluZm9baV0sIHdyaXRlci51aW50MzIoLyogaWQgMTMsIHdpcmVUeXBlIDIgPSovMTA2KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguVGVuc29yQW5ub3RhdGlvbi5lbmNvZGUobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDE0LCB3aXJlVHlwZSAyID0qLzExNCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyICE9IG51bGwgJiYgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmVuY29kZShtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDE1LCB3aXJlVHlwZSAyID0qLzEyMikuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBHcmFwaFByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguR3JhcGhQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklHcmFwaFByb3RvfSBtZXNzYWdlIEdyYXBoUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBHcmFwaFByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgR3JhcGhQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICogQHJldHVybnMge29ubnguR3JhcGhQcm90b30gR3JhcGhQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5HcmFwaFByb3RvKCk7XG4gICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uubm9kZSAmJiBtZXNzYWdlLm5vZGUubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm5vZGUgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uubm9kZS5wdXNoKCRyb290Lm9ubnguTm9kZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSA1OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmluaXRpYWxpemVyICYmIG1lc3NhZ2UuaW5pdGlhbGl6ZXIubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemVyID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemVyLnB1c2goJHJvb3Qub25ueC5UZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAxNToge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplciAmJiBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplciA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zcGFyc2VJbml0aWFsaXplci5wdXNoKCRyb290Lm9ubnguU3BhcnNlVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgMTA6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDExOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmlucHV0ICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmlucHV0LnB1c2goJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAxMjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5vdXRwdXQucHVzaCgkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDEzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLnZhbHVlSW5mbyAmJiBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudmFsdWVJbmZvID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnZhbHVlSW5mby5wdXNoKCRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgMTQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAmJiBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5wdXNoKCRyb290Lm9ubnguVGVuc29yQW5ub3RhdGlvbi5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIEdyYXBoUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LkdyYXBoUHJvdG99IEdyYXBoUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBHcmFwaFByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBWZXJpZmllcyBhIEdyYXBoUHJvdG8gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAqL1xuICAgICAgICBHcmFwaFByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvYmplY3QgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5vZGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibm9kZVwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm5vZGUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJub2RlOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5ub2RlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguTm9kZVByb3RvLnZlcmlmeShtZXNzYWdlLm5vZGVbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJub2RlLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJuYW1lXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5uYW1lKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibmFtZTogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXplciAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJpbml0aWFsaXplclwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmluaXRpYWxpemVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW5pdGlhbGl6ZXI6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2UuaW5pdGlhbGl6ZXJbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJpbml0aWFsaXplci5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInNwYXJzZUluaXRpYWxpemVyXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXIpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJzcGFyc2VJbml0aWFsaXplcjogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TcGFyc2VUZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS5zcGFyc2VJbml0aWFsaXplcltpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcInNwYXJzZUluaXRpYWxpemVyLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmlucHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImlucHV0XCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW5wdXQpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJpbnB1dDogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by52ZXJpZnkobWVzc2FnZS5pbnB1dFtpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImlucHV0LlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm91dHB1dFwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm91dHB1dCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm91dHB1dDogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udmVyaWZ5KG1lc3NhZ2Uub3V0cHV0W2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib3V0cHV0LlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWVJbmZvICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInZhbHVlSW5mb1wiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnZhbHVlSW5mbykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInZhbHVlSW5mbzogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudmFsdWVJbmZvLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udmVyaWZ5KG1lc3NhZ2UudmFsdWVJbmZvW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidmFsdWVJbmZvLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJxdWFudGl6YXRpb25Bbm5vdGF0aW9uXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInF1YW50aXphdGlvbkFubm90YXRpb246IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLnZlcmlmeShtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb25baV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJxdWFudGl6YXRpb25Bbm5vdGF0aW9uLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBHcmFwaFByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguR3JhcGhQcm90b30gR3JhcGhQcm90b1xuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LkdyYXBoUHJvdG8pXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguR3JhcGhQcm90bygpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5ub2RlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5ub2RlKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguR3JhcGhQcm90by5ub2RlOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLm5vZGUgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5ub2RlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm5vZGVbaV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLm5vZGU6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5ub2RlW2ldID0gJHJvb3Qub25ueC5Ob2RlUHJvdG8uZnJvbU9iamVjdChvYmplY3Qubm9kZVtpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5uYW1lICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gU3RyaW5nKG9iamVjdC5uYW1lKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QuaW5pdGlhbGl6ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmluaXRpYWxpemVyKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguR3JhcGhQcm90by5pbml0aWFsaXplcjogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXplciA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmluaXRpYWxpemVyLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmluaXRpYWxpemVyW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguR3JhcGhQcm90by5pbml0aWFsaXplcjogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemVyW2ldID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC5pbml0aWFsaXplcltpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5zcGFyc2VJbml0aWFsaXplcikge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXIpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLnNwYXJzZUluaXRpYWxpemVyOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXJbaV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLnNwYXJzZUluaXRpYWxpemVyOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXJbaV0gPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLmZyb21PYmplY3Qob2JqZWN0LnNwYXJzZUluaXRpYWxpemVyW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5pbnB1dCkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuaW5wdXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLmlucHV0OiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW5wdXQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5wdXRbaV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLmlucHV0OiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXRbaV0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmZyb21PYmplY3Qob2JqZWN0LmlucHV0W2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm91dHB1dCkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qub3V0cHV0KSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguR3JhcGhQcm90by5vdXRwdXQ6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qub3V0cHV0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm91dHB1dFtpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkdyYXBoUHJvdG8ub3V0cHV0OiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0W2ldID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5mcm9tT2JqZWN0KG9iamVjdC5vdXRwdXRbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QudmFsdWVJbmZvKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC52YWx1ZUluZm8pKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLnZhbHVlSW5mbzogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS52YWx1ZUluZm8gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC52YWx1ZUluZm8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudmFsdWVJbmZvW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguR3JhcGhQcm90by52YWx1ZUluZm86IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS52YWx1ZUluZm9baV0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmZyb21PYmplY3Qob2JqZWN0LnZhbHVlSW5mb1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguR3JhcGhQcm90by5xdWFudGl6YXRpb25Bbm5vdGF0aW9uOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25baV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLnF1YW50aXphdGlvbkFubm90YXRpb246IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2ldID0gJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLmZyb21PYmplY3Qob2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25baV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBHcmFwaFByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguR3JhcGhQcm90b30gbWVzc2FnZSBHcmFwaFByb3RvXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgIG9iamVjdC5ub2RlID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LmluaXRpYWxpemVyID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC52YWx1ZUluZm8gPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC5zcGFyc2VJbml0aWFsaXplciA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IFwiXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3Qubm9kZSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5ub2RlLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3Qubm9kZVtqXSA9ICRyb290Lm9ubnguTm9kZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uubm9kZVtqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm5hbWVcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXplciAmJiBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5pbml0aWFsaXplciA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbml0aWFsaXplci5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmluaXRpYWxpemVyW2pdID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by50b09iamVjdChtZXNzYWdlLmluaXRpYWxpemVyW2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbnB1dFtqXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udG9PYmplY3QobWVzc2FnZS5pbnB1dFtqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5vdXRwdXRbal0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLnRvT2JqZWN0KG1lc3NhZ2Uub3V0cHV0W2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnZhbHVlSW5mbyAmJiBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QudmFsdWVJbmZvID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlSW5mb1tqXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udG9PYmplY3QobWVzc2FnZS52YWx1ZUluZm9bal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAmJiBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25bal0gPSAkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24udG9PYmplY3QobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyICYmIG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnNwYXJzZUluaXRpYWxpemVyID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnNwYXJzZUluaXRpYWxpemVyLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3Quc3BhcnNlSW5pdGlhbGl6ZXJbal0gPSAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc3BhcnNlSW5pdGlhbGl6ZXJbal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydHMgdGhpcyBHcmFwaFByb3RvIHRvIEpTT04uXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIEdyYXBoUHJvdG9cbiAgICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdHlwZVVybFByZWZpeCA9IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyBcIi9vbm54LkdyYXBoUHJvdG9cIjtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gR3JhcGhQcm90bztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5UZW5zb3JQcm90byA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJvcGVydGllcyBvZiBhIFRlbnNvclByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAaW50ZXJmYWNlIElUZW5zb3JQcm90b1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXJ8TG9uZz58bnVsbH0gW2RpbXNdIFRlbnNvclByb3RvIGRpbXNcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8bnVsbH0gW2RhdGFUeXBlXSBUZW5zb3JQcm90byBkYXRhVHlwZVxuICAgICAgICAgKiBAcHJvcGVydHkge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnR8bnVsbH0gW3NlZ21lbnRdIFRlbnNvclByb3RvIHNlZ21lbnRcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyPnxudWxsfSBbZmxvYXREYXRhXSBUZW5zb3JQcm90byBmbG9hdERhdGFcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyPnxudWxsfSBbaW50MzJEYXRhXSBUZW5zb3JQcm90byBpbnQzMkRhdGFcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48VWludDhBcnJheT58bnVsbH0gW3N0cmluZ0RhdGFdIFRlbnNvclByb3RvIHN0cmluZ0RhdGFcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyfExvbmc+fG51bGx9IFtpbnQ2NERhdGFdIFRlbnNvclByb3RvIGludDY0RGF0YVxuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbbmFtZV0gVGVuc29yUHJvdG8gbmFtZVxuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBUZW5zb3JQcm90byBkb2NTdHJpbmdcbiAgICAgICAgICogQHByb3BlcnR5IHtVaW50OEFycmF5fG51bGx9IFtyYXdEYXRhXSBUZW5zb3JQcm90byByYXdEYXRhXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFtleHRlcm5hbERhdGFdIFRlbnNvclByb3RvIGV4dGVybmFsRGF0YVxuICAgICAgICAgKiBAcHJvcGVydHkge29ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9ufG51bGx9IFtkYXRhTG9jYXRpb25dIFRlbnNvclByb3RvIGRhdGFMb2NhdGlvblxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXI+fG51bGx9IFtkb3VibGVEYXRhXSBUZW5zb3JQcm90byBkb3VibGVEYXRhXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbdWludDY0RGF0YV0gVGVuc29yUHJvdG8gdWludDY0RGF0YVxuICAgICAgICAgKi9cblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3JQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVGVuc29yUHJvdG8uXG4gICAgICAgICAqIEBpbXBsZW1lbnRzIElUZW5zb3JQcm90b1xuICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gVGVuc29yUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgICAgICAgdGhpcy5kaW1zID0gW107XG4gICAgICAgICAgICB0aGlzLmZsb2F0RGF0YSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5pbnQzMkRhdGEgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuc3RyaW5nRGF0YSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5pbnQ2NERhdGEgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuZXh0ZXJuYWxEYXRhID0gW107XG4gICAgICAgICAgICB0aGlzLmRvdWJsZURhdGEgPSBbXTtcbiAgICAgICAgICAgIHRoaXMudWludDY0RGF0YSA9IFtdO1xuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JQcm90byBkaW1zLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyfExvbmc+fSBkaW1zXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmRpbXMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JQcm90byBkYXRhVHlwZS5cbiAgICAgICAgICogQG1lbWJlciB7bnVtYmVyfSBkYXRhVHlwZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5kYXRhVHlwZSA9IDA7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclByb3RvIHNlZ21lbnQuXG4gICAgICAgICAqIEBtZW1iZXIge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnR8bnVsbHx1bmRlZmluZWR9IHNlZ21lbnRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuc2VnbWVudCA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclByb3RvIGZsb2F0RGF0YS5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcj59IGZsb2F0RGF0YVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5mbG9hdERhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JQcm90byBpbnQzMkRhdGEuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXI+fSBpbnQzMkRhdGFcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuaW50MzJEYXRhID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGVuc29yUHJvdG8gc3RyaW5nRGF0YS5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPFVpbnQ4QXJyYXk+fSBzdHJpbmdEYXRhXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLnN0cmluZ0RhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JQcm90byBpbnQ2NERhdGEuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXJ8TG9uZz59IGludDY0RGF0YVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5pbnQ2NERhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JQcm90byBuYW1lLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IG5hbWVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUubmFtZSA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclByb3RvIGRvY1N0cmluZy5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuZG9jU3RyaW5nID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGVuc29yUHJvdG8gcmF3RGF0YS5cbiAgICAgICAgICogQG1lbWJlciB7VWludDhBcnJheX0gcmF3RGF0YVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5yYXdEYXRhID0gJHV0aWwubmV3QnVmZmVyKFtdKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGVuc29yUHJvdG8gZXh0ZXJuYWxEYXRhLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz59IGV4dGVybmFsRGF0YVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5leHRlcm5hbERhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JQcm90byBkYXRhTG9jYXRpb24uXG4gICAgICAgICAqIEBtZW1iZXIge29ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9ufSBkYXRhTG9jYXRpb25cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuZGF0YUxvY2F0aW9uID0gMDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGVuc29yUHJvdG8gZG91YmxlRGF0YS5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcj59IGRvdWJsZURhdGFcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuZG91YmxlRGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclByb3RvIHVpbnQ2NERhdGEuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXJ8TG9uZz59IHVpbnQ2NERhdGFcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUudWludDY0RGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgVGVuc29yUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90b30gVGVuc29yUHJvdG8gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFRlbnNvclByb3RvKHByb3BlcnRpZXMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yUHJvdG99IG1lc3NhZ2UgVGVuc29yUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltcyAhPSBudWxsICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovMTApLmZvcmsoKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZGltcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmludDY0KG1lc3NhZ2UuZGltc1tpXSk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGF0YVR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcImRhdGFUeXBlXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMCA9Ki8xNikuaW50MzIobWVzc2FnZS5kYXRhVHlwZSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5zZWdtZW50ICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJzZWdtZW50XCIpKVxuICAgICAgICAgICAgICAgICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC5lbmNvZGUobWVzc2FnZS5zZWdtZW50LCB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovMjYpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5mbG9hdERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmZsb2F0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDQsIHdpcmVUeXBlIDIgPSovMzQpLmZvcmsoKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIuZmxvYXQobWVzc2FnZS5mbG9hdERhdGFbaV0pO1xuICAgICAgICAgICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmludDMyRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki80MikuZm9yaygpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci5pbnQzMihtZXNzYWdlLmludDMyRGF0YVtpXSk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5nRGF0YSAhPSBudWxsICYmIG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki81MCkuYnl0ZXMobWVzc2FnZS5zdHJpbmdEYXRhW2ldKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmludDY0RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNywgd2lyZVR5cGUgMiA9Ki81OCkuZm9yaygpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci5pbnQ2NChtZXNzYWdlLmludDY0RGF0YVtpXSk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDgsIHdpcmVUeXBlIDIgPSovNjYpLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucmF3RGF0YSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwicmF3RGF0YVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDksIHdpcmVUeXBlIDIgPSovNzQpLmJ5dGVzKG1lc3NhZ2UucmF3RGF0YSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb3VibGVEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5kb3VibGVEYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTAsIHdpcmVUeXBlIDIgPSovODIpLmZvcmsoKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZG91YmxlRGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmRvdWJsZShtZXNzYWdlLmRvdWJsZURhdGFbaV0pO1xuICAgICAgICAgICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnVpbnQ2NERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLnVpbnQ2NERhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMSwgd2lyZVR5cGUgMiA9Ki85MCkuZm9yaygpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIudWludDY0KG1lc3NhZ2UudWludDY0RGF0YVtpXSk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMiwgd2lyZVR5cGUgMiA9Ki85OCkuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmV4dGVybmFsRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlKG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDEzLCB3aXJlVHlwZSAyID0qLzEwNikuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRhdGFMb2NhdGlvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiZGF0YUxvY2F0aW9uXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTQsIHdpcmVUeXBlIDAgPSovMTEyKS5pbnQzMihtZXNzYWdlLmRhdGFMb2NhdGlvbik7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yUHJvdG99IG1lc3NhZ2UgVGVuc29yUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFRlbnNvclByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG99IFRlbnNvclByb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JQcm90bygpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmRpbXMgJiYgbWVzc2FnZS5kaW1zLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1zID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1zLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1zLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGF0YVR5cGUgPSByZWFkZXIuaW50MzIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnNlZ21lbnQgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSA0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmZsb2F0RGF0YSAmJiBtZXNzYWdlLmZsb2F0RGF0YS5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZmxvYXREYXRhID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5mbG9hdERhdGEucHVzaChyZWFkZXIuZmxvYXQoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmZsb2F0RGF0YS5wdXNoKHJlYWRlci5mbG9hdCgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSA1OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmludDMyRGF0YSAmJiBtZXNzYWdlLmludDMyRGF0YS5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50MzJEYXRhID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pbnQzMkRhdGEucHVzaChyZWFkZXIuaW50MzIoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludDMyRGF0YS5wdXNoKHJlYWRlci5pbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSA2OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLnN0cmluZ0RhdGEgJiYgbWVzc2FnZS5zdHJpbmdEYXRhLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zdHJpbmdEYXRhID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnN0cmluZ0RhdGEucHVzaChyZWFkZXIuYnl0ZXMoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgNzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnQ2NERhdGEgJiYgbWVzc2FnZS5pbnQ2NERhdGEubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludDY0RGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50NjREYXRhLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pbnQ2NERhdGEucHVzaChyZWFkZXIuaW50NjQoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgODoge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDEyOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSA5OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnJhd0RhdGEgPSByZWFkZXIuYnl0ZXMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAxMzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5leHRlcm5hbERhdGEgJiYgbWVzc2FnZS5leHRlcm5hbERhdGEubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmV4dGVybmFsRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5leHRlcm5hbERhdGEucHVzaCgkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgMTQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGF0YUxvY2F0aW9uID0gcmVhZGVyLmludDMyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgMTA6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZG91YmxlRGF0YSAmJiBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRvdWJsZURhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRvdWJsZURhdGEucHVzaChyZWFkZXIuZG91YmxlKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kb3VibGVEYXRhLnB1c2gocmVhZGVyLmRvdWJsZSgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAxMToge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS51aW50NjREYXRhICYmIG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudWludDY0RGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudWludDY0RGF0YS5wdXNoKHJlYWRlci51aW50NjQoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnVpbnQ2NERhdGEucHVzaChyZWFkZXIudWludDY0KCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgVGVuc29yUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90b30gVGVuc29yUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVmVyaWZpZXMgYSBUZW5zb3JQcm90byBtZXNzYWdlLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kaW1zICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRpbXNcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5kaW1zKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZGltczogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZGltcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1zW2ldKSAmJiAhKG1lc3NhZ2UuZGltc1tpXSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1zW2ldLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXS5oaWdoKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkaW1zOiBpbnRlZ2VyfExvbmdbXSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGF0YVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZGF0YVR5cGVcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kYXRhVHlwZSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRhdGFUeXBlOiBpbnRlZ2VyIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5zZWdtZW50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInNlZ21lbnRcIikpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQudmVyaWZ5KG1lc3NhZ2Uuc2VnbWVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJzZWdtZW50LlwiICsgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5mbG9hdERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZmxvYXREYXRhXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuZmxvYXREYXRhKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZmxvYXREYXRhOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5mbG9hdERhdGFbaV0gIT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJmbG9hdERhdGE6IG51bWJlcltdIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbnQzMkRhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiaW50MzJEYXRhXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW50MzJEYXRhKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW50MzJEYXRhOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50MzJEYXRhW2ldKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImludDMyRGF0YTogaW50ZWdlcltdIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5zdHJpbmdEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInN0cmluZ0RhdGFcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5zdHJpbmdEYXRhKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwic3RyaW5nRGF0YTogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5zdHJpbmdEYXRhW2ldICYmIHR5cGVvZiBtZXNzYWdlLnN0cmluZ0RhdGFbaV0ubGVuZ3RoID09PSBcIm51bWJlclwiIHx8ICR1dGlsLmlzU3RyaW5nKG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwic3RyaW5nRGF0YTogYnVmZmVyW10gZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmludDY0RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJpbnQ2NERhdGFcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnQ2NERhdGEpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJpbnQ2NERhdGE6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmludDY0RGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pbnQ2NERhdGFbaV0pICYmICEobWVzc2FnZS5pbnQ2NERhdGFbaV0gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50NjREYXRhW2ldLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50NjREYXRhW2ldLmhpZ2gpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImludDY0RGF0YTogaW50ZWdlcnxMb25nW10gZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UubmFtZSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm5hbWU6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnJhd0RhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwicmF3RGF0YVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLnJhd0RhdGEgJiYgdHlwZW9mIG1lc3NhZ2UucmF3RGF0YS5sZW5ndGggPT09IFwibnVtYmVyXCIgfHwgJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5yYXdEYXRhKSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInJhd0RhdGE6IGJ1ZmZlciBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZXh0ZXJuYWxEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImV4dGVybmFsRGF0YVwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmV4dGVybmFsRGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImV4dGVybmFsRGF0YTogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by52ZXJpZnkobWVzc2FnZS5leHRlcm5hbERhdGFbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJleHRlcm5hbERhdGEuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kYXRhTG9jYXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZGF0YUxvY2F0aW9uXCIpKVxuICAgICAgICAgICAgICAgIHN3aXRjaCAobWVzc2FnZS5kYXRhTG9jYXRpb24pIHtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkYXRhTG9jYXRpb246IGVudW0gdmFsdWUgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb3VibGVEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvdWJsZURhdGFcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5kb3VibGVEYXRhKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZG91YmxlRGF0YTogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZG91YmxlRGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmRvdWJsZURhdGFbaV0gIT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkb3VibGVEYXRhOiBudW1iZXJbXSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudWludDY0RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJ1aW50NjREYXRhXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudWludDY0RGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInVpbnQ2NERhdGE6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnVpbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudWludDY0RGF0YVtpXSkgJiYgIShtZXNzYWdlLnVpbnQ2NERhdGFbaV0gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudWludDY0RGF0YVtpXS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnVpbnQ2NERhdGFbaV0uaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidWludDY0RGF0YTogaW50ZWdlcnxMb25nW10gZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgVGVuc29yUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG99IFRlbnNvclByb3RvXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlRlbnNvclByb3RvKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclByb3RvKCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRpbXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmRpbXMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UZW5zb3JQcm90by5kaW1zOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbXMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5kaW1zLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLmRpbXNbaV0gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuZGltc1tpXSkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltc1tpXSA9IHBhcnNlSW50KG9iamVjdC5kaW1zW2ldLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltc1tpXSA9IG9iamVjdC5kaW1zW2ldO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbXNbaV0gPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbXNbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmRpbXNbaV0ubG93ID4+PiAwLCBvYmplY3QuZGltc1tpXS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5kYXRhVHlwZSAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGF0YVR5cGUgPSBvYmplY3QuZGF0YVR5cGUgfCAwO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5zZWdtZW50ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zZWdtZW50ICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UZW5zb3JQcm90by5zZWdtZW50OiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5zZWdtZW50ID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5TZWdtZW50LmZyb21PYmplY3Qob2JqZWN0LnNlZ21lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5mbG9hdERhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmZsb2F0RGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRlbnNvclByb3RvLmZsb2F0RGF0YTogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5mbG9hdERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5mbG9hdERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZmxvYXREYXRhW2ldID0gTnVtYmVyKG9iamVjdC5mbG9hdERhdGFbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5pbnQzMkRhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmludDMyRGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRlbnNvclByb3RvLmludDMyRGF0YTogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5pbnQzMkRhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbnQzMkRhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50MzJEYXRhW2ldID0gb2JqZWN0LmludDMyRGF0YVtpXSB8IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LnN0cmluZ0RhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnN0cmluZ0RhdGEpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UZW5zb3JQcm90by5zdHJpbmdEYXRhOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnN0cmluZ0RhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5zdHJpbmdEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zdHJpbmdEYXRhW2ldID09PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgJHV0aWwuYmFzZTY0LmRlY29kZShvYmplY3Quc3RyaW5nRGF0YVtpXSwgbWVzc2FnZS5zdHJpbmdEYXRhW2ldID0gJHV0aWwubmV3QnVmZmVyKCR1dGlsLmJhc2U2NC5sZW5ndGgob2JqZWN0LnN0cmluZ0RhdGFbaV0pKSwgMCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG9iamVjdC5zdHJpbmdEYXRhW2ldLmxlbmd0aCA+PSAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zdHJpbmdEYXRhW2ldID0gb2JqZWN0LnN0cmluZ0RhdGFbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmludDY0RGF0YSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuaW50NjREYXRhKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVGVuc29yUHJvdG8uaW50NjREYXRhOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmludDY0RGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmludDY0RGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCR1dGlsLkxvbmcpXG4gICAgICAgICAgICAgICAgICAgICAgICAobWVzc2FnZS5pbnQ2NERhdGFbaV0gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuaW50NjREYXRhW2ldKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnQ2NERhdGFbaV0gPT09IFwic3RyaW5nXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludDY0RGF0YVtpXSA9IHBhcnNlSW50KG9iamVjdC5pbnQ2NERhdGFbaV0sIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnQ2NERhdGFbaV0gPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludDY0RGF0YVtpXSA9IG9iamVjdC5pbnQ2NERhdGFbaV07XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaW50NjREYXRhW2ldID09PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pbnQ2NERhdGFbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmludDY0RGF0YVtpXS5sb3cgPj4+IDAsIG9iamVjdC5pbnQ2NERhdGFbaV0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IFN0cmluZyhvYmplY3QubmFtZSk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5yYXdEYXRhICE9IG51bGwpXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QucmF3RGF0YSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgJHV0aWwuYmFzZTY0LmRlY29kZShvYmplY3QucmF3RGF0YSwgbWVzc2FnZS5yYXdEYXRhID0gJHV0aWwubmV3QnVmZmVyKCR1dGlsLmJhc2U2NC5sZW5ndGgob2JqZWN0LnJhd0RhdGEpKSwgMCk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAob2JqZWN0LnJhd0RhdGEubGVuZ3RoID49IDApXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucmF3RGF0YSA9IG9iamVjdC5yYXdEYXRhO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5leHRlcm5hbERhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmV4dGVybmFsRGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRlbnNvclByb3RvLmV4dGVybmFsRGF0YTogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5leHRlcm5hbERhdGEubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZXh0ZXJuYWxEYXRhW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVGVuc29yUHJvdG8uZXh0ZXJuYWxEYXRhOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2ldID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmZyb21PYmplY3Qob2JqZWN0LmV4dGVybmFsRGF0YVtpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3dpdGNoIChvYmplY3QuZGF0YUxvY2F0aW9uKSB7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmRhdGFMb2NhdGlvbiA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRhdGFMb2NhdGlvbiA9IG9iamVjdC5kYXRhTG9jYXRpb247XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJERUZBVUxUXCI6XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5kYXRhTG9jYXRpb24gPSAwO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIkVYVEVSTkFMXCI6XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5kYXRhTG9jYXRpb24gPSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5kb3VibGVEYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5kb3VibGVEYXRhKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVGVuc29yUHJvdG8uZG91YmxlRGF0YTogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5kb3VibGVEYXRhID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZG91YmxlRGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kb3VibGVEYXRhW2ldID0gTnVtYmVyKG9iamVjdC5kb3VibGVEYXRhW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QudWludDY0RGF0YSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QudWludDY0RGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRlbnNvclByb3RvLnVpbnQ2NERhdGE6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UudWludDY0RGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnVpbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKVxuICAgICAgICAgICAgICAgICAgICAgICAgKG1lc3NhZ2UudWludDY0RGF0YVtpXSA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC51aW50NjREYXRhW2ldKSkudW5zaWduZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LnVpbnQ2NERhdGFbaV0gPT09IFwic3RyaW5nXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnVpbnQ2NERhdGFbaV0gPSBwYXJzZUludChvYmplY3QudWludDY0RGF0YVtpXSwgMTApO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LnVpbnQ2NERhdGFbaV0gPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnVpbnQ2NERhdGFbaV0gPSBvYmplY3QudWludDY0RGF0YVtpXTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC51aW50NjREYXRhW2ldID09PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS51aW50NjREYXRhW2ldID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC51aW50NjREYXRhW2ldLmxvdyA+Pj4gMCwgb2JqZWN0LnVpbnQ2NERhdGFbaV0uaGlnaCA+Pj4gMCkudG9OdW1iZXIodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVGVuc29yUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG99IG1lc3NhZ2UgVGVuc29yUHJvdG9cbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgIG9iamVjdC5kaW1zID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LmZsb2F0RGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC5pbnQzMkRhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3Quc3RyaW5nRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC5pbnQ2NERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC51aW50NjREYXRhID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LmV4dGVybmFsRGF0YSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZGF0YVR5cGUgPSAwO1xuICAgICAgICAgICAgICAgIG9iamVjdC5zZWdtZW50ID0gbnVsbDtcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuYnl0ZXMgPT09IFN0cmluZylcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnJhd0RhdGEgPSBcIlwiO1xuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QucmF3RGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5ieXRlcyAhPT0gQXJyYXkpXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QucmF3RGF0YSA9ICR1dGlsLm5ld0J1ZmZlcihvYmplY3QucmF3RGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSBcIlwiO1xuICAgICAgICAgICAgICAgIG9iamVjdC5kYXRhTG9jYXRpb24gPSBvcHRpb25zLmVudW1zID09PSBTdHJpbmcgPyBcIkRFRkFVTFRcIiA6IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kaW1zICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZGltcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZGltc1tqXSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5kaW1zW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuZGltc1tqXSkgOiBtZXNzYWdlLmRpbXNbal07XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5kaW1zW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLmRpbXNbal0pIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuZGltc1tqXS5sb3cgPj4+IDAsIG1lc3NhZ2UuZGltc1tqXS5oaWdoID4+PiAwKS50b051bWJlcigpIDogbWVzc2FnZS5kaW1zW2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGF0YVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZGF0YVR5cGVcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRhdGFUeXBlID0gbWVzc2FnZS5kYXRhVHlwZTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnNlZ21lbnQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwic2VnbWVudFwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3Quc2VnbWVudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC50b09iamVjdChtZXNzYWdlLnNlZ21lbnQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZmxvYXREYXRhICYmIG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5mbG9hdERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZmxvYXREYXRhW2pdID0gb3B0aW9ucy5qc29uICYmICFpc0Zpbml0ZShtZXNzYWdlLmZsb2F0RGF0YVtqXSkgPyBTdHJpbmcobWVzc2FnZS5mbG9hdERhdGFbal0pIDogbWVzc2FnZS5mbG9hdERhdGFbal07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbnQzMkRhdGEgJiYgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmludDMyRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbnQzMkRhdGFbal0gPSBtZXNzYWdlLmludDMyRGF0YVtqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnN0cmluZ0RhdGEgJiYgbWVzc2FnZS5zdHJpbmdEYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5zdHJpbmdEYXRhID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5zdHJpbmdEYXRhW2pdID0gb3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nID8gJHV0aWwuYmFzZTY0LmVuY29kZShtZXNzYWdlLnN0cmluZ0RhdGFbal0sIDAsIG1lc3NhZ2Uuc3RyaW5nRGF0YVtqXS5sZW5ndGgpIDogb3B0aW9ucy5ieXRlcyA9PT0gQXJyYXkgPyBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChtZXNzYWdlLnN0cmluZ0RhdGFbal0pIDogbWVzc2FnZS5zdHJpbmdEYXRhW2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW50NjREYXRhICYmIG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5pbnQ2NERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuaW50NjREYXRhW2pdID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmludDY0RGF0YVtqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmludDY0RGF0YVtqXSkgOiBtZXNzYWdlLmludDY0RGF0YVtqXTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmludDY0RGF0YVtqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5pbnQ2NERhdGFbal0pIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuaW50NjREYXRhW2pdLmxvdyA+Pj4gMCwgbWVzc2FnZS5pbnQ2NERhdGFbal0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKSA6IG1lc3NhZ2UuaW50NjREYXRhW2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJuYW1lXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5uYW1lID0gbWVzc2FnZS5uYW1lO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucmF3RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJyYXdEYXRhXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5yYXdEYXRhID0gb3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nID8gJHV0aWwuYmFzZTY0LmVuY29kZShtZXNzYWdlLnJhd0RhdGEsIDAsIG1lc3NhZ2UucmF3RGF0YS5sZW5ndGgpIDogb3B0aW9ucy5ieXRlcyA9PT0gQXJyYXkgPyBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChtZXNzYWdlLnJhd0RhdGEpIDogbWVzc2FnZS5yYXdEYXRhO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG91YmxlRGF0YSAmJiBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvdWJsZURhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZG91YmxlRGF0YS5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmRvdWJsZURhdGFbal0gPSBvcHRpb25zLmpzb24gJiYgIWlzRmluaXRlKG1lc3NhZ2UuZG91YmxlRGF0YVtqXSkgPyBTdHJpbmcobWVzc2FnZS5kb3VibGVEYXRhW2pdKSA6IG1lc3NhZ2UuZG91YmxlRGF0YVtqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnVpbnQ2NERhdGEgJiYgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC51aW50NjREYXRhID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnVpbnQ2NERhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS51aW50NjREYXRhW2pdID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnVpbnQ2NERhdGFbal0gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS51aW50NjREYXRhW2pdKSA6IG1lc3NhZ2UudWludDY0RGF0YVtqXTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnVpbnQ2NERhdGFbal0gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UudWludDY0RGF0YVtqXSkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS51aW50NjREYXRhW2pdLmxvdyA+Pj4gMCwgbWVzc2FnZS51aW50NjREYXRhW2pdLmhpZ2ggPj4+IDApLnRvTnVtYmVyKHRydWUpIDogbWVzc2FnZS51aW50NjREYXRhW2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gbWVzc2FnZS5kb2NTdHJpbmc7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5leHRlcm5hbERhdGEgJiYgbWVzc2FnZS5leHRlcm5hbERhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmV4dGVybmFsRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5leHRlcm5hbERhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5leHRlcm5hbERhdGFbal0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udG9PYmplY3QobWVzc2FnZS5leHRlcm5hbERhdGFbal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGF0YUxvY2F0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRhdGFMb2NhdGlvblwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QuZGF0YUxvY2F0aW9uID0gb3B0aW9ucy5lbnVtcyA9PT0gU3RyaW5nID8gJHJvb3Qub25ueC5UZW5zb3JQcm90by5EYXRhTG9jYXRpb25bbWVzc2FnZS5kYXRhTG9jYXRpb25dID09PSB1bmRlZmluZWQgPyBtZXNzYWdlLmRhdGFMb2NhdGlvbiA6ICRyb290Lm9ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uW21lc3NhZ2UuZGF0YUxvY2F0aW9uXSA6IG1lc3NhZ2UuZGF0YUxvY2F0aW9uO1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydHMgdGhpcyBUZW5zb3JQcm90byB0byBKU09OLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFRlbnNvclByb3RvXG4gICAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdHlwZVVybFByZWZpeCA9IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyBcIi9vbm54LlRlbnNvclByb3RvXCI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERhdGFUeXBlIGVudW0uXG4gICAgICAgICAqIEBuYW1lIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVcbiAgICAgICAgICogQGVudW0ge251bWJlcn1cbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVOREVGSU5FRD0wIFVOREVGSU5FRCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ9MSBGTE9BVCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gVUlOVDg9MiBVSU5UOCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UOD0zIElOVDggdmFsdWVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVJTlQxNj00IFVJTlQxNiB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UMTY9NSBJTlQxNiB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UMzI9NiBJTlQzMiB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UNjQ9NyBJTlQ2NCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gU1RSSU5HPTggU1RSSU5HIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBCT09MPTkgQk9PTCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQxNj0xMCBGTE9BVDE2IHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBET1VCTEU9MTEgRE9VQkxFIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVSU5UMzI9MTIgVUlOVDMyIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVSU5UNjQ9MTMgVUlOVDY0IHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBDT01QTEVYNjQ9MTQgQ09NUExFWDY0IHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBDT01QTEVYMTI4PTE1IENPTVBMRVgxMjggdmFsdWVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEJGTE9BVDE2PTE2IEJGTE9BVDE2IHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVDhFNE0zRk49MTcgRkxPQVQ4RTRNM0ZOIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVDhFNE0zRk5VWj0xOCBGTE9BVDhFNE0zRk5VWiB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ4RTVNMj0xOSBGTE9BVDhFNU0yIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBGTE9BVDhFNU0yRk5VWj0yMCBGTE9BVDhFNU0yRk5VWiB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8uRGF0YVR5cGUgPSAoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWVzQnlJZCA9IHt9LCB2YWx1ZXMgPSBPYmplY3QuY3JlYXRlKHZhbHVlc0J5SWQpO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMF0gPSBcIlVOREVGSU5FRFwiXSA9IDA7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFsxXSA9IFwiRkxPQVRcIl0gPSAxO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMl0gPSBcIlVJTlQ4XCJdID0gMjtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzNdID0gXCJJTlQ4XCJdID0gMztcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzRdID0gXCJVSU5UMTZcIl0gPSA0O1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbNV0gPSBcIklOVDE2XCJdID0gNTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzZdID0gXCJJTlQzMlwiXSA9IDY7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs3XSA9IFwiSU5UNjRcIl0gPSA3O1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbOF0gPSBcIlNUUklOR1wiXSA9IDg7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs5XSA9IFwiQk9PTFwiXSA9IDk7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFsxMF0gPSBcIkZMT0FUMTZcIl0gPSAxMDtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzExXSA9IFwiRE9VQkxFXCJdID0gMTE7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFsxMl0gPSBcIlVJTlQzMlwiXSA9IDEyO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMTNdID0gXCJVSU5UNjRcIl0gPSAxMztcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzE0XSA9IFwiQ09NUExFWDY0XCJdID0gMTQ7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFsxNV0gPSBcIkNPTVBMRVgxMjhcIl0gPSAxNTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzE2XSA9IFwiQkZMT0FUMTZcIl0gPSAxNjtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzE3XSA9IFwiRkxPQVQ4RTRNM0ZOXCJdID0gMTc7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFsxOF0gPSBcIkZMT0FUOEU0TTNGTlVaXCJdID0gMTg7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFsxOV0gPSBcIkZMT0FUOEU1TTJcIl0gPSAxOTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzIwXSA9IFwiRkxPQVQ4RTVNMkZOVVpcIl0gPSAyMDtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgICAgIH0pKCk7XG5cbiAgICAgICAgVGVuc29yUHJvdG8uU2VnbWVudCA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgU2VnbWVudC5cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAgICAgKiBAaW50ZXJmYWNlIElTZWdtZW50XG4gICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcnxMb25nfG51bGx9IFtiZWdpbl0gU2VnbWVudCBiZWdpblxuICAgICAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbZW5kXSBTZWdtZW50IGVuZFxuICAgICAgICAgICAgICovXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBTZWdtZW50LlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFNlZ21lbnQuXG4gICAgICAgICAgICAgKiBAaW1wbGVtZW50cyBJU2VnbWVudFxuICAgICAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnQ9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgZnVuY3Rpb24gU2VnbWVudChwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBTZWdtZW50IGJlZ2luLlxuICAgICAgICAgICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd9IGJlZ2luXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VnbWVudC5wcm90b3R5cGUuYmVnaW4gPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLDAsZmFsc2UpIDogMDtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBTZWdtZW50IGVuZC5cbiAgICAgICAgICAgICAqIEBtZW1iZXIge251bWJlcnxMb25nfSBlbmRcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZWdtZW50LnByb3RvdHlwZS5lbmQgPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLDAsZmFsc2UpIDogMDtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IFNlZ21lbnQgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclByb3RvLklTZWdtZW50PX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90by5TZWdtZW50fSBTZWdtZW50IGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNlZ21lbnQuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNlZ21lbnQocHJvcGVydGllcyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTZWdtZW50IG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudC52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JQcm90by5JU2VnbWVudH0gbWVzc2FnZSBTZWdtZW50IG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNlZ21lbnQuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgICAgIGlmICghd3JpdGVyKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmJlZ2luICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJiZWdpblwiKSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAwID0qLzgpLmludDY0KG1lc3NhZ2UuYmVnaW4pO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmVuZCAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiZW5kXCIpKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDAgPSovMTYpLmludDY0KG1lc3NhZ2UuZW5kKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU2VnbWVudCBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclByb3RvLlNlZ21lbnQudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnR9IG1lc3NhZ2UgU2VnbWVudCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZWdtZW50LmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGVjb2RlcyBhIFNlZ21lbnQgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvLlNlZ21lbnR9IFNlZ21lbnRcbiAgICAgICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VnbWVudC5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQoKTtcbiAgICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmJlZ2luID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZW5kID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGVjb2RlcyBhIFNlZ21lbnQgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG8uU2VnbWVudH0gU2VnbWVudFxuICAgICAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZWdtZW50LmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBWZXJpZmllcyBhIFNlZ21lbnQgbWVzc2FnZS5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VnbWVudC52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJvYmplY3QgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5iZWdpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJiZWdpblwiKSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5iZWdpbikgJiYgIShtZXNzYWdlLmJlZ2luICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmJlZ2luLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuYmVnaW4uaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYmVnaW46IGludGVnZXJ8TG9uZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmVuZCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJlbmRcIikpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZW5kKSAmJiAhKG1lc3NhZ2UuZW5kICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVuZC5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVuZC5oaWdoKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJlbmQ6IGludGVnZXJ8TG9uZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgU2VnbWVudCBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG8uU2VnbWVudH0gU2VnbWVudFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZWdtZW50LmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JQcm90by5TZWdtZW50KCk7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdC5iZWdpbiAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLmJlZ2luID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmJlZ2luKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5iZWdpbiA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuYmVnaW4gPSBwYXJzZUludChvYmplY3QuYmVnaW4sIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5iZWdpbiA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuYmVnaW4gPSBvYmplY3QuYmVnaW47XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuYmVnaW4gPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmJlZ2luID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5iZWdpbi5sb3cgPj4+IDAsIG9iamVjdC5iZWdpbi5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3QuZW5kICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKVxuICAgICAgICAgICAgICAgICAgICAgICAgKG1lc3NhZ2UuZW5kID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmVuZCkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZW5kID09PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5lbmQgPSBwYXJzZUludChvYmplY3QuZW5kLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZW5kID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5lbmQgPSBvYmplY3QuZW5kO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmVuZCA9PT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZW5kID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5lbmQubG93ID4+PiAwLCBvYmplY3QuZW5kLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFNlZ21lbnQgbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uU2VnbWVudH0gbWVzc2FnZSBTZWdtZW50XG4gICAgICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNlZ21lbnQudG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbG9uZyA9IG5ldyAkdXRpbC5Mb25nKDAsIDAsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5iZWdpbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmJlZ2luID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gXCIwXCIgOiAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxvbmcgPSBuZXcgJHV0aWwuTG9uZygwLCAwLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuZW5kID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gbG9uZy50b1N0cmluZygpIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbG9uZy50b051bWJlcigpIDogbG9uZztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuZW5kID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gXCIwXCIgOiAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5iZWdpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJiZWdpblwiKSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmJlZ2luID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmJlZ2luID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuYmVnaW4pIDogbWVzc2FnZS5iZWdpbjtcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmJlZ2luID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLmJlZ2luKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmJlZ2luLmxvdyA+Pj4gMCwgbWVzc2FnZS5iZWdpbi5oaWdoID4+PiAwKS50b051bWJlcigpIDogbWVzc2FnZS5iZWdpbjtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5lbmQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZW5kXCIpKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZW5kID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmVuZCA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmVuZCkgOiBtZXNzYWdlLmVuZDtcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmVuZCA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5lbmQpIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuZW5kLmxvdyA+Pj4gMCwgbWVzc2FnZS5lbmQuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKSA6IG1lc3NhZ2UuZW5kO1xuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENvbnZlcnRzIHRoaXMgU2VnbWVudCB0byBKU09OLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNlZ21lbnQucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgU2VnbWVudFxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VnbWVudC5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgXCIvb25ueC5UZW5zb3JQcm90by5TZWdtZW50XCI7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gU2VnbWVudDtcbiAgICAgICAgfSkoKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGF0YUxvY2F0aW9uIGVudW0uXG4gICAgICAgICAqIEBuYW1lIG9ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uXG4gICAgICAgICAqIEBlbnVtIHtudW1iZXJ9XG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBERUZBVUxUPTAgREVGQVVMVCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRVhURVJOQUw9MSBFWFRFUk5BTCB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uID0gKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIHZhbHVlc0J5SWQgPSB7fSwgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzBdID0gXCJERUZBVUxUXCJdID0gMDtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzFdID0gXCJFWFRFUk5BTFwiXSA9IDE7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgICAgICB9KSgpO1xuXG4gICAgICAgIHJldHVybiBUZW5zb3JQcm90bztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5TcGFyc2VUZW5zb3JQcm90byA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJvcGVydGllcyBvZiBhIFNwYXJzZVRlbnNvclByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAaW50ZXJmYWNlIElTcGFyc2VUZW5zb3JQcm90b1xuICAgICAgICAgKiBAcHJvcGVydHkge29ubnguSVRlbnNvclByb3RvfG51bGx9IFt2YWx1ZXNdIFNwYXJzZVRlbnNvclByb3RvIHZhbHVlc1xuICAgICAgICAgKiBAcHJvcGVydHkge29ubnguSVRlbnNvclByb3RvfG51bGx9IFtpbmRpY2VzXSBTcGFyc2VUZW5zb3JQcm90byBpbmRpY2VzXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbZGltc10gU3BhcnNlVGVuc29yUHJvdG8gZGltc1xuICAgICAgICAgKi9cblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBTcGFyc2VUZW5zb3JQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgU3BhcnNlVGVuc29yUHJvdG8uXG4gICAgICAgICAqIEBpbXBsZW1lbnRzIElTcGFyc2VUZW5zb3JQcm90b1xuICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklTcGFyc2VUZW5zb3JQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gU3BhcnNlVGVuc29yUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgICAgICAgdGhpcy5kaW1zID0gW107XG4gICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNwYXJzZVRlbnNvclByb3RvIHZhbHVlcy5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5JVGVuc29yUHJvdG98bnVsbHx1bmRlZmluZWR9IHZhbHVlc1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFNwYXJzZVRlbnNvclByb3RvLnByb3RvdHlwZS52YWx1ZXMgPSBudWxsO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTcGFyc2VUZW5zb3JQcm90byBpbmRpY2VzLlxuICAgICAgICAgKiBAbWVtYmVyIHtvbm54LklUZW5zb3JQcm90b3xudWxsfHVuZGVmaW5lZH0gaW5kaWNlc1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFNwYXJzZVRlbnNvclByb3RvLnByb3RvdHlwZS5pbmRpY2VzID0gbnVsbDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogU3BhcnNlVGVuc29yUHJvdG8gZGltcy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcnxMb25nPn0gZGltc1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFNwYXJzZVRlbnNvclByb3RvLnByb3RvdHlwZS5kaW1zID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBTcGFyc2VUZW5zb3JQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVNwYXJzZVRlbnNvclByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlNwYXJzZVRlbnNvclByb3RvfSBTcGFyc2VUZW5zb3JQcm90byBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgU3BhcnNlVGVuc29yUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgU3BhcnNlVGVuc29yUHJvdG8ocHJvcGVydGllcyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlNwYXJzZVRlbnNvclByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklTcGFyc2VUZW5zb3JQcm90b30gbWVzc2FnZSBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFNwYXJzZVRlbnNvclByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIGlmICghd3JpdGVyKVxuICAgICAgICAgICAgICAgIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS52YWx1ZXMgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcInZhbHVlc1wiKSlcbiAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclByb3RvLmVuY29kZShtZXNzYWdlLnZhbHVlcywgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLzEwKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5kaWNlcyAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiaW5kaWNlc1wiKSlcbiAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclByb3RvLmVuY29kZShtZXNzYWdlLmluZGljZXMsIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8xOCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRpbXMgIT0gbnVsbCAmJiBtZXNzYWdlLmRpbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLzI2KS5mb3JrKCk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRpbXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci5pbnQ2NChtZXNzYWdlLmRpbXNbaV0pO1xuICAgICAgICAgICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlNwYXJzZVRlbnNvclByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklTcGFyc2VUZW5zb3JQcm90b30gbWVzc2FnZSBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFNwYXJzZVRlbnNvclByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgU3BhcnNlVGVuc29yUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5TcGFyc2VUZW5zb3JQcm90b30gU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBTcGFyc2VUZW5zb3JQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvKCk7XG4gICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudmFsdWVzID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5kaWNlcyA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmRpbXMgJiYgbWVzc2FnZS5kaW1zLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1zID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1zLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1zLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgU3BhcnNlVGVuc29yUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5TcGFyc2VUZW5zb3JQcm90b30gU3BhcnNlVGVuc29yUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBTcGFyc2VUZW5zb3JQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVmVyaWZpZXMgYSBTcGFyc2VUZW5zb3JQcm90byBtZXNzYWdlLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAqL1xuICAgICAgICBTcGFyc2VUZW5zb3JQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS52YWx1ZXMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidmFsdWVzXCIpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by52ZXJpZnkobWVzc2FnZS52YWx1ZXMpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidmFsdWVzLlwiICsgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbmRpY2VzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImluZGljZXNcIikpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnZlcmlmeShtZXNzYWdlLmluZGljZXMpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW5kaWNlcy5cIiArIGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkaW1zXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuZGltcykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRpbXM6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRpbXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXSkgJiYgIShtZXNzYWdlLmRpbXNbaV0gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbXNbaV0uaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZGltczogaW50ZWdlcnxMb25nW10gZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgU3BhcnNlVGVuc29yUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TcGFyc2VUZW5zb3JQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguU3BhcnNlVGVuc29yUHJvdG99IFNwYXJzZVRlbnNvclByb3RvXG4gICAgICAgICAqL1xuICAgICAgICBTcGFyc2VUZW5zb3JQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlNwYXJzZVRlbnNvclByb3RvKCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LnZhbHVlcyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudmFsdWVzICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5TcGFyc2VUZW5zb3JQcm90by52YWx1ZXM6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnZhbHVlcyA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3QudmFsdWVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QuaW5kaWNlcyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5kaWNlcyAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguU3BhcnNlVGVuc29yUHJvdG8uaW5kaWNlczogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5kaWNlcyA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3QuaW5kaWNlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRpbXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmRpbXMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5TcGFyc2VUZW5zb3JQcm90by5kaW1zOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbXMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5kaW1zLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLmRpbXNbaV0gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuZGltc1tpXSkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltc1tpXSA9IHBhcnNlSW50KG9iamVjdC5kaW1zW2ldLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltc1tpXSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltc1tpXSA9IG9iamVjdC5kaW1zW2ldO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbXNbaV0gPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbXNbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmRpbXNbaV0ubG93ID4+PiAwLCBvYmplY3QuZGltc1tpXS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFNwYXJzZVRlbnNvclByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LlNwYXJzZVRlbnNvclByb3RvfSBtZXNzYWdlIFNwYXJzZVRlbnNvclByb3RvXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgU3BhcnNlVGVuc29yUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRpbXMgPSBbXTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlcyA9IG51bGw7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmluZGljZXMgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWVzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInZhbHVlc1wiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QudmFsdWVzID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by50b09iamVjdChtZXNzYWdlLnZhbHVlcywgb3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbmRpY2VzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImluZGljZXNcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmluZGljZXMgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuaW5kaWNlcywgb3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kaW1zICYmIG1lc3NhZ2UuZGltcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZGltcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZGltc1tqXSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5kaW1zW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuZGltc1tqXSkgOiBtZXNzYWdlLmRpbXNbal07XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5kaW1zW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLmRpbXNbal0pIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuZGltc1tqXS5sb3cgPj4+IDAsIG1lc3NhZ2UuZGltc1tqXS5oaWdoID4+PiAwKS50b051bWJlcigpIDogbWVzc2FnZS5kaW1zW2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydHMgdGhpcyBTcGFyc2VUZW5zb3JQcm90byB0byBKU09OLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBTcGFyc2VUZW5zb3JQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFNwYXJzZVRlbnNvclByb3RvXG4gICAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlNwYXJzZVRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgICAqL1xuICAgICAgICBTcGFyc2VUZW5zb3JQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdHlwZVVybFByZWZpeCA9IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyBcIi9vbm54LlNwYXJzZVRlbnNvclByb3RvXCI7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIFNwYXJzZVRlbnNvclByb3RvO1xuICAgIH0pKCk7XG5cbiAgICBvbm54LlRlbnNvclNoYXBlUHJvdG8gPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBUZW5zb3JTaGFwZVByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAaW50ZXJmYWNlIElUZW5zb3JTaGFwZVByb3RvXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguVGVuc29yU2hhcGVQcm90by5JRGltZW5zaW9uPnxudWxsfSBbZGltXSBUZW5zb3JTaGFwZVByb3RvIGRpbVxuICAgICAgICAgKi9cblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3JTaGFwZVByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBUZW5zb3JTaGFwZVByb3RvLlxuICAgICAgICAgKiBAaW1wbGVtZW50cyBJVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JTaGFwZVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBUZW5zb3JTaGFwZVByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHRoaXMuZGltID0gW107XG4gICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclNoYXBlUHJvdG8gZGltLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb24+fSBkaW1cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclNoYXBlUHJvdG8ucHJvdG90eXBlLmRpbSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgVGVuc29yU2hhcGVQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yU2hhcGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvfSBUZW5zb3JTaGFwZVByb3RvIGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFRlbnNvclNoYXBlUHJvdG8ocHJvcGVydGllcyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yU2hhcGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JTaGFwZVByb3RvfSBtZXNzYWdlIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIGlmICghd3JpdGVyKVxuICAgICAgICAgICAgICAgIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kaW0gIT0gbnVsbCAmJiBtZXNzYWdlLmRpbS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRpbS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbi5lbmNvZGUobWVzc2FnZS5kaW1baV0sIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8xMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yU2hhcGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JTaGFwZVByb3RvfSBtZXNzYWdlIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90b30gVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclNoYXBlUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvKCk7XG4gICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZGltICYmIG1lc3NhZ2UuZGltLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltLnB1c2goJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbi5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG99IFRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBWZXJpZmllcyBhIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvYmplY3QgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRpbSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkaW1cIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5kaW0pKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkaW06IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRpbS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLnZlcmlmeShtZXNzYWdlLmRpbVtpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRpbS5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG99IFRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclNoYXBlUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8oKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QuZGltKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5kaW0pKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UZW5zb3JTaGFwZVByb3RvLmRpbTogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5kaW0gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5kaW0ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZGltW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVGVuc29yU2hhcGVQcm90by5kaW06IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1baV0gPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLmZyb21PYmplY3Qob2JqZWN0LmRpbVtpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvfSBtZXNzYWdlIFRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKVxuICAgICAgICAgICAgICAgIG9iamVjdC5kaW0gPSBbXTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRpbSAmJiBtZXNzYWdlLmRpbS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZGltID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmRpbS5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmRpbVtqXSA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24udG9PYmplY3QobWVzc2FnZS5kaW1bal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydHMgdGhpcyBUZW5zb3JTaGFwZVByb3RvIHRvIEpTT04uXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yU2hhcGVQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yU2hhcGVQcm90by5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdHlwZVVybFByZWZpeCA9IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyBcIi9vbm54LlRlbnNvclNoYXBlUHJvdG9cIjtcbiAgICAgICAgfTtcblxuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbiA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgRGltZW5zaW9uLlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgICAgICogQGludGVyZmFjZSBJRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcnxMb25nfG51bGx9IFtkaW1WYWx1ZV0gRGltZW5zaW9uIGRpbVZhbHVlXG4gICAgICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZGltUGFyYW1dIERpbWVuc2lvbiBkaW1QYXJhbVxuICAgICAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2Rlbm90YXRpb25dIERpbWVuc2lvbiBkZW5vdGF0aW9uXG4gICAgICAgICAgICAgKi9cblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IERpbWVuc2lvbi5cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIERpbWVuc2lvbi5cbiAgICAgICAgICAgICAqIEBpbXBsZW1lbnRzIElEaW1lbnNpb25cbiAgICAgICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uSURpbWVuc2lvbj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBmdW5jdGlvbiBEaW1lbnNpb24ocHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGltZW5zaW9uIGRpbVZhbHVlLlxuICAgICAgICAgICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd8bnVsbHx1bmRlZmluZWR9IGRpbVZhbHVlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5wcm90b3R5cGUuZGltVmFsdWUgPSBudWxsO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERpbWVuc2lvbiBkaW1QYXJhbS5cbiAgICAgICAgICAgICAqIEBtZW1iZXIge3N0cmluZ3xudWxsfHVuZGVmaW5lZH0gZGltUGFyYW1cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgRGltZW5zaW9uLnByb3RvdHlwZS5kaW1QYXJhbSA9IG51bGw7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGltZW5zaW9uIGRlbm90YXRpb24uXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRlbm90YXRpb25cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgRGltZW5zaW9uLnByb3RvdHlwZS5kZW5vdGF0aW9uID0gXCJcIjtcblxuICAgICAgICAgICAgLy8gT25lT2YgZmllbGQgbmFtZXMgYm91bmQgdG8gdmlydHVhbCBnZXR0ZXJzIGFuZCBzZXR0ZXJzXG4gICAgICAgICAgICB2YXIgJG9uZU9mRmllbGRzO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERpbWVuc2lvbiB2YWx1ZS5cbiAgICAgICAgICAgICAqIEBtZW1iZXIge1wiZGltVmFsdWVcInxcImRpbVBhcmFtXCJ8dW5kZWZpbmVkfSB2YWx1ZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRGltZW5zaW9uLnByb3RvdHlwZSwgXCJ2YWx1ZVwiLCB7XG4gICAgICAgICAgICAgICAgZ2V0OiAkdXRpbC5vbmVPZkdldHRlcigkb25lT2ZGaWVsZHMgPSBbXCJkaW1WYWx1ZVwiLCBcImRpbVBhcmFtXCJdKSxcbiAgICAgICAgICAgICAgICBzZXQ6ICR1dGlsLm9uZU9mU2V0dGVyKCRvbmVPZkZpZWxkcylcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgRGltZW5zaW9uIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yU2hhcGVQcm90by5JRGltZW5zaW9uPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbn0gRGltZW5zaW9uIGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRGltZW5zaW9uKHByb3BlcnRpZXMpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgRGltZW5zaW9uIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uSURpbWVuc2lvbn0gbWVzc2FnZSBEaW1lbnNpb24gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgRGltZW5zaW9uLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5kaW1WYWx1ZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiZGltVmFsdWVcIikpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki84KS5pbnQ2NChtZXNzYWdlLmRpbVZhbHVlKTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5kaW1QYXJhbSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiZGltUGFyYW1cIikpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMiA9Ki8xOCkuc3RyaW5nKG1lc3NhZ2UuZGltUGFyYW0pO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmRlbm90YXRpb24gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcImRlbm90YXRpb25cIikpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMiA9Ki8yNikuc3RyaW5nKG1lc3NhZ2UuZGVub3RhdGlvbik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIERpbWVuc2lvbiBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb259IG1lc3NhZ2UgRGltZW5zaW9uIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERlY29kZXMgYSBEaW1lbnNpb24gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbn0gRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uKCk7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1WYWx1ZSA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbVBhcmFtID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRlbm90YXRpb24gPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGVjb2RlcyBhIERpbWVuc2lvbiBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb259IERpbWVuc2lvblxuICAgICAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBEaW1lbnNpb24uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFZlcmlmaWVzIGEgRGltZW5zaW9uIG1lc3NhZ2UuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBEaW1lbnNpb24udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5kaW1WYWx1ZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkaW1WYWx1ZVwiKSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzLnZhbHVlID0gMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1WYWx1ZSkgJiYgIShtZXNzYWdlLmRpbVZhbHVlICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbVZhbHVlLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltVmFsdWUuaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZGltVmFsdWU6IGludGVnZXJ8TG9uZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5kaW1QYXJhbSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkaW1QYXJhbVwiKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcy52YWx1ZSA9PT0gMSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcInZhbHVlOiBtdWx0aXBsZSB2YWx1ZXNcIjtcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kaW1QYXJhbSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkaW1QYXJhbTogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmRlbm90YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZGVub3RhdGlvblwiKSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZGVub3RhdGlvbjogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBEaW1lbnNpb24gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbn0gRGltZW5zaW9uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdC5kaW1WYWx1ZSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLmRpbVZhbHVlID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmRpbVZhbHVlKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1WYWx1ZSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltVmFsdWUgPSBwYXJzZUludChvYmplY3QuZGltVmFsdWUsIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1WYWx1ZSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltVmFsdWUgPSBvYmplY3QuZGltVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltVmFsdWUgPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbVZhbHVlID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5kaW1WYWx1ZS5sb3cgPj4+IDAsIG9iamVjdC5kaW1WYWx1ZS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3QuZGltUGFyYW0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1QYXJhbSA9IFN0cmluZyhvYmplY3QuZGltUGFyYW0pO1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3QuZGVub3RhdGlvbiAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRlbm90YXRpb24gPSBTdHJpbmcob2JqZWN0LmRlbm90YXRpb24pO1xuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBEaW1lbnNpb24gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9ufSBtZXNzYWdlIERpbWVuc2lvblxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBEaW1lbnNpb24udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZGVub3RhdGlvbiA9IFwiXCI7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltVmFsdWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZGltVmFsdWVcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmRpbVZhbHVlID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmRpbVZhbHVlID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuZGltVmFsdWUpIDogbWVzc2FnZS5kaW1WYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmRpbVZhbHVlID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLmRpbVZhbHVlKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmRpbVZhbHVlLmxvdyA+Pj4gMCwgbWVzc2FnZS5kaW1WYWx1ZS5oaWdoID4+PiAwKS50b051bWJlcigpIDogbWVzc2FnZS5kaW1WYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMub25lb2ZzKVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlID0gXCJkaW1WYWx1ZVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5kaW1QYXJhbSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkaW1QYXJhbVwiKSkge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZGltUGFyYW0gPSBtZXNzYWdlLmRpbVBhcmFtO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5vbmVvZnMpXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QudmFsdWUgPSBcImRpbVBhcmFtXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmRlbm90YXRpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZGVub3RhdGlvblwiKSlcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmRlbm90YXRpb24gPSBtZXNzYWdlLmRlbm90YXRpb247XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ29udmVydHMgdGhpcyBEaW1lbnNpb24gdG8gSlNPTi5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgRGltZW5zaW9uLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIERpbWVuc2lvblxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgXCIvb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblwiO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmV0dXJuIERpbWVuc2lvbjtcbiAgICAgICAgfSkoKTtcblxuICAgICAgICByZXR1cm4gVGVuc29yU2hhcGVQcm90bztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5UeXBlUHJvdG8gPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBUeXBlUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBpbnRlcmZhY2UgSVR5cGVQcm90b1xuICAgICAgICAgKiBAcHJvcGVydHkge29ubnguVHlwZVByb3RvLklUZW5zb3J8bnVsbH0gW3RlbnNvclR5cGVdIFR5cGVQcm90byB0ZW5zb3JUeXBlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UeXBlUHJvdG8uSVNlcXVlbmNlfG51bGx9IFtzZXF1ZW5jZVR5cGVdIFR5cGVQcm90byBzZXF1ZW5jZVR5cGVcbiAgICAgICAgICogQHByb3BlcnR5IHtvbm54LlR5cGVQcm90by5JTWFwfG51bGx9IFttYXBUeXBlXSBUeXBlUHJvdG8gbWFwVHlwZVxuICAgICAgICAgKiBAcHJvcGVydHkge29ubnguVHlwZVByb3RvLklPcHRpb25hbHxudWxsfSBbb3B0aW9uYWxUeXBlXSBUeXBlUHJvdG8gb3B0aW9uYWxUeXBlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UeXBlUHJvdG8uSVNwYXJzZVRlbnNvcnxudWxsfSBbc3BhcnNlVGVuc29yVHlwZV0gVHlwZVByb3RvIHNwYXJzZVRlbnNvclR5cGVcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2Rlbm90YXRpb25dIFR5cGVQcm90byBkZW5vdGF0aW9uXG4gICAgICAgICAqL1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFR5cGVQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVHlwZVByb3RvLlxuICAgICAgICAgKiBAaW1wbGVtZW50cyBJVHlwZVByb3RvXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVR5cGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gVHlwZVByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogVHlwZVByb3RvIHRlbnNvclR5cGUuXG4gICAgICAgICAqIEBtZW1iZXIge29ubnguVHlwZVByb3RvLklUZW5zb3J8bnVsbHx1bmRlZmluZWR9IHRlbnNvclR5cGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVHlwZVByb3RvLnByb3RvdHlwZS50ZW5zb3JUeXBlID0gbnVsbDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVHlwZVByb3RvIHNlcXVlbmNlVHlwZS5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5UeXBlUHJvdG8uSVNlcXVlbmNlfG51bGx8dW5kZWZpbmVkfSBzZXF1ZW5jZVR5cGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVHlwZVByb3RvLnByb3RvdHlwZS5zZXF1ZW5jZVR5cGUgPSBudWxsO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUeXBlUHJvdG8gbWFwVHlwZS5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5UeXBlUHJvdG8uSU1hcHxudWxsfHVuZGVmaW5lZH0gbWFwVHlwZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUeXBlUHJvdG8ucHJvdG90eXBlLm1hcFR5cGUgPSBudWxsO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUeXBlUHJvdG8gb3B0aW9uYWxUeXBlLlxuICAgICAgICAgKiBAbWVtYmVyIHtvbm54LlR5cGVQcm90by5JT3B0aW9uYWx8bnVsbHx1bmRlZmluZWR9IG9wdGlvbmFsVHlwZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUeXBlUHJvdG8ucHJvdG90eXBlLm9wdGlvbmFsVHlwZSA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFR5cGVQcm90byBzcGFyc2VUZW5zb3JUeXBlLlxuICAgICAgICAgKiBAbWVtYmVyIHtvbm54LlR5cGVQcm90by5JU3BhcnNlVGVuc29yfG51bGx8dW5kZWZpbmVkfSBzcGFyc2VUZW5zb3JUeXBlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by5wcm90b3R5cGUuc3BhcnNlVGVuc29yVHlwZSA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFR5cGVQcm90byBkZW5vdGF0aW9uLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRlbm90YXRpb25cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVHlwZVByb3RvLnByb3RvdHlwZS5kZW5vdGF0aW9uID0gXCJcIjtcblxuICAgICAgICAvLyBPbmVPZiBmaWVsZCBuYW1lcyBib3VuZCB0byB2aXJ0dWFsIGdldHRlcnMgYW5kIHNldHRlcnNcbiAgICAgICAgdmFyICRvbmVPZkZpZWxkcztcblxuICAgICAgICAvKipcbiAgICAgICAgICogVHlwZVByb3RvIHZhbHVlLlxuICAgICAgICAgKiBAbWVtYmVyIHtcInRlbnNvclR5cGVcInxcInNlcXVlbmNlVHlwZVwifFwibWFwVHlwZVwifFwib3B0aW9uYWxUeXBlXCJ8XCJzcGFyc2VUZW5zb3JUeXBlXCJ8dW5kZWZpbmVkfSB2YWx1ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVHlwZVByb3RvLnByb3RvdHlwZSwgXCJ2YWx1ZVwiLCB7XG4gICAgICAgICAgICBnZXQ6ICR1dGlsLm9uZU9mR2V0dGVyKCRvbmVPZkZpZWxkcyA9IFtcInRlbnNvclR5cGVcIiwgXCJzZXF1ZW5jZVR5cGVcIiwgXCJtYXBUeXBlXCIsIFwib3B0aW9uYWxUeXBlXCIsIFwic3BhcnNlVGVuc29yVHlwZVwiXSksXG4gICAgICAgICAgICBzZXQ6ICR1dGlsLm9uZU9mU2V0dGVyKCRvbmVPZkZpZWxkcylcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgVHlwZVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVR5cGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90byBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVHlwZVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFR5cGVQcm90byhwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFR5cGVQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVR5cGVQcm90b30gbWVzc2FnZSBUeXBlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBUeXBlUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRlbnNvclR5cGUgIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcInRlbnNvclR5cGVcIikpXG4gICAgICAgICAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yLmVuY29kZShtZXNzYWdlLnRlbnNvclR5cGUsIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8xMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnNlcXVlbmNlVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwic2VxdWVuY2VUeXBlXCIpKVxuICAgICAgICAgICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmVuY29kZShtZXNzYWdlLnNlcXVlbmNlVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLzM0KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubWFwVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwibWFwVHlwZVwiKSlcbiAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5NYXAuZW5jb2RlKG1lc3NhZ2UubWFwVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCA1LCB3aXJlVHlwZSAyID0qLzQyKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGVub3RhdGlvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiZGVub3RhdGlvblwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDYsIHdpcmVUeXBlIDIgPSovNTApLnN0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwic3BhcnNlVGVuc29yVHlwZVwiKSlcbiAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IuZW5jb2RlKG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLzY2KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3B0aW9uYWxUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJvcHRpb25hbFR5cGVcIikpXG4gICAgICAgICAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwuZW5jb2RlKG1lc3NhZ2Uub3B0aW9uYWxUeXBlLCB3cml0ZXIudWludDMyKC8qIGlkIDksIHdpcmVUeXBlIDIgPSovNzQpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVHlwZVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVHlwZVByb3RvfSBtZXNzYWdlIFR5cGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFR5cGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90bygpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnRlbnNvclR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSA0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnNlcXVlbmNlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5tYXBUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uTWFwLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgOToge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5vcHRpb25hbFR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5PcHRpb25hbC5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDg6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDY6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGVub3RhdGlvbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFR5cGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVmVyaWZpZXMgYSBUeXBlUHJvdG8gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICB2YXIgcHJvcGVydGllcyA9IHt9O1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudGVuc29yVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJ0ZW5zb3JUeXBlXCIpKSB7XG4gICAgICAgICAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IudmVyaWZ5KG1lc3NhZ2UudGVuc29yVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcInRlbnNvclR5cGUuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5zZXF1ZW5jZVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwic2VxdWVuY2VUeXBlXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMudmFsdWUgPT09IDEpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInZhbHVlOiBtdWx0aXBsZSB2YWx1ZXNcIjtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzLnZhbHVlID0gMTtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLnZlcmlmeShtZXNzYWdlLnNlcXVlbmNlVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcInNlcXVlbmNlVHlwZS5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm1hcFR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibWFwVHlwZVwiKSkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLnZhbHVlID09PSAxKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ2YWx1ZTogbXVsdGlwbGUgdmFsdWVzXCI7XG4gICAgICAgICAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by5NYXAudmVyaWZ5KG1lc3NhZ2UubWFwVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm1hcFR5cGUuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vcHRpb25hbFR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwib3B0aW9uYWxUeXBlXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMudmFsdWUgPT09IDEpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInZhbHVlOiBtdWx0aXBsZSB2YWx1ZXNcIjtcbiAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzLnZhbHVlID0gMTtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsLnZlcmlmeShtZXNzYWdlLm9wdGlvbmFsVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm9wdGlvbmFsVHlwZS5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwic3BhcnNlVGVuc29yVHlwZVwiKSkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLnZhbHVlID09PSAxKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ2YWx1ZTogbXVsdGlwbGUgdmFsdWVzXCI7XG4gICAgICAgICAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IudmVyaWZ5KG1lc3NhZ2Uuc3BhcnNlVGVuc29yVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcInNwYXJzZVRlbnNvclR5cGUuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRlbm90YXRpb25cIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkZW5vdGF0aW9uOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgVHlwZVByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90b1xuICAgICAgICAgKi9cbiAgICAgICAgVHlwZVByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHlwZVByb3RvKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90bygpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC50ZW5zb3JUeXBlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50ZW5zb3JUeXBlICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UeXBlUHJvdG8udGVuc29yVHlwZTogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UudGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvci5mcm9tT2JqZWN0KG9iamVjdC50ZW5zb3JUeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3Quc2VxdWVuY2VUeXBlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zZXF1ZW5jZVR5cGUgIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlR5cGVQcm90by5zZXF1ZW5jZVR5cGU6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnNlcXVlbmNlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmZyb21PYmplY3Qob2JqZWN0LnNlcXVlbmNlVHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm1hcFR5cGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm1hcFR5cGUgIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlR5cGVQcm90by5tYXBUeXBlOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5tYXBUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uTWFwLmZyb21PYmplY3Qob2JqZWN0Lm1hcFR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5vcHRpb25hbFR5cGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm9wdGlvbmFsVHlwZSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVHlwZVByb3RvLm9wdGlvbmFsVHlwZTogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3B0aW9uYWxUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwuZnJvbU9iamVjdChvYmplY3Qub3B0aW9uYWxUeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3Quc3BhcnNlVGVuc29yVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3BhcnNlVGVuc29yVHlwZSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVHlwZVByb3RvLnNwYXJzZVRlbnNvclR5cGU6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IuZnJvbU9iamVjdChvYmplY3Quc3BhcnNlVGVuc29yVHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRlbm90YXRpb24gIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRlbm90YXRpb24gPSBTdHJpbmcob2JqZWN0LmRlbm90YXRpb24pO1xuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFR5cGVQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvfSBtZXNzYWdlIFR5cGVQcm90b1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cylcbiAgICAgICAgICAgICAgICBvYmplY3QuZGVub3RhdGlvbiA9IFwiXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50ZW5zb3JUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInRlbnNvclR5cGVcIikpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QudGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvci50b09iamVjdChtZXNzYWdlLnRlbnNvclR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLm9uZW9mcylcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlID0gXCJ0ZW5zb3JUeXBlXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5zZXF1ZW5jZVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwic2VxdWVuY2VUeXBlXCIpKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnNlcXVlbmNlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLnRvT2JqZWN0KG1lc3NhZ2Uuc2VxdWVuY2VUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5vbmVvZnMpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC52YWx1ZSA9IFwic2VxdWVuY2VUeXBlXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5tYXBUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm1hcFR5cGVcIikpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QubWFwVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLk1hcC50b09iamVjdChtZXNzYWdlLm1hcFR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLm9uZW9mcylcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlID0gXCJtYXBUeXBlXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRlbm90YXRpb25cIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRlbm90YXRpb24gPSBtZXNzYWdlLmRlbm90YXRpb247XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5zcGFyc2VUZW5zb3JUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInNwYXJzZVRlbnNvclR5cGVcIikpIHtcbiAgICAgICAgICAgICAgICBvYmplY3Quc3BhcnNlVGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci50b09iamVjdChtZXNzYWdlLnNwYXJzZVRlbnNvclR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLm9uZW9mcylcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlID0gXCJzcGFyc2VUZW5zb3JUeXBlXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vcHRpb25hbFR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwib3B0aW9uYWxUeXBlXCIpKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm9wdGlvbmFsVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLk9wdGlvbmFsLnRvT2JqZWN0KG1lc3NhZ2Uub3B0aW9uYWxUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5vbmVvZnMpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC52YWx1ZSA9IFwib3B0aW9uYWxUeXBlXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIFR5cGVQcm90byB0byBKU09OLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgVHlwZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgVHlwZVByb3RvXG4gICAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICAgKi9cbiAgICAgICAgVHlwZVByb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArIFwiL29ubnguVHlwZVByb3RvXCI7XG4gICAgICAgIH07XG5cbiAgICAgICAgVHlwZVByb3RvLlRlbnNvciA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVGVuc29yLlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAgICAgKiBAaW50ZXJmYWNlIElUZW5zb3JcbiAgICAgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfG51bGx9IFtlbGVtVHlwZV0gVGVuc29yIGVsZW1UeXBlXG4gICAgICAgICAgICAgKiBAcHJvcGVydHkge29ubnguSVRlbnNvclNoYXBlUHJvdG98bnVsbH0gW3NoYXBlXSBUZW5zb3Igc2hhcGVcbiAgICAgICAgICAgICAqL1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVGVuc29yLlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBUZW5zb3IuXG4gICAgICAgICAgICAgKiBAaW1wbGVtZW50cyBJVGVuc29yXG4gICAgICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVRlbnNvcj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBmdW5jdGlvbiBUZW5zb3IocHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVGVuc29yIGVsZW1UeXBlLlxuICAgICAgICAgICAgICogQG1lbWJlciB7bnVtYmVyfSBlbGVtVHlwZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFRlbnNvci5wcm90b3R5cGUuZWxlbVR5cGUgPSAwO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFRlbnNvciBzaGFwZS5cbiAgICAgICAgICAgICAqIEBtZW1iZXIge29ubnguSVRlbnNvclNoYXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IHNoYXBlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgVGVuc29yLnByb3RvdHlwZS5zaGFwZSA9IG51bGw7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBUZW5zb3IgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JVGVuc29yPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uVGVuc29yfSBUZW5zb3IgaW5zdGFuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgVGVuc29yLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUZW5zb3IocHJvcGVydGllcyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3IgbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uVGVuc29yLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JVGVuc29yfSBtZXNzYWdlIFRlbnNvciBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBUZW5zb3IuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgICAgIGlmICghd3JpdGVyKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJlbGVtVHlwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAwID0qLzgpLmludDMyKG1lc3NhZ2UuZWxlbVR5cGUpO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLnNoYXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJzaGFwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmVuY29kZShtZXNzYWdlLnNoYXBlLCB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovMTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvciBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5UZW5zb3IudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklUZW5zb3J9IG1lc3NhZ2UgVGVuc29yIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFRlbnNvci5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERlY29kZXMgYSBUZW5zb3IgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5UZW5zb3J9IFRlbnNvclxuICAgICAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBUZW5zb3IuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yKCk7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5lbGVtVHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGVjb2RlcyBhIFRlbnNvciBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uVGVuc29yfSBUZW5zb3JcbiAgICAgICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgVGVuc29yLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBWZXJpZmllcyBhIFRlbnNvciBtZXNzYWdlLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBUZW5zb3IudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZWxlbVR5cGVcIikpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZWxlbVR5cGUpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZWxlbVR5cGU6IGludGVnZXIgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzaGFwZVwiKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8udmVyaWZ5KG1lc3NhZ2Uuc2hhcGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJzaGFwZS5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ3JlYXRlcyBhIFRlbnNvciBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlRlbnNvcn0gVGVuc29yXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFRlbnNvci5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvcigpO1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3QuZWxlbVR5cGUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5lbGVtVHlwZSA9IG9iamVjdC5lbGVtVHlwZSB8IDA7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdC5zaGFwZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnNoYXBlICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVHlwZVByb3RvLlRlbnNvci5zaGFwZTogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LnNoYXBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFRlbnNvciBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uVGVuc29yfSBtZXNzYWdlIFRlbnNvclxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBUZW5zb3IudG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5lbGVtVHlwZSA9IDA7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5zaGFwZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImVsZW1UeXBlXCIpKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZWxlbVR5cGUgPSBtZXNzYWdlLmVsZW1UeXBlO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLnNoYXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInNoYXBlXCIpKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3Quc2hhcGUgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8udG9PYmplY3QobWVzc2FnZS5zaGFwZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ29udmVydHMgdGhpcyBUZW5zb3IgdG8gSlNPTi5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBUZW5zb3IucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgVGVuc29yXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlRlbnNvclxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGVmYXVsdCB0eXBlIHVybFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBUZW5zb3IuZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZVVybFByZWZpeCA9IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArIFwiL29ubnguVHlwZVByb3RvLlRlbnNvclwiO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmV0dXJuIFRlbnNvcjtcbiAgICAgICAgfSkoKTtcblxuICAgICAgICBUeXBlUHJvdG8uU2VxdWVuY2UgPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogUHJvcGVydGllcyBvZiBhIFNlcXVlbmNlLlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAgICAgKiBAaW50ZXJmYWNlIElTZXF1ZW5jZVxuICAgICAgICAgICAgICogQHByb3BlcnR5IHtvbm54LklUeXBlUHJvdG98bnVsbH0gW2VsZW1UeXBlXSBTZXF1ZW5jZSBlbGVtVHlwZVxuICAgICAgICAgICAgICovXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBTZXF1ZW5jZS5cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgU2VxdWVuY2UuXG4gICAgICAgICAgICAgKiBAaW1wbGVtZW50cyBJU2VxdWVuY2VcbiAgICAgICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JU2VxdWVuY2U9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgZnVuY3Rpb24gU2VxdWVuY2UocHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogU2VxdWVuY2UgZWxlbVR5cGUuXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtvbm54LklUeXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IGVsZW1UeXBlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZXF1ZW5jZS5wcm90b3R5cGUuZWxlbVR5cGUgPSBudWxsO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgU2VxdWVuY2UgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTZXF1ZW5jZT19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlNlcXVlbmNlfSBTZXF1ZW5jZSBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZXF1ZW5jZS5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2VxdWVuY2UocHJvcGVydGllcyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTZXF1ZW5jZSBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5TZXF1ZW5jZS52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JU2VxdWVuY2V9IG1lc3NhZ2UgU2VxdWVuY2UgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VxdWVuY2UuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgICAgIGlmICghd3JpdGVyKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJlbGVtVHlwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5UeXBlUHJvdG8uZW5jb2RlKG1lc3NhZ2UuZWxlbVR5cGUsIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8xMCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU2VxdWVuY2UgbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uU2VxdWVuY2UudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNlcXVlbmNlfSBtZXNzYWdlIFNlcXVlbmNlIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNlcXVlbmNlLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGVjb2RlcyBhIFNlcXVlbmNlIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TZXF1ZW5jZX0gU2VxdWVuY2VcbiAgICAgICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VxdWVuY2UuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uU2VxdWVuY2UoKTtcbiAgICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmVsZW1UeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBEZWNvZGVzIGEgU2VxdWVuY2UgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU2VxdWVuY2V9IFNlcXVlbmNlXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNlcXVlbmNlLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBWZXJpZmllcyBhIFNlcXVlbmNlIG1lc3NhZ2UuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VxdWVuY2UudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZWxlbVR5cGVcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UeXBlUHJvdG8udmVyaWZ5KG1lc3NhZ2UuZWxlbVR5cGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJlbGVtVHlwZS5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ3JlYXRlcyBhIFNlcXVlbmNlIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU2VxdWVuY2VcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TZXF1ZW5jZX0gU2VxdWVuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VxdWVuY2UuZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLlNlcXVlbmNlKCk7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdC5lbGVtVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmVsZW1UeXBlICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVHlwZVByb3RvLlNlcXVlbmNlLmVsZW1UeXBlOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5lbGVtVHlwZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBTZXF1ZW5jZSBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5TZXF1ZW5jZX0gbWVzc2FnZSBTZXF1ZW5jZVxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZXF1ZW5jZS50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5lbGVtVHlwZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZWxlbVR5cGVcIikpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5lbGVtVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZWxlbVR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENvbnZlcnRzIHRoaXMgU2VxdWVuY2UgdG8gSlNPTi5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TZXF1ZW5jZVxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNlcXVlbmNlLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFNlcXVlbmNlXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNlcXVlbmNlXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNlcXVlbmNlLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyBcIi9vbm54LlR5cGVQcm90by5TZXF1ZW5jZVwiO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmV0dXJuIFNlcXVlbmNlO1xuICAgICAgICB9KSgpO1xuXG4gICAgICAgIFR5cGVQcm90by5NYXAgPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogUHJvcGVydGllcyBvZiBhIE1hcC5cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgICAgICogQGludGVyZmFjZSBJTWFwXG4gICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcnxudWxsfSBba2V5VHlwZV0gTWFwIGtleVR5cGVcbiAgICAgICAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVHlwZVByb3RvfG51bGx9IFt2YWx1ZVR5cGVdIE1hcCB2YWx1ZVR5cGVcbiAgICAgICAgICAgICAqL1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgTWFwLlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBNYXAuXG4gICAgICAgICAgICAgKiBAaW1wbGVtZW50cyBJTWFwXG4gICAgICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU1hcD19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBmdW5jdGlvbiBNYXAocHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogTWFwIGtleVR5cGUuXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGtleVR5cGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBNYXAucHJvdG90eXBlLmtleVR5cGUgPSAwO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIE1hcCB2YWx1ZVR5cGUuXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtvbm54LklUeXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IHZhbHVlVHlwZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIE1hcC5wcm90b3R5cGUudmFsdWVUeXBlID0gbnVsbDtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IE1hcCBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklNYXA9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5NYXB9IE1hcCBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBNYXAuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hcChwcm9wZXJ0aWVzKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1hcCBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5NYXAudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklNYXB9IG1lc3NhZ2UgTWFwIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIE1hcC5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2Uua2V5VHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwia2V5VHlwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAwID0qLzgpLmludDMyKG1lc3NhZ2Uua2V5VHlwZSk7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWVUeXBlICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJ2YWx1ZVR5cGVcIikpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLmVuY29kZShtZXNzYWdlLnZhbHVlVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLzE4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBNYXAgbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uTWFwLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JTWFwfSBtZXNzYWdlIE1hcCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBNYXAuZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBEZWNvZGVzIGEgTWFwIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uTWFwfSBNYXBcbiAgICAgICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgTWFwLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgICAgICByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICAgICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLCBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLk1hcCgpO1xuICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uua2V5VHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnZhbHVlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGVjb2RlcyBhIE1hcCBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uTWFwfSBNYXBcbiAgICAgICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgTWFwLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBWZXJpZmllcyBhIE1hcCBtZXNzYWdlLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBNYXAudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2Uua2V5VHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJrZXlUeXBlXCIpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmtleVR5cGUpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwia2V5VHlwZTogaW50ZWdlciBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLnZhbHVlVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJ2YWx1ZVR5cGVcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UeXBlUHJvdG8udmVyaWZ5KG1lc3NhZ2UudmFsdWVUeXBlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidmFsdWVUeXBlLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgTWFwIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uTWFwfSBNYXBcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgTWFwLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlR5cGVQcm90by5NYXApXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uTWFwKCk7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdC5rZXlUeXBlICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uua2V5VHlwZSA9IG9iamVjdC5rZXlUeXBlIHwgMDtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0LnZhbHVlVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnZhbHVlVHlwZSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlR5cGVQcm90by5NYXAudmFsdWVUeXBlOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudmFsdWVUeXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZnJvbU9iamVjdChvYmplY3QudmFsdWVUeXBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIE1hcCBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5NYXBcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uTWFwfSBtZXNzYWdlIE1hcFxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBNYXAudG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5rZXlUeXBlID0gMDtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlVHlwZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmtleVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwia2V5VHlwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmtleVR5cGUgPSBtZXNzYWdlLmtleVR5cGU7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWVUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInZhbHVlVHlwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudmFsdWVUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIE1hcCB0byBKU09OLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk1hcFxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIE1hcC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBNYXBcbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBnZXRUeXBlVXJsXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uTWFwXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIE1hcC5nZXRUeXBlVXJsID0gZnVuY3Rpb24gZ2V0VHlwZVVybCh0eXBlVXJsUHJlZml4KSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgXCIvb25ueC5UeXBlUHJvdG8uTWFwXCI7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gTWFwO1xuICAgICAgICB9KSgpO1xuXG4gICAgICAgIFR5cGVQcm90by5PcHRpb25hbCA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGFuIE9wdGlvbmFsLlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAgICAgKiBAaW50ZXJmYWNlIElPcHRpb25hbFxuICAgICAgICAgICAgICogQHByb3BlcnR5IHtvbm54LklUeXBlUHJvdG98bnVsbH0gW2VsZW1UeXBlXSBPcHRpb25hbCBlbGVtVHlwZVxuICAgICAgICAgICAgICovXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBPcHRpb25hbC5cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGFuIE9wdGlvbmFsLlxuICAgICAgICAgICAgICogQGltcGxlbWVudHMgSU9wdGlvbmFsXG4gICAgICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU9wdGlvbmFsPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGZ1bmN0aW9uIE9wdGlvbmFsKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIE9wdGlvbmFsIGVsZW1UeXBlLlxuICAgICAgICAgICAgICogQG1lbWJlciB7b25ueC5JVHlwZVByb3RvfG51bGx8dW5kZWZpbmVkfSBlbGVtVHlwZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgT3B0aW9uYWwucHJvdG90eXBlLmVsZW1UeXBlID0gbnVsbDtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IE9wdGlvbmFsIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JT3B0aW9uYWw9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5PcHRpb25hbH0gT3B0aW9uYWwgaW5zdGFuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgT3B0aW9uYWwuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE9wdGlvbmFsKHByb3BlcnRpZXMpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgT3B0aW9uYWwgbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uT3B0aW9uYWwudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uT3B0aW9uYWxcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSU9wdGlvbmFsfSBtZXNzYWdlIE9wdGlvbmFsIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIE9wdGlvbmFsLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiZWxlbVR5cGVcIikpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguVHlwZVByb3RvLmVuY29kZShtZXNzYWdlLmVsZW1UeXBlLCB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovMTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE9wdGlvbmFsIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklPcHRpb25hbH0gbWVzc2FnZSBPcHRpb25hbCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBPcHRpb25hbC5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERlY29kZXMgYW4gT3B0aW9uYWwgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLk9wdGlvbmFsfSBPcHRpb25hbFxuICAgICAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBPcHRpb25hbC5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5PcHRpb25hbCgpO1xuICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERlY29kZXMgYW4gT3B0aW9uYWwgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uT3B0aW9uYWx9IE9wdGlvbmFsXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIE9wdGlvbmFsLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBWZXJpZmllcyBhbiBPcHRpb25hbCBtZXNzYWdlLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIE9wdGlvbmFsLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImVsZW1UeXBlXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLmVsZW1UeXBlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZWxlbVR5cGUuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYW4gT3B0aW9uYWwgbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLk9wdGlvbmFsfSBPcHRpb25hbFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBPcHRpb25hbC5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwoKTtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVsZW1UeXBlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZWxlbVR5cGUgIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UeXBlUHJvdG8uT3B0aW9uYWwuZWxlbVR5cGU6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5lbGVtVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LmVsZW1UeXBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhbiBPcHRpb25hbCBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5PcHRpb25hbH0gbWVzc2FnZSBPcHRpb25hbFxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBPcHRpb25hbC50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5lbGVtVHlwZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZWxlbVR5cGVcIikpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5lbGVtVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZWxlbVR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENvbnZlcnRzIHRoaXMgT3B0aW9uYWwgdG8gSlNPTi5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5PcHRpb25hbFxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIE9wdGlvbmFsLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIE9wdGlvbmFsXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLk9wdGlvbmFsXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVVcmxQcmVmaXhdIHlvdXIgY3VzdG9tIHR5cGVVcmxQcmVmaXgoZGVmYXVsdCBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIilcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIE9wdGlvbmFsLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyBcIi9vbm54LlR5cGVQcm90by5PcHRpb25hbFwiO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmV0dXJuIE9wdGlvbmFsO1xuICAgICAgICB9KSgpO1xuXG4gICAgICAgIFR5cGVQcm90by5TcGFyc2VUZW5zb3IgPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogUHJvcGVydGllcyBvZiBhIFNwYXJzZVRlbnNvci5cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgICAgICogQGludGVyZmFjZSBJU3BhcnNlVGVuc29yXG4gICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcnxudWxsfSBbZWxlbVR5cGVdIFNwYXJzZVRlbnNvciBlbGVtVHlwZVxuICAgICAgICAgICAgICogQHByb3BlcnR5IHtvbm54LklUZW5zb3JTaGFwZVByb3RvfG51bGx9IFtzaGFwZV0gU3BhcnNlVGVuc29yIHNoYXBlXG4gICAgICAgICAgICAgKi9cblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFNwYXJzZVRlbnNvci5cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgU3BhcnNlVGVuc29yLlxuICAgICAgICAgICAgICogQGltcGxlbWVudHMgSVNwYXJzZVRlbnNvclxuICAgICAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklTcGFyc2VUZW5zb3I9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgZnVuY3Rpb24gU3BhcnNlVGVuc29yKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFNwYXJzZVRlbnNvciBlbGVtVHlwZS5cbiAgICAgICAgICAgICAqIEBtZW1iZXIge251bWJlcn0gZWxlbVR5cGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTcGFyc2VUZW5zb3IucHJvdG90eXBlLmVsZW1UeXBlID0gMDtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBTcGFyc2VUZW5zb3Igc2hhcGUuXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtvbm54LklUZW5zb3JTaGFwZVByb3RvfG51bGx8dW5kZWZpbmVkfSBzaGFwZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNwYXJzZVRlbnNvci5wcm90b3R5cGUuc2hhcGUgPSBudWxsO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgU3BhcnNlVGVuc29yIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNwYXJzZVRlbnNvcj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcn0gU3BhcnNlVGVuc29yIGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNwYXJzZVRlbnNvci5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3BhcnNlVGVuc29yKHByb3BlcnRpZXMpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU3BhcnNlVGVuc29yIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvci52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UeXBlUHJvdG8uSVNwYXJzZVRlbnNvcn0gbWVzc2FnZSBTcGFyc2VUZW5zb3IgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU3BhcnNlVGVuc29yLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwiZWxlbVR5cGVcIikpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki84KS5pbnQzMihtZXNzYWdlLmVsZW1UeXBlKTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwic2hhcGVcIikpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5lbmNvZGUobWVzc2FnZS5zaGFwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLzE4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBTcGFyc2VUZW5zb3IgbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvclxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JU3BhcnNlVGVuc29yfSBtZXNzYWdlIFNwYXJzZVRlbnNvciBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTcGFyc2VUZW5zb3IuZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBEZWNvZGVzIGEgU3BhcnNlVGVuc29yIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yfSBTcGFyc2VUZW5zb3JcbiAgICAgICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU3BhcnNlVGVuc29yLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgICAgICByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICAgICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLCBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcigpO1xuICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSByZWFkZXIuaW50MzIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zaGFwZSA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERlY29kZXMgYSBTcGFyc2VUZW5zb3IgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcn0gU3BhcnNlVGVuc29yXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNwYXJzZVRlbnNvci5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVmVyaWZpZXMgYSBTcGFyc2VUZW5zb3IgbWVzc2FnZS5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU3BhcnNlVGVuc29yLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImVsZW1UeXBlXCIpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVsZW1UeXBlKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImVsZW1UeXBlOiBpbnRlZ2VyIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc2hhcGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwic2hhcGVcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLnZlcmlmeShtZXNzYWdlLnNoYXBlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwic2hhcGUuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBTcGFyc2VUZW5zb3IgbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3J9IFNwYXJzZVRlbnNvclxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTcGFyc2VUZW5zb3IuZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3IoKTtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVsZW1UeXBlICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSBvYmplY3QuZWxlbVR5cGUgfCAwO1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3Quc2hhcGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zaGFwZSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3Iuc2hhcGU6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zaGFwZSA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5zaGFwZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBTcGFyc2VUZW5zb3IgbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLlNwYXJzZVRlbnNvcn0gbWVzc2FnZSBTcGFyc2VUZW5zb3JcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU3BhcnNlVGVuc29yLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZWxlbVR5cGUgPSAwO1xuICAgICAgICAgICAgICAgICAgICBvYmplY3Quc2hhcGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJlbGVtVHlwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmVsZW1UeXBlID0gbWVzc2FnZS5lbGVtVHlwZTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzaGFwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc2hhcGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENvbnZlcnRzIHRoaXMgU3BhcnNlVGVuc29yIHRvIEpTT04uXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uU3BhcnNlVGVuc29yXG4gICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU3BhcnNlVGVuc29yLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdHlwZSB1cmwgZm9yIFNwYXJzZVRlbnNvclxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZVVybFByZWZpeF0geW91ciBjdXN0b20gdHlwZVVybFByZWZpeChkZWZhdWx0IFwidHlwZS5nb29nbGVhcGlzLmNvbVwiKVxuICAgICAgICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGRlZmF1bHQgdHlwZSB1cmxcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU3BhcnNlVGVuc29yLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZVVybFByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVVcmxQcmVmaXggKyBcIi9vbm54LlR5cGVQcm90by5TcGFyc2VUZW5zb3JcIjtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJldHVybiBTcGFyc2VUZW5zb3I7XG4gICAgICAgIH0pKCk7XG5cbiAgICAgICAgcmV0dXJuIFR5cGVQcm90bztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5PcGVyYXRvclNldElkUHJvdG8gPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3BlcnRpZXMgb2YgYW4gT3BlcmF0b3JTZXRJZFByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAaW50ZXJmYWNlIElPcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvbWFpbl0gT3BlcmF0b3JTZXRJZFByb3RvIGRvbWFpblxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcnxMb25nfG51bGx9IFt2ZXJzaW9uXSBPcGVyYXRvclNldElkUHJvdG8gdmVyc2lvblxuICAgICAgICAgKi9cblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBPcGVyYXRvclNldElkUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhbiBPcGVyYXRvclNldElkUHJvdG8uXG4gICAgICAgICAqIEBpbXBsZW1lbnRzIElPcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBPcGVyYXRvclNldElkUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPcGVyYXRvclNldElkUHJvdG8gZG9tYWluLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvbWFpblxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBPcGVyYXRvclNldElkUHJvdG8ucHJvdG90eXBlLmRvbWFpbiA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE9wZXJhdG9yU2V0SWRQcm90byB2ZXJzaW9uLlxuICAgICAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gdmVyc2lvblxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBPcGVyYXRvclNldElkUHJvdG8ucHJvdG90eXBlLnZlcnNpb24gPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLDAsZmFsc2UpIDogMDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBPcGVyYXRvclNldElkUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54Lk9wZXJhdG9yU2V0SWRQcm90b30gT3BlcmF0b3JTZXRJZFByb3RvIGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBPcGVyYXRvclNldElkUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgT3BlcmF0b3JTZXRJZFByb3RvKHByb3BlcnRpZXMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvfSBtZXNzYWdlIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIE9wZXJhdG9yU2V0SWRQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJkb21haW5cIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLzEwKS5zdHJpbmcobWVzc2FnZS5kb21haW4pO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudmVyc2lvbiAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwidmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDAgPSovMTYpLmludDY0KG1lc3NhZ2UudmVyc2lvbik7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvfSBtZXNzYWdlIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIE9wZXJhdG9yU2V0SWRQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhbiBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICogQHJldHVybnMge29ubnguT3BlcmF0b3JTZXRJZFByb3RvfSBPcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBPcGVyYXRvclNldElkUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8oKTtcbiAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgICAgIGNhc2UgMToge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kb21haW4gPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgMjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS52ZXJzaW9uID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYW4gT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54Lk9wZXJhdG9yU2V0SWRQcm90b30gT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgT3BlcmF0b3JTZXRJZFByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBWZXJpZmllcyBhbiBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICovXG4gICAgICAgIE9wZXJhdG9yU2V0SWRQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9tYWluXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb21haW4pKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkb21haW46IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJ2ZXJzaW9uXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudmVyc2lvbikgJiYgIShtZXNzYWdlLnZlcnNpb24gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudmVyc2lvbi5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnZlcnNpb24uaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ2ZXJzaW9uOiBpbnRlZ2VyfExvbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGFuIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguT3BlcmF0b3JTZXRJZFByb3RvfSBPcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICovXG4gICAgICAgIE9wZXJhdG9yU2V0SWRQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90bylcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8oKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QuZG9tYWluICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5kb21haW4gPSBTdHJpbmcob2JqZWN0LmRvbWFpbik7XG4gICAgICAgICAgICBpZiAob2JqZWN0LnZlcnNpb24gIT0gbnVsbClcbiAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgKG1lc3NhZ2UudmVyc2lvbiA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC52ZXJzaW9uKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LnZlcnNpb24gPT09IFwic3RyaW5nXCIpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudmVyc2lvbiA9IHBhcnNlSW50KG9iamVjdC52ZXJzaW9uLCAxMCk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC52ZXJzaW9uID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnZlcnNpb24gPSBvYmplY3QudmVyc2lvbjtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LnZlcnNpb24gPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudmVyc2lvbiA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QudmVyc2lvbi5sb3cgPj4+IDAsIG9iamVjdC52ZXJzaW9uLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCk7XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGFuIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguT3BlcmF0b3JTZXRJZFByb3RvfSBtZXNzYWdlIE9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIE9wZXJhdG9yU2V0SWRQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgIG9iamVjdC5kb21haW4gPSBcIlwiO1xuICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsb25nID0gbmV3ICR1dGlsLkxvbmcoMCwgMCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QudmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC52ZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gXCIwXCIgOiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvbWFpblwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9tYWluID0gbWVzc2FnZS5kb21haW47XG4gICAgICAgICAgICBpZiAobWVzc2FnZS52ZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInZlcnNpb25cIikpXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLnZlcnNpb24gPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC52ZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UudmVyc2lvbikgOiBtZXNzYWdlLnZlcnNpb247XG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QudmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS52ZXJzaW9uKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLnZlcnNpb24ubG93ID4+PiAwLCBtZXNzYWdlLnZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKSA6IG1lc3NhZ2UudmVyc2lvbjtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnZlcnRzIHRoaXMgT3BlcmF0b3JTZXRJZFByb3RvIHRvIEpTT04uXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBPcGVyYXRvclNldElkUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHR5cGUgdXJsIGZvciBPcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQGZ1bmN0aW9uIGdldFR5cGVVcmxcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgICAqL1xuICAgICAgICBPcGVyYXRvclNldElkUHJvdG8uZ2V0VHlwZVVybCA9IGZ1bmN0aW9uIGdldFR5cGVVcmwodHlwZVVybFByZWZpeCkge1xuICAgICAgICAgICAgaWYgKHR5cGVVcmxQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHR5cGVVcmxQcmVmaXggPSBcInR5cGUuZ29vZ2xlYXBpcy5jb21cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0eXBlVXJsUHJlZml4ICsgXCIvb25ueC5PcGVyYXRvclNldElkUHJvdG9cIjtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gT3BlcmF0b3JTZXRJZFByb3RvO1xuICAgIH0pKCk7XG5cbiAgICAvKipcbiAgICAgKiBPcGVyYXRvclN0YXR1cyBlbnVtLlxuICAgICAqIEBuYW1lIG9ubnguT3BlcmF0b3JTdGF0dXNcbiAgICAgKiBAZW51bSB7bnVtYmVyfVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBFWFBFUklNRU5UQUw9MCBFWFBFUklNRU5UQUwgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gU1RBQkxFPTEgU1RBQkxFIHZhbHVlXG4gICAgICovXG4gICAgb25ueC5PcGVyYXRvclN0YXR1cyA9IChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHZhbHVlc0J5SWQgPSB7fSwgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMF0gPSBcIkVYUEVSSU1FTlRBTFwiXSA9IDA7XG4gICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzFdID0gXCJTVEFCTEVcIl0gPSAxO1xuICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH0pKCk7XG5cbiAgICBvbm54LkZ1bmN0aW9uUHJvdG8gPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBGdW5jdGlvblByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAaW50ZXJmYWNlIElGdW5jdGlvblByb3RvXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBGdW5jdGlvblByb3RvIG5hbWVcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48c3RyaW5nPnxudWxsfSBbaW5wdXRdIEZ1bmN0aW9uUHJvdG8gaW5wdXRcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48c3RyaW5nPnxudWxsfSBbb3V0cHV0XSBGdW5jdGlvblByb3RvIG91dHB1dFxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxzdHJpbmc+fG51bGx9IFthdHRyaWJ1dGVdIEZ1bmN0aW9uUHJvdG8gYXR0cmlidXRlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSUF0dHJpYnV0ZVByb3RvPnxudWxsfSBbYXR0cmlidXRlUHJvdG9dIEZ1bmN0aW9uUHJvdG8gYXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JTm9kZVByb3RvPnxudWxsfSBbbm9kZV0gRnVuY3Rpb25Qcm90byBub2RlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIEZ1bmN0aW9uUHJvdG8gZG9jU3RyaW5nXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSU9wZXJhdG9yU2V0SWRQcm90bz58bnVsbH0gW29wc2V0SW1wb3J0XSBGdW5jdGlvblByb3RvIG9wc2V0SW1wb3J0XG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb21haW5dIEZ1bmN0aW9uUHJvdG8gZG9tYWluXG4gICAgICAgICAqL1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEZ1bmN0aW9uUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIEZ1bmN0aW9uUHJvdG8uXG4gICAgICAgICAqIEBpbXBsZW1lbnRzIElGdW5jdGlvblByb3RvXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKiBAcGFyYW0ge29ubnguSUZ1bmN0aW9uUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIEZ1bmN0aW9uUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgICAgICAgdGhpcy5pbnB1dCA9IFtdO1xuICAgICAgICAgICAgdGhpcy5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlID0gW107XG4gICAgICAgICAgICB0aGlzLmF0dHJpYnV0ZVByb3RvID0gW107XG4gICAgICAgICAgICB0aGlzLm5vZGUgPSBbXTtcbiAgICAgICAgICAgIHRoaXMub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogRnVuY3Rpb25Qcm90byBuYW1lLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IG5hbWVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLm5hbWUgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGdW5jdGlvblByb3RvIGlucHV0LlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48c3RyaW5nPn0gaW5wdXRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLmlucHV0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRnVuY3Rpb25Qcm90byBvdXRwdXQuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5LjxzdHJpbmc+fSBvdXRwdXRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLm91dHB1dCA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZ1bmN0aW9uUHJvdG8gYXR0cmlidXRlLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48c3RyaW5nPn0gYXR0cmlidXRlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5hdHRyaWJ1dGUgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGdW5jdGlvblByb3RvIGF0dHJpYnV0ZVByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JQXR0cmlidXRlUHJvdG8+fSBhdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgRnVuY3Rpb25Qcm90by5wcm90b3R5cGUuYXR0cmlidXRlUHJvdG8gPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGdW5jdGlvblByb3RvIG5vZGUuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklOb2RlUHJvdG8+fSBub2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5ub2RlID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRnVuY3Rpb25Qcm90byBkb2NTdHJpbmcuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9jU3RyaW5nXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGdW5jdGlvblByb3RvIG9wc2V0SW1wb3J0LlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvPn0gb3BzZXRJbXBvcnRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEZ1bmN0aW9uUHJvdG8ucHJvdG90eXBlLm9wc2V0SW1wb3J0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRnVuY3Rpb25Qcm90byBkb21haW4uXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9tYWluXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS5kb21haW4gPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IEZ1bmN0aW9uUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkZ1bmN0aW9uUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSUZ1bmN0aW9uUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICogQHJldHVybnMge29ubnguRnVuY3Rpb25Qcm90b30gRnVuY3Rpb25Qcm90byBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgRnVuY3Rpb25Qcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvblByb3RvKHByb3BlcnRpZXMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgRnVuY3Rpb25Qcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LkZ1bmN0aW9uUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JRnVuY3Rpb25Qcm90b30gbWVzc2FnZSBGdW5jdGlvblByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgRnVuY3Rpb25Qcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1lc3NhZ2UsIFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovMTApLnN0cmluZyhtZXNzYWdlLm5hbWUpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8zNCkuc3RyaW5nKG1lc3NhZ2UuaW5wdXRbaV0pO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki80Mikuc3RyaW5nKG1lc3NhZ2Uub3V0cHV0W2ldKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmF0dHJpYnV0ZSAhPSBudWxsICYmIG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDYsIHdpcmVUeXBlIDIgPSovNTApLnN0cmluZyhtZXNzYWdlLmF0dHJpYnV0ZVtpXSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5ub2RlICE9IG51bGwgJiYgbWVzc2FnZS5ub2RlLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uubm9kZS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5Ob2RlUHJvdG8uZW5jb2RlKG1lc3NhZ2Uubm9kZVtpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCA3LCB3aXJlVHlwZSAyID0qLzU4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwobWVzc2FnZSwgXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA4LCB3aXJlVHlwZSAyID0qLzY2KS5zdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgIT0gbnVsbCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmVuY29kZShtZXNzYWdlLm9wc2V0SW1wb3J0W2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDksIHdpcmVUeXBlIDIgPSovNzQpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtZXNzYWdlLCBcImRvbWFpblwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEwLCB3aXJlVHlwZSAyID0qLzgyKS5zdHJpbmcobWVzc2FnZS5kb21haW4pO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gIT0gbnVsbCAmJiBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZW5jb2RlKG1lc3NhZ2UuYXR0cmlidXRlUHJvdG9baV0sIHdyaXRlci51aW50MzIoLyogaWQgMTEsIHdpcmVUeXBlIDIgPSovOTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgRnVuY3Rpb25Qcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LkZ1bmN0aW9uUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JRnVuY3Rpb25Qcm90b30gbWVzc2FnZSBGdW5jdGlvblByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgRnVuY3Rpb25Qcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LkZ1bmN0aW9uUHJvdG99IEZ1bmN0aW9uUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLCBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguRnVuY3Rpb25Qcm90bygpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgNDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pbnB1dCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pbnB1dC5wdXNoKHJlYWRlci5zdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgNToge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5vdXRwdXQucHVzaChyZWFkZXIuc3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDY6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuYXR0cmlidXRlICYmIG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXR0cmlidXRlLnB1c2gocmVhZGVyLnN0cmluZygpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAxMToge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5hdHRyaWJ1dGVQcm90byAmJiBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGVQcm90byA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGVQcm90by5wdXNoKCRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgNzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uubm9kZSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5ub2RlLnB1c2goJHJvb3Qub25ueC5Ob2RlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgODoge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgOToge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5vcHNldEltcG9ydCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydC5wdXNoKCRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIDEwOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRvbWFpbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LkZ1bmN0aW9uUHJvdG99IEZ1bmN0aW9uUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBWZXJpZmllcyBhIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvYmplY3QgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UubmFtZSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm5hbWU6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiaW5wdXRcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnB1dCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImlucHV0OiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmlucHV0W2ldKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImlucHV0OiBzdHJpbmdbXSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm91dHB1dFwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm91dHB1dCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm91dHB1dDogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2Uub3V0cHV0W2ldKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm91dHB1dDogc3RyaW5nW10gZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmF0dHJpYnV0ZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJhdHRyaWJ1dGVcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5hdHRyaWJ1dGUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhdHRyaWJ1dGU6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmF0dHJpYnV0ZS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmF0dHJpYnV0ZVtpXSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhdHRyaWJ1dGU6IHN0cmluZ1tdIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGVQcm90byAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJhdHRyaWJ1dGVQcm90b1wiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmF0dHJpYnV0ZVByb3RvKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXR0cmlidXRlUHJvdG86IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmF0dHJpYnV0ZVByb3RvLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8udmVyaWZ5KG1lc3NhZ2UuYXR0cmlidXRlUHJvdG9baV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhdHRyaWJ1dGVQcm90by5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5vZGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibm9kZVwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm5vZGUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJub2RlOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5ub2RlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguTm9kZVByb3RvLnZlcmlmeShtZXNzYWdlLm5vZGVbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJub2RlLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm9wc2V0SW1wb3J0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm9wc2V0SW1wb3J0XCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uub3BzZXRJbXBvcnQpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJvcHNldEltcG9ydDogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8udmVyaWZ5KG1lc3NhZ2Uub3BzZXRJbXBvcnRbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJvcHNldEltcG9ydC5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb21haW5cIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvbWFpbikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRvbWFpbjogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5GdW5jdGlvblByb3RvfSBGdW5jdGlvblByb3RvXG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguRnVuY3Rpb25Qcm90bylcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5GdW5jdGlvblByb3RvKCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5pbnB1dCkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuaW5wdXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5GdW5jdGlvblByb3RvLmlucHV0OiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW5wdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXRbaV0gPSBTdHJpbmcob2JqZWN0LmlucHV0W2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3Qub3V0cHV0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5vdXRwdXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5GdW5jdGlvblByb3RvLm91dHB1dDogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5vdXRwdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0W2ldID0gU3RyaW5nKG9iamVjdC5vdXRwdXRbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5hdHRyaWJ1dGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmF0dHJpYnV0ZSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkZ1bmN0aW9uUHJvdG8uYXR0cmlidXRlOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmF0dHJpYnV0ZS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGVbaV0gPSBTdHJpbmcob2JqZWN0LmF0dHJpYnV0ZVtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5hdHRyaWJ1dGVQcm90bykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkZ1bmN0aW9uUHJvdG8uYXR0cmlidXRlUHJvdG86IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5hdHRyaWJ1dGVQcm90by5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5hdHRyaWJ1dGVQcm90b1tpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkZ1bmN0aW9uUHJvdG8uYXR0cmlidXRlUHJvdG86IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGVQcm90b1tpXSA9ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZnJvbU9iamVjdChvYmplY3QuYXR0cmlidXRlUHJvdG9baV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3Qubm9kZSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qubm9kZSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkZ1bmN0aW9uUHJvdG8ubm9kZTogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5ub2RlID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qubm9kZS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5ub2RlW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguRnVuY3Rpb25Qcm90by5ub2RlOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uubm9kZVtpXSA9ICRyb290Lm9ubnguTm9kZVByb3RvLmZyb21PYmplY3Qob2JqZWN0Lm5vZGVbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QuZG9jU3RyaW5nICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm9wc2V0SW1wb3J0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5vcHNldEltcG9ydCkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkZ1bmN0aW9uUHJvdG8ub3BzZXRJbXBvcnQ6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5vcHNldEltcG9ydC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5vcHNldEltcG9ydFtpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkZ1bmN0aW9uUHJvdG8ub3BzZXRJbXBvcnQ6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydFtpXSA9ICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmZyb21PYmplY3Qob2JqZWN0Lm9wc2V0SW1wb3J0W2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRvbWFpbiAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gU3RyaW5nKG9iamVjdC5kb21haW4pO1xuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIEZ1bmN0aW9uUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguRnVuY3Rpb25Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5GdW5jdGlvblByb3RvfSBtZXNzYWdlIEZ1bmN0aW9uUHJvdG9cbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3Qubm9kZSA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC5hdHRyaWJ1dGVQcm90byA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvbWFpbiA9IFwiXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm5hbWVcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5pbnB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmlucHV0W2pdID0gbWVzc2FnZS5pbnB1dFtqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAmJiBtZXNzYWdlLm91dHB1dC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3Qub3V0cHV0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Lm91dHB1dFtqXSA9IG1lc3NhZ2Uub3V0cHV0W2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlICYmIG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuYXR0cmlidXRlW2pdID0gbWVzc2FnZS5hdHRyaWJ1dGVbal07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3Qubm9kZSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5ub2RlLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3Qubm9kZVtqXSA9ICRyb290Lm9ubnguTm9kZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uubm9kZVtqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSBtZXNzYWdlLmRvY1N0cmluZztcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm9wc2V0SW1wb3J0ICYmIG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3Qub3BzZXRJbXBvcnRbal0gPSAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by50b09iamVjdChtZXNzYWdlLm9wc2V0SW1wb3J0W2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb21haW5cIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvbWFpbiA9IG1lc3NhZ2UuZG9tYWluO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8gJiYgbWVzc2FnZS5hdHRyaWJ1dGVQcm90by5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuYXR0cmlidXRlUHJvdG8gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuYXR0cmlidXRlUHJvdG8ubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5hdHRyaWJ1dGVQcm90b1tqXSA9ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8udG9PYmplY3QobWVzc2FnZS5hdHRyaWJ1dGVQcm90b1tqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIEZ1bmN0aW9uUHJvdG8gdG8gSlNPTi5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogR2V0cyB0aGUgZGVmYXVsdCB0eXBlIHVybCBmb3IgRnVuY3Rpb25Qcm90b1xuICAgICAgICAgKiBAZnVuY3Rpb24gZ2V0VHlwZVVybFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5GdW5jdGlvblByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlVXJsUHJlZml4XSB5b3VyIGN1c3RvbSB0eXBlVXJsUHJlZml4KGRlZmF1bHQgXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCIpXG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBkZWZhdWx0IHR5cGUgdXJsXG4gICAgICAgICAqL1xuICAgICAgICBGdW5jdGlvblByb3RvLmdldFR5cGVVcmwgPSBmdW5jdGlvbiBnZXRUeXBlVXJsKHR5cGVVcmxQcmVmaXgpIHtcbiAgICAgICAgICAgIGlmICh0eXBlVXJsUHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlVXJsUHJlZml4ID0gXCJ0eXBlLmdvb2dsZWFwaXMuY29tXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHlwZVVybFByZWZpeCArIFwiL29ubnguRnVuY3Rpb25Qcm90b1wiO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBGdW5jdGlvblByb3RvO1xuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gb25ueDtcbn0pKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gJHJvb3Q7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7ZmxhdGJ1ZmZlcnN9IGZyb20gJ2ZsYXRidWZmZXJzJztcbmltcG9ydCBMb25nIGZyb20gJ2xvbmcnO1xuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7b25ueHJ1bnRpbWV9IGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7b25ueH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4vdGVuc29yJztcblxuLy8gY2hlY2sgdGhlIGlucHV0cyBzaGFwZSBiZWZvcmUgcnVubmluZyBhbiBPUC5cbi8vIHJldHVybiB0cnVlIHdoZW4gdGhlIGlucHV0cyBwYXNzIHRoZSBjaGVja1xuLy8gcmV0dXJuIGZhbHNlIHdoZW4gdGhlIGlucHV0cyBkbyBub3QgZml0IHRoZSByZXF1aXJlbWVudFxuLy8gdGhyb3cgZXhjZXB0aW9uIHdoZW4gZmF0YWwgZXJyb3Igb3Igbm90IGltcGxlbWVudGVkXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tJbnB1dHNTaGFwZShpbnB1dHM6IFRlbnNvcltdLCAuLi5leHBlY3RlZERpbWVuc2lvbnM6IG51bWJlcltdKTogYm9vbGVhbiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IGV4cGVjdGVkRGltZW5zaW9ucy5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIWlucHV0c1tpXS5kaW1zIHx8IGlucHV0c1tpXS5kaW1zLmxlbmd0aCAhPT0gZXhwZWN0ZWREaW1lbnNpb25zW2ldKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vLyBFdmFsdWF0ZXMgdGhlIGdpdmVuIGV4cHJlc3Npb24gYW5kIGFzc2VydHMgZXJyb3IgbWVzc2FnZSBpZiBjb25kaXRpb24gaXMgdW5tZXQuXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0KGV4cHI6IGJvb2xlYW4sIG1zZzogKCkgPT4gc3RyaW5nKSB7XG4gIGlmICghZXhwcikge1xuICAgIHRocm93IG5ldyBFcnJvcih0eXBlb2YgbXNnID09PSAnc3RyaW5nJyA/IG1zZyA6IG1zZygpKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQXJyYXlVdGlsIHtcbiAgLyoqXG4gICAqIFZlcmlmaWVzIGlmIDIgaW5wdXQgYXJyYXlzIGNvbnRhaW4gdGhlIHNhbWUgZWxlbWVudHMuXG4gICAqIEBwYXJhbSBuMSBBcnJheSAxXG4gICAqIEBwYXJhbSBuMiBBcnJheSAyXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgdGhlc2UgMiBhcmUgZXF1YWxcbiAgICovXG4gIHN0YXRpYyBhcnJheXNFcXVhbChcbiAgICAgIG4xOiByZWFkb25seSBudW1iZXJbXXxJbnQ4QXJyYXl8VWludDhBcnJheXxJbnQxNkFycmF5fFVpbnQxNkFycmF5fEludDMyQXJyYXl8VWludDMyQXJyYXl8VWludDhDbGFtcGVkQXJyYXl8XG4gICAgICBGbG9hdDMyQXJyYXl8RmxvYXQ2NEFycmF5LFxuICAgICAgbjI6IHJlYWRvbmx5IG51bWJlcltdfEludDhBcnJheXxVaW50OEFycmF5fEludDE2QXJyYXl8VWludDE2QXJyYXl8SW50MzJBcnJheXxVaW50MzJBcnJheXxVaW50OENsYW1wZWRBcnJheXxcbiAgICAgIEZsb2F0MzJBcnJheXxGbG9hdDY0QXJyYXkpIHtcbiAgICBpZiAobjEubGVuZ3RoICE9PSBuMi5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuMS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG4xW2ldICE9PSBuMltpXSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNYXRNdWxVdGlsIHtcbiAgLyoqXG4gICAqIEZpeCB0aGUgaW5wdXQgc2hhcGVzIGZvciBNYXRNdWwgb3BlcmF0aW9uIGlmIHRoZXkgbmVlZCBmaXhpbmdcbiAgICogQHBhcmFtIGRpbXNBIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQS4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBkaW1zQiBUaGUgc2hhcGUgb2YgdGVuc29yIEIuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcmV0dXJucyBBIHR1cGxlIGNvbnRhaW5pbmcgdGhlIHByZXByb2Nlc3NlZCBpbnB1dCBzaGFwZXMgYXMgcmVxdWlyZWQgYnkgT05OWCBzcGVjaWZpY2F0aW9uc1xuICAgKi9cbiAgc3RhdGljIHByZXByb2Nlc3NJbnB1dFNoYXBlcyhkaW1zQTogcmVhZG9ubHkgbnVtYmVyW10sIGRpbXNCOiByZWFkb25seSBudW1iZXJbXSk6XG4gICAgICBbcmVhZG9ubHkgbnVtYmVyW10sIHJlYWRvbmx5IG51bWJlcltdXSB7XG4gICAgLy8gSWYgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIDEtRCwgaXQgaXMgcHJvbW90ZWQgdG8gYSBtYXRyaXggYnkgcHJlcGVuZGluZ1xuICAgIC8vIGEgMSB0byBpdHMgZGltZW5zaW9ucy4gQWZ0ZXIgbWF0cml4IG11bHRpcGxpY2F0aW9uIHRoZSBwcmVwZW5kZWQgMSBpc1xuICAgIC8vIHJlbW92ZWQuXG4gICAgY29uc3QgYSA9IChkaW1zQS5sZW5ndGggPT09IDEpID8gWzEsIGRpbXNBWzBdXSA6IGRpbXNBO1xuXG4gICAgLy8gSWYgdGhlIHNlY29uZCBhcmd1bWVudCBpcyAxLUQsIGl0IGlzIHByb21vdGVkIHRvIGEgbWF0cml4IGJ5IGFwcGVuZGluZ1xuICAgIC8vIGEgMSB0byBpdHMgZGltZW5zaW9ucy4gQWZ0ZXIgbWF0cml4IG11bHRpcGxpY2F0aW9uIHRoZSBhcHBlbmRlZCAxIGlzXG4gICAgLy8gcmVtb3ZlZC5cbiAgICBjb25zdCBiID0gKGRpbXNCLmxlbmd0aCA9PT0gMSkgPyBbZGltc0JbMF0sIDFdIDogZGltc0I7XG5cbiAgICByZXR1cm4gW2EsIGJdO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpeCB0aGUgb3V0cHV0IHNoYXBlIGNvbXB1dGVkIGZvciBNYXRNdWwgb3BlcmF0aW9uIGlmIGl0IG5lZWRzIGZpeGluZ1xuICAgKiBAcGFyYW0gb3V0cHV0U2hhcGUgVGhlIGNvbXB1dGVkIG91dHB1dFNoYXBlLiBTaG91bGQgYmUgYW4gYXJyYXkgKGF0bGVhc3Qgb2YgbGVuZ3RoIDIpIG9mIHBvc2l0aXZlIGludGVnZXJzLlxuICAgKiBUaGlzIHdpbGwgYmUgbXV0YXRlZC5cbiAgICogQHBhcmFtIGFSYW5rIFRoZSByYW5rIG9mIHRlbnNvciBBLlxuICAgKiBAcGFyYW0gYlJhbmsgVGhlIHJhbmsgb2YgdGVuc29yIEIuXG4gICAqL1xuICBzdGF0aWMgcG9zdHByb2Nlc3NPdXRwdXRTaGFwZShvdXRwdXRTaGFwZTogbnVtYmVyW10sIGFSYW5rOiBudW1iZXIsIGJSYW5rOiBudW1iZXIpIHtcbiAgICAvLyBSZW1vdmUgcHJlcGVuZGVkIGRpbWVuc2lvbiBpZiBmaXJzdCBpbnB1dCBpcyAxZFxuICAgIGlmIChhUmFuayA9PT0gMSkge1xuICAgICAgLy8gb3V0cHV0U2hhcGUgPSBvdXRwdXRTaGFwZS5zbGljZSgwLCBvdXRwdXRTaGFwZS5sZW5ndGggLSAyKS5jb25jYXQob3V0cHV0U2hhcGUuc2xpY2Uob3V0cHV0U2hhcGUubGVuZ3RoIC0gMSkpO1xuICAgICAgb3V0cHV0U2hhcGUuc3BsaWNlKG91dHB1dFNoYXBlLmxlbmd0aCAtIDIsIDEpO1xuICAgIH1cbiAgICAvLyBSZW1vdmUgYXBwZW5kZWQgZGltZW5zaW9uIGlmIHNlY29uZCBpbnB1dCBpcyAxZFxuICAgIGlmIChiUmFuayA9PT0gMSkge1xuICAgICAgb3V0cHV0U2hhcGUucG9wKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgc2hhcGUgd2hlbiBtYXRyaXggbXVsdGlwbGljYXRpb25cbiAgICogQHBhcmFtIGEgVGhlIHNoYXBlIG9mIHRlbnNvciBBLiBTaG91bGQgYmUgYSB0dXBsZSBvZiAyIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEBwYXJhbSBiIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQi4gU2hvdWxkIGJlIGEgdHVwbGUgb2YgMiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcmV0dXJucyBUaGUgZXhwZWN0ZWQgc2hhcGUgb2YgdGhlIHJlc3VsdCwgb3IgdW5kZWZpbmVkIGlmIE4vQVxuICAgKi9cbiAgc3RhdGljIGNhbGNNYXRNdWxTaGFwZShhOiBbbnVtYmVyLCBudW1iZXJdLCBiOiBbbnVtYmVyLCBudW1iZXJdKTogW251bWJlciwgbnVtYmVyXXx1bmRlZmluZWQge1xuICAgIHJldHVybiAoYVsxXSAhPT0gYlswXSkgPyB1bmRlZmluZWQgOiBbYVswXSwgYlsxXV07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEJyb2FkY2FzdFV0aWwge1xuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZSB3aGVuIGJyb2FkY2FzdGluZyAyIHRlbnNvcnNcbiAgICogQHBhcmFtIGEgVGhlIHNoYXBlIG9mIHRlbnNvciBBLiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHBhcmFtIGIgVGhlIHNoYXBlIG9mIHRlbnNvciBCLiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHBhcmFtIGlzTWF0TXVsIFdoZXRoZXIgdGhlIG9wZXJhdGlvbiBpcyBNYXRNdWxcbiAgICogQHJldHVybnMgVGhlIGV4cGVjdGVkIHNoYXBlIG9mIHRoZSByZXN1bHQsIG9yIHVuZGVmaW5lZCBpZiBOL0FcbiAgICovXG4gIHN0YXRpYyBjYWxjU2hhcGUoYWRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBiZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGlzTWF0TXVsID0gZmFsc2UpOiByZWFkb25seSBudW1iZXJbXXx1bmRlZmluZWQge1xuICAgIGNvbnN0IGFyYW5rID0gYWRpbXMubGVuZ3RoO1xuICAgIGNvbnN0IGJyYW5rID0gYmRpbXMubGVuZ3RoO1xuICAgIGlmIChhcmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIGJkaW1zO1xuICAgIH1cbiAgICBpZiAoYnJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBhZGltcztcbiAgICB9XG4gICAgY29uc3QgY3JhbmsgPSBNYXRoLm1heChhZGltcy5sZW5ndGgsIGJkaW1zLmxlbmd0aCk7XG4gICAgY29uc3QgY2RpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihjcmFuayk7XG5cbiAgICAvLyBjYWxjdWxhdGUgdGhlIGxhc3QgMiBkaW1lbnNpb24gaWYgaXQgaXMgTWF0TXVsXG4gICAgaWYgKGlzTWF0TXVsKSB7XG4gICAgICBpZiAoYXJhbmsgPCAyIHx8IGJyYW5rIDwgMikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY29uc3QgY1NoYXBlTWF0TXVsID1cbiAgICAgICAgICBNYXRNdWxVdGlsLmNhbGNNYXRNdWxTaGFwZShbYWRpbXNbYXJhbmsgLSAyXSwgYWRpbXNbYXJhbmsgLSAxXV0sIFtiZGltc1ticmFuayAtIDJdLCBiZGltc1ticmFuayAtIDFdXSk7XG4gICAgICBpZiAoY1NoYXBlTWF0TXVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIFtjZGltc1tjcmFuayAtIDJdLCBjZGltc1tjcmFuayAtIDFdXSA9IGNTaGFwZU1hdE11bDtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gaXNNYXRNdWwgPyAzIDogMTsgaSA8PSBjcmFuazsgaSsrKSB7XG4gICAgICBjb25zdCBhTGVuID0gYXJhbmsgLSBpIDwgMCA/IDEgOiBhZGltc1thcmFuayAtIGldO1xuICAgICAgY29uc3QgYkxlbiA9IGJyYW5rIC0gaSA8IDAgPyAxIDogYmRpbXNbYnJhbmsgLSBpXTtcblxuICAgICAgaWYgKGFMZW4gIT09IGJMZW4gJiYgYUxlbiA+IDEgJiYgYkxlbiA+IDEpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGNkaW1zW2NyYW5rIC0gaV0gPSBNYXRoLm1heChhTGVuLCBiTGVuKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2RpbXM7XG4gIH1cblxuICAvKipcbiAgICogR2l2ZW4gdGhlIGluZGljZXMgb2YgYSBicm9hZGNhc3RlZCB0ZW5zb3IsIGNhbGN1bGF0ZSB0aGUgb3JpZ2luYWwgaW5kaWNlc1xuICAgKiBAcGFyYW0gYnJvYWRjYXN0ZWRJbmRpY2VzIFRoZSBnaXZlbiBpbmRpY2VzIG9mIHRoZSBicm9hZGNhc3RlZCB0ZW5zb3IuXG4gICAqIEBwYXJhbSBvcmlnaW5hbFNoYXBlIFRoZSBvcmlnaW5hbCBzaGFwZSBvZiB0aGUgdGVuc29yIGJlZm9yZSBicm9hZGNhc1xuICAgKiBAcmV0dXJucyBUaGUgY2FsY3VsYXRlZCBpbmRpY2VzIHRoYXQgbWFwcyB0byB0aGUgb3JpZ2luYWwgdGVuc29yLlxuICAgKi9cbiAgc3RhdGljIGluZGV4KGJyb2FkY2FzdGVkSW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIG9yaWdpbmFsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyW10ge1xuICAgIC8vIE5PVEUgMTogd2UgYXNzdW1lIHRoZSBwYXJhbWV0ZXIgYnJvYWRjYXN0ZWRJbmRpY2VzIGlzIHZhbGlkLiBpZS4gaXQgc2hvdWxkIGhhdmUgdGhlIHNhbWVcbiAgICAvLyBsZW5ndGggYXMgdGhlIGJyb2FkY2FzdGVkIHNoYXBlLCBhbmQgZm9yIGVhY2ggZGltZW5zaW9uIHRoZSBpbmRleCBzaG91bGRcbiAgICAvLyBub3QgYmUgb3V0IG9mIHJhbmdlLlxuICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlcyA9IG5ldyBBcnJheShvcmlnaW5hbFNoYXBlLmxlbmd0aCk7XG4gICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgoYnJvYWRjYXN0ZWRJbmRpY2VzLCBvcmlnaW5hbFNoYXBlLCBvcmlnaW5hbEluZGljZXMpO1xuICAgIHJldHVybiBvcmlnaW5hbEluZGljZXM7XG4gIH1cblxuICAvKipcbiAgICogR2l2ZW4gdGhlIGluZGljZXMgb2YgYSBicm9hZGNhc3RlZCB0ZW5zb3IsIGNhbGN1bGF0ZSB0aGUgb3JpZ2luYWwgaW5kaWNlc1xuICAgKiBAcGFyYW0gYnJvYWRjYXN0ZWRJbmRpY2VzIFRoZSBnaXZlbiBpbmRpY2VzIG9mIHRoZSBicm9hZGNhc3RlZCB0ZW5zb3IuXG4gICAqIEBwYXJhbSBvcmlnaW5hbFNoYXBlIFRoZSBvcmlnaW5hbCBzaGFwZSBvZiB0aGUgdGVuc29yIGJlZm9yZSBicm9hZGNhc3RcbiAgICogQHBhcmFtIG9yaWdpbmFsSW5kaWNlcyBUaGUgbWFwcGluZyBvZiBicm9hZGNhc3RlZEluZGljZXMgdG8gdGhlIG9yaWdpbmFsSW5kaWNlcyAob3V0cHV0IHBhcmFtZXRlciAtIHdpbGwgYmVcbiAgICogICAgIG11dGF0ZWQpLlxuICAgKi9cbiAgc3RhdGljIGZpbGxJbmRleChicm9hZGNhc3RlZEluZGljZXM6IHJlYWRvbmx5IG51bWJlcltdLCBvcmlnaW5hbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgb3JpZ2luYWxJbmRpY2VzOiBudW1iZXJbXSkge1xuICAgIC8vIE5PVEUgMTogd2UgYXNzdW1lIHRoZSBwYXJhbWV0ZXIgYnJvYWRjYXN0ZWRJbmRpY2VzIGlzIHZhbGlkLiBpZS4gaXQgc2hvdWxkIGhhdmUgdGhlIHNhbWUgbGVuZ3RoIGFzIHRoZVxuICAgIC8vIGJyb2FkY2FzdGVkIHNoYXBlLCBhbmQgZm9yIGVhY2ggZGltZW5zaW9uIHRoZSBpbmRleCBzaG91bGQgbm90IGJlIG91dCBvZiByYW5nZS5cbiAgICAvLyBOT1RFIDI6IHdlIGFzc3VtZSB0aGUgcGFyYW1ldGVyIG9yaWdpbmFsSW5kaWNlcyBoYXMgdGhlIHNhbWUgbGVuZ3RoIGFzIHRoZSBvcmlnaW5hbFNoYXBlXG4gICAgY29uc3QgZGltT2Zmc2V0ID0gYnJvYWRjYXN0ZWRJbmRpY2VzLmxlbmd0aCAtIG9yaWdpbmFsU2hhcGUubGVuZ3RoO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JpZ2luYWxTaGFwZS5sZW5ndGg7IGkrKykge1xuICAgICAgb3JpZ2luYWxJbmRpY2VzW2ldID0gYnJvYWRjYXN0ZWRJbmRpY2VzW2RpbU9mZnNldCArIGldICUgb3JpZ2luYWxTaGFwZVtpXTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSB0aGUgYnJvYWRjYXN0aW5nIG9wZXJhdGlvbiBvbiB0aGUgc3BlY2lmaWMgb3BlcmF0b3JcbiAgICogQHBhcmFtIGEgVGhlIGlucHV0IHRlbnNvciBBXG4gICAqIEBwYXJhbSBiIFRoZSBpbnB1dCB0ZW5zb3IgQlxuICAgKiBAcGFyYW0gb3AgVGhlIG9wZXJhdG9yIGxhbWJkYSBmdW5jdGlvblxuICAgKiBAcGFyYW0gaW5wbGFjZSBXaGV0aGVyIHRvIHdyaXRlIHRoZSByZXN1bHQgYmFjayB0byBBLlxuICAgKiBAcmV0dXJucyBUaGUgcmVzdWx0IHRlbnNvciwgb3IgdW5kZWZpbmVkIGlmIGlucHV0IG5vdCBicm9hZGNhc3RhYmxlLlxuICAgKi9cbiAgc3RhdGljIGNhbGMoXG4gICAgICBhOiBUZW5zb3IsIGI6IFRlbnNvciwgb3A6IChhOiBzdHJpbmd8bnVtYmVyLCBiOiBzdHJpbmd8bnVtYmVyKSA9PiAoc3RyaW5nIHwgbnVtYmVyKSwgaW5wbGFjZTogYm9vbGVhbixcbiAgICAgIHJlc3VsdFR5cGU/OiBUZW5zb3IuRGF0YVR5cGUpOiBUZW5zb3J8dW5kZWZpbmVkIHtcbiAgICBjb25zdCBvdXRwdXRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGEuZGltcywgYi5kaW1zKTtcblxuICAgIGlmIChvdXRwdXRTaGFwZSkge1xuICAgICAgaWYgKGlucGxhY2UgJiYgIVNoYXBlVXRpbC5hcmVFcXVhbChvdXRwdXRTaGFwZSwgYS5kaW1zKSkge1xuICAgICAgICAvLyBCIGlzIG5vdCBicm9hZGNhc3RhYmxlIHRvIEEsIGZhaWxlZCB0byBjYWxjdWxhdGUgaW5wbGFjZS5cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dHB1dFNoYXBlKTtcbiAgICAgIGNvbnN0IGMgPSBpbnBsYWNlID8gYSA6IG5ldyBUZW5zb3Iob3V0cHV0U2hhcGUsIHJlc3VsdFR5cGUgfHwgYS50eXBlKTtcblxuICAgICAgLy8gYm90aCBpbnB1dHMgYXJlIHNjYWxhcnNcbiAgICAgIGlmIChvdXRwdXRTaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgYy5zZXQoW10sIG9wKGEuZ2V0KFtdKSBhcyBudW1iZXIsIGIuZ2V0KFtdKSBhcyBudW1iZXIpKTtcbiAgICAgIH1cblxuICAgICAgLy8gYXRsZWFzdCBvbmUgaW5wdXQgaXMgYSBub24tc2NhbGFyXG4gICAgICBlbHNlIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kaWNlcyA9IG5ldyBBcnJheTxudW1iZXI+KG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlc0EgPSBuZXcgQXJyYXkoYS5kaW1zLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlc0IgPSBuZXcgQXJyYXkoYi5kaW1zLmxlbmd0aCk7XG4gICAgICAgIGxldCB2YWxBOiBzdHJpbmd8bnVtYmVyID0gMDtcbiAgICAgICAgbGV0IHZhbEI6IHN0cmluZ3xudW1iZXIgPSAwO1xuICAgICAgICBsZXQgaXNBU2NhbGFyID0gZmFsc2U7XG4gICAgICAgIGxldCBpc0JTY2FsYXIgPSBmYWxzZTtcbiAgICAgICAgaWYgKGEuZGltcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB2YWxBID0gYS5nZXQoW10pIGFzIG51bWJlcjtcbiAgICAgICAgICBpc0FTY2FsYXIgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChiLmRpbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdmFsQiA9IGIuZ2V0KFtdKSBhcyBudW1iZXI7XG4gICAgICAgICAgaXNCU2NhbGFyID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzdDogbnVtYmVyO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemU7IGkrKykge1xuICAgICAgICAgIC8vIHRyYXZlcnNhbCBpbmRpY2VzXG4gICAgICAgICAgcmVzdCA9IGk7XG4gICAgICAgICAgZm9yIChsZXQgaiA9IG91dHB1dFNoYXBlLmxlbmd0aCAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgICAgICAgICBvdXRwdXRJbmRpY2VzW2pdID0gcmVzdCAlIG91dHB1dFNoYXBlW2pdO1xuICAgICAgICAgICAgcmVzdCA9IE1hdGguZmxvb3IocmVzdCAvIG91dHB1dFNoYXBlW2pdKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWlzQVNjYWxhcikge1xuICAgICAgICAgICAgLy8gbWFwIG91dHB1dEluZGljZXMgKHdoaWNoIGlzIGFjdHVhbGx5IGJyb2FkY2FzdGVkKSB0byB0aGUgb3JpZ2luYWxJbmRpY2VzXG4gICAgICAgICAgICBCcm9hZGNhc3RVdGlsLmZpbGxJbmRleChvdXRwdXRJbmRpY2VzLCBhLmRpbXMsIG9yaWdpbmFsSW5kaWNlc0EpO1xuICAgICAgICAgICAgdmFsQSA9IGEuZ2V0KG9yaWdpbmFsSW5kaWNlc0EpIGFzIG51bWJlcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFpc0JTY2FsYXIpIHtcbiAgICAgICAgICAgIEJyb2FkY2FzdFV0aWwuZmlsbEluZGV4KG91dHB1dEluZGljZXMsIGIuZGltcywgb3JpZ2luYWxJbmRpY2VzQik7XG4gICAgICAgICAgICB2YWxCID0gYi5nZXQob3JpZ2luYWxJbmRpY2VzQikgYXMgbnVtYmVyO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGMuc2V0KG91dHB1dEluZGljZXMsIG9wKHZhbEEsIHZhbEIpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gYztcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSBpZiBhIHNoYXBlIGlzIHVuaWRpcmVjdGlvbmFsIGJyb2FkY2FzdGFibGUgdG8gYW5vdGhlciBzaGFwZVxuICAgKiBAcGFyYW0gc2hhcGUgVGhlIGlucHV0IHNoYXBlXG4gICAqIEBwYXJhbSBmaW5hbFNoYXBlIFRoZSBkZXNpcmVkIHNoYXBlIGFmdGVyIGJyb2FkY2FzdGluZ1xuICAgKi9cbiAgc3RhdGljIGlzVmFsaWRCcm9hZGNhc3Qoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBmaW5hbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICAgIC8vIGFsaWduIHNoYXBlIHRvIHRoZSByaWdodFxuICAgIGNvbnN0IGlucHV0UmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBmaW5hbFJhbmsgPSBmaW5hbFNoYXBlLmxlbmd0aDtcbiAgICBpZiAoaW5wdXRSYW5rID4gZmluYWxSYW5rKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAxOyBpIDw9IGlucHV0UmFuazsgaSsrKSB7XG4gICAgICBpZiAoc2hhcGVbaW5wdXRSYW5rIC0gaV0gIT09IDEgJiYgc2hhcGVbaW5wdXRSYW5rIC0gaV0gIT09IGZpbmFsU2hhcGVbZmluYWxSYW5rIC0gaV0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgdGhlIGJyb2FkY2FzdGVkIGRpbXMgaW4gaW5wdXQgc2hhcGUgYmFzZWQgb24gdGhlIGdpdmVuIG91dHB1dCBzaGFwZS5cbiAgICogTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gb25seSByZXR1cm5zIHRoZSBicm9hZGNhc3RlZCBkaW1zLlxuICAgKiBAcGFyYW0gaW5wdXRTaGFwZSBUaGUgaW5wdXQgc2hhcGVcbiAgICogQHBhcmFtIG91dHB1dFNoYXBlIFRoZSBvdXRwdXQgc2hhcGVcbiAgICogQHJldHVybnMgVGhlIGJyb2FkY2FzdGVkIGRpbXMgaW4gaW5wdXQgc2hhcGUuXG4gICAqL1xuICBzdGF0aWMgZ2V0QnJvYWRjYXN0RGltcyhpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IGluUmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IGRpbXM6IG51bWJlcltdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpblJhbms7IGkrKykge1xuICAgICAgY29uc3QgZGltID0gaW5SYW5rIC0gMSAtIGk7XG4gICAgICBjb25zdCBhID0gaW5wdXRTaGFwZVtkaW1dIHx8IDE7XG4gICAgICBjb25zdCBiID0gb3V0cHV0U2hhcGVbb3V0cHV0U2hhcGUubGVuZ3RoIC0gMSAtIGldIHx8IDE7XG4gICAgICBpZiAoYiA+IDEgJiYgYSA9PT0gMSkge1xuICAgICAgICBkaW1zLnVuc2hpZnQoZGltKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRpbXM7XG4gIH1cbn1cblxuLy8gY29weSBhcnJheSBoZWxwZXJcbi8vIG1pbWljcyBtZW1jcHkgYXMgbXVjaCBhcyBwb3NzaWJsZVxuZXhwb3J0IGZ1bmN0aW9uIGFycmF5Q29weUhlbHBlcihcbiAgICB0YXJnZXQ6IG51bWJlcltdfFRlbnNvci5OdW1iZXJUeXBlLCBzb3VyY2U6IG51bWJlcltdfFRlbnNvci5OdW1iZXJUeXBlLCB0YXJnZXRJbmRleDogbnVtYmVyLCBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgIGJsb2NrU2l6ZTogbnVtYmVyKSB7XG4gIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gc291cmNlLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc291cmNlSW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICB9XG4gIGlmICh0YXJnZXRJbmRleCA8IDAgfHwgdGFyZ2V0SW5kZXggPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0SW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICB9XG4gIGlmIChzb3VyY2VJbmRleCArIGJsb2NrU2l6ZSA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBpbmRpY2VzIHRvIGJlIGNvcGllZCBhcmUgb3V0c2lkZSBib3VuZHMnKTtcbiAgfVxuICBpZiAodGFyZ2V0SW5kZXggKyBibG9ja1NpemUgPiB0YXJnZXQubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXQgYXJyYXkgaXMgdG9vIHNtYWxsIHRvIGhvbGQgcmVzdWx0Jyk7XG4gIH1cblxuICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBibG9ja1NpemU7IG9mZnNldCsrKSB7XG4gICAgdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XSA9IHNvdXJjZVtzb3VyY2VJbmRleCArIG9mZnNldF07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEdlbW1VdGlsIHtcbiAgLy8gd2lsbCBtYWtlIHN1cmUgaW5wdXQgc2hhcGVzIGFyZSBjb21wYXRpYmxlIGZvciB0aGlzIG9wXG4gIC8vIGFuZCByZXR1cm4gYmFjayB0aGUgc2hhcGUgb2YgdGhlIG91dHB1dCBpbiB0aGUgZm9ybSBvZiBhIHR1cGxlXG4gIC8vIHdpbGwgdGhyb3cgZXhjZXB0aW9uIGlmIHRoZSBpbnB1dCBzaGFwZXMgYXJlIG5vdCBjb21wYXRpYmxlXG4gIHN0YXRpYyBnZXRTaGFwZU9mR2VtbVJlc3VsdChcbiAgICAgIGxlZnRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHRyYW5zTGVmdDogYm9vbGVhbiwgcmlnaHRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHRyYW5zUmlnaHQ6IGJvb2xlYW4sXG4gICAgICBiaWFzU2hhcGU/OiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAobGVmdFNoYXBlLmxlbmd0aCAhPT0gMiB8fCByaWdodFNoYXBlLmxlbmd0aCAhPT0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzaGFwZSBuZWVkIHRvIGJlIG9mIHNpemUgMicpO1xuICAgIH1cblxuICAgIGxldCBNOiBudW1iZXI7XG4gICAgbGV0IEs6IG51bWJlcjtcbiAgICBsZXQgTjogbnVtYmVyO1xuXG4gICAgaWYgKHRyYW5zTGVmdCkge1xuICAgICAgTSA9IGxlZnRTaGFwZVsxXTtcbiAgICAgIEsgPSBsZWZ0U2hhcGVbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIE0gPSBsZWZ0U2hhcGVbMF07XG4gICAgICBLID0gbGVmdFNoYXBlWzFdO1xuICAgIH1cblxuICAgIGxldCBrRGltID0gLTE7XG5cbiAgICBpZiAodHJhbnNSaWdodCkge1xuICAgICAgTiA9IHJpZ2h0U2hhcGVbMF07XG4gICAgICBrRGltID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgTiA9IHJpZ2h0U2hhcGVbMV07XG4gICAgICBrRGltID0gMDtcbiAgICB9XG5cbiAgICBpZiAocmlnaHRTaGFwZVtrRGltXSAhPT0gSykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdkaW1lbnNpb24gbWlzbWF0Y2gnKTtcbiAgICB9XG5cbiAgICBpZiAoTSA8PSAwIHx8IE4gPD0gMCB8fCBLIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzaGFwZSBzcGVjaWZpZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoYmlhc1NoYXBlICYmICFCcm9hZGNhc3RVdGlsLmlzVmFsaWRCcm9hZGNhc3QoYmlhc1NoYXBlLCBbTSwgTl0pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dlbW06IGludmFsaWQgYmlhcyBzaGFwZSBmb3IgYnJvYWRjYXN0Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtNLCBOLCBLXTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUHJvdG9VdGlsIHtcbiAgc3RhdGljIHRlbnNvckRhdGFUeXBlRnJvbVByb3RvKHR5cGVQcm90bzogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZXxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUpOiBUZW5zb3IuRGF0YVR5cGUge1xuICAgIHN3aXRjaCAodHlwZVByb3RvKSB7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UODpcbiAgICAgICAgcmV0dXJuICdpbnQ4JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODpcbiAgICAgICAgcmV0dXJuICd1aW50OCc7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuQk9PTDpcbiAgICAgICAgcmV0dXJuICdib29sJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjpcbiAgICAgICAgcmV0dXJuICdpbnQxNic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2OlxuICAgICAgICByZXR1cm4gJ3VpbnQxNic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI6XG4gICAgICAgIHJldHVybiAnaW50MzInO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjpcbiAgICAgICAgcmV0dXJuICd1aW50MzInO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkZMT0FUOlxuICAgICAgICByZXR1cm4gJ2Zsb2F0MzInO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkRPVUJMRTpcbiAgICAgICAgcmV0dXJuICdmbG9hdDY0JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5TVFJJTkc6XG4gICAgICAgIHJldHVybiAnc3RyaW5nJztcblxuICAgICAgLy8gRm9yIElOVDY0L1VJTlQ2NCwgcmVkdWNlIHRoZWlyIHZhbHVlIHRvIDMyLWJpdHMuXG4gICAgICAvLyBTaG91bGQgdGhyb3cgZXhjZXB0aW9uIHdoZW4gb3ZlcmZsb3dcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NDpcbiAgICAgICAgcmV0dXJuICdpbnQzMic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0OlxuICAgICAgICByZXR1cm4gJ3VpbnQzMic7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgZGF0YSB0eXBlOiAke29ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVbdHlwZVByb3RvXX1gKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdGVuc29yRGF0YVR5cGVTdHJpbmdUb0VudW0odHlwZTogc3RyaW5nKTogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZSB7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UODtcbiAgICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg7XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuQk9PTDtcbiAgICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMTY7XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMTY7XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDMyO1xuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyO1xuICAgICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkZMT0FUO1xuICAgICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkRPVUJMRTtcbiAgICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlNUUklORztcbiAgICAgIGNhc2UgJ2ludDY0JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ7XG4gICAgICBjYXNlICd1aW50NjQnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgZGF0YSB0eXBlOiAke3R5cGV9YCk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHRlbnNvckRpbXNGcm9tUHJvdG8oZGltczogQXJyYXk8bnVtYmVyfExvbmc+KTogbnVtYmVyW10ge1xuICAgIC8vIGdldCByaWQgb2YgTG9uZyB0eXBlIGZvciBkaW1zXG4gICAgcmV0dXJuIGRpbXMubWFwKGQgPT4gTG9uZy5pc0xvbmcoZCkgPyBkLnRvTnVtYmVyKCkgOiBkKTtcbiAgfVxuXG4gIHN0YXRpYyB0ZW5zb3JWYWx1ZVR5cGVGcm9tUHJvdG8odmFsdWVUeXBlOiBvbm54LlR5cGVQcm90by5JVGVuc29yKTogR3JhcGguVmFsdWVUeXBlIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGVuc29yVHlwZTogUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKHZhbHVlVHlwZS5lbGVtVHlwZSEpLFxuICAgICAgc2hhcGU6IHtkaW1zOiBQcm90b1V0aWwudGVuc29yRGltc0Zyb21Qcm90byh2YWx1ZVR5cGUuc2hhcGUhLmRpbSEubWFwKGQgPT4gZC5kaW1WYWx1ZSEpKX1cbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIHRlbnNvckRpbXNGcm9tT1JURm9ybWF0KHRlbnNvcjogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3IpIHtcbiAgICBjb25zdCBkaW1zID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZW5zb3IuZGltc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGRpbXMucHVzaChMb25nVXRpbC5sb25nVG9OdW1iZXIodGVuc29yLmRpbXMoaSkhKSk7XG4gICAgfVxuICAgIHJldHVybiBkaW1zO1xuICB9XG5cbiAgc3RhdGljIHRlbnNvckF0dHJpYnV0ZXNGcm9tT1JURm9ybWF0KG5vZGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZSkge1xuICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGUuYXR0cmlidXRlc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGF0dHJpYnV0ZXMucHVzaChub2RlLmF0dHJpYnV0ZXMoaSkhKTtcbiAgICB9XG4gICAgcmV0dXJuIGF0dHJpYnV0ZXM7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIExvbmdVdGlsIHtcbiAgLy8gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgdG8gZ2V0IGEgbnVtYmVyIGZyb20gbG9uZyB0eXBlIG9mIGRhdGEgZm9yIGF0dHJpYnV0ZSwgZGltLCBhbmQgaXIgdmVyc2lvbixcbiAgLy8gd2hpY2ggdmFsdWVzIGFyZSBzaWduZWQgaW50ZWdlcnMuXG4gIC8vIFRvIG1ha2UgaXQgbW9yZSBnZW5lcmljLCBhZGQgYW4gb3B0aW9uYWwgcGFyYW10ZXIgdG8gY29udmVydCB0byBhIHVuc2lnbmVkIG51bWJlci5cbiAgc3RhdGljIGxvbmdUb051bWJlcihuOiBMb25nfGZsYXRidWZmZXJzLkxvbmd8bnVtYmVyLCB1bnNpZ25lZD86IGJvb2xlYW4pIHtcbiAgICBpZiAoTG9uZy5pc0xvbmcobikpIHtcbiAgICAgIHJldHVybiBuLnRvTnVtYmVyKCk7XG4gICAgfSBlbHNlIGlmIChuIGluc3RhbmNlb2YgZmxhdGJ1ZmZlcnMuTG9uZykge1xuICAgICAgcmV0dXJuIExvbmcuZnJvbVZhbHVlKHtsb3c6IG4ubG93LCBoaWdoOiBuLmhpZ2gsIHVuc2lnbmVkOiB1bnNpZ25lZCA/PyBmYWxzZX0pLnRvTnVtYmVyKCk7XG4gICAgfVxuICAgIHJldHVybiBuO1xuICB9XG4gIHN0YXRpYyBpc0xvbmcobjogdW5rbm93bikge1xuICAgIHJldHVybiBMb25nLmlzTG9uZyhuKSB8fCBuIGluc3RhbmNlb2YgZmxhdGJ1ZmZlcnMuTG9uZztcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU2hhcGVVdGlsIHtcbiAgc3RhdGljIHNpemUoZGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXIge1xuICAgIHJldHVybiBTaGFwZVV0aWwuZ2V0U2l6ZUZyb21EaW1lbnNpb25SYW5nZShkaW1zLCAwLCBkaW1zLmxlbmd0aCk7XG4gIH1cblxuICAvLyBgYXhpc2AgaW5jbHVzaXZlXG4gIHN0YXRpYyBzaXplRnJvbURpbWVuc2lvbihkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhpczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoYXhpcyA8IDAgfHwgYXhpcyA+IGRpbXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgZGltZW5zaW9uIG9mICR7YXhpc30gZm9yIHNpemVGcm9tRGltZW5zaW9uIGFzIFRlbnNvciBoYXMgJHtkaW1zLmxlbmd0aH0gZGltZW5zaW9ucy5gKTtcbiAgICB9XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5nZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXMsIGF4aXMsIGRpbXMubGVuZ3RoKTtcbiAgfVxuXG4gIC8vIGBheGlzYCBleGNsdXNpdmVcbiAgc3RhdGljIHNpemVUb0RpbWVuc2lvbihkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhpczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoYXhpcyA8IDAgfHwgYXhpcyA+IGRpbXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgZGltZW5zaW9uIG9mICR7YXhpc30gZm9yIHNpemVUb0RpbWVuc2lvbiBhcyBUZW5zb3IgaGFzICR7ZGltcy5sZW5ndGh9IGRpbWVuc2lvbnMuYCk7XG4gICAgfVxuICAgIHJldHVybiBTaGFwZVV0aWwuZ2V0U2l6ZUZyb21EaW1lbnNpb25SYW5nZShkaW1zLCAwLCBheGlzKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgbGV0IHNpemUgPSAxO1xuICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICAvLyBzYWZldHkgY2hlY2sgYXMgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IG11bHRpcGxlIG90aGVyIG1ldGhvZHMgcmVxdWlyaW5nIHNpemUuXG4gICAgICAvLyBzaXplIGNhbm5vdCBiZSAwIG9yIG5lZ2F0aXZlLlxuICAgICAgaWYgKGRpbXNbaV0gPD0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICAgICAgJ2Nhbm5vdCBnZXQgdmFsaWQgc2l6ZSBmcm9tIHNwZWNpZmllZCBkaW1lbnNpb24gcmFuZ2UuIE1vc3QgbGlrZWx5IHRoZSByYW5nZSBjb250YWlucyAwIG9yIG5lZ2F0aXZlIHZhbHVlcyBpbiB0aGVtLicpO1xuICAgICAgfVxuICAgICAgc2l6ZSAqPSBkaW1zW2ldO1xuICAgIH1cbiAgICByZXR1cm4gc2l6ZTtcbiAgfVxuXG4gIHN0YXRpYyBjb21wdXRlU3RyaWRlcyhkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCByYW5rID0gZGltcy5sZW5ndGg7XG4gICAgaWYgKHJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9IGVsc2UgaWYgKHJhbmsgPT09IDEpIHtcbiAgICAgIHJldHVybiBbMV07XG4gICAgfVxuICAgIGNvbnN0IHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMV0gPSAxO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gZGltc1tyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogZGltc1tpICsgMV07XG4gICAgfVxuICAgIHJldHVybiBzdHJpZGVzO1xuICB9XG5cbiAgc3RhdGljIHRyYW5zcG9zZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCBjb3B5ID0gZGltcy5zbGljZSgpO1xuICAgIHJldHVybiBjb3B5LnJldmVyc2UoKTtcbiAgfVxuXG4gIHN0YXRpYyBpbmRpY2VzVG9PZmZzZXQoaW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzPzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoYXhpcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBheGlzID0gaW5kaWNlcy5sZW5ndGg7XG4gICAgfVxuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhpczsgKytpKSB7XG4gICAgICBvZmZzZXQgKz0gc3RyaWRlc1tpXSAqIGluZGljZXNbaV07XG4gICAgfVxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgb2Zmc2V0VG9JbmRpY2VzKG9mZnNldDogbnVtYmVyLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCByYW5rID0gc3RyaWRlcy5sZW5ndGg7XG4gICAgaWYgKHJhbmsgPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9IGVsc2UgaWYgKHJhbmsgPT09IDEpIHtcbiAgICAgIHJldHVybiBbb2Zmc2V0ICogc3RyaWRlc1swXV07XG4gICAgfVxuICAgIGNvbnN0IGluZGljZXM6IG51bWJlcltdID0gbmV3IEFycmF5KHN0cmlkZXMubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluZGljZXMubGVuZ3RoIC0gMTsgKytpKSB7XG4gICAgICBpbmRpY2VzW2ldID0gTWF0aC5mbG9vcihvZmZzZXQgLyBzdHJpZGVzW2ldKTtcbiAgICAgIG9mZnNldCAtPSBpbmRpY2VzW2ldICogc3RyaWRlc1tpXTtcbiAgICB9XG4gICAgaW5kaWNlc1tpbmRpY2VzLmxlbmd0aCAtIDFdID0gb2Zmc2V0O1xuICAgIHJldHVybiBpbmRpY2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIG5vcm1haWx6ZSBheGlzIG9mIHJhbmdlIFstciwgcikgaW50byBbMCwgcikuXG4gICAqL1xuICBzdGF0aWMgbm9ybWFsaXplQXhpcyhheGlzOiBudW1iZXIsIHRlbnNvclJhbms6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGF4aXMgPCAtdGVuc29yUmFuayAmJiBheGlzID49IHRlbnNvclJhbmspIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5zdXBwb3J0ZWQgYXhpcyBmb3IgdGhpcyBvcGVyYXRpb24uJyk7XG4gICAgfVxuICAgIHJldHVybiBheGlzIDwgMCA/IGF4aXMgKyB0ZW5zb3JSYW5rIDogYXhpcztcbiAgfVxuXG4gIHN0YXRpYyBub3JtYWxpemVBeGVzKGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdLCB0ZW5zb3JSYW5rOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIGF4ZXMubWFwKHggPT4gdGhpcy5ub3JtYWxpemVBeGlzKHgsIHRlbnNvclJhbmspKTtcbiAgfVxuXG4gIC8vIEluY3JlbWVudCBhbiBpbmRleCBpbnRvIGEgdGVuc29yIChpbiBsZXhpY29ncmFwaGljXG4gIC8vIG9yZGVyaW5nKSwgd3JhcHBpbmcgYXJvdW5kIHRoZSBzcGVjaWZpZWQgdXBwZXJfYm91bmQuXG4gIC8qKlxuICAgKiBJbmNyZW1lbnQgYW4gaW5kZXggaW50byBhIHRlbnNvciAoaW4gbGV4aWNvZ3JhcGhpYyBvcmRlcmluZyksIHdyYXBwaW5nIGFyb3VuZCB0aGUgc3BlY2lmaWVkIHVwcGVyX2JvdW5kLlxuICAgKiBAcGFyYW0gaW5kZXggR2l2ZW4gaW5kZXggdG8gaW5jcmVtZW50IChXaWxsIGJlIG11dGF0ZWQpXG4gICAqIEBwYXJhbSBkaW1zIFRoZSBkaW1lbnNpb25zIG9mIHRoZSB0ZW5zb3IgZm9yIHdoaWNoIHRoZSBnaXZlbiBpbmRleCBjb3JyZXNwb25kcyB0b1xuICAgKiBAcGFyYW0gYXhpc1RvSW5jcmVtZW50T24gVGhlIDEtaW5kZXhlZCBheGlzIHRvIGluY3JlbWVudCBvbi4gSWYgdW5kZWZpbmVkLCBheGlzVG9JbmNyZW1lbnRPbiA9PSByYW5rXG4gICAqL1xuICBzdGF0aWMgaW5jcmVtZW50SW5kZXgoaW5kZXg6IG51bWJlcltdLCBkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhpc1RvSW5jcmVtZW50T24/OiBudW1iZXIpIHtcbiAgICBpZiAoZGltcy5sZW5ndGggPT09IDAgfHwgaW5kZXgubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luZGV4IGluY3JlbWVudGluZyB1bnN1cHBvcnRlZCBmb3Igc2NhbGFyIFRlbnNvcicpO1xuICAgIH1cbiAgICBpZiAoYXhpc1RvSW5jcmVtZW50T24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgYXhpc1RvSW5jcmVtZW50T24gPSBkaW1zLmxlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGF4aXNUb0luY3JlbWVudE9uIDw9IDAgfHwgYXhpc1RvSW5jcmVtZW50T24gPiBkaW1zLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luY29ycmVjdCBheGlzIHRvIGluY3JlbWVudCBvbicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAobGV0IGsgPSBheGlzVG9JbmNyZW1lbnRPbiAtIDE7IGsgPj0gMDsgLS1rKSB7XG4gICAgICBpbmRleFtrXSsrO1xuICAgICAgaWYgKGluZGV4W2tdIDwgZGltc1trXSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGluZGV4W2tdID0gMDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJvZHVjZXMgYSBuZXcgZGltZW5zaW9ucyBhcnJheSBiYXNlZCBvbiB0aGUgdmFsdWVzIGluIHRoZSAnb3JpZ2luYWxEaW1lbnNpb25zJyBhbmQgJ3NoYXBlJyBhcnJheVxuICAgKiBVc2VkIGluIFJlc2hhcGVcbiAgICogQHBhcmFtIG9yaWdpbmFsRGltcyBPcmlnaW5hbCBTaGFwZSBhcnJheVxuICAgKiBAcGFyYW0gc2hhcGVIaW50cyBhcnJheSBjb250YWluaW5nIHZhbHVlcyB0byBjb21wdXRlIHRoZSBuZXcgZGltZW5zaW9uc1xuICAgKiBGb3IgZXhhbXBsZTpcbiAgICogb3JpZ2luYWxEaW1zID0gWzIsMl0gYW5kIHNoYXBlSGludHMgPSBbMCwtMV0gd2lsbCByZXR1cm4gWzIsMl1cbiAgICogb3JpZ2luYWxEaW1zID0gWzIsMl0gYW5kIHNoYXBlSGludHMgPSBbNF0gd2lsbCByZXR1cm4gWzRdXG4gICAqIG9yaWdpbmFsRGltcyA9IFsyLDJdIGFuZCBzaGFwZUhpbnRzID0gWzVdIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uXG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvT3BlcmF0b3JzLm1kI1Jlc2hhcGVcbiAgICovXG5cbiAgc3RhdGljIGNhbGN1bGF0ZVJlc2hhcGVkRGltcyhvcmlnaW5hbERpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBzaGFwZUhpbnRzOiBBcnJheUxpa2U8bnVtYmVyPik6IG51bWJlcltdIHtcbiAgICAvLyByZXNoYXBlIHRvIGEgU2NhbGFyIFRlbnNvclxuICAgIGlmIChzaGFwZUhpbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKG9yaWdpbmFsRGltcy5sZW5ndGggPT09IDAgfHwgU2hhcGVVdGlsLnNpemUob3JpZ2luYWxEaW1zKSA9PT0gMSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCByZXNoYXBlIHRvIGEgc2NhbGFyIFRlbnNvcicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG5EaW1zID0gc2hhcGVIaW50cy5sZW5ndGg7XG4gICAgY29uc3QgcmVzaGFwZWREaW1zID0gbmV3IEFycmF5PG51bWJlcj4obkRpbXMpO1xuICAgIGxldCB1bmtub3duRGltZW5zaW9uID0gLTE7XG4gICAgbGV0IG5ld1RlbnNvclNpemUgPSAxO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbkRpbXM7IGkrKykge1xuICAgICAgaWYgKHNoYXBlSGludHNbaV0gPCAtMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2EgZGltZW5zaW9uIGluIHNoYXBlIGhpbnRzIGNhbm5vdCBiZSBsZXNzIHRoYW4gLTEnKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaGFwZUhpbnRzW2ldID09PSAtMSkge1xuICAgICAgICBpZiAodW5rbm93bkRpbWVuc2lvbiAhPT0gLTEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2F0IG1vc3Qgb25lIGRpbWVuc2lvbiBpbiBzaGFwZSBoaW50cyBjYW4gYmUgLTEnKTtcbiAgICAgICAgfVxuICAgICAgICB1bmtub3duRGltZW5zaW9uID0gaTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzaGFwZUhpbnRzW2ldID09PSAwKSB7XG4gICAgICAgICAgaWYgKGkgPj0gb3JpZ2luYWxEaW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgZGltZW5zaW9uIHdpdGggdmFsdWUgemVybyBleGNlZWRzIHRoZSBkaW1lbnNpb24gc2l6ZSBvZiB0aGUgaW5wdXQgdGVuc29yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc2hhcGVkRGltc1tpXSA9IG9yaWdpbmFsRGltc1tpXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNoYXBlZERpbXNbaV0gPSBzaGFwZUhpbnRzW2ldO1xuICAgICAgICB9XG4gICAgICAgIG5ld1RlbnNvclNpemUgKj0gcmVzaGFwZWREaW1zW2ldO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG9sZFRlbnNvclNpemUgPSBTaGFwZVV0aWwuc2l6ZShvcmlnaW5hbERpbXMpO1xuICAgIGlmICh1bmtub3duRGltZW5zaW9uICE9PSAtMSkge1xuICAgICAgaWYgKG9sZFRlbnNvclNpemUgJSBuZXdUZW5zb3JTaXplICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdGhlIGlucHV0IHRlbnNvciBjYW5ub3QgYmUgcmVzaGFwZWQgdG8gdGhlIHJlcXVlc3RlZCBzaGFwZS4gSW5wdXQgc2hhcGU6IFske1xuICAgICAgICAgICAgb3JpZ2luYWxEaW1zfV0gT3V0cHV0IHNoYXBlOiBbJHtzaGFwZUhpbnRzfV1gKTtcbiAgICAgIH1cbiAgICAgIHJlc2hhcGVkRGltc1t1bmtub3duRGltZW5zaW9uXSA9IG9sZFRlbnNvclNpemUgLyBuZXdUZW5zb3JTaXplO1xuICAgIH1cbiAgICAvLyB2YWxpZGF0ZSBzaXplcyBmcm9tIG9yaWdpbmFsRGltcyBhbmQgcmVzaGFwZWREaW1zIG1hdGNoXG4gICAgZWxzZSB7XG4gICAgICBpZiAobmV3VGVuc29yU2l6ZSAhPT0gb2xkVGVuc29yU2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Jlc2hhcGVkRGltcyBhbmQgb3JpZ2luYWxEaW1zIGRvblxcJ3QgaGF2ZSBtYXRjaGluZyBzaXplcycpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzaGFwZWREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIFNvcnRzIGEgZ2l2ZW4gYXJyYXkgYmFzZWQgb24gdGhlIGluZGljZXMgaW4gdGhlIFBlcm0gYXJyYXlcbiAgICogVXNlZCBpbiBUcmFuc3Bvc2VcbiAgICogQHBhcmFtIGEgQXJyYXkgdG8gYmUgc29ydGVkIHN1Y2ggYXMgZGltcyBvciBzdHJpZGVzXG4gICAqIEBwYXJhbSBwZXJtIFBlcm0gZ2l2ZW47IGlmIG51bGwgYSB3aWxsIGJlIHJldmVyc2VkXG4gICAqL1xuICBzdGF0aWMgc29ydEJhc2VkT25QZXJtKGE6IHJlYWRvbmx5IG51bWJlcltdLCBwZXJtPzogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgaWYgKHBlcm0pIHtcbiAgICAgIHJldHVybiBwZXJtLm1hcCgodikgPT4gYVt2XSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBhLnNsaWNlKCkucmV2ZXJzZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQYWRzIGEgZ2l2ZW4gc2hhcGUgYWNjb3JkaW5nIHRvIHRoZSBwYWRkaW5nIHZhbHVlc1xuICAgKiBAcGFyYW0gZGltcyBzaGFwZSBvZiB0aGUgVGVuc29yIHRvIGJlIHBhZGRlZFxuICAgKiBAcGFyYW0gcGFkIHBhZCB2YWx1ZXNcbiAgICovXG4gIHN0YXRpYyBwYWRTaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgcGFkOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCByYW5rID0gZGltcy5sZW5ndGg7XG4gICAgcmV0dXJuIGRpbXMubWFwKCh2LCBpKSA9PiB2ICsgcGFkW2ldICsgcGFkW2kgKyByYW5rXSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBpZiB0aGUgdHdvIHNoYXBlcyBhcmUgaWRlbnRpY2FsXG4gICAqIEBwYXJhbSBzaGFwZTFcbiAgICogQHBhcmFtIHNoYXBlMlxuICAgKi9cbiAgc3RhdGljIGFyZUVxdWFsKHNoYXBlMTogcmVhZG9ubHkgbnVtYmVyW10sIHNoYXBlMjogcmVhZG9ubHkgbnVtYmVyW10pOiBib29sZWFuIHtcbiAgICBpZiAoc2hhcGUxLmxlbmd0aCAhPT0gc2hhcGUyLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gc2hhcGUxLmV2ZXJ5KCh2LCBpKSA9PiB2ID09PSBzaGFwZTJbaV0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBpZiB0aGUgZ2l2ZW4gYGRpbXNgIG9yIGBzaGFwZWAgaXMgdmFsaWQgaW4gT05OWC5qcyBjb250ZXh0IGFuZCByZXR1cm5zIGRhdGEgc2l6ZVxuICAgKiBAcGFyYW0gZGltcyAtIGlucHV0IGBkaW1zYCB0aGF0IG5lZWRzIHRvIGJlIGNoZWNrZWRcbiAgICovXG4gIHN0YXRpYyB2YWxpZGF0ZURpbXNBbmRDYWxjU2l6ZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgaWYgKGRpbXMubGVuZ3RoID4gNikge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignT25seSByYW5rIDAgdG8gNiBpcyBzdXBwb3J0ZWQgZm9yIHRlbnNvciBzaGFwZS4nKTtcbiAgICB9XG4gICAgbGV0IHNpemUgPSAxO1xuICAgIGZvciAoY29uc3QgbiBvZiBkaW1zKSB7XG4gICAgICBpZiAoIU51bWJlci5pc0ludGVnZXIobikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCBzaGFwZTogJHtufSBpcyBub3QgYW4gaW50ZWdlcmApO1xuICAgICAgfVxuICAgICAgaWYgKG4gPCAwIHx8IG4gPiAyMTQ3NDgzNjQ3KSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgc2hhcGU6IGxlbmd0aCAke259IGlzIG5vdCBhbGxvd2VkYCk7XG4gICAgICB9XG4gICAgICBzaXplICo9IG47XG4gICAgfVxuICAgIHJldHVybiBzaXplO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgdGhlIHNoYXBlIG9mIG91dHB1dCB0ZW5zb3IgeSA9IGZsYXR0ZW4oeCwgYXhpcylcbiAgICogQHBhcmFtIGRpbXMgLSBzaGFwZSBvZiBpbnB1dCB0ZW5zb3JcbiAgICogQHBhcmFtIGF4aXMgLSBmbGF0dGVuIGF4aXMsIGluIHRoZSByYW5nZSBbLXIsIHJdXG4gICAqL1xuICBzdGF0aWMgZmxhdHRlblNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzOiBudW1iZXIpOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgaWYgKGF4aXMgPCAwKSB7XG4gICAgICBheGlzICs9IGRpbXMubGVuZ3RoO1xuICAgIH1cbiAgICBjb25zdCB0b3RhbCA9IGRpbXMucmVkdWNlKCh4LCB5KSA9PiB4ICogeSwgMSk7XG4gICAgY29uc3QgcmlnaHQgPSBkaW1zLnNsaWNlKGF4aXMpLnJlZHVjZSgoeCwgeSkgPT4geCAqIHksIDEpO1xuICAgIGNvbnN0IG91dHB1dERpbXMgPSBbdG90YWwgLyByaWdodCwgcmlnaHRdO1xuXG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyB0aGUgc2hhcGUgb2Ygb3V0cHV0IHRlbnNvciB5ID0gc3F1ZWV6ZSh4LCBheGVzKVxuICAgKiBAcGFyYW0gZGltcyAtIHNoYXBlIG9mIGlucHV0IHRlbnNvclxuICAgKiBAcGFyYW0gYXhlcyAtIHNxdWVlemUgYXhlc1xuICAgKi9cbiAgc3RhdGljIHNxdWVlemVTaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhlczogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cbiAgICAvLyBzYW5pdHkgY2hlY2tcbiAgICBheGVzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4ZXMoYXhlcywgZGltcy5sZW5ndGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpblNxdWVlemVMaXN0ID0gYXhlcy5pbmRleE9mKGkpID49IDA7XG4gICAgICBpZiAoaW5TcXVlZXplTGlzdCAmJiBkaW1zW2ldICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignc3F1ZWV6ZSBhbiBheGlzIG9mIHNpemUgZGlmZmVyZW50IHRoYW4gMScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoKGF4ZXMubGVuZ3RoID09PSAwICYmIGRpbXNbaV0gPiAxKSB8fCAoYXhlcy5sZW5ndGggPiAwICYmICFpblNxdWVlemVMaXN0KSkge1xuICAgICAgICBvdXRwdXREaW1zLnB1c2goZGltc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyB0aGUgc2hhcGUgb2Ygb3V0cHV0IHRlbnNvciB5ID0gdW5zcXVlZXplKHgsIGF4ZXMpXG4gICAqIEBwYXJhbSBkaW1zIC0gc2hhcGUgb2YgaW5wdXQgdGVuc29yXG4gICAqIEBwYXJhbSBheGVzIC0gdW5zcXVlZXplIGF4ZXNcbiAgICovXG4gIHN0YXRpYyB1bnNxdWVlemVTaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhlczogcmVhZG9ubHkgbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSB7XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IG5ldyBBcnJheTxudW1iZXI+KGRpbXMubGVuZ3RoICsgYXhlcy5sZW5ndGgpO1xuXG4gICAgLy8gaW5pdGlhbGl6ZSB0aGUgYXJyYXkgZWxlbWVudHMgdG8gMFxuICAgIG91dHB1dERpbXMuZmlsbCgwKTtcblxuICAgIC8vIHNldCBhbGwgYXhlcyBpbmRpY2VzIHRvIDEgaW4gb3V0cHV0RGltcyBhbmQgY2hlY2sgZm9yIGR1cGxpY2F0ZXNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF4ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhheGVzW2ldLCBvdXRwdXREaW1zLmxlbmd0aCk7XG4gICAgICBpZiAoYXhpcyA+PSBvdXRwdXREaW1zLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1xcJ2F4ZXNcXCcgaGFzIGFuIG91dCBvZiByYW5nZSBheGlzJyk7XG4gICAgICB9XG4gICAgICBpZiAob3V0cHV0RGltc1theGlzXSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1xcJ2F4ZXNcXCcgaGFzIGEgZHVwbGljYXRlIGF4aXMnKTtcbiAgICAgIH1cblxuICAgICAgb3V0cHV0RGltc1theGlzXSA9IDE7XG4gICAgfVxuXG4gICAgLy8gZmlsbCBpbiB0aGUgemVybyBlbnRyaWVzIG9mIG91dHB1dERpbXMgd2l0aCB0aGUgaW5wdXQgdGVuc29yJ3Mgc2hhcGVcbiAgICBsZXQgaW5wdXREaW1zSXRlcmF0b3IgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0RGltcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG91dHB1dERpbXNbaV0gPT09IDApIHtcbiAgICAgICAgb3V0cHV0RGltc1tpXSA9IGRpbXNbaW5wdXREaW1zSXRlcmF0b3IrK107XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2FuaXR5IGNoZWNrIGFzc2VydGlvbi4gJ2lucHV0RGltc0l0ZXJhdG9yJ1xuICAgIC8vIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mICdkaW1zJ1xuICAgIGlmIChpbnB1dERpbXNJdGVyYXRvciAhPT0gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIHVuc3F1ZWV6ZWQgZGltZW5zaW9uIGNvdWxkIG5vdCBiZSBlc3RhYmxpc2hlZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG59XG5cbi8vIGJ1bmNoIG9mIGhlbHBlciBtZXRob2RzIHRoYXQgZG8gYSB2YXJpZXR5IG9mIG1hdGggb3BlcmF0aW9uc1xuZXhwb3J0IGNsYXNzIE1hdGhVdGlsIHtcbiAgLy8geSA9ICh4KngpICsgeVxuICBzdGF0aWMgc3FyKFxuICAgICAgdGFyZ2V0OiBudW1iZXJbXXxUZW5zb3IuTnVtYmVyVHlwZSwgc291cmNlOiBudW1iZXJbXXxUZW5zb3IuTnVtYmVyVHlwZSwgdGFyZ2V0SW5kZXg6IG51bWJlciwgc291cmNlSW5kZXg6IG51bWJlcixcbiAgICAgIGJsb2NrU2l6ZTogbnVtYmVyKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gKz0gTWF0aC5wb3coc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XSwgMik7XG4gICAgfVxuICB9XG5cbiAgLy8geSA9IGF4ICsgeVxuICBzdGF0aWMgYXhweShcbiAgICAgIHRhcmdldDogbnVtYmVyW118VGVuc29yLk51bWJlclR5cGUsIHNvdXJjZTogbnVtYmVyW118VGVuc29yLk51bWJlclR5cGUsIHRhcmdldEluZGV4OiBudW1iZXIsIHNvdXJjZUluZGV4OiBudW1iZXIsXG4gICAgICBibG9ja1NpemU6IG51bWJlciwgYWxwaGE6IG51bWJlcikge1xuICAgIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCA8IDAgfHwgdGFyZ2V0SW5kZXggPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmIChzb3VyY2VJbmRleCArIGJsb2NrU2l6ZSA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggKyBibG9ja1NpemUgPiB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBibG9ja1NpemU7IG9mZnNldCsrKSB7XG4gICAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdICs9IChhbHBoYSAqIHNvdXJjZVtzb3VyY2VJbmRleCArIG9mZnNldF0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIHkgPSBwb3coeCwgYilcbiAgc3RhdGljIHBvd3goXG4gICAgICB0YXJnZXQ6IG51bWJlcltdfFRlbnNvci5OdW1iZXJUeXBlLCBzb3VyY2U6IG51bWJlcltdfFRlbnNvci5OdW1iZXJUeXBlLCB0YXJnZXRJbmRleDogbnVtYmVyLCBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgICAgYmxvY2tTaXplOiBudW1iZXIsIGI6IG51bWJlcikge1xuICAgIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCA8IDAgfHwgdGFyZ2V0SW5kZXggPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmIChzb3VyY2VJbmRleCArIGJsb2NrU2l6ZSA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggKyBibG9ja1NpemUgPiB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBibG9ja1NpemU7IG9mZnNldCsrKSB7XG4gICAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdID0gTWF0aC5wb3coc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XSwgYik7XG4gICAgfVxuICB9XG5cbiAgLy8geSA9IHggKiB5XG4gIHN0YXRpYyBtdWwoXG4gICAgICB0YXJnZXQ6IG51bWJlcltdfFRlbnNvci5OdW1iZXJUeXBlLCBzb3VyY2U6IG51bWJlcltdfFRlbnNvci5OdW1iZXJUeXBlLCB0YXJnZXRJbmRleDogbnVtYmVyLCBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgICAgYmxvY2tTaXplOiBudW1iZXIpIHtcbiAgICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlSW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0SW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBpbmRpY2VzIHRvIGJlIGNvcGllZCBhcmUgb3V0c2lkZSBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXQgYXJyYXkgaXMgdG9vIHNtYWxsIHRvIGhvbGQgcmVzdWx0Jyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgICAgdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XSA9IChzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdICogdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XSk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTcGxpdFV0aWwge1xuICAvKipcbiAgICogQ2FsY3VsYXRlcyBuZXcgU2hhcGVzIGZyb20gZXhpc3Rpbmcgb25lIGFuZCB0aGUgc3BsaXRzIGdpdmVuIGFsb25nIHRoZSBheGlzIHByb3ZpZGVzXG4gICAqIEBwYXJhbSBkaW1zIFNoYXBlIG9mIHRoZSBUZW5zb3IgdG8gYmUgc3BsaXR0ZWQgaW50byB0d28gb3IgbW9yZSBTaGFwZXNcbiAgICogQHBhcmFtIGF4aXMgVGhlIGRpbWVuc2lvbiBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgc3BsaXRcbiAgICogQHBhcmFtIHNwbGl0cyBPZmZzZXRzIGZvciB0aGUgc3RhcnQgb2YgZWFjaCBzcGxpdFxuICAgKi9cbiAgc3RhdGljIHNwbGl0U2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlciwgc3BsaXQ6IG51bWJlcltdLCBudW1PdXRwdXRzPzogbnVtYmVyKTpcbiAgICAgIFtudW1iZXJbXVtdLCBudW1iZXJbXV0ge1xuICAgIGlmIChzcGxpdC5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmICghbnVtT3V0cHV0cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25lZWQgdG8ga25vdyBudW1iZXIgb2Ygb3V0cHV0cyB3aGVuIHRoZSBcXCdzcGxpdFxcJyBhdHRyaWJ1dGUgaXMgbm90IHNwZWNpZmllZCcpO1xuICAgICAgfVxuICAgICAgU3BsaXRVdGlsLmRldGVybWluZVNwbGl0KGRpbXNbYXhpc10sIG51bU91dHB1dHMsIHNwbGl0KTtcbiAgICB9XG5cbiAgICBjb25zdCBzaGFwZXM6IG51bWJlcltdW10gPSBbXTtcbiAgICBjb25zdCBvZmZzZXRzID0gWzBdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3BsaXQubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmIChpICE9PSAwKSB7XG4gICAgICAgIG9mZnNldHMucHVzaChvZmZzZXRzW2kgLSAxXSArIHNwbGl0W2kgLSAxXSk7XG4gICAgICB9XG4gICAgICBjb25zdCBzaGFwZSA9IGRpbXMuc2xpY2UoKTtcbiAgICAgIHNoYXBlW2F4aXNdID0gc3BsaXRbaV07XG4gICAgICBzaGFwZXMucHVzaChzaGFwZSk7XG4gICAgfVxuICAgIHJldHVybiBbc2hhcGVzLCBvZmZzZXRzXTtcbiAgfVxuXG4gIHN0YXRpYyBkZXRlcm1pbmVTcGxpdChudW1FbGVtZW50c0Fsb25nQXhpczogbnVtYmVyLCBudW1PdXRwdXRzOiBudW1iZXIsIHNwbGl0OiBudW1iZXJbXSkge1xuICAgIC8vIElmICdzcGxpdCcgaXMgbm90IHNwZWNpZmllZCBieSB0aGUgdXNlciwgd2UgbmVlZCB0byBwYXJ0aXRpb24gdGhlIG51bWJlciBvZiBlbGVtZW50cyBlcXVhbGx5IGFtb25nIHRoZSBvdXRwdXRzXG4gICAgaWYgKG51bUVsZW1lbnRzQWxvbmdBeGlzICUgbnVtT3V0cHV0cyAhPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3Qgc3BsaXQgdGVuc29yIHRvIGVxdWFsIHNpemVkIHBhcnRzJyk7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtT3V0cHV0czsgKytpKSB7XG4gICAgICBzcGxpdC5wdXNoKG51bUVsZW1lbnRzQWxvbmdBeGlzIC8gbnVtT3V0cHV0cyk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBSZWR1Y2VVdGlsIHtcbiAgLyoqXG4gICAqIFBlcmZvcm0gcmVkdWNlIG9wZXJhdGlvbnMgb24gdGhlIHNwZWNpZmljIG9wZXJhdG9yXG4gICAqIEBwYXJhbSBhIElucHV0IHRlbnNvciBkYXRhXG4gICAqIEBwYXJhbSBheGVzIFRoZSBkaW1lbnNpb25zIGFsb25nIHdoaWNoIHRoZSBUZW5zb3Igd2lsbCBiZSByZWR1Y2VkXG4gICAqIEBwYXJhbSBrZWVwZGltcyBJZiBzZXQgdG8gdHJ1ZSwgdGhlIGF4ZXMgd2hpY2ggYXJlIHJlZHVjZWQgYXJlIGxlZnQgaW4gdGhlXG4gICAqICAgIHJlc3VsdCBhcyBkaW1lbnNpb25zIHdpdGggc2l6ZSBvbmUuXG4gICAqIEBwYXJhbSBvcDEgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgb24gZWFjaCBlbGVtZW50IGluIHRoZSB0ZW5zb3JcbiAgICogQHBhcmFtIG9wMiBUaGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZCBiZXR3ZWVuIGVsZW1lbnRzIGluIHRoZSB0ZW5zb3JcbiAgICovXG4gIHN0YXRpYyBjYWxjUmVkdWNlKFxuICAgICAgYTogVGVuc29yLCBheGVzOiBudW1iZXJbXSwga2VlcGRpbXM6IGJvb2xlYW4sIG9wMTogKGI6IG51bWJlcikgPT4gbnVtYmVyLFxuICAgICAgb3AyOiAoYTogbnVtYmVyLCBiOiBudW1iZXIpID0+IG51bWJlcik6IFRlbnNvciB7XG4gICAgY29uc3QgZGltcyA9IGEuZGltcy5zbGljZSgwKTtcbiAgICAvLyBpZiBheGVzIGlzIG5vdCBzZXQsIHBlcmZvcm0gcmVkdWNlIG9uIGFsbCBheGVzXG4gICAgaWYgKGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBkaW1zLmZvckVhY2goKF9kLCBpbmQpID0+IGF4ZXMucHVzaChpbmQpKTtcbiAgICB9XG4gICAgLy8gZ2V0IGEgdGVtcG9yYXJ5IGJyb2FkY2FzdGFibGUgb3V0cHV0IHNoYXBlXG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IFJlZHVjZVV0aWwuY2FsY1JlZHVjZVNoYXBlKGRpbXMsIGF4ZXMsIHRydWUpO1xuXG4gICAgLy8gbG9vcCB0aHJvdWdoIHRoZSBvdXRwdXQgYW5kIGNhbGN1bGF0ZSByZXN1bHQgb25lIGJ5IG9uZVxuICAgIGNvbnN0IHNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRwdXREaW1zKTtcbiAgICBjb25zdCB5ID0gbmV3IFRlbnNvcihvdXRwdXREaW1zLCBhLnR5cGUpO1xuICAgIGNvbnN0IHN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMob3V0cHV0RGltcyk7XG4gICAgY29uc3QgaW5wdXRTdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGRpbXMpO1xuICAgIGNvbnN0IGluZGljZXNZID0gbmV3IEFycmF5KGRpbXMubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemU7IGkrKykge1xuICAgICAgY29uc3QgaW5kaWNlcyA9IFNoYXBlVXRpbC5vZmZzZXRUb0luZGljZXMoaSwgc3RyaWRlcyk7XG4gICAgICAvLyBtYXAgaW5kZXhcbiAgICAgIEJyb2FkY2FzdFV0aWwuZmlsbEluZGV4KGluZGljZXMsIGRpbXMsIGluZGljZXNZKTtcbiAgICAgIHkuc2V0KFxuICAgICAgICAgIGluZGljZXMsXG4gICAgICAgICAgUmVkdWNlVXRpbC5jYWxjUmVkdWNlQnlBeGlzKFxuICAgICAgICAgICAgICBhLm51bWJlckRhdGEsIGF4ZXMsIGRpbXMsIDAsIFNoYXBlVXRpbC5pbmRpY2VzVG9PZmZzZXQoaW5kaWNlc1ksIGlucHV0U3RyaWRlcyksIG9wMSwgb3AyKSk7XG4gICAgfVxuXG4gICAgaWYgKGtlZXBkaW1zKSB7XG4gICAgICByZXR1cm4geTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8ga2VlcGRpbXMgPT0gMCwgY2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZVxuICAgICAgcmV0dXJuIG5ldyBUZW5zb3IoXG4gICAgICAgICAgUmVkdWNlVXRpbC5jYWxjUmVkdWNlU2hhcGUoZGltcywgYXhlcywga2VlcGRpbXMpLCB5LnR5cGUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB5LmRhdGEsIHkuZGF0YUlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSByZWR1Y2Ugb3BlcmF0aW9ucyBvbiB0aGUgc3BlY2lmaWMgb3BlcmF0b3Igb24gc3BlY2lmaWMgYXhlc1xuICAgKiBAcGFyYW0gYSBJbnB1dCB0ZW5zb3IgZGF0YVxuICAgKiBAcGFyYW0gYXhlcyBUaGUgZGltZW5zaW9ucyBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgcmVkdWNlZFxuICAgKiBAcGFyYW0gZGltcyBUaGUgaW5wdXQgZGltZW5zaW9uLlxuICAgKiBAcGFyYW0gY3VyQXhpc0luZCBJbmRleCBpbiBheGVzIHNwZWNpZnlpbmcgdGhlIGN1cnJlbnQgZGltZW5zaW9uIGFsb25nXG4gICAqICAgICAgd2hpY2ggdGhlIHRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIHBvcyBUaGUgY3VycmVudCBpbmRleCBvZiBlbGVtZW50IHRvIHBlcmZvcm0gb3BlcmF0aW9uXG4gICAqIEBwYXJhbSBvcDEgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgb24gZWFjaCBlbGVtZW50IGluIHRoZSB0ZW5zb3JcbiAgICogQHBhcmFtIG9wMiBUaGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZCBiZXR3ZWVuIGVsZW1lbnRzIGluIHRoZSB0ZW5zb3JcbiAgICovXG4gIHN0YXRpYyBjYWxjUmVkdWNlQnlBeGlzKFxuICAgICAgaW5wdXQ6IFRlbnNvci5OdW1iZXJUeXBlLCBheGVzOiBudW1iZXJbXSwgZGltczogbnVtYmVyW10sIGN1ckF4aXNJbmQ6IG51bWJlciwgcG9zOiBudW1iZXIsXG4gICAgICBvcDE6IChiOiBudW1iZXIpID0+IG51bWJlciwgb3AyOiAoYTogbnVtYmVyLCBiOiBudW1iZXIpID0+IG51bWJlcik6IG51bWJlciB7XG4gICAgbGV0IHJlcyA9IDA7XG4gICAgaWYgKGN1ckF4aXNJbmQgPj0gYXhlcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBvcDEoaW5wdXRbcG9zXSk7XG4gICAgfVxuICAgIGNvbnN0IGF4aXMgPSBheGVzW2N1ckF4aXNJbmRdO1xuICAgIGNvbnN0IHN0ZXAgPSBheGlzID49IGRpbXMubGVuZ3RoID8gMSA6IFNoYXBlVXRpbC5zaXplKGRpbXMuc2xpY2UoYXhpcyArIDEpKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbXNbYXhpc107IGkrKykge1xuICAgICAgcmVzID0gaSA9PT0gMCA/IFJlZHVjZVV0aWwuY2FsY1JlZHVjZUJ5QXhpcyhpbnB1dCwgYXhlcywgZGltcywgY3VyQXhpc0luZCArIDEsIHBvcywgb3AxLCBvcDIpIDpcbiAgICAgICAgICAgICAgICAgICAgICBvcDIocmVzLCBSZWR1Y2VVdGlsLmNhbGNSZWR1Y2VCeUF4aXMoaW5wdXQsIGF4ZXMsIGRpbXMsIGN1ckF4aXNJbmQgKyAxLCBwb3MsIG9wMSwgb3AyKSk7XG4gICAgICBwb3MgKz0gc3RlcDtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlIG9mIGEgcmVkdWNlIG9wZXJhdGlvblxuICAgKiBAcGFyYW0gZGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvblxuICAgKiBAcGFyYW0gYXhlcyBUaGUgZGltZW5zaW9ucyBhbG9uZyB3aGljaCB0aGUgVGVuc29yIHdpbGwgYmUgcmVkdWNlZFxuICAgKiBAcGFyYW0ga2VlcGRpbXMgSWYgc2V0IHRvIHRydWUsIHRoZSBheGVzIHdoaWNoIGFyZSByZWR1Y2VkIGFyZSBsZWZ0IGluIHRoZVxuICAgKiAgICByZXN1bHQgYXMgZGltZW5zaW9ucyB3aXRoIHNpemUgb25lLlxuICAgKi9cbiAgc3RhdGljIGNhbGNSZWR1Y2VTaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhlczogcmVhZG9ubHkgbnVtYmVyW10sIGtlZXBEaW1zOiBib29sZWFuKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IG91dHB1dERpbXMgPSBkaW1zLnNsaWNlKCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBheGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoa2VlcERpbXMpIHtcbiAgICAgICAgb3V0cHV0RGltc1theGVzW2ldXSA9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXREaW1zW2F4ZXNbaV1dID0gMDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dERpbXMuZmlsdGVyKGRpbSA9PiBkaW0gIT09IDApO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQb29sQ29udlV0aWwge1xuICAvKipcbiAgICogQWRqdXN0IHRoZSBrZXJuZWwsIHN0cmlkZXMsIHBhZHMgdG8gY29ycmVjdCByYW5rLiBTZXQgdG8gZGVmYXVsdCB2YWx1ZSBpZiBub3QgcHJlc2VudFxuICAgKiBAcGFyYW0gaXNHbG9iYWxPcGVyYXRvciBJZiB0cnVlLCBwZXJmb3JtIGdsb2JhbCBwb29saW5nLlxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBkaWxhdGlvbnMgRGlsYXRpb24gYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKi9cbiAgc3RhdGljIGFkanVzdFBvb2xBdHRyaWJ1dGVzKFxuICAgICAgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbiwgaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSwga2VybmVsU2hhcGU6IG51bWJlcltdLCBzdHJpZGVzOiBudW1iZXJbXSxcbiAgICAgIGRpbGF0aW9uczogbnVtYmVyW10sIHBhZHM6IG51bWJlcltdKSB7XG4gICAgaWYgKCFpc0dsb2JhbE9wZXJhdG9yICYmIGtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXREaW1zLmxlbmd0aCAtIDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHNwZWNpZmllZCBrZXJuZWwgc2hhcGVzIHNob3VsZCBiZSAyIGxlc3MgdGhhbiBsZW5ndGggb2YgaW5wdXQgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChpc0dsb2JhbE9wZXJhdG9yKSB7XG4gICAgICAvLyBhZGp1c3Qga2VybmVsIHNoYXBlIHRvIGNvdmVyIHRoZSBpbnB1dCBkaW1zXG4gICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBpbnB1dERpbXMubGVuZ3RoIC0gMjsgZGltKyspIHtcbiAgICAgICAgaWYgKGRpbSA+PSBrZXJuZWxTaGFwZS5sZW5ndGgpIHtcbiAgICAgICAgICBrZXJuZWxTaGFwZS5wdXNoKGlucHV0RGltc1tkaW0gKyAyXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2VybmVsU2hhcGVbZGltXSA9IGlucHV0RGltc1tkaW0gKyAyXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkanVzdCBzdHJpZGVzIGxlbmd0aCB0byBtYXRjaCBrZXJuZWwgc2hhcGUgbGVuZ3RoXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IHN0cmlkZXMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChzdHJpZGVzW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpZGVzIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJpZGVzLnB1c2goMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRqdXN0IGRpbGF0aW9uIHZhbHVlXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IGRpbGF0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGRpbGF0aW9uc1tkaW1dIDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZGlsYXRpb25zIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaWxhdGlvbnMucHVzaCgxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGp1c3QgcGFkcyBsZW5ndGggdG8gbWF0Y2ggMiAqIGtlcm5lbCBzaGFwZSBsZW5ndGhcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGggKiAyOyBkaW0rKykge1xuICAgICAgaWYgKGRpbSA8IHBhZHMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChwYWRzW2RpbV0gPCAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwYWQgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhZHMucHVzaCgwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzYW5pdHkgY2hlY2tzIGZvciB2YWx1ZXMgaW4ga2VybmVsIHNoYXBlcyBhbmQgcGFkc1xuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aDsgZGltKyspIHtcbiAgICAgIGlmIChrZXJuZWxTaGFwZVtkaW1dIDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdrZXJuZWwgc2hhcGVzIG5lZWQgdG8gYmUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhZHNbZGltXSA+PSBrZXJuZWxTaGFwZVtkaW1dIHx8IHBhZHNbZGltICsga2VybmVsU2hhcGUubGVuZ3RoXSA+PSBrZXJuZWxTaGFwZVtkaW1dKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncGFkcyBzaG91bGQgYmUgc21hbGxlciB0aGFuIGtlcm5lbCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGFkanVzdCBwYWQgdmFsdWVzIGJhc2VkIG9uICdhdXRvUGFkJyBhdHRyaWJ1dGVcbiAgc3RhdGljIGFkanVzdFBhZHNCYXNlZE9uQXV0b1BhZChcbiAgICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLCBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgICAga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwYWRzOiBudW1iZXJbXSwgYXV0b1BhZD86IHN0cmluZykge1xuICAgIGlmICghYXV0b1BhZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwYWRzLmxlbmd0aCAhPT0gMiAqIChpbnB1dERpbXMubGVuZ3RoIC0gMikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHBhZHMgc2hvdWxkIGJlIHR3aWNlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKHN0cmlkZXMubGVuZ3RoICE9PSAoaW5wdXREaW1zLmxlbmd0aCAtIDIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xlbmd0aCBvZiBzdHJpZGVzIHNob3VsZCBiZSB0aGUgbGVuZ3RoIG9mIGRhdGEgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChrZXJuZWxTaGFwZS5sZW5ndGggIT09IChpbnB1dERpbXMubGVuZ3RoIC0gMikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIGtlcm5lbCBzaGFwZXMgc2hvdWxkIGJlIHRoZSBsZW5ndGggb2YgZGF0YSBkaW1lbnNpb25zJyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICBQb29sQ29udlV0aWwuYWRqdXN0UGFkQW5kUmV0dXJuU2hhcGUoXG4gICAgICAgICAgaW5wdXREaW1zW2RpbSArIDJdLCBzdHJpZGVzW2RpbV0sIGRpbGF0aW9uc1tkaW1dLCBrZXJuZWxTaGFwZVtkaW1dLCBwYWRzLCBkaW0sIGRpbSArIGlucHV0RGltcy5sZW5ndGggLSAyLFxuICAgICAgICAgIGF1dG9QYWQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIG91dHB1dCBzaGFwZSBmb3IgUG9vbCBvcHMgYmFzZWQgb24gaW5wdXQgYXR0cmlidXRlcy4gKFNob3VsZCBiZSB1c2VkIG9ubHkgZm9yIFBvb2wgb3BzKVxuICAgKiBAcGFyYW0gaXNHbG9iYWxPcGVyYXRvciBJZiB0cnVlLCBwZXJmb3JtIGdsb2JhbCBwb29saW5nLlxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLiAoaW5wdXRzWzBdLmRpbXMpXG4gICAqIEBwYXJhbSBzdHJpZGVzIFN0cmlkZSBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBkaWxhdGlvbnMgRGlsYXRpb24gYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBwYWRzIFBhZGRpbmcgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBhdXRvUGFkIERFUFJFQ0FURUQgYXR0cmlidXRlIHN1cHBvcnRlZCBmb3IgbGVnYWN5IG1vZGVscy4gU3BlY2lmaWVzIGhvdyB0byBpbXBsaWNpdGx5IGNhbGN1bGF0ZSBwYWRzIGluIGVhY2hcbiAgICogICAgIGRpbWVuc2lvbi4gQ2FuIHRha2UgdmFsdWVzIE5PVFNFVCwgU0FNRV9VUFBFUiwgU0FNRV9MT1dFUiwgb3IgVkFMSUQuXG4gICAqL1xuICBzdGF0aWMgY29tcHV0ZVBvb2xPdXRwdXRTaGFwZShcbiAgICAgIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sIHN0cmlkZXM6IG51bWJlcltdLCBkaWxhdGlvbnM6IG51bWJlcltdLFxuICAgICAga2VybmVsU2hhcGU6IG51bWJlcltdLCBwYWRzOiBudW1iZXJbXSwgYXV0b1BhZD86IHN0cmluZyk6IG51bWJlcltdIHtcbiAgICBpZiAoaW5wdXREaW1zLmxlbmd0aCA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHNoYXBlIG11c3QgYmUgb2Ygc2l6ZSBncmVhdGVyIHRoYW4gMCcpO1xuICAgIH1cblxuICAgIC8vIEFkZCBiYXRjaCBzaXplIGFuZCBudW1iZXIgb2YgY2hhbm5lbHMgb2Ygb3V0cHV0XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IFtpbnB1dERpbXNbMF0sIGlucHV0RGltc1sxXV07XG5cbiAgICBQb29sQ29udlV0aWwuY29tcHV0ZVNoYXBlSGVscGVyKFxuICAgICAgICBpc0dsb2JhbE9wZXJhdG9yLCBpbnB1dERpbXMsIG91dHB1dERpbXMsIHN0cmlkZXMsIGRpbGF0aW9ucywga2VybmVsU2hhcGUsIHBhZHMsIGF1dG9QYWQpO1xuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgb3V0cHV0IHNoYXBlIGZvciBDb252IG9wIGJhc2VkIG9uIGlucHV0IGF0dHJpYnV0ZXMuIChTaG91bGQgYmUgdXNlZCBvbmx5IGZvciBDb252IG9wKVxuICAgKiBAcGFyYW0gaW5wdXREaW1zIFRoZSBpbnB1dCB0ZW5zb3IgZGltZW5zaW9uLiAoaW5wdXRzWzBdLmRpbXMpXG4gICAqIEBwYXJhbSBmaWx0ZXJEaW1zIFRoZSBmaWx0ZXIgdGVuc29yIGRpbWVuc2lvbi4gKGlucHV0c1sxXS5kaW1zKVxuICAgKiBAcGFyYW0gc3RyaWRlcyBTdHJpZGUgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0ga2VybmVsU2hhcGUgVGhlIHNpemUgb2YgdGhlIGtlcm5lbCBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBwYWRzIFBhZGRpbmcgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZGluZyBhbG9uZyBlYWNoIGF4aXMuXG4gICAqIEBwYXJhbSBhdXRvUGFkIERFUFJFQ0FURUQgYXR0cmlidXRlIHN1cHBvcnRlZCBmb3IgbGVnYWN5IG1vZGVscy4gU3BlY2lmaWVzIGhvdyB0byBpbXBsaWNpdGx5IGNhbGN1bGF0ZSBwYWRzIGluIGVhY2hcbiAgICogICAgIGRpbWVuc2lvbi4gQ2FuIHRha2UgdmFsdWVzIE5PVFNFVCwgU0FNRV9VUFBFUiwgU0FNRV9MT1dFUiwgb3IgVkFMSUQuXG4gICAqL1xuICBzdGF0aWMgY29tcHV0ZUNvbnZPdXRwdXRTaGFwZShcbiAgICAgIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sIGZpbHRlckRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBzdHJpZGVzOiBudW1iZXJbXSwgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICAgIGtlcm5lbFNoYXBlOiBudW1iZXJbXSwgcGFkczogbnVtYmVyW10sIGF1dG9QYWQ/OiBzdHJpbmcpOiBudW1iZXJbXSB7XG4gICAgaWYgKGlucHV0RGltcy5sZW5ndGggPD0gMCB8fCBmaWx0ZXJEaW1zLmxlbmd0aCA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgaW5wdXQgdGVuc29yIGRpbXMgb3IgaW52YWxpZCBmaWx0ZXIgdGVuc29yIGRpbXMnKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgYmF0Y2ggc2l6ZSBhbmQgbnVtYmVyIG9mIGNoYW5uZWxzIG9mIG91dHB1dFxuICAgIGNvbnN0IG91dHB1dERpbXMgPSBbaW5wdXREaW1zWzBdLCBmaWx0ZXJEaW1zWzBdXTtcblxuICAgIFBvb2xDb252VXRpbC5jb21wdXRlU2hhcGVIZWxwZXIoZmFsc2UsIGlucHV0RGltcywgb3V0cHV0RGltcywgc3RyaWRlcywgZGlsYXRpb25zLCBrZXJuZWxTaGFwZSwgcGFkcywgYXV0b1BhZCk7XG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cblxuICAvLyB3aWxsIGNvbXB1dGUgb3V0cHV0IHNoYXBlcyBmb3IgZGF0YSBkaW1lbnNpb25zIE9OTFkgKGkuZS4pIG5vIGJhdGNoIHNpemUgYW5kIGNoYW5uZWxzXG4gIC8vIGNhbGxlZCBieSBjb21wdXRlUG9vbE91dHB1dFNoYXBlKCkgYW5kIGNvbXB1dGVDb252T3V0cHV0U2hhcGUoKVxuICAvLyBhZGp1c3QgcGFkcyBiYXNlZCBvbiAnYXV0b1BhZCcgYXR0cmlidXRlIHByaW9yIHRvIHNoYXBlIGNvbXB1dGF0aW9uXG4gIHByaXZhdGUgc3RhdGljIGNvbXB1dGVTaGFwZUhlbHBlcihcbiAgICAgIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sIG91dHB1dERpbXM6IG51bWJlcltdLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSxcbiAgICAgIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcGFkczogbnVtYmVyW10sIGF1dG9QYWQ/OiBzdHJpbmcpIHtcbiAgICBpZiAoaXNHbG9iYWxPcGVyYXRvcikge1xuICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICAgIG91dHB1dERpbXMucHVzaCgxKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICAgIG91dHB1dERpbXMucHVzaChQb29sQ29udlV0aWwuYWRqdXN0UGFkQW5kUmV0dXJuU2hhcGUoXG4gICAgICAgICAgICBpbnB1dERpbXNbZGltICsgMl0sIHN0cmlkZXNbZGltXSwgZGlsYXRpb25zW2RpbV0sIGtlcm5lbFNoYXBlW2RpbV0sIHBhZHMsIGRpbSwgZGltICsgaW5wdXREaW1zLmxlbmd0aCAtIDIsXG4gICAgICAgICAgICBhdXRvUGFkKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gaGVscGVyIGZvciBjb21wdXRlU2hhcGVIZWxwZXIoKSBhbmQgYWRqdXN0UGFkc0Jhc2VkT25BdXRvUGFkKClcbiAgLy8gYWRqdXN0cyBwYWQgdmFsdWUgZm9yIGdpdmVuICdhdXRvUGFkJyBzdHJpbmcgYW5kIGNvbXB1dGVzIG91dHB1dCBzaGFwZSBhbG9uZyBhIHBhcnRpY3VsYXIgZGltZW5zaW9uXG4gIHByaXZhdGUgc3RhdGljIGFkanVzdFBhZEFuZFJldHVyblNoYXBlKFxuICAgICAgaW5TaXplOiBudW1iZXIsIHN0cmlkZTogbnVtYmVyLCBkaWxhdGlvbjogbnVtYmVyLCBrZXJuZWw6IG51bWJlciwgcGFkczogbnVtYmVyW10sIHBhZEhlYWRJbmRleDogbnVtYmVyLFxuICAgICAgcGFkVGFpbEluZGV4OiBudW1iZXIsIGF1dG9QYWQ/OiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGNvbnN0IGRrZXJuZWwgPSBkaWxhdGlvbiAqIChrZXJuZWwgLSAxKSArIDE7XG4gICAgaWYgKGF1dG9QYWQgJiYgYXV0b1BhZCAhPT0gJ05PVFNFVCcpIHtcbiAgICAgIHN3aXRjaCAoYXV0b1BhZCkge1xuICAgICAgICBjYXNlICdWQUxJRCc6XG4gICAgICAgICAgcGFkc1twYWRIZWFkSW5kZXhdID0gMDtcbiAgICAgICAgICBwYWRzW3BhZFRhaWxJbmRleF0gPSAwO1xuICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKCgoaW5TaXplIC0gZGtlcm5lbCkgLyBzdHJpZGUpICsgMSk7XG4gICAgICAgIGNhc2UgJ1NBTUVfTE9XRVInOlxuICAgICAgICBjYXNlICdTQU1FX1VQUEVSJzpcbiAgICAgICAgICBpZiAoZGlsYXRpb24gIT09IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRGlsYXRpb24gbm90IHN1cHBvcnRlZCBmb3IgU0FNRV9VUFBFUiBvciBTQU1FX0xPV0VSJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGxlZ2FjeVRhcmdldFNpemUgPSAoaW5TaXplICsgc3RyaWRlIC0gMSkgLyBzdHJpZGU7XG4gICAgICAgICAgICBjb25zdCBwYWROZWVkZWQgPSAobGVnYWN5VGFyZ2V0U2l6ZSAtIDEpICogc3RyaWRlICsga2VybmVsIC0gaW5TaXplO1xuICAgICAgICAgICAgcGFkc1twYWRIZWFkSW5kZXhdID1cbiAgICAgICAgICAgICAgICAoYXV0b1BhZCA9PT0gJ1NBTUVfTE9XRVInKSA/IE1hdGguZmxvb3IoKHBhZE5lZWRlZCArIDEpIC8gMikgOiBNYXRoLmZsb29yKHBhZE5lZWRlZCAvIDIpO1xuICAgICAgICAgICAgcGFkc1twYWRUYWlsSW5kZXhdID0gcGFkTmVlZGVkIC0gcGFkc1twYWRIZWFkSW5kZXhdO1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKChpblNpemUgKyBwYWROZWVkZWQgLSBrZXJuZWwpIC8gc3RyaWRlKSArIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIEF1dG9QYWQgdHlwZScpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcigoKGluU2l6ZSArIHBhZHNbcGFkSGVhZEluZGV4XSArIHBhZHNbcGFkVGFpbEluZGV4XSAtIGRrZXJuZWwpIC8gc3RyaWRlKSArIDEpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgTUlOX0NMSVAgPSAtMy40MDI4MjM0NjYzODUyODg2ZSszODtcbmV4cG9ydCBjb25zdCBNQVhfQ0xJUCA9IDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzg7XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVVdGY4U3RyaW5nKGJ1ZmZlcjogVWludDhBcnJheSk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoYnVmZmVyKTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtHdWlkfSBmcm9tICdndWlkLXR5cGVzY3JpcHQnO1xuaW1wb3J0IExvbmcgZnJvbSAnbG9uZyc7XG5cbmltcG9ydCB7b25ueHJ1bnRpbWV9IGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7b25ueH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHtkZWNvZGVVdGY4U3RyaW5nLCBQcm90b1V0aWwsIFNoYXBlVXRpbH0gZnJvbSAnLi91dGlsJztcblxuaW1wb3J0IG9ydEZicyA9IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnM7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBUZW5zb3Ige1xuICBleHBvcnQgaW50ZXJmYWNlIERhdGFUeXBlTWFwIHtcbiAgICBib29sOiBVaW50OEFycmF5O1xuICAgIGZsb2F0MzI6IEZsb2F0MzJBcnJheTtcbiAgICBmbG9hdDY0OiBGbG9hdDY0QXJyYXk7XG4gICAgc3RyaW5nOiBzdHJpbmdbXTtcbiAgICBpbnQ4OiBJbnQ4QXJyYXk7XG4gICAgdWludDg6IFVpbnQ4QXJyYXk7XG4gICAgaW50MTY6IEludDE2QXJyYXk7XG4gICAgdWludDE2OiBVaW50MTZBcnJheTtcbiAgICBpbnQzMjogSW50MzJBcnJheTtcbiAgICB1aW50MzI6IFVpbnQzMkFycmF5O1xuICAgIGludDY0OiBCaWdJbnQ2NEFycmF5O1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgRGF0YVR5cGUgPSBrZXlvZiBEYXRhVHlwZU1hcDtcblxuICBleHBvcnQgdHlwZSBTdHJpbmdUeXBlID0gVGVuc29yLkRhdGFUeXBlTWFwWydzdHJpbmcnXTtcbiAgZXhwb3J0IHR5cGUgQm9vbGVhblR5cGUgPSBUZW5zb3IuRGF0YVR5cGVNYXBbJ2Jvb2wnXTtcbiAgZXhwb3J0IHR5cGUgSW50ZWdlclR5cGUgPSBUZW5zb3IuRGF0YVR5cGVNYXBbJ2ludDgnXXxUZW5zb3IuRGF0YVR5cGVNYXBbJ3VpbnQ4J118VGVuc29yLkRhdGFUeXBlTWFwWydpbnQxNiddfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRlbnNvci5EYXRhVHlwZU1hcFsndWludDE2J118VGVuc29yLkRhdGFUeXBlTWFwWydpbnQzMiddfFRlbnNvci5EYXRhVHlwZU1hcFsndWludDMyJ107XG4gIGV4cG9ydCB0eXBlIEZsb2F0VHlwZSA9IFRlbnNvci5EYXRhVHlwZU1hcFsnZmxvYXQzMiddfFRlbnNvci5EYXRhVHlwZU1hcFsnZmxvYXQ2NCddO1xuICBleHBvcnQgdHlwZSBOdW1iZXJUeXBlID0gQm9vbGVhblR5cGV8SW50ZWdlclR5cGV8RmxvYXRUeXBlO1xuXG4gIGV4cG9ydCB0eXBlIElkID0gR3VpZDtcbn1cblxudHlwZSBUZW5zb3JEYXRhID0gVGVuc29yLkRhdGFUeXBlTWFwW1RlbnNvci5EYXRhVHlwZV07XG5cbnR5cGUgRGF0YVByb3ZpZGVyID0gKGlkOiBUZW5zb3IuSWQpID0+IFRlbnNvckRhdGE7XG50eXBlIEFzeW5jRGF0YVByb3ZpZGVyID0gKGlkOiBUZW5zb3IuSWQpID0+IFByb21pc2U8VGVuc29yRGF0YT47XG5cbmV4cG9ydCBjbGFzcyBUZW5zb3Ige1xuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIHRlbnNvciBkYXRhXG4gICAqL1xuICBnZXQgZGF0YSgpOiBUZW5zb3JEYXRhIHtcbiAgICBpZiAodGhpcy5jYWNoZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhUHJvdmlkZXIhKHRoaXMuZGF0YUlkKTtcbiAgICAgIGlmIChkYXRhLmxlbmd0aCAhPT0gdGhpcy5zaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTGVuZ3RoIG9mIGRhdGEgcHJvdmlkZWQgYnkgdGhlIERhdGEgUHJvdmlkZXIgaXMgaW5jb25zaXN0ZW50IHdpdGggdGhlIGRpbXMgb2YgdGhpcyBUZW5zb3IuJyk7XG4gICAgICB9XG4gICAgICB0aGlzLmNhY2hlID0gZGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FjaGU7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIHN0cmluZyB0ZW5zb3IgZGF0YS4gU2hvdWxkIG9ubHkgdXNlIHdoZW4gdHlwZSBpcyBTVFJJTkdcbiAgICovXG4gIGdldCBzdHJpbmdEYXRhKCkge1xuICAgIGlmICh0aGlzLnR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIHR5cGUgaXMgbm90IHN0cmluZycpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmRhdGEgYXMgVGVuc29yLlN0cmluZ1R5cGU7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIGludGVnZXIgdGVuc29yIGRhdGEuIFNob3VsZCBvbmx5IHVzZSB3aGVuIHR5cGUgaXMgb25lIG9mIHRoZSBmb2xsb3dpbmc6IChVSU5UOCwgSU5UOCwgVUlOVDE2LFxuICAgKiBJTlQxNiwgSU5UMzIsIFVJTlQzMiwgQk9PTClcbiAgICovXG4gIGdldCBpbnRlZ2VyRGF0YSgpIHtcbiAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhIGFzIFRlbnNvci5JbnRlZ2VyVHlwZTtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZGF0YSB0eXBlIGlzIG5vdCBpbnRlZ2VyICh1aW50OCwgaW50OCwgdWludDE2LCBpbnQxNiwgaW50MzIsIHVpbnQzMiwgYm9vbCknKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIGZsb2F0IHRlbnNvciBkYXRhLiBTaG91bGQgb25seSB1c2Ugd2hlbiB0eXBlIGlzIG9uZSBvZiB0aGUgZm9sbG93aW5nOiAoRkxPQVQsIERPVUJMRSlcbiAgICovXG4gIGdldCBmbG9hdERhdGEoKSB7XG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEgYXMgVGVuc29yLkZsb2F0VHlwZTtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZGF0YSB0eXBlIGlzIG5vdCBmbG9hdCAoZmxvYXQzMiwgZmxvYXQ2NCknKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSB1bmRlcmx5aW5nIG51bWJlciB0ZW5zb3IgZGF0YS4gU2hvdWxkIG9ubHkgdXNlIHdoZW4gdHlwZSBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZzogKFVJTlQ4LCBJTlQ4LCBVSU5UMTYsXG4gICAqIElOVDE2LCBJTlQzMiwgVUlOVDMyLCBCT09MLCBGTE9BVCwgRE9VQkxFKVxuICAgKi9cbiAgZ2V0IG51bWJlckRhdGEoKSB7XG4gICAgaWYgKHRoaXMudHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB0aGlzLmRhdGEgYXMgVGVuc29yLk51bWJlclR5cGU7XG4gICAgfVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3R5cGUgY2Fubm90IGJlIG5vbi1udW1iZXIgKHN0cmluZyknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdmFsdWUgb2YgYW4gZWxlbWVudCBhdCB0aGUgZ2l2ZW4gaW5kaWNlc1xuICAgKi9cbiAgZ2V0KGluZGljZXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yLkRhdGFUeXBlTWFwW1RlbnNvci5EYXRhVHlwZV1bbnVtYmVyXSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVtTaGFwZVV0aWwuaW5kaWNlc1RvT2Zmc2V0KGluZGljZXMsIHRoaXMuc3RyaWRlcyldO1xuICB9XG5cbiAgLyoqXG4gICAqIHNldCB2YWx1ZSBvZiBhbiBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRpY2VzXG4gICAqL1xuICBzZXQoaW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIHZhbHVlOiBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkRhdGFUeXBlXVtudW1iZXJdKSB7XG4gICAgdGhpcy5kYXRhW1NoYXBlVXRpbC5pbmRpY2VzVG9PZmZzZXQoaW5kaWNlcywgdGhpcy5zdHJpZGVzKV0gPSB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgdGVuc29yIGRhdGEgYXN5bmNocm9ub3VzbHlcbiAgICovXG4gIGFzeW5jIGdldERhdGEoKTogUHJvbWlzZTxUZW5zb3JEYXRhPiB7XG4gICAgaWYgKHRoaXMuY2FjaGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5jYWNoZSA9IGF3YWl0IHRoaXMuYXN5bmNEYXRhUHJvdmlkZXIhKHRoaXMuZGF0YUlkKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FjaGU7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIHRlbnNvclxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNpemU6IG51bWJlcjtcblxuICBwcml2YXRlIF9zdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbiAgLyoqXG4gICAqIGdldCB0aGUgc3RyaWRlcyBmb3IgZWFjaCBkaW1lbnNpb25cbiAgICovXG4gIGdldCBzdHJpZGVzKCk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAoIXRoaXMuX3N0cmlkZXMpIHtcbiAgICAgIHRoaXMuX3N0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXModGhpcy5kaW1zKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3N0cmlkZXM7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICAgIC8qKlxuICAgICAgICogZ2V0IHRoZSBkaW1lbnNpb25zIG9mIHRoZSB0ZW5zb3JcbiAgICAgICAqL1xuICAgICAgcHVibGljIHJlYWRvbmx5IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgICAgLyoqXG4gICAgICAgKiBnZXQgdGhlIHR5cGUgb2YgdGhlIHRlbnNvclxuICAgICAgICovXG4gICAgICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogVGVuc29yLkRhdGFUeXBlLCBwcml2YXRlIGRhdGFQcm92aWRlcj86IERhdGFQcm92aWRlcixcbiAgICAgIHByaXZhdGUgYXN5bmNEYXRhUHJvdmlkZXI/OiBBc3luY0RhdGFQcm92aWRlciwgcHJpdmF0ZSBjYWNoZT86IFRlbnNvckRhdGEsXG4gICAgICAvKipcbiAgICAgICAqIGdldCB0aGUgZGF0YSBJRCB0aGF0IHVzZWQgdG8gbWFwIHRvIGEgdGVuc29yIGRhdGFcbiAgICAgICAqL1xuICAgICAgcHVibGljIHJlYWRvbmx5IGRhdGFJZDogR3VpZCA9IEd1aWQuY3JlYXRlKCkpIHtcbiAgICB0aGlzLnNpemUgPSBTaGFwZVV0aWwudmFsaWRhdGVEaW1zQW5kQ2FsY1NpemUoZGltcyk7XG4gICAgY29uc3Qgc2l6ZSA9IHRoaXMuc2l6ZTtcbiAgICBjb25zdCBlbXB0eSA9IChkYXRhUHJvdmlkZXIgPT09IHVuZGVmaW5lZCAmJiBhc3luY0RhdGFQcm92aWRlciA9PT0gdW5kZWZpbmVkICYmIGNhY2hlID09PSB1bmRlZmluZWQpO1xuXG4gICAgaWYgKGNhY2hlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChjYWNoZS5sZW5ndGggIT09IHNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0lucHV0IGRpbXMgZG9lc25cXCd0IG1hdGNoIGRhdGEgbGVuZ3RoLicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKGNhY2hlICE9PSB1bmRlZmluZWQgJiYgKCFBcnJheS5pc0FycmF5KGNhY2hlKSB8fCAhY2FjaGUuZXZlcnkoaSA9PiB0eXBlb2YgaSA9PT0gJ3N0cmluZycpKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjYWNoZSBzaG91bGQgYmUgYSBzdHJpbmcgYXJyYXknKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVtcHR5KSB7XG4gICAgICAgIHRoaXMuY2FjaGUgPSBuZXcgQXJyYXk8c3RyaW5nPihzaXplKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGNhY2hlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgY29uc3RydWN0b3IgPSBkYXRhdmlld0NvbnN0cnVjdG9yKHR5cGUpO1xuICAgICAgICBpZiAoIShjYWNoZSBpbnN0YW5jZW9mIGNvbnN0cnVjdG9yKSkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGNhY2hlIHNob3VsZCBiZSB0eXBlICR7Y29uc3RydWN0b3IubmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZW1wdHkpIHtcbiAgICAgICAgY29uc3QgYnVmID0gbmV3IEFycmF5QnVmZmVyKHNpemUgKiBzaXplb2YodHlwZSkpO1xuICAgICAgICB0aGlzLmNhY2hlID0gY3JlYXRlVmlldyhidWYsIHR5cGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3QgbmV3IFRlbnNvciBmcm9tIGEgT05OWCBUZW5zb3Igb2JqZWN0XG4gICAqIEBwYXJhbSB0ZW5zb3JQcm90byB0aGUgT05OWCBUZW5zb3JcbiAgICovXG4gIHN0YXRpYyBmcm9tUHJvdG8odGVuc29yUHJvdG86IG9ubnguSVRlbnNvclByb3RvKTogVGVuc29yIHtcbiAgICBpZiAoIXRlbnNvclByb3RvKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBjb25zdHJ1Y3QgVmFsdWUgZnJvbSBhbiBlbXB0eSB0ZW5zb3InKTtcbiAgICB9XG4gICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byh0ZW5zb3JQcm90by5kYXRhVHlwZSEpO1xuICAgIGNvbnN0IGRpbXMgPSBQcm90b1V0aWwudGVuc29yRGltc0Zyb21Qcm90byh0ZW5zb3JQcm90by5kaW1zISk7XG5cbiAgICBjb25zdCB2YWx1ZSA9IG5ldyBUZW5zb3IoZGltcywgdHlwZSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFdoZW4gaXQncyBTVFJJTkcgdHlwZSwgdGhlIHZhbHVlIHNob3VsZCBhbHdheXMgYmUgc3RvcmVkIGluIGZpZWxkXG4gICAgICAvLyAnc3RyaW5nRGF0YSdcbiAgICAgIHRlbnNvclByb3RvLnN0cmluZ0RhdGEhLmZvckVhY2goKHN0ciwgaSkgPT4ge1xuICAgICAgICB2YWx1ZS5kYXRhW2ldID0gZGVjb2RlVXRmOFN0cmluZyhzdHIpO1xuICAgICAgfSk7XG5cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgICB0ZW5zb3JQcm90by5yYXdEYXRhICYmIHR5cGVvZiB0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGggPT09ICdudW1iZXInICYmXG4gICAgICAgIHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCA+IDApIHtcbiAgICAgIC8vIE5PVCBjb25zaWRlcmluZyBzZWdtZW50IGZvciBub3cgKElNUE9SVEFOVClcblxuICAgICAgLy8gcG9wdWxhdGUgdmFsdWUgZnJvbSByYXdEYXRhXG4gICAgICBjb25zdCBkYXRhRGVzdCA9IHZhbHVlLmRhdGE7XG4gICAgICBjb25zdCBkYXRhU291cmNlID1cbiAgICAgICAgICBuZXcgRGF0YVZpZXcodGVuc29yUHJvdG8ucmF3RGF0YS5idWZmZXIsIHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZU9mZnNldCwgdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoKTtcbiAgICAgIGNvbnN0IGVsZW1lbnRTaXplID0gc2l6ZW9mUHJvdG8odGVuc29yUHJvdG8uZGF0YVR5cGUhKTtcbiAgICAgIGNvbnN0IGxlbmd0aCA9IHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCAvIGVsZW1lbnRTaXplO1xuXG4gICAgICBpZiAodGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoICUgZWxlbWVudFNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGJ1ZmZlciBsZW5ndGgnKTtcbiAgICAgIH1cbiAgICAgIGlmIChkYXRhRGVzdC5sZW5ndGggIT09IGxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2J1ZmZlciBsZW5ndGggbWlzbWF0Y2gnKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBuID0gcmVhZFByb3RvKGRhdGFTb3VyY2UsIHRlbnNvclByb3RvLmRhdGFUeXBlISwgaSAqIGVsZW1lbnRTaXplKTtcbiAgICAgICAgZGF0YURlc3RbaV0gPSBuO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBwb3B1bGF0ZSB2YWx1ZSBmcm9tIGFycmF5XG4gICAgICBsZXQgYXJyYXk6IEFycmF5PG51bWJlcnxMb25nPjtcbiAgICAgIHN3aXRjaCAodGVuc29yUHJvdG8uZGF0YVR5cGUpIHtcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkZMT0FUOlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8uZmxvYXREYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDMyOlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMTY6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMTY6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4OlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MOlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8uaW50MzJEYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8uaW50NjREYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkRPVUJMRTpcbiAgICAgICAgICBhcnJheSA9IHRlbnNvclByb3RvLmRvdWJsZURhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyOlxuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0OlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8udWludDY0RGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIHJ1biBoZXJlXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bnNwZWNpZmljIGVycm9yJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhcnJheSA9PT0gbnVsbCB8fCBhcnJheSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZmFpbGVkIHRvIHBvcHVsYXRlIGRhdGEgZnJvbSBhIHRlbnNvcnByb3RvIHZhbHVlJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRhdGEgPSB2YWx1ZS5kYXRhO1xuICAgICAgaWYgKGRhdGEubGVuZ3RoICE9PSBhcnJheS5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhcnJheSBsZW5ndGggbWlzbWF0Y2gnKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gYXJyYXlbaV07XG4gICAgICAgIGlmIChMb25nLmlzTG9uZyhlbGVtZW50KSkge1xuICAgICAgICAgIGRhdGFbaV0gPSBsb25nVG9OdW1iZXIoZWxlbWVudCwgdGVuc29yUHJvdG8uZGF0YVR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRhdGFbaV0gPSBlbGVtZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBuZXcgVGVuc29yIGZyb20gcmF3IGRhdGFcbiAgICogQHBhcmFtIGRhdGEgdGhlIHJhdyBkYXRhIG9iamVjdC4gU2hvdWxkIGJlIGEgc3RyaW5nIGFycmF5IGZvciAnc3RyaW5nJyB0ZW5zb3IsIGFuZCB0aGUgY29ycmVzcG9uZGluZyB0eXBlZCBhcnJheVxuICAgKiBmb3Igb3RoZXIgdHlwZXMgb2YgdGVuc29yLlxuICAgKiBAcGFyYW0gZGltcyB0aGUgZGltZW5zaW9ucyBvZiB0aGUgdGVuc29yXG4gICAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIG9mIHRoZSB0ZW5zb3JcbiAgICovXG4gIHN0YXRpYyBmcm9tRGF0YShkYXRhOiBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkRhdGFUeXBlXSwgZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHR5cGU6IFRlbnNvci5EYXRhVHlwZSkge1xuICAgIHJldHVybiBuZXcgVGVuc29yKGRpbXMsIHR5cGUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBkYXRhKTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tT3J0VGVuc29yKG9ydFRlbnNvcjogb3J0RmJzLlRlbnNvcikge1xuICAgIGlmICghb3J0VGVuc29yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBjb25zdHJ1Y3QgVmFsdWUgZnJvbSBhbiBlbXB0eSB0ZW5zb3InKTtcbiAgICB9XG4gICAgY29uc3QgZGltcyA9IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbU9SVEZvcm1hdChvcnRUZW5zb3IpO1xuICAgIGNvbnN0IHR5cGUgPSBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8ob3J0VGVuc29yLmRhdGFUeXBlKCkpO1xuXG4gICAgY29uc3QgdmFsdWUgPSBuZXcgVGVuc29yKGRpbXMsIHR5cGUpO1xuXG4gICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBXaGVuIGl0J3MgU1RSSU5HIHR5cGUsIHRoZSB2YWx1ZSBzaG91bGQgYWx3YXlzIGJlIHN0b3JlZCBpbiBmaWVsZFxuICAgICAgLy8gJ3N0cmluZ0RhdGEnXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9ydFRlbnNvci5zdHJpbmdEYXRhTGVuZ3RoKCk7IGkrKykge1xuICAgICAgICB2YWx1ZS5kYXRhW2ldID0gb3J0VGVuc29yLnN0cmluZ0RhdGEoaSk7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKFxuICAgICAgICBvcnRUZW5zb3IucmF3RGF0YUFycmF5KCkgJiYgdHlwZW9mIG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCkgPT09ICdudW1iZXInICYmIG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCkgPiAwKSB7XG4gICAgICAvLyBOT1QgY29uc2lkZXJpbmcgc2VnbWVudCBmb3Igbm93IChJTVBPUlRBTlQpXG5cbiAgICAgIC8vIHBvcHVsYXRlIHZhbHVlIGZyb20gcmF3RGF0YVxuICAgICAgY29uc3QgZGF0YURlc3QgPSB2YWx1ZS5kYXRhO1xuICAgICAgY29uc3QgZGF0YVNvdXJjZSA9IG5ldyBEYXRhVmlldyhcbiAgICAgICAgICBvcnRUZW5zb3IucmF3RGF0YUFycmF5KCkhLmJ1ZmZlciwgb3J0VGVuc29yLnJhd0RhdGFBcnJheSgpIS5ieXRlT2Zmc2V0LCBvcnRUZW5zb3IucmF3RGF0YUxlbmd0aCgpKTtcbiAgICAgIGNvbnN0IGVsZW1lbnRTaXplID0gc2l6ZW9mUHJvdG8ob3J0VGVuc29yLmRhdGFUeXBlKCkpO1xuICAgICAgY29uc3QgbGVuZ3RoID0gb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSAvIGVsZW1lbnRTaXplO1xuXG4gICAgICBpZiAob3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSAlIGVsZW1lbnRTaXplICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBidWZmZXIgbGVuZ3RoJyk7XG4gICAgICB9XG4gICAgICBpZiAoZGF0YURlc3QubGVuZ3RoICE9PSBsZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdidWZmZXIgbGVuZ3RoIG1pc21hdGNoJyk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgbiA9IHJlYWRQcm90byhkYXRhU291cmNlLCBvcnRUZW5zb3IuZGF0YVR5cGUoKSwgaSAqIGVsZW1lbnRTaXplKTtcbiAgICAgICAgZGF0YURlc3RbaV0gPSBuO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2l6ZW9mKHR5cGU6IFRlbnNvci5EYXRhVHlwZSk6IG51bWJlciB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2Jvb2wnOlxuICAgIGNhc2UgJ2ludDgnOlxuICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2UgJ2ludDE2JzpcbiAgICBjYXNlICd1aW50MTYnOlxuICAgICAgcmV0dXJuIDI7XG4gICAgY2FzZSAnaW50MzInOlxuICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICByZXR1cm4gNDtcbiAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgIHJldHVybiA4O1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCBjYWxjdWxhdGUgc2l6ZW9mKCkgb24gdHlwZSAke3R5cGV9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2l6ZW9mUHJvdG8odHlwZTogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZXxvcnRGYnMuVGVuc29yRGF0YVR5cGUpOiBudW1iZXIge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w6XG4gICAgICByZXR1cm4gMTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2OlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjpcbiAgICAgIHJldHVybiAyO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjpcbiAgICAgIHJldHVybiA0O1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NDpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICByZXR1cm4gODtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgY2FsY3VsYXRlIHNpemVvZigpIG9uIHR5cGUgJHtvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlW3R5cGVdfWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpZXcoZGF0YUJ1ZmZlcjogQXJyYXlCdWZmZXIsIHR5cGU6IFRlbnNvci5EYXRhVHlwZSkge1xuICByZXR1cm4gbmV3IChkYXRhdmlld0NvbnN0cnVjdG9yKHR5cGUpKShkYXRhQnVmZmVyKTtcbn1cblxuZnVuY3Rpb24gZGF0YXZpZXdDb25zdHJ1Y3Rvcih0eXBlOiBUZW5zb3IuRGF0YVR5cGUpIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnYm9vbCc6XG4gICAgY2FzZSAndWludDgnOlxuICAgICAgcmV0dXJuIFVpbnQ4QXJyYXk7XG4gICAgY2FzZSAnaW50OCc6XG4gICAgICByZXR1cm4gSW50OEFycmF5O1xuICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgIHJldHVybiBJbnQxNkFycmF5O1xuICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICByZXR1cm4gVWludDE2QXJyYXk7XG4gICAgY2FzZSAnaW50MzInOlxuICAgICAgcmV0dXJuIEludDMyQXJyYXk7XG4gICAgY2FzZSAndWludDMyJzpcbiAgICAgIHJldHVybiBVaW50MzJBcnJheTtcbiAgICBjYXNlICdpbnQ2NCc6XG4gICAgICByZXR1cm4gQmlnSW50NjRBcnJheTtcbiAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIHJldHVybiBGbG9hdDMyQXJyYXk7XG4gICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICByZXR1cm4gRmxvYXQ2NEFycmF5O1xuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBzaG91bGQgbmV2ZXIgcnVuIHRvIGhlcmVcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5zcGVjaWZpZWQgZXJyb3InKTtcbiAgfVxufVxuXG4vLyBjb252ZXJ0IGEgbG9uZyBudW1iZXIgdG8gYSAzMi1iaXQgaW50ZWdlciAoY2FzdC1kb3duKVxuZnVuY3Rpb24gbG9uZ1RvTnVtYmVyKGk6IExvbmcsIHR5cGU6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGV8b3J0RmJzLlRlbnNvckRhdGFUeXBlKTogbnVtYmVyIHtcbiAgLy8gSU5UNjQsIFVJTlQzMiwgVUlOVDY0XG4gIGlmICh0eXBlID09PSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0IHx8IHR5cGUgPT09IG9ydEZicy5UZW5zb3JEYXRhVHlwZS5JTlQ2NCkge1xuICAgIGlmIChpLmdyZWF0ZXJUaGFuT3JFcXVhbCgyMTQ3NDgzNjQ4KSB8fCBpLmxlc3NUaGFuKC0yMTQ3NDgzNjQ4KSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW50NjQgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChcbiAgICAgIHR5cGUgPT09IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyIHx8IHR5cGUgPT09IG9ydEZicy5UZW5zb3JEYXRhVHlwZS5VSU5UMzIgfHxcbiAgICAgIHR5cGUgPT09IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0IHx8IHR5cGUgPT09IG9ydEZicy5UZW5zb3JEYXRhVHlwZS5VSU5UNjQpIHtcbiAgICBpZiAoaS5ncmVhdGVyVGhhbk9yRXF1YWwoNDI5NDk2NzI5NikgfHwgaS5sZXNzVGhhbigwKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndWludDY0IGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgbm90IGEgTE9ORyB0eXBlOiAke29ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVbdHlwZV19YCk7XG4gIH1cblxuICByZXR1cm4gaS50b051bWJlcigpO1xufVxuXG4vLyByZWFkIG9uZSB2YWx1ZSBmcm9tIFRlbnNvclByb3RvXG5mdW5jdGlvbiByZWFkUHJvdG8odmlldzogRGF0YVZpZXcsIHR5cGU6IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGV8b3J0RmJzLlRlbnNvckRhdGFUeXBlLCBieXRlT2Zmc2V0OiBudW1iZXIpOiBudW1iZXIge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuQk9PTDpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDg6XG4gICAgICByZXR1cm4gdmlldy5nZXRVaW50OChieXRlT2Zmc2V0KTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UODpcbiAgICAgIHJldHVybiB2aWV3LmdldEludDgoYnl0ZU9mZnNldCk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjpcbiAgICAgIHJldHVybiB2aWV3LmdldFVpbnQxNihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMTY6XG4gICAgICByZXR1cm4gdmlldy5nZXRJbnQxNihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ6XG4gICAgICByZXR1cm4gdmlldy5nZXRGbG9hdDMyKGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICAgIHJldHVybiB2aWV3LmdldEludDMyKGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI6XG4gICAgICByZXR1cm4gdmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgICAgcmV0dXJuIGxvbmdUb051bWJlcihcbiAgICAgICAgICBMb25nLmZyb21CaXRzKHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQsIHRydWUpLCB2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0ICsgNCwgdHJ1ZSksIGZhbHNlKSwgdHlwZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkRPVUJMRTpcbiAgICAgIHJldHVybiB2aWV3LmdldEZsb2F0NjQoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgIHJldHVybiBsb25nVG9OdW1iZXIoXG4gICAgICAgICAgTG9uZy5mcm9tQml0cyh2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0LCB0cnVlKSwgdmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCArIDQsIHRydWUpLCB0cnVlKSwgdHlwZSk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY2Fubm90IHJlYWQgZnJvbSBEYXRhVmlldyBmb3IgdHlwZSAke29ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVbdHlwZV19YCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLyoqXG4gKiByZXByZXNlbnQgYSB2ZXJzaW9uIGlycmVsZXZhbnQgYWJzdHJhY3Rpb24gb2YgZm9yIEdMU0wgc291cmNlIGNvZGVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHbHNsIHtcbiAgcmVhZG9ubHkgdmVyc2lvbjogc3RyaW5nO1xuICByZWFkb25seSBhdHRyaWJ1dGU6IHN0cmluZztcbiAgcmVhZG9ubHkgdmFyeWluZ1ZlcnRleDogc3RyaW5nO1xuICByZWFkb25seSB2YXJ5aW5nRnJhZzogc3RyaW5nO1xuICByZWFkb25seSB0ZXh0dXJlMkQ6IHN0cmluZztcbiAgcmVhZG9ubHkgb3V0cHV0OiBzdHJpbmc7XG4gIHJlYWRvbmx5IG91dHB1dERlY2xhcmF0aW9uOiBzdHJpbmc7XG59XG5cbmNvbnN0IEdMU0xfRVNfMl8wOiBHbHNsID0ge1xuICB2ZXJzaW9uOiAnJyxcbiAgYXR0cmlidXRlOiAnYXR0cmlidXRlJyxcbiAgdmFyeWluZ1ZlcnRleDogJ3ZhcnlpbmcnLFxuICB2YXJ5aW5nRnJhZzogJ3ZhcnlpbmcnLFxuICB0ZXh0dXJlMkQ6ICd0ZXh0dXJlMkQnLFxuICBvdXRwdXQ6ICdnbF9GcmFnQ29sb3InLFxuICBvdXRwdXREZWNsYXJhdGlvbjogJycsXG59O1xuY29uc3QgR0xTTF9FU18zXzA6IEdsc2wgPSB7XG4gIHZlcnNpb246ICcjdmVyc2lvbiAzMDAgZXMnLFxuICBhdHRyaWJ1dGU6ICdpbicsXG4gIHZhcnlpbmdWZXJ0ZXg6ICdvdXQnLFxuICB2YXJ5aW5nRnJhZzogJ2luJyxcbiAgdGV4dHVyZTJEOiAndGV4dHVyZScsXG4gIG91dHB1dDogJ291dHB1dENvbG9yJyxcbiAgb3V0cHV0RGVjbGFyYXRpb246ICdvdXQgdmVjNCBvdXRwdXRDb2xvcjsnLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEdsc2wodmVyc2lvbjogMXwyKSB7XG4gIHJldHVybiB2ZXJzaW9uID09PSAxID8gR0xTTF9FU18yXzAgOiBHTFNMX0VTXzNfMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZlcnRleFNoYWRlclNvdXJjZSh2ZXJzaW9uOiAxfDIpOiBzdHJpbmcge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbCh2ZXJzaW9uKTtcbiAgcmV0dXJuIGAke2dsc2wudmVyc2lvbn1cbiAgICAgIHByZWNpc2lvbiBoaWdocCBmbG9hdDtcbiAgICAgICR7Z2xzbC5hdHRyaWJ1dGV9IHZlYzMgcG9zaXRpb247XG4gICAgICAke2dsc2wuYXR0cmlidXRlfSB2ZWMyIHRleHR1cmVDb29yZDtcblxuICAgICAgJHtnbHNsLnZhcnlpbmdWZXJ0ZXh9IHZlYzIgVGV4Q29vcmRzO1xuXG4gICAgICB2b2lkIG1haW4oKVxuICAgICAge1xuICAgICAgICAgIGdsX1Bvc2l0aW9uID0gdmVjNChwb3NpdGlvbiwgMS4wKTtcbiAgICAgICAgICBUZXhDb29yZHMgPSB0ZXh0dXJlQ29vcmQ7XG4gICAgICB9YDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZyYWdTaGFkZXJQcmVhbWJsZSh2ZXJzaW9uOiAxfDIpOiBzdHJpbmcge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbCh2ZXJzaW9uKTtcbiAgcmV0dXJuIGAke2dsc2wudmVyc2lvbn1cbiAgICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7XG4gICAgcHJlY2lzaW9uIGhpZ2hwIGludDtcbiAgICBwcmVjaXNpb24gaGlnaHAgc2FtcGxlcjJEO1xuICAgICR7Z2xzbC52YXJ5aW5nRnJhZ30gdmVjMiBUZXhDb29yZHM7XG4gICAgJHtnbHNsLm91dHB1dERlY2xhcmF0aW9ufVxuICAgIGNvbnN0IHZlYzIgaGFsZkNSID0gdmVjMigwLjUsIDAuNSk7XG5cbiAgICAvLyBDdXN0b20gdmVjdG9yIHR5cGVzIHRvIGhhbmRsZSBoaWdoZXIgZGltZW5hbGl0aWVzLlxuICAgIHN0cnVjdCBpdmVjNVxuICAgIHtcbiAgICAgIGludCB4O1xuICAgICAgaW50IHk7XG4gICAgICBpbnQgejtcbiAgICAgIGludCB3O1xuICAgICAgaW50IHU7XG4gICAgfTtcblxuICAgIHN0cnVjdCBpdmVjNlxuICAgIHtcbiAgICAgIGludCB4O1xuICAgICAgaW50IHk7XG4gICAgICBpbnQgejtcbiAgICAgIGludCB3O1xuICAgICAgaW50IHU7XG4gICAgICBpbnQgdjtcbiAgICB9O1xuXG4gICAgaW50IGltb2QoaW50IHgsIGludCB5KSB7XG4gICAgICByZXR1cm4geCAtIHkgKiAoeCAvIHkpO1xuICAgIH1cblxuICAgIGA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWZhdWx0RnJhZ1NoYWRlck1haW4odmVyc2lvbjogMXwyLCBvdXRwdXRTaGFwZUxlbmd0aDogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2wodmVyc2lvbik7XG4gIHJldHVybiBgXG4gIHZvaWQgbWFpbigpIHtcbiAgICBpbnQgaW5kaWNlc1ske291dHB1dFNoYXBlTGVuZ3RofV07XG4gICAgdG9WZWMoVGV4Q29vcmRzLCBpbmRpY2VzKTtcbiAgICB2ZWM0IHJlc3VsdCA9IHZlYzQocHJvY2VzcyhpbmRpY2VzKSk7XG4gICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gIH1cbiAgYDtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uL3RlbnNvcic7XG5cbi8qKlxuICogTGF5b3V0IGluZm8gaXMgdXNlZCBmb3IgbWFwcGluZyBuLWRpbWVuc2lvbmFsIGFycmF5IHRvIDJEIHRleHR1cmVzXG4gKiBUaGUgbGF5b3V0IGlzIGNyZWF0ZWQgYnkgdGhlIFRleHR1cmVMYXlvdXRTdHJhdGVneSBiYXNlZCBvblxuICogdGhlIFRlbnNvcidzIGRpbWVuc2lvbnMgYW5kIHN0cmlkZXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlTGF5b3V0IHtcbiAgd2lkdGg6IG51bWJlcjtcbiAgaGVpZ2h0OiBudW1iZXI7XG4gIC8qKlxuICAgKiBzcGVjaWZ5IHRoZSBudW1iZXIgb2YgdmFsdWUgdGhhdCBlbmNvZGVkIGluIGEgc2luZ2xlIHBpeGVsXG4gICAqL1xuICBjaGFubmVsczogMXwyfDN8NDtcbiAgLyoqXG4gICAqIHdoZXRoZXIgaW4gcGFja2VkIG1vZGUgb3Igbm90XG4gICAqL1xuICBpc1BhY2tlZD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiB0aGUgbm9ybWFsaXplZCBzaGFwZVxuICAgKi9cbiAgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICAvKipcbiAgICogdGhlIHN0cmlkZSBvZiBlYWNoIGRpbWVuc2lvbnMsIGNhbGN1bGF0ZWQgYWNjb3JkaW5nIHRvIHNoYXBlXG4gICAqL1xuICBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbiAgLyoqXG4gICAqIHRoZSBvcmlnaW5hbCBzaGFwZShkaW1zKSBvZiB0aGUgY29ycmVzcG9uZGluZyB0ZW5zb3JcbiAgICovXG4gIHVucGFja2VkU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gIHJldmVyc2VkV0g/OiBib29sZWFuO1xufVxuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlRGF0YSBleHRlbmRzIFRleHR1cmVMYXlvdXQge1xuICB0ZW5zb3I6IFRlbnNvcjtcbiAgdGV4dHVyZTogV2ViR0xUZXh0dXJlO1xufVxuXG5leHBvcnQgZW51bSBUZXh0dXJlVHlwZSB7XG4gIHVucGFja2VkLCAgICAgICAgICAgICAgLy8gPC0tIG5vcm1hbCB1bnBhY2tlZCB0ZXh0dXJlXG4gIHVucGFja2VkUmV2ZXJzZWQsICAgICAgLy8gPC0tIHVucGFja2VkIHRleHR1cmUgdXNlZCBpbiBvbGQgT05OWC5qcyBpbXBsZW1lbnRhdGlvbiAoZGVwcmVjYXRlZClcbiAgcGFja2VkLCAgICAgICAgICAgICAgICAvLyA8LS0gbm9ybWFsIHBhY2tlZCB0ZXh0dXJlXG4gIGRvd25sb2FkVWludDhBc0Zsb2F0LCAgLy8gPC0tIE9OTFkgdXNlZCBpbiB0ZXh0dXJlIGRvd25sb2FkaW5nIGZvciBpT1MgZGV2aWNlc1xuICBwYWNrZWRMYXN0RGltZW5zaW9uICAgIC8vIDwtLSBPTkxZIHVzZWQgaW4gb2xkIE9OTlguanMgQ29udiBpbXBsZW1lbnRhdGlvbiBmb3IgaW5wdXQgVyAoZGVwcmVjYXRlZClcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW5zb3JJbmZvIHtcbiAgaWQ/OiBUZW5zb3IuSWQ7XG4gIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICB0eXBlOiBUZW5zb3IuRGF0YVR5cGU7XG4gIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtVmFyaWFibGUge1xuICB0eXBlOiAnZmxvYXQnfCdpbnQnO1xuICBuYW1lOiBzdHJpbmc7XG4gIGFycmF5TGVuZ3RoPzogbnVtYmVyO1xuICBkYXRhOiBudW1iZXJ8bnVtYmVyW107XG59XG5cbi8qKlxuICogQSBzZXQgb2YgbWV0YWRhdGEgb2YgYSBzaGFkZXIgcHJvZ3JhbS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtTWV0YWRhdGEge1xuICAvKipcbiAgICogdGhlIG5hbWUgb2YgdGhlIHByb2dyYW0uIHVzZWQgZm9yIGRlYnVnZ2luZyBhbmQgcHJvZmlsaW5nXG4gICAqL1xuICBuYW1lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiB0ZXh0dXJlIHR5cGVzIGZvciBlYWNoIGlucHV0XG4gICAqL1xuICBpbnB1dFR5cGVzOiBUZXh0dXJlVHlwZVtdO1xuICAvKipcbiAgICogbmFtZXMgb2YgZWFjaCBpbnB1dFxuICAgKi9cbiAgaW5wdXROYW1lczogc3RyaW5nW107XG4gIC8qKlxuICAgKiBhbiBvcHRpb25hbCBzdHJpbmcgYXMgYSBjYWNoZSBoaW50IGluIHRoZSBhcnRpZmFjdCBjYWNoZVxuICAgKi9cbiAgY2FjaGVIaW50Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgUHJvZ3JhbUluZm9Mb2FkZXIgYWxsb3dzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbUluZm9Mb2FkZXIgZXh0ZW5kcyBQcm9ncmFtTWV0YWRhdGEge1xuICAvKipcbiAgICogYSBmdW5jdGlvbiB0byBnZXQgdGhlIHByb2dyYW0gaW5mb1xuICAgKi9cbiAgZ2V0KCk6IFByb2dyYW1JbmZvO1xufVxuXG4vKipcbiAqIEEgc2V0IG9mIGRhdGEgdGhhdCByZXByZXNlbnQgYSBzaGFkZXIgcHJvZ3JhbVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1JbmZvIGV4dGVuZHMgUHJvZ3JhbU1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIGluZm9ybWF0aW9uIG9mIHVuaWZvcm0gdmFyaWFibGVzXG4gICAqL1xuICB2YXJpYWJsZXM/OiBQcm9ncmFtVmFyaWFibGVbXTtcbiAgLyoqXG4gICAqIHRlbnNvciBpbmZvIGZvciBvdXRwdXRcbiAgICovXG4gIG91dHB1dDogVGVuc29ySW5mbztcbiAgLyoqXG4gICAqIHRoZSBzaGFkZXIncyBwcm9jZXNzaW5nIHNvdXJjZSBjb2RlXG4gICAqL1xuICBzaGFkZXJTb3VyY2U6IHN0cmluZztcbiAgLyoqXG4gICAqIHdoZXRoZXIgdGhlIHNoYWRlciBzb3VyY2UgY29udGFpbnMgYSBjdXN0b21pemVkIG1haW4gZnVuY3Rpb24gaW1wbGVtZW50YXRpb25cbiAgICovXG4gIGhhc01haW4/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZhcmlhYmxlSW5mbyB7XG4gIHR5cGU6ICdmbG9hdCd8J2ludCc7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJyYXlMZW5ndGg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbVZhcmlhYmxlIHtcbiAgdHlwZTogJ2Zsb2F0J3wnaW50JztcbiAgbmFtZTogc3RyaW5nO1xuICBhcnJheUxlbmd0aD86IG51bWJlcjtcbiAgZGF0YTogbnVtYmVyfG51bWJlcltdO1xufVxuXG4vKipcbiAqIEluZm9ybWF0aW9uIG9mIHVuaWZvcm1zIHRoYXQgc2hhZGVyIHVzZXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbmlmb3JtSW5mbyB7XG4gIHR5cGU6ICdzYW1wbGVyMkQnfFZhcmlhYmxlSW5mb1sndHlwZSddO1xuICBuYW1lOiBzdHJpbmc7XG4gIGFycmF5TGVuZ3RoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVuaWZvcm1Mb2NhdGlvbiBleHRlbmRzIFVuaWZvcm1JbmZvIHtcbiAgbG9jYXRpb246IFdlYkdMVW5pZm9ybUxvY2F0aW9uO1xufVxuXG4vKipcbiAqIEFydGlmYWN0IGlzIHRoZSByZXN1bHQgb2YgY29tcGlsYXRpb25cbiAqIEl0IGRvZXMgbm90IGNvbnRhaW4gaW5wdXQgb2Ygb3V0cHV0IGRhdGFcbiAqIEhvd2V2ZXIgYW55dGhpbmcgdGhhdCBjb3VsZCBiZSBydW4gYXMgYSBcInByb2dyYW1cIlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFydGlmYWN0IHtcbiAgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvO1xuICBwcm9ncmFtOiBXZWJHTFByb2dyYW07XG4gIHVuaWZvcm1Mb2NhdGlvbnM6IFVuaWZvcm1Mb2NhdGlvbltdO1xuICBhdHRyaWJMb2NhdGlvbnM6IHtwb3NpdGlvbjogbnVtYmVyOyB0ZXh0dXJlQ29vcmQ6IG51bWJlcn07XG59XG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgQXJ0aWZhY3Qge1xuICB0eXBlIFVuaWZvcm1Mb2NhdGlvbnMgPSBBcnRpZmFjdFsndW5pZm9ybUxvY2F0aW9ucyddO1xuICB0eXBlIEF0dHJpYkxvY2F0aW9ucyA9IEFydGlmYWN0WydhdHRyaWJMb2NhdGlvbnMnXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVbmlmb3JtRGF0YSB7XG4gIFtuYW1lOiBzdHJpbmddOiBudW1iZXJ8bnVtYmVyW107XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICcuLi8uLi91dGlsJztcbi8qKlxuICogR2l2ZW4gYSBub24gUkdCQSBzaGFwZSBjYWxjdWxhdGUgdGhlIFIgdmVyc2lvblxuICogSXQgaXMgYXNzdW1lZCB0aGF0IHRoZSBkaW1lbnNpb25zIGFyZSBtdWx0aXBsZXMgb2YgZ2l2ZW4gY2hhbm5lbHNcbiAqIE5PVEU6IGl0IGlzIGFsd2F5cyB0aGUgbGFzdCBkaW0gdGhhdCBnZXRzIHBhY2tlZC5cbiAqIEBwYXJhbSB1bnBhY2tlZFNoYXBlIG9yaWdpbmFsIHNoYXBlIHRvIGNyZWF0ZSBhIHBhY2tlZCB2ZXJzaW9uIGZyb21cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFBhY2tlZFNoYXBlKHVucGFja2VkU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICBjb25zdCBsZW4gPSB1bnBhY2tlZFNoYXBlLmxlbmd0aDtcbiAgcmV0dXJuIHVucGFja2VkU2hhcGUuc2xpY2UoMCwgbGVuIC0gMSkuY29uY2F0KHVucGFja2VkU2hhcGVbbGVuIC0gMV0gLyA0KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcGVhdGVkVHJ5KFxuICAgIGNoZWNrRm46ICgpID0+IGJvb2xlYW4sIGRlbGF5Rm4gPSAoX2NvdW50ZXI6IG51bWJlcikgPT4gMCwgbWF4Q291bnRlcj86IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGxldCB0cnlDb3VudCA9IDA7XG5cbiAgICBjb25zdCB0cnlGbiA9ICgpID0+IHtcbiAgICAgIGlmIChjaGVja0ZuKCkpIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRyeUNvdW50Kys7XG5cbiAgICAgIGNvbnN0IG5leHRCYWNrb2ZmID0gZGVsYXlGbih0cnlDb3VudCk7XG5cbiAgICAgIGlmIChtYXhDb3VudGVyICE9IG51bGwgJiYgdHJ5Q291bnQgPj0gbWF4Q291bnRlcikge1xuICAgICAgICByZWplY3QoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2V0VGltZW91dCh0cnlGbiwgbmV4dEJhY2tvZmYpO1xuICAgIH07XG5cbiAgICB0cnlGbigpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGZ1bmN0aW9uIG5hbWUgZnJvbSBhbiBpbnB1dCBzYW1wbGVyIG5hbWUuXG4gKiBAcGFyYW0gc2FtcGxlck5hbWUgTmFtZSBvZiB0aGUgc2FtcGxlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZShzYW1wbGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0KHR5cGVvZiBzYW1wbGVyTmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgc2FtcGxlck5hbWUubGVuZ3RoICE9PSAwLCAoKSA9PiAnZW1wdHkgc3RyaW5nIGZvdW5kIGZvciBzYW1wbGVyIG5hbWUnKTtcbiAgcmV0dXJuICdnZXQnICsgc2FtcGxlck5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzYW1wbGVyTmFtZS5zbGljZSgxKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGZ1bmN0aW9uIG5hbWUgZnJvbSBhbiBpbnB1dCBzYW1wbGVyIG5hbWUgYXQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHNhbXBsZXJOYW1lIE5hbWUgb2YgdGhlIHNhbXBsZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWVBdE91dENvb3JkcyhzYW1wbGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0KHR5cGVvZiBzYW1wbGVyTmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgc2FtcGxlck5hbWUubGVuZ3RoICE9PSAwLCAoKSA9PiAnZW1wdHkgc3RyaW5nIGZvdW5kIGZvciBzYW1wbGVyIG5hbWUnKTtcbiAgcmV0dXJuICdnZXQnICsgc2FtcGxlck5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzYW1wbGVyTmFtZS5zbGljZSgxKSArICdBdE91dENvb3Jkcyc7XG59XG5cbi8qKiBSZXR1cm5zIGEgbmV3IGlucHV0IHNoYXBlIChhIGNvcHkpIHRoYXQgaGFzIGEgc3F1ZWV6ZWQgbG9naWNhbCBzaGFwZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzcXVlZXplSW5wdXRTaGFwZShpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgc3F1ZWV6ZWRTaGFwZTogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gIC8vIERlZXAgY29weS5cbiAgbGV0IG5ld0lucHV0U2hhcGU6IG51bWJlcltdID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dFNoYXBlKSk7XG4gIG5ld0lucHV0U2hhcGUgPSBzcXVlZXplZFNoYXBlO1xuICByZXR1cm4gbmV3SW5wdXRTaGFwZTtcbn1cblxuLyoqIFJldHVybnMgYSBsaXN0IG9mIHNxdWVlemVkIHBhcmFtZXRlcnMgZm9yIHNoYWRlciBmdW5jdGlvbnMgKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXM6IHN0cmluZ1tdLCBrZXB0RGltczogbnVtYmVyW10pOiBzdHJpbmcge1xuICByZXR1cm4ga2VwdERpbXMubWFwKGQgPT4gcGFyYW1zW2RdKS5qb2luKCcsICcpO1xufVxuXG4vKiogUmV0dXJucyB0aGUgZGF0YSB0eXBlIGZvciBkaWZmZXJlbnQgcmFua3MuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29vcmRzRGF0YVR5cGUocmFuazogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPD0gMSkge1xuICAgIHJldHVybiAnaW50JztcbiAgfSBlbHNlIGlmIChyYW5rID09PSAyKSB7XG4gICAgcmV0dXJuICdpdmVjMic7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gMykge1xuICAgIHJldHVybiAnaXZlYzMnO1xuICB9IGVsc2UgaWYgKHJhbmsgPT09IDQpIHtcbiAgICByZXR1cm4gJ2l2ZWM0JztcbiAgfSBlbHNlIGlmIChyYW5rID09PSA1KSB7XG4gICAgcmV0dXJuICdpdmVjNSc7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gNikge1xuICAgIHJldHVybiAnaXZlYzYnO1xuICB9IGVsc2Uge1xuICAgIHRocm93IEVycm9yKGBHUFUgZm9yIHJhbmsgJHtyYW5rfSBpcyBub3QgeWV0IHN1cHBvcnRlZGApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbENoYW5uZWxzKHJhbmsgPSA2KTogc3RyaW5nW10ge1xuICByZXR1cm4gWyd4JywgJ3knLCAneicsICd3JywgJ3UnLCAndiddLnNsaWNlKDAsIHJhbmspO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge2dldEdsQ2hhbm5lbHN9IGZyb20gJy4uL3V0aWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZlY0NoYW5uZWxzKG5hbWU6IHN0cmluZywgcmFuazogbnVtYmVyKTogc3RyaW5nW10ge1xuICByZXR1cm4gZ2V0R2xDaGFubmVscyhyYW5rKS5tYXAoZCA9PiBgJHtuYW1lfS4ke2R9YCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGFubmVscyhuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gW25hbWVdO1xuICB9XG4gIHJldHVybiBnZXRWZWNDaGFubmVscyhuYW1lLCByYW5rKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVucGFja0Zyb21DaGFubmVsKCk6IHN0cmluZyB7XG4gIHJldHVybiBgXG4gICAgZmxvYXQgZ2V0Q2hhbm5lbCh2ZWM0IGZyYWcsIGludCBkaW0pIHtcbiAgICAgIGludCBtb2RDb29yZCA9IGltb2QoZGltLCAyKTtcbiAgICAgIHJldHVybiBtb2RDb29yZCA9PSAwID8gZnJhZy5yIDogZnJhZy5nO1xuICAgIH1cblxuICAgIGZsb2F0IGdldENoYW5uZWwodmVjNCBmcmFnLCB2ZWMyIGlubmVyRGltcykge1xuICAgICAgdmVjMiBtb2RDb29yZCA9IG1vZChpbm5lckRpbXMsIDIuKTtcbiAgICAgIHJldHVybiBtb2RDb29yZC54ID09IDAuID9cbiAgICAgICAgKG1vZENvb3JkLnkgPT0gMC4gPyBmcmFnLnIgOiBmcmFnLmcpIDpcbiAgICAgICAgKG1vZENvb3JkLnkgPT0gMC4gPyBmcmFnLmIgOiBmcmFnLmEpO1xuICAgIH1cbiAgYDtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge2dldEdsc2x9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7Z2V0Q29vcmRzRGF0YVR5cGV9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHtnZXRDaGFubmVsc30gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgcGFja1Byb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ3BhY2snLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkUmV2ZXJzZWRdXG59O1xuXG5jb25zdCBjcmVhdGVQYWNrUHJvZ3JhbUluZm8gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dC5kaW1zO1xuXG4gIGNvbnN0IGlucHV0UmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICAvLyBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVNoYXBlIHdvbid0IGNoYW5nZSBvdXRwdXQgcmFuay4gTmVlZCB0byB2ZXJpZnkgYnkgcnVubmluZyB0ZXN0c1xuICBjb25zdCBvdXRwdXRSYW5rID0gaW5wdXQuZGltcy5sZW5ndGg7XG5cbiAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShvdXRwdXRSYW5rKTtcbiAgY29uc3QgY2hhbm5lbHMgPSBnZXRDaGFubmVscygncmMnLCBvdXRwdXRSYW5rKTtcbiAgY29uc3Qgc2V0dXAgPSBnZXRTZXR1cChvdXRwdXRSYW5rLCBjaGFubmVscywgaW5wdXRTaGFwZVtpbnB1dFNoYXBlLmxlbmd0aCAtIDJdLCBpbnB1dFNoYXBlW2lucHV0U2hhcGUubGVuZ3RoIC0gMV0pO1xuXG4gIGxldCByZXZlcnNlZElucHV0V0g7XG4gIGlmIChpbnB1dFJhbmsgPT09IDApIHtcbiAgICByZXZlcnNlZElucHV0V0ggPSBbMSwgMV07XG4gIH0gZWxzZSBpZiAoaW5wdXRSYW5rID09PSAxKSB7XG4gICAgcmV2ZXJzZWRJbnB1dFdIID0gW2lucHV0U2hhcGVbMF0sIDFdO1xuICB9IGVsc2Uge1xuICAgIHJldmVyc2VkSW5wdXRXSCA9IFtpbnB1dFNoYXBlW291dHB1dFJhbmsgLSAxXSwgaW5wdXRTaGFwZVtvdXRwdXRSYW5rIC0gMl1dO1xuICB9XG4gIGNvbnN0IG91dE9mQm91bmRzQ29uZGl0aW9uID0gZ2V0T3V0T2ZCb3VuZHNDb25kaXRpb24ob3V0cHV0UmFuaywgcmV2ZXJzZWRJbnB1dFdILCBjaGFubmVscyk7XG4gIGNvbnN0IG91dHB1dCA9IGdldE91dHB1dChpbnB1dFNoYXBlLCBjaGFubmVscyk7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgJHtjb29yZHNEYXRhVHlwZX0gcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcblxuICAgICAgICAgIGlmKCR7b3V0T2ZCb3VuZHNDb25kaXRpb259KSB7XG4gICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQoMCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICR7c2V0dXB9XG5cbiAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNCgke291dHB1dH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgYDtcbiAgcmV0dXJuIHtcbiAgICAuLi5wYWNrUHJvZ3JhbU1ldGFkYXRhLFxuICAgIGhhc01haW46IHRydWUsXG4gICAgb3V0cHV0OiB7ZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZH0sXG4gICAgc2hhZGVyU291cmNlXG4gIH07XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja1Byb2dyYW1JbmZvTG9hZGVyID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvTG9hZGVyID0+XG4gICAgKHsuLi5wYWNrUHJvZ3JhbU1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tQcm9ncmFtSW5mbyhoYW5kbGVyLCBpbnB1dCl9KTtcblxuLyoqXG4gKiBjaGVjayBvdXRwdXQgY29vcmRpbmF0ZSBsb2NhdGlvbiBhbmQgcmV0dXJuIGZhbHNlIGlmIGl0IGlzIG91dHNpZGUgaW5wdXQncyB3aWR0aC9oZWlnaHQgYm91bmRhcnlcbiAqL1xuZnVuY3Rpb24gZ2V0T3V0T2ZCb3VuZHNDb25kaXRpb24ocmFuazogbnVtYmVyLCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGRpbXM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPT09IDApIHtcbiAgICByZXR1cm4gJ2ZhbHNlJztcbiAgfVxuICBpZiAocmFuayA9PT0gMSkge1xuICAgIHJldHVybiBgcmMgPiAke3NoYXBlWzBdfWA7XG4gIH1cblxuICBsZXQgY29uZCA9ICcnO1xuICBmb3IgKGxldCBpID0gcmFuayAtIDI7IGkgPCByYW5rOyBpKyspIHtcbiAgICBjb25kICs9IGAke2RpbXNbaV19ID49ICR7c2hhcGVbaSAtIHJhbmsgKyAyXX1gO1xuICAgIGlmIChpIDwgcmFuayAtIDEpIHtcbiAgICAgIGNvbmQgKz0gJ3x8JztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29uZDtcbn1cblxuLyoqXG4gKiBjb2RlIHNuaXBwZXQgdG8gc2FtcGxlIGlucHV0IHRleHR1cmUgd2l0aCBvdXRwdXQgY29vcmRpYW50ZXNcbiAqL1xuZnVuY3Rpb24gZ2V0T3V0cHV0KHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgZGltczogc3RyaW5nW10pOiBzdHJpbmcge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gIGlmIChyYW5rID09PSAwKSB7XG4gICAgcmV0dXJuICdnZXRBKCksIDAsIDAsIDAnO1xuICB9XG5cbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gYGdldEEocmMpLFxuICAgICAgICAgICAgcmMgKyAxID49ICR7c2hhcGVbMF19ID8gMC4gOiBnZXRBKHJjICsgMSksXG4gICAgICAgICAgICAwLCAwYDtcbiAgfVxuXG4gIGNvbnN0IGNvb3JkMDAgPSAnciwgYyc7XG4gIGNvbnN0IGNvb3JkMDEgPSAnciwgY3AxJztcbiAgY29uc3QgY29vcmQxMCA9ICdycDEsIGMnO1xuICBjb25zdCBjb29yZDExID0gJ3JwMSwgY3AxJztcbiAgbGV0IEQgPSAnJztcbiAgaWYgKHJhbmsgPiAyKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMjsgKytpKSB7XG4gICAgICBEID0gRCArIGAke2RpbXNbaV19LGA7XG4gICAgfVxuICB9XG4gIHJldHVybiBgZ2V0QSgke0R9JHtjb29yZDAwfSksXG4gICAgICAgICAgckVkZ2UgPyAwLiA6IGdldEEoJHtEfSR7Y29vcmQxMH0pLFxuICAgICAgICAgIGNFZGdlID8gMC4gOiBnZXRBKCR7RH0ke2Nvb3JkMDF9KSxcbiAgICAgICAgICByRWRnZSB8fCBjRWRnZSA/IDAuIDogZ2V0QSgke0R9JHtjb29yZDExfSlgO1xufVxuXG4vKipcbiAqIGNvZGUgc25pcHBldCB0byBzZXR1cCA0IGNvb3JkaW5hdGVzIGFuZCBlZGdlIGNvbmRpdGlvbnNcbiAqL1xuZnVuY3Rpb24gZ2V0U2V0dXAocmFuazogbnVtYmVyLCBkaW1zOiBzdHJpbmdbXSwgcm93czogbnVtYmVyLCBjb2xzOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAocmFuayA9PT0gMCB8fCByYW5rID09PSAxKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIC8vIHJhbmsgPj0gMiBmb3Igd2lkdGgraGVpZ2h0IHBhY2suXG4gIGVsc2Uge1xuICAgIGNvbnN0IHNldHVwID0gYFxuICAgIGludCByID0gJHtkaW1zW3JhbmsgLSAyXX07XG4gICAgaW50IGMgPSAke2RpbXNbcmFuayAtIDFdfTtcbiAgICBpbnQgcnAxID0gJHtkaW1zW3JhbmsgLSAyXX0gKyAxO1xuICAgIGludCBjcDEgPSAke2RpbXNbcmFuayAtIDFdfSArIDE7XG4gICAgYm9vbCByRWRnZSA9IHJwMSA+PSAke2NvbHN9O1xuICAgIGJvb2wgY0VkZ2UgPSBjcDEgPj0gJHtyb3dzfTtcbiAgICBgO1xuICAgIHJldHVybiBzZXR1cDtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7dW5wYWNrRnJvbUNoYW5uZWx9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1NZXRhZGF0YSA9IChvdXRwdXRTaGFwZTNEOiByZWFkb25seSBudW1iZXJbXSkgPT5cbiAgICAoe25hbWU6ICdSZXNoYXBlIChwYWNrZWQpJywgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnBhY2tlZF0sIGlucHV0TmFtZXM6IFsnQSddLCBjYWNoZUhpbnQ6IGAke291dHB1dFNoYXBlM0R9YH0pO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtSW5mbyA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQzRDogVGVuc29yLCBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLCBvdXRwdXRTaGFwZTNEOiByZWFkb25seSBudW1iZXJbXSk6XG4gICAgICAgIFByb2dyYW1JbmZvID0+IHtcbiAgICAgICAgICBjb25zdCBpbnB1dFNoYXBlM0QgPSBpbnB1dDNELmRpbXMgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAgICAgICAgIGNvbnN0IHNxdWVlemVkT3V0cHV0U2hhcGUgPSBvdXRwdXRTaGFwZTNEIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcblxuICAgICAgICAgIGxldCBtYWluTG9vcCA9ICcnO1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgb3V0cHV0Q29vcmRzID0gJyc7XG4gICAgICAgICAgICBzd2l0Y2ggKGkpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG91dHB1dENvb3JkcyA9ICdvdXRwdXRDb29yZHMgPSByYzsnO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgb3V0cHV0Q29vcmRzID0gJ291dHB1dENvb3JkcyA9IGl2ZWMzKHJjLngsIHJjLnkrMSwgcmMueik7JztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIG91dHB1dENvb3JkcyA9ICdvdXRwdXRDb29yZHMgPSBpdmVjMyhyYy54LCByYy55LCByYy56KzEpOyc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBvdXRwdXRDb29yZHMgPSAnb3V0cHV0Q29vcmRzID0gaXZlYzMocmMueCwgcmMueSsxLCByYy56KzEpOyc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG1haW5Mb29wICs9IGBcbiAgICAgICAgJHtvdXRwdXRDb29yZHN9XG4gICAgICAgICR7aSA+IDAgPyAnaWYob3V0cHV0Q29vcmRzLnkgPCByb3dzICYmIG91dHB1dENvb3Jkcy56IDwgY29scyl7JyA6ICcnfVxuICAgICAgICAgIGludCBmbGF0dGVuZWRJbmRleCA9IGdldEZsYXR0ZW5lZEluZGV4KG91dHB1dENvb3Jkcyk7XG5cbiAgICAgICAgICBpdmVjMyBpbnB1dFJDID0gaW5wdXRDb29yZHNGcm9tUmVzaGFwZWRPdXRDb29yZHMoZmxhdHRlbmVkSW5kZXgpO1xuICAgICAgICAgIHZlYzIgaW5uZXJEaW1zID0gdmVjMihmbG9hdChpbnB1dFJDLnkpLGZsb2F0KGlucHV0UkMueikpO1xuXG4gICAgICAgICAgcmVzdWx0WyR7aX1dID0gZ2V0Q2hhbm5lbChnZXRBKGlucHV0UkMueCwgaW5wdXRSQy55LCBpbnB1dFJDLnopLCBpbm5lckRpbXMpO1xuXG4gICAgICAgICR7aSA+IDAgPyAnfScgOiAnJ31cbiAgICAgIGA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICAgICAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7Z2V0UmVzaGFwZWRJbnB1dENvb3JkcyhpbnB1dFNoYXBlM0QpfVxuICAgICAgJHtnZXRGbGF0dGVuZWRJbmRleEZyb20zRChzcXVlZXplZE91dHB1dFNoYXBlKX1cbiAgICAgICR7dW5wYWNrRnJvbUNoYW5uZWwoKX1cblxuICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICBpdmVjMyByYyA9IGdldE91dHB1dENvb3JkcygpO1xuXG4gICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwLjApO1xuXG4gICAgICAgIGl2ZWMzIG91dHB1dENvb3JkcztcbiAgICAgICAgaW50IHJvd3MgPSAke3NxdWVlemVkT3V0cHV0U2hhcGVbMl19O1xuICAgICAgICBpbnQgY29scyA9ICR7c3F1ZWV6ZWRPdXRwdXRTaGFwZVsxXX07XG5cbiAgICAgICAgJHttYWluTG9vcH1cbiAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICB9XG4gICAgYDtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgICAgIG91dHB1dDoge2RpbXM6IHNxdWVlemVkT3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0M0QudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZH0sXG4gICAgICAgICAgICBzaGFkZXJTb3VyY2UsXG4gICAgICAgICAgICBoYXNNYWluOiB0cnVlXG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDNEOiBUZW5zb3IsIG91dHB1dFNoYXBlM0Q6IHJlYWRvbmx5IG51bWJlcltdKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVQYWNrZWRSZXNoYXBlM0RQcm9ncmFtTWV0YWRhdGEob3V0cHV0U2hhcGUzRCk7XG4gICAgICByZXR1cm4gey4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvKGhhbmRsZXIsIGlucHV0M0QsIG1ldGFkYXRhLCBvdXRwdXRTaGFwZTNEKX07XG4gICAgfTtcblxuZXhwb3J0IGZ1bmN0aW9uIHByb2Nlc3NEaW1zM0Qoc2hhcGU6IEFycmF5TGlrZTxudW1iZXI+KTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHtcbiAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbMSwgMSwgMV07XG4gIH1cbiAgLy8gVE9ETzogc3F1ZWV6ZSBvdGhlciBzaGFwZXMgdG8gMkQgY2FzZVxuICBsZXQgYmF0Y2ggPSAxO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNoYXBlLmxlbmd0aCAtIDI7ICsraSkge1xuICAgIGJhdGNoICo9IHNoYXBlW2ldO1xuICB9XG4gIHJldHVybiBbYmF0Y2gsIHNoYXBlLmxlbmd0aCA+IDEgPyBzaGFwZVtzaGFwZS5sZW5ndGggLSAyXSA6IDEsIHNoYXBlW3NoYXBlLmxlbmd0aCAtIDFdXTtcbn1cblxuLy8gRm9yIHBhY2tlZCByZXNoYXBlLCB3ZSBuZWVkIHRvIHJlLWFycmFuZ2UgdGV4ZWwgZGF0YSBmb3Igb3V0cHV0IHNoYXBlLlxuLy8gT3VyIHBhY2sgaXMgZGVzaWduZWQgdG8gcGFjayBhIDJ4MiB0aWxlIGluIGxhc3QgaCBhbmQgdyBkaW1lbnNpb24sIHNvXG4vLyBmb3IgdGhlIHJlc2hhcGVkIG5ldyB0ZW5zb3IsIHdlIGp1c3QgbmVlZCB0byByZS1hcnJhbmdlIHRoZSBsYXN0IGggYW5kXG4vLyB3IGRpbWVuc2lvbi4gRm9yIGFueSBzaGFwZSB0aGF0IGlzIG5vdCBpbiAzRCwgaS5lLiBbYmF0Y2gsIFcsIEhdLCB3ZVxuLy8gZmlyc3QgY29udmVydCBpdCB0byAzRCBieSBjb2xsYXBzaW5nIG90aGVyIGRpbWVuc2lvbiB0byBiYXRjaCBkaW0sIHRoZW5cbi8vIHByb2Nlc3Mgd2l0aCB0aGUgbGFzdCB0d28gZGltZW5zaW9ucy5cbi8vIE5vdGU6IHdlIG9ubHkgbmVlZCB0aGUgc2hhcGUgdGVuc29yIHRvIGNhbGN1bGF0ZSBvdXRwdXQgc2hhcGUsIHNvIHRoZVxuLy8gY29udGVudCBpbiBzaGFwZSB0ZW5zb3IgaXMgbmV2ZXIgdXBsb2FkZWQgdG8gR1BVLiBJdCBpcyBhbHdheXMga2VwdCBpbiBDUFUuXG4vLyBUT0RPOiBvcHRpbWl6ZSB0aGUgYWxnb3JpdGhtIC0tIGluIHNvbWUgY2FzZXMsIGlmIHRoZSBsYXN0IHR3byBkaW1zIGFyZVxuLy8gdGhlIHNhbWUgYmV0d2VlbiBpbnB1dCBzaGFwZSBhbmQgb3V0cHV0IHNoYXBlLCB0aGUgcGFja2VkIHJlc2hhcGUgY2FuIGJlXG4vLyB0cmVhdGVkIGFzIG5vLW9wLlxuZXhwb3J0IGZ1bmN0aW9uIGlzUmVzaGFwZUNoZWFwKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCByZXNoYXBlZERpbXM6IHJlYWRvbmx5IG51bWJlcltdKSB7XG4gIGxldCBpc0NoZWFwUmVzaGFwZSA9IGZhbHNlO1xuICBpZiAoZGltcy5sZW5ndGggPT09IDAgfHwgcmVzaGFwZWREaW1zLmxlbmd0aCA9PT0gMCkgeyAgLy8gc2NhbGFyXG4gICAgaXNDaGVhcFJlc2hhcGUgPSB0cnVlO1xuICB9IGVsc2UgaWYgKGRpbXMubGVuZ3RoIDwgMiB8fCByZXNoYXBlZERpbXMubGVuZ3RoIDwgMikgeyAgLy8gMURcbiAgICBpc0NoZWFwUmVzaGFwZSA9IGRpbXNbZGltcy5sZW5ndGggLSAxXSA9PT0gcmVzaGFwZWREaW1zW3Jlc2hhcGVkRGltcy5sZW5ndGggLSAxXTtcbiAgfSBlbHNlIHsgIC8vIDJEICtcbiAgICBpc0NoZWFwUmVzaGFwZSA9IGRpbXNbZGltcy5sZW5ndGggLSAxXSA9PT0gcmVzaGFwZWREaW1zW3Jlc2hhcGVkRGltcy5sZW5ndGggLSAxXSAmJlxuICAgICAgICBkaW1zW2RpbXMubGVuZ3RoIC0gMl0gPT09IHJlc2hhcGVkRGltc1tyZXNoYXBlZERpbXMubGVuZ3RoIC0gMl07XG4gIH1cblxuICByZXR1cm4gaXNDaGVhcFJlc2hhcGU7XG59XG5cbmZ1bmN0aW9uIGdldFJlc2hhcGVkSW5wdXRDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSk6IHN0cmluZyB7XG4gIGNvbnN0IHN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoc2hhcGUpO1xuICBjb25zdCBjb29yZHMgPSBbJ2InLCAncicsICdjJ107XG4gIGNvbnN0IGluZGV4ID0gJ2luZGV4JztcbiAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9IHN0cmlkZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1tpXX0gPSAke2luZGV4fSAvICR7c3RyaWRlfWA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsaW5lMiA9IGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYGludCAke2Nvb3Jkc1tpICsgMV19ID0gJHtpbmRleH0gLSAke2Nvb3Jkc1tpXX0gKiAke3N0cmlkZX1gIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgaW5kZXggLT0gJHtjb29yZHNbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuam9pbignJyk7XG5cbiAgcmV0dXJuIGBcbiAgICBpdmVjMyBpbnB1dENvb3Jkc0Zyb21SZXNoYXBlZE91dENvb3JkcyhpbnQgaW5kZXgpIHtcbiAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgIHJldHVybiBpdmVjMyhiLCByLCBjKTtcbiAgICB9XG4gIGA7XG59XG5cbmZ1bmN0aW9uIGdldEZsYXR0ZW5lZEluZGV4RnJvbTNEKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pOiBzdHJpbmcge1xuICBjb25zdCBzdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHNoYXBlKTtcblxuICByZXR1cm4gYFxuICBpbnQgZ2V0RmxhdHRlbmVkSW5kZXgoaXZlYzMgY29vcmRzKSB7XG4gICAgLy8gcmV2ZXJzZSB5LCB6IG9yZGVyXG4gICAgcmV0dXJuIGNvb3Jkcy54ICogJHtzdHJpZGVzWzBdfSArIGNvb3Jkcy56ICogJHtzdHJpZGVzWzFdfSArIGNvb3Jkcy55O1xuICB9XG5gO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge2dldEdsc2x9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1RleHR1cmVEYXRhLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3QgZW5jb2RlQXNVaW50OCA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZXh0dXJlRGF0YSk6IFRleHR1cmVEYXRhID0+IHtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dC5zaGFwZTtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAvKipcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL3RlbnNvcmZsb3cvdGZqcy1jb3JlL2Jsb2IvbWFzdGVyL3NyYy9rZXJuZWxzL3dlYmdsL2VuY29kZV9mbG9hdF9ncHUudHNcbiAgICovXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICBjb25zdCBmbG9hdCBGTE9BVF9NQVggPSAxLjcwMTQxMTg0ZTM4O1xuICAgIGNvbnN0IGZsb2F0IEZMT0FUX01JTiA9IDEuMTc1NDk0MzVlLTM4O1xuXG4gICAgYm9vbCBpc05hTihmbG9hdCB2YWwpIHtcbiAgICAgIHJldHVybiAodmFsIDwgMS4wIHx8IDAuMCA8IHZhbCB8fCB2YWwgPT0gMC4wKSA/IGZhbHNlIDogdHJ1ZTtcbiAgICB9XG5cbiAgICBoaWdocCB2ZWM0IGVuY29kZUFzVWludDgoaGlnaHAgZmxvYXQgdikge1xuICAgICAgaWYgKGlzTmFOKHYpKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KDI1NSwgMjU1LCAyNTUsIDI1NSk7XG4gICAgICB9XG5cbiAgICAgIGhpZ2hwIGZsb2F0IGF2ID0gYWJzKHYpO1xuXG4gICAgICBpZihhdiA8IEZMT0FUX01JTikge1xuICAgICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjApO1xuICAgICAgfSBlbHNlIGlmKHYgPiBGTE9BVF9NQVgpIHtcbiAgICAgICAgcmV0dXJuIHZlYzQoMC4wLCAwLjAsIDEyOC4wLCAxMjcuMCkgLyAyNTUuMDtcbiAgICAgIH0gZWxzZSBpZih2IDwgLUZMT0FUX01BWCkge1xuICAgICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgIDEyOC4wLCAyNTUuMCkgLyAyNTUuMDtcbiAgICAgIH1cblxuICAgICAgaGlnaHAgdmVjNCBjID0gdmVjNCgwLDAsMCwwKTtcblxuICAgICAgaGlnaHAgZmxvYXQgZSA9IGZsb29yKGxvZzIoYXYpKTtcbiAgICAgIGhpZ2hwIGZsb2F0IG0gPSBleHAyKGZyYWN0KGxvZzIoYXYpKSkgLSAxLjA7XG5cbiAgICAgIGNbMl0gPSBmbG9vcigxMjguMCAqIG0pO1xuICAgICAgbSAtPSBjWzJdIC8gMTI4LjA7XG4gICAgICBjWzFdID0gZmxvb3IoMzI3NjguMCAqIG0pO1xuICAgICAgbSAtPSBjWzFdIC8gMzI3NjguMDtcbiAgICAgIGNbMF0gPSBmbG9vcig4Mzg4NjA4LjAgKiBtKTtcblxuICAgICAgaGlnaHAgZmxvYXQgZWJpYXMgPSBlICsgMTI3LjA7XG4gICAgICBjWzNdID0gZmxvb3IoZWJpYXMgLyAyLjApO1xuICAgICAgZWJpYXMgLT0gY1szXSAqIDIuMDtcbiAgICAgIGNbMl0gKz0gZmxvb3IoZWJpYXMpICogMTI4LjA7XG5cbiAgICAgIGNbM10gKz0gMTI4LjAgKiBzdGVwKDAuMCwgLXYpO1xuXG4gICAgICByZXR1cm4gYyAvIDI1NS4wO1xuICAgIH1cblxuICAgIHZvaWQgbWFpbigpIHtcbiAgICAgIGZsb2F0IHZhbHVlID0gJHtnbHNsLnRleHR1cmUyRH0oWCxUZXhDb29yZHMpLnI7XG4gICAgICAke2dsc2wub3V0cHV0fSA9IGVuY29kZUFzVWludDgodmFsdWUpO1xuICAgIH1gO1xuICBjb25zdCBwcm9ncmFtSW5mbyA9IHtcbiAgICBuYW1lOiAnVWludDhFbmNvZGUnLFxuICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgaW5wdXROYW1lczogWydYJ10sXG4gICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnRlbnNvci50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUuZG93bmxvYWRVaW50OEFzRmxvYXR9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgICBoYXNNYWluOiB0cnVlXG4gIH07XG4gIHJldHVybiBpbmZlcmVuY2VIYW5kbGVyLmV4ZWN1dGVQcm9ncmFtKHByb2dyYW1JbmZvLCBbaW5wdXQudGVuc29yXSk7XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHtnZXRDb29yZHNEYXRhVHlwZX0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQge2dldENoYW5uZWxzLCB1bnBhY2tGcm9tQ2hhbm5lbH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgdW5wYWNrUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAndW5wYWNrJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS5wYWNrZWRdXG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVW5wYWNrUHJvZ3JhbUluZm8gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCByYW5rID0gaW5wdXQuZGltcy5sZW5ndGg7XG5cbiAgY29uc3QgY2hhbm5lbHMgPSBnZXRDaGFubmVscygncmMnLCByYW5rKTtcbiAgY29uc3QgaW5uZXJEaW1zID0gY2hhbm5lbHMuc2xpY2UoLTIpO1xuICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKHJhbmspO1xuICBjb25zdCB1bnBhY2tDaGFubmVsID0gdW5wYWNrRnJvbUNoYW5uZWwoKTtcbiAgY29uc3QgaXNTY2FsYXIgPSAoaW5wdXQuZGltcy5sZW5ndGggPT09IDApO1xuICBjb25zdCBzb3VyY2VDb29yZHMgPSBpc1NjYWxhciA/ICcnIDogZ2V0U291cmNlQ29vcmRzKHJhbmssIGNoYW5uZWxzKTtcbiAgY29uc3QgY29vcmRzID0gcmFuayA8PSAxID8gJ3JjJyA6IGB2ZWMyKCR7aW5uZXJEaW1zLmpvaW4oJywnKX0pYDtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgJHt1bnBhY2tDaGFubmVsfVxuICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICR7Y29vcmRzRGF0YVR5cGV9IHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAvLyBTYW1wbGUgdGhlIHRleHR1cmUgd2l0aCB0aGUgY29vcmRzIHRvIGdldCB0aGUgcmdiYSBjaGFubmVsIHZhbHVlLlxuICAgICAgIHZlYzQgcGFja2VkSW5wdXQgPSBnZXRBKCR7c291cmNlQ29vcmRzfSk7XG5cbiAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQoZ2V0Q2hhbm5lbChwYWNrZWRJbnB1dCwgJHtjb29yZHN9KSwgMCwgMCwgMCk7XG4gICAgIH1cbiAgIGA7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi51bnBhY2tQcm9ncmFtTWV0YWRhdGEsXG4gICAgaGFzTWFpbjogdHJ1ZSxcbiAgICBvdXRwdXQ6IHtkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgIHNoYWRlclNvdXJjZVxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvTG9hZGVyID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvTG9hZGVyID0+XG4gICAgKHsuLi51bnBhY2tQcm9ncmFtTWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrUHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXQpfSk7XG5cbmZ1bmN0aW9uIGdldFNvdXJjZUNvb3JkcyhyYW5rOiBudW1iZXIsIGRpbXM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gJ3JjJztcbiAgfVxuXG4gIGxldCBjb29yZHMgPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyBpKyspIHtcbiAgICBjb29yZHMgKz0gZGltc1tpXTtcbiAgICBpZiAoaSA8IHJhbmsgLSAxKSB7XG4gICAgICBjb29yZHMgKz0gJywnO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY29vcmRzO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0xvZ2dlcn0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBFbmNvZGVyIHtcbiAgZXhwb3J0IGludGVyZmFjZSBEYXRhVHlwZU1hcCB7XG4gICAgZmxvYXQ6IEZsb2F0MzJBcnJheTtcbiAgICBieXRlOiBVaW50OEFycmF5O1xuICAgIGludDogVWludDMyQXJyYXk7XG4gIH1cbiAgZXhwb3J0IHR5cGUgRGF0YVR5cGUgPSBrZXlvZiBEYXRhVHlwZU1hcDtcbiAgdHlwZSBEYXRhQXJyYXlUeXBlID0gRGF0YVR5cGVNYXBbRGF0YVR5cGVdO1xufVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cbmV4cG9ydCBjb25zdCBlbnVtIEVuY29kZXJVc2FnZSB7XG4gIERlZmF1bHQgPSAwLFxuICBVcGxvYWRPbmx5LFxuICBEb3dubG9hZDRCeXRlc0FzRmxvYXQzMixcbn1cbi8qIGVzbGludC1lbmFibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXG5cbi8qKlxuICogQWJzdHJhY3Rpb24gZm9yIG1hcHBpbmcgZGF0YSB0eXBlcyB0byB0ZXh0dXJlIHRleGxldHNcbiAqIEVuY29kaW5nIG1lYW5zIGhvdyBhIEZsb2F0MzIgaXMgbWFwcGVkIHRvIDEgb3IgNCBjaGFubmVscyBmb3IgZWFjaCB0ZXhsZXRcbiAqIERlY29kaW5nIG1lYW5zIGhvdyBhIHRleGxldCdzIGNoYW5uZWxzIGFyZSBtYXBwZWQgdG8gYSByZXN1bHRpbmcgRmxvYXQzMlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFFbmNvZGVyIHtcbiAgaW50ZXJuYWxGb3JtYXQ6IG51bWJlcjtcbiAgZm9ybWF0OiBudW1iZXI7XG4gIHRleHR1cmVUeXBlOiBudW1iZXI7XG4gIGNoYW5uZWxTaXplOiBudW1iZXI7XG4gIGVuY29kZShzcmM6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgdGV4dHVyZVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZTtcbiAgYWxsb2NhdGUoc2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlO1xuICBkZWNvZGUoYnVmZmVyOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUsIGRhdGFTaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGU7XG59XG4vKipcbiAqIFdlYkdMMiBkYXRhIGVuY29kZXJcbiAqIFVzZXMgUjMyRiBhcyB0aGUgZm9ybWF0IGZvciB0ZXhsZXRcbiAqL1xuZXhwb3J0IGNsYXNzIFJlZEZsb2F0MzJEYXRhRW5jb2RlciBpbXBsZW1lbnRzIERhdGFFbmNvZGVyIHtcbiAgaW50ZXJuYWxGb3JtYXQ6IG51bWJlcjtcbiAgZm9ybWF0OiBudW1iZXI7XG4gIHRleHR1cmVUeXBlOiBudW1iZXI7XG4gIGNoYW5uZWxTaXplOiBudW1iZXI7XG4gIGNvbnN0cnVjdG9yKGdsOiBXZWJHTDJSZW5kZXJpbmdDb250ZXh0LCBjaGFubmVscyA9IDEpIHtcbiAgICBpZiAoY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SMzJGO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5SRUQ7XG4gICAgICB0aGlzLnRleHR1cmVUeXBlID0gZ2wuRkxPQVQ7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIGlmIChjaGFubmVscyA9PT0gNCkge1xuICAgICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLlJHQkEzMkY7XG4gICAgICB0aGlzLmZvcm1hdCA9IGdsLlJHQkE7XG4gICAgICB0aGlzLnRleHR1cmVUeXBlID0gZ2wuRkxPQVQ7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgb2YgY2hhbm5lbHM6ICR7Y2hhbm5lbHN9YCk7XG4gICAgfVxuICB9XG4gIGVuY29kZShzcmM6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgdGV4dHVyZVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgbGV0IHJlc3VsdDogRmxvYXQzMkFycmF5O1xuICAgIGxldCBzb3VyY2U6IEZsb2F0MzJBcnJheTtcbiAgICBpZiAoc3JjLmNvbnN0cnVjdG9yICE9PSBGbG9hdDMyQXJyYXkpIHtcbiAgICAgIExvZ2dlci53YXJuaW5nKCdFbmNvZGVyJywgJ2RhdGEgd2FzIG5vdCBvZiB0eXBlIEZsb2F0MzI7IGNyZWF0aW5nIG5ldyBGbG9hdDMyQXJyYXknKTtcbiAgICAgIHNvdXJjZSA9IG5ldyBGbG9hdDMyQXJyYXkoc3JjKTtcbiAgICB9XG4gICAgaWYgKHRleHR1cmVTaXplICogdGhpcy5jaGFubmVsU2l6ZSA+IHNyYy5sZW5ndGgpIHtcbiAgICAgIExvZ2dlci53YXJuaW5nKCdFbmNvZGVyJywgJ1NvdXJjZSBkYXRhIHRvbyBzbWFsbC4gQWxsb2NhdGluZyBsYXJnZXIgYXJyYXknKTtcbiAgICAgIHNvdXJjZSA9IHNyYyBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICByZXN1bHQgPSB0aGlzLmFsbG9jYXRlKHRleHR1cmVTaXplICogdGhpcy5jaGFubmVsU2l6ZSkgYXMgRmxvYXQzMkFycmF5O1xuICAgICAgc291cmNlLmZvckVhY2goKHYsIGkpID0+IHJlc3VsdFtpXSA9IHYpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzb3VyY2UgPSBzcmMgYXMgRmxvYXQzMkFycmF5O1xuICAgICAgcmVzdWx0ID0gc291cmNlO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGFsbG9jYXRlKHNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoc2l6ZSAqIDQpO1xuICB9XG4gIGRlY29kZShidWZmZXI6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgZGF0YVNpemU6IG51bWJlcik6IEZsb2F0MzJBcnJheSB7XG4gICAgaWYgKHRoaXMuY2hhbm5lbFNpemUgPT09IDEpIHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IChidWZmZXIgYXMgRmxvYXQzMkFycmF5KS5maWx0ZXIoKF92YWx1ZSwgaW5kZXgpID0+IGluZGV4ICUgNCA9PT0gMCkuc3ViYXJyYXkoMCwgZGF0YVNpemUpO1xuICAgICAgcmV0dXJuIGZpbHRlcmVkRGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1ZmZlci5zdWJhcnJheSgwLCBkYXRhU2l6ZSkgYXMgRmxvYXQzMkFycmF5O1xuICB9XG59XG4vKipcbiAqIERhdGEgZW5jb2RlciBmb3IgV2ViR0wgMSB3aXRoIHN1cHBvcnQgZm9yIGZsb2F0aW5nIHBvaW50IHRleHR1cmVcbiAqL1xuZXhwb3J0IGNsYXNzIFJHQkFGbG9hdERhdGFFbmNvZGVyIGltcGxlbWVudHMgRGF0YUVuY29kZXIge1xuICBpbnRlcm5hbEZvcm1hdDogbnVtYmVyO1xuICBmb3JtYXQ6IG51bWJlcjtcbiAgdGV4dHVyZVR5cGU6IG51bWJlcjtcbiAgY2hhbm5lbFNpemU6IG51bWJlcjtcbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgY2hhbm5lbHMgPSAxLCB0ZXh0dXJlVHlwZT86IG51bWJlcikge1xuICAgIGlmIChjaGFubmVscyAhPT0gMSAmJiBjaGFubmVscyAhPT0gNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG51bWJlciBvZiBjaGFubmVsczogJHtjaGFubmVsc31gKTtcbiAgICB9XG4gICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLlJHQkE7XG4gICAgdGhpcy5mb3JtYXQgPSBnbC5SR0JBO1xuICAgIHRoaXMuY2hhbm5lbFNpemUgPSBjaGFubmVscztcbiAgICB0aGlzLnRleHR1cmVUeXBlID0gdGV4dHVyZVR5cGUgfHwgZ2wuRkxPQVQ7XG4gIH1cbiAgZW5jb2RlKHNyYzogRmxvYXQzMkFycmF5LCB0ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICBsZXQgZGVzdCA9IHNyYztcbiAgICBpZiAodGhpcy5jaGFubmVsU2l6ZSA9PT0gMSkge1xuICAgICAgTG9nZ2VyLnZlcmJvc2UoJ0VuY29kZXInLCAnRXhwbG9kaW5nIGludG8gYSBsYXJnZXIgYXJyYXknKTtcbiAgICAgIGRlc3QgPSB0aGlzLmFsbG9jYXRlKHRleHR1cmVTaXplKSBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICBzcmMuZm9yRWFjaCgodiwgaSkgPT4gZGVzdFtpICogNF0gPSB2KTtcbiAgICB9XG4gICAgcmV0dXJuIGRlc3Q7XG4gIH1cbiAgYWxsb2NhdGUoc2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShzaXplICogNCk7XG4gIH1cbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogRmxvYXQzMkFycmF5IHtcbiAgICBpZiAodGhpcy5jaGFubmVsU2l6ZSA9PT0gMSkge1xuICAgICAgY29uc3QgZmlsdGVyZWREYXRhID0gKGJ1ZmZlciBhcyBGbG9hdDMyQXJyYXkpLmZpbHRlcigoX3ZhbHVlLCBpbmRleCkgPT4gaW5kZXggJSA0ID09PSAwKS5zdWJhcnJheSgwLCBkYXRhU2l6ZSk7XG4gICAgICByZXR1cm4gZmlsdGVyZWREYXRhO1xuICAgIH1cbiAgICByZXR1cm4gYnVmZmVyLnN1YmFycmF5KDAsIGRhdGFTaXplKSBhcyBGbG9hdDMyQXJyYXk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFVpbnQ4RGF0YUVuY29kZXIgaW1wbGVtZW50cyBEYXRhRW5jb2RlciB7XG4gIGludGVybmFsRm9ybWF0OiBudW1iZXI7XG4gIGZvcm1hdDogbnVtYmVyO1xuICB0ZXh0dXJlVHlwZTogbnVtYmVyO1xuICBjaGFubmVsU2l6ZSA9IDQ7XG4gIGNvbnN0cnVjdG9yKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIGNoYW5uZWxzID0gMSkge1xuICAgIGlmIChjaGFubmVscyA9PT0gMSkge1xuICAgICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLkFMUEhBO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5BTFBIQTsgIC8vIG5vdCB0ZXN0ZWRcbiAgICAgIHRoaXMudGV4dHVyZVR5cGUgPSBnbC5VTlNJR05FRF9CWVRFO1xuICAgICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIH0gZWxzZSBpZiAoY2hhbm5lbHMgPT09IDQpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SR0JBO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5SR0JBO1xuICAgICAgdGhpcy50ZXh0dXJlVHlwZSA9IGdsLlVOU0lHTkVEX0JZVEU7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgb2YgY2hhbm5lbHM6ICR7Y2hhbm5lbHN9YCk7XG4gICAgfVxuICB9XG4gIGVuY29kZShzcmM6IFVpbnQ4QXJyYXksIF90ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc3JjLmJ1ZmZlciwgc3JjLmJ5dGVPZmZzZXQsIHNyYy5ieXRlTGVuZ3RoKTtcbiAgfVxuICBhbGxvY2F0ZShzaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShzaXplICogdGhpcy5jaGFubmVsU2l6ZSk7XG4gIH1cbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogVWludDhBcnJheSB7XG4gICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgIHJldHVybiBidWZmZXIuc3ViYXJyYXkoMCwgZGF0YVNpemUpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXJyYXkgdHlwZTogJHtidWZmZXIuY29uc3RydWN0b3J9YCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtTaGFwZVV0aWx9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5pbXBvcnQge1RleHR1cmVMYXlvdXRTdHJhdGVneSwgV2lkdGhIZWlnaHRQcmVmc30gZnJvbSAnLi90ZXh0dXJlLWxheW91dC1zdHJhdGVneSc7XG5pbXBvcnQge1RleHR1cmVMYXlvdXQsIFRleHR1cmVUeXBlfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUgPVxuICAgICh0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgICB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUpOiBUZXh0dXJlTGF5b3V0ID0+IHtcbiAgICAgIGNvbnN0IGNoYW5uZWwgPSAodGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnVucGFja2VkIHx8IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS51bnBhY2tlZFJldmVyc2VkKSA/IDEgOiA0O1xuICAgICAgY29uc3QgaXNQYWNrZWQgPSB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkO1xuICAgICAgY29uc3QgcmV2ZXJzZVdIID0gKHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS51bnBhY2tlZFJldmVyc2VkIHx8IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpO1xuICAgICAgY29uc3QgYnJlYWtBeGlzID0gdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24gPyBzaGFwZS5sZW5ndGggLSAxIDogdW5kZWZpbmVkO1xuICAgICAgY29uc3QgdW5wYWNrZWRTaGFwZSA9IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uID9cbiAgICAgICAgICBzaGFwZS5tYXAoKGQsIGkpID0+IGkgPT09IHNoYXBlLmxlbmd0aCAtIDEgPyBkICogNCA6IGQpIDpcbiAgICAgICAgICB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZShcbiAgICAgICAgICB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3ksIHNoYXBlLCBjaGFubmVsLCB1bnBhY2tlZFNoYXBlLCB7aXNQYWNrZWQsIHJldmVyc2VXSCwgYnJlYWtBeGlzfSk7XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodCA9XG4gICAgKHRleHR1cmVMYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5LCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZSk6XG4gICAgICAgIFtudW1iZXIsIG51bWJlcl0gPT4ge1xuICAgICAgICAgIGNvbnN0IGxheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUodGV4dHVyZUxheW91dFN0cmF0ZWd5LCBzaGFwZSwgdGV4dHVyZVR5cGUpO1xuICAgICAgICAgIHJldHVybiBbbGF5b3V0LndpZHRoLCBsYXlvdXQuaGVpZ2h0XTtcbiAgICAgICAgfTtcblxuLyoqXG4gKiBDcmVhdGUgYSBUZXh0dXJlTGF5b3V0IG9iamVjdCBmcm9tIHNoYXBlLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZSA9XG4gICAgKHRleHR1cmVMYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5LCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGNoYW5uZWxzOiAxfDQgPSAxLFxuICAgICB1bnBhY2tlZFNoYXBlPzogcmVhZG9ubHkgbnVtYmVyW10sIHByZWZzPzogV2lkdGhIZWlnaHRQcmVmcyk6IFRleHR1cmVMYXlvdXQgPT4ge1xuICAgICAgY29uc3QgaXNQYWNrZWQgPSAhIShwcmVmcyAmJiBwcmVmcy5pc1BhY2tlZCk7XG4gICAgICBjb25zdCBbd2lkdGgsIGhlaWdodF0gPSB0ZXh0dXJlTGF5b3V0U3RyYXRlZ3kuY29tcHV0ZVRleHR1cmVXSChpc1BhY2tlZCA/IHVucGFja2VkU2hhcGUgfHwgc2hhcGUgOiBzaGFwZSwgcHJlZnMpO1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGxldCBpbmZlcnJlZERpbXMgPSBzaGFwZS5zbGljZSgwKTtcbiAgICAgIGlmIChyYW5rID09PSAwKSB7XG4gICAgICAgIGluZmVycmVkRGltcyA9IFsxXTtcbiAgICAgIH1cbiAgICAgIGlmIChjaGFubmVscyA9PT0gMSkge1xuICAgICAgICAvLyB1bnBhY2tlZFNoYXBlIHdpbGwgdGFrZSBgc2hhcGVgIGFuZCBub3QgYGluZmVycmVkRGltc2Agc28gYXMgdG8gY3JlYXRlIGEgc2NhbGFyIFRlbnNvciBpZiBuZWVkIGJlXG4gICAgICAgIHVucGFja2VkU2hhcGUgPSBzaGFwZTtcbiAgICAgIH0gZWxzZSBpZiAoaXNQYWNrZWQpIHtcbiAgICAgICAgaWYgKGNoYW5uZWxzICE9PSA0KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhIHBhY2tlZCB0ZXh0dXJlIG11c3QgYmUgNC1jaGFubmVsJyk7XG4gICAgICAgIH1cbiAgICAgICAgdW5wYWNrZWRTaGFwZSA9IHNoYXBlO1xuICAgICAgICBpZiAocmFuayA+IDApIHtcbiAgICAgICAgICBpbmZlcnJlZERpbXNbcmFuayAtIDFdID0gTWF0aC5jZWlsKGluZmVycmVkRGltc1tyYW5rIC0gMV0gLyAyKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmFuayA+IDEpIHtcbiAgICAgICAgICBpbmZlcnJlZERpbXNbcmFuayAtIDJdID0gTWF0aC5jZWlsKGluZmVycmVkRGltc1tyYW5rIC0gMl0gLyAyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghdW5wYWNrZWRTaGFwZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VucGFja2VkIHNoYXBlIGlzIG5lZWRlZCB3aGVuIHVzaW5nIGNoYW5uZWxzID4gMScpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgd2lkdGgsXG4gICAgICAgIGhlaWdodCxcbiAgICAgICAgY2hhbm5lbHMsXG4gICAgICAgIGlzUGFja2VkLFxuICAgICAgICBzaGFwZTogaW5mZXJyZWREaW1zLFxuICAgICAgICBzdHJpZGVzOiBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoaW5mZXJyZWREaW1zKSxcbiAgICAgICAgdW5wYWNrZWRTaGFwZSxcbiAgICAgICAgcmV2ZXJzZWRXSDogKHByZWZzICYmIHByZWZzLnJldmVyc2VXSClcbiAgICAgIH07XG4gICAgfTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtTaGFwZVV0aWx9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5pbXBvcnQge2NyZWF0ZVBhY2tQcm9ncmFtSW5mb0xvYWRlcn0gZnJvbSAnLi9vcHMvcGFjayc7XG5pbXBvcnQge2NyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvTG9hZGVyLCBpc1Jlc2hhcGVDaGVhcCwgcHJvY2Vzc0RpbXMzRH0gZnJvbSAnLi9vcHMvcmVzaGFwZS1wYWNrZWQnO1xuaW1wb3J0IHtlbmNvZGVBc1VpbnQ4fSBmcm9tICcuL29wcy91aW50OC1lbmNvZGUnO1xuaW1wb3J0IHtjcmVhdGVVbnBhY2tQcm9ncmFtSW5mb0xvYWRlcn0gZnJvbSAnLi9vcHMvdW5wYWNrJztcbmltcG9ydCB7V2ViR0xTZXNzaW9uSGFuZGxlcn0gZnJvbSAnLi9zZXNzaW9uLWhhbmRsZXInO1xuaW1wb3J0IHtFbmNvZGVyVXNhZ2V9IGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHtjYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQsIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUsIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGV9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQnO1xuaW1wb3J0IHtBcnRpZmFjdCwgUHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBUZXh0dXJlRGF0YSwgVGV4dHVyZUxheW91dCwgVGV4dHVyZVR5cGV9IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBnZXRQcm9ncmFtSW5mb1VuaXF1ZUtleSA9XG4gICAgKHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mb3xQcm9ncmFtSW5mb0xvYWRlciwgaW5wdXRUZXh0dXJlRGF0YXM6IFRleHR1cmVEYXRhW10pOiBzdHJpbmcgPT4ge1xuICAgICAgY29uc3QgaW5wdXRzID1cbiAgICAgICAgICBpbnB1dFRleHR1cmVEYXRhcy5tYXAodGV4dHVyZSA9PiBgJHt0ZXh0dXJlLnVucGFja2VkU2hhcGUuam9pbignLCcpfTske3RleHR1cmUud2lkdGh9eCR7dGV4dHVyZS5oZWlnaHR9YClcbiAgICAgICAgICAgICAgLmpvaW4oJ18nKTtcbiAgICAgIGxldCBrZXkgPSBwcm9ncmFtSW5mby5uYW1lO1xuICAgICAgaWYgKHByb2dyYW1JbmZvLmNhY2hlSGludCkge1xuICAgICAgICBrZXkgKz0gJ1snICsgcHJvZ3JhbUluZm8uY2FjaGVIaW50ICsgJ10nO1xuICAgICAgfVxuICAgICAga2V5ICs9ICc6JyArIGlucHV0cztcbiAgICAgIHJldHVybiBrZXk7XG4gICAgfTtcblxuZXhwb3J0IGNsYXNzIFdlYkdMSW5mZXJlbmNlSGFuZGxlciBpbXBsZW1lbnRzIEluZmVyZW5jZUhhbmRsZXIge1xuICBwcml2YXRlIHBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgcHJpdmF0ZSB1bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgY29uc3RydWN0b3IocHVibGljIHNlc3Npb246IFdlYkdMU2Vzc2lvbkhhbmRsZXIpIHtcbiAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMgW3dpZHRoLCBoZWlnaHRdXG4gICAqL1xuICBjYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICByZXR1cm4gY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KHRoaXMuc2Vzc2lvbi5sYXlvdXRTdHJhdGVneSwgc2hhcGUsIHRleHR1cmVUeXBlKTtcbiAgfVxuXG4gIGV4ZWN1dGVQcm9ncmFtKHByb2dyYW06IFByb2dyYW1JbmZvfFByb2dyYW1JbmZvTG9hZGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdKTogVGV4dHVyZURhdGEge1xuICAgIGlmIChpbnB1dHMubGVuZ3RoIDwgcHJvZ3JhbS5pbnB1dE5hbWVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnB1dCBzaXplIG11c3RuJ3QgYmUgbGVzcyB0aGFuICR7cHJvZ3JhbS5pbnB1dE5hbWVzLmxlbmd0aH0uYCk7XG4gICAgfVxuICAgIGlmIChwcm9ncmFtLmlucHV0TmFtZXMubGVuZ3RoICE9PSBwcm9ncmFtLmlucHV0VHlwZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IG5hbWVzIHNpemUgZG9lcyBub3QgbWF0Y2ggaW5wdXQgdHlwZXMnKTtcbiAgICB9XG5cbiAgICAvLyBjcmVhdGUgdGV4dHVyZSBpbmZvIGZvciBpbnB1dFxuICAgIGNvbnN0IGlucHV0VGV4dHVyZURhdGFzOiBUZXh0dXJlRGF0YVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm9ncmFtLmlucHV0TmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlucHV0VGV4dHVyZURhdGFzW2ldID0gdGhpcy5nZXRPckNyZWF0ZVRleHR1cmVEYXRhKGlucHV0c1tpXSwgcHJvZ3JhbS5pbnB1dFR5cGVzW2ldKTtcbiAgICB9XG5cbiAgICBjb25zdCBrZXkgPSBnZXRQcm9ncmFtSW5mb1VuaXF1ZUtleShwcm9ncmFtLCBpbnB1dFRleHR1cmVEYXRhcyk7XG4gICAgbGV0IGFydGlmYWN0ID0gdGhpcy5zZXNzaW9uLnByb2dyYW1NYW5hZ2VyLmdldEFydGlmYWN0KGtleSk7XG4gICAgY29uc3QgcHJvZ3JhbUluZm8gPSBhcnRpZmFjdCA/XG4gICAgICAgIGFydGlmYWN0LnByb2dyYW1JbmZvIDpcbiAgICAgICAgKHR5cGVvZiAocHJvZ3JhbSBhcyBQcm9ncmFtSW5mb0xvYWRlcikuZ2V0ID09PSAnZnVuY3Rpb24nID8gKHByb2dyYW0gYXMgUHJvZ3JhbUluZm9Mb2FkZXIpLmdldCgpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHByb2dyYW0gYXMgUHJvZ3JhbUluZm8pKTtcblxuICAgIC8vIGNyZWF0ZSB0ZXh0dXJlIGluZm8gZm9yIG91dHB1dFxuICAgIGNvbnN0IG91dHB1dFRleHR1cmVMYXlvdXQgPSBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlKFxuICAgICAgICB0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksIHByb2dyYW1JbmZvLm91dHB1dC5kaW1zLCBwcm9ncmFtSW5mby5vdXRwdXQudGV4dHVyZVR5cGUpO1xuICAgIGNvbnN0IG91dHB1dFRleHR1cmVEYXRhID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShvdXRwdXRUZXh0dXJlTGF5b3V0LCBwcm9ncmFtSW5mby5vdXRwdXQudHlwZSk7XG5cbiAgICBpZiAoIWFydGlmYWN0KSB7XG4gICAgICBhcnRpZmFjdCA9IHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5idWlsZChwcm9ncmFtSW5mbywgaW5wdXRUZXh0dXJlRGF0YXMsIG91dHB1dFRleHR1cmVEYXRhKTtcbiAgICAgIHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5zZXRBcnRpZmFjdChrZXksIGFydGlmYWN0KTtcbiAgICB9XG5cbiAgICB0aGlzLnJ1blByb2dyYW0oYXJ0aWZhY3QsIGlucHV0VGV4dHVyZURhdGFzLCBvdXRwdXRUZXh0dXJlRGF0YSk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhO1xuICB9XG5cbiAgcnVuKHByb2dyYW06IFByb2dyYW1JbmZvTG9hZGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdKTogVGVuc29yIHtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuZXhlY3V0ZVByb2dyYW0ocHJvZ3JhbSwgaW5wdXRzKTtcbiAgICByZXR1cm4gb3V0cHV0VGV4dHVyZURhdGEudGVuc29yO1xuICB9XG5cbiAgcHJpdmF0ZSBydW5Qcm9ncmFtKGFydGlmYWN0OiBBcnRpZmFjdCwgaW5wdXRzOiBUZXh0dXJlRGF0YVtdLCBvdXRwdXQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgLy8gaW5wdXQgc2hvdWxkIG1hdGNoXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmICghIWlucHV0c1tpXS5pc1BhY2tlZCAhPT0gKGFydGlmYWN0LnByb2dyYW1JbmZvLmlucHV0VHlwZXNbaV0gPT09IFRleHR1cmVUeXBlLnBhY2tlZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnB1dFske2l9XSBwcm9wZXJ0eSBwYWNrZWQgaW5jb25zaXN0ZW50YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gb3V0cHV0IHNob3VsZCBtYXRjaFxuICAgIGlmICghIW91dHB1dC5pc1BhY2tlZCAhPT0gKGFydGlmYWN0LnByb2dyYW1JbmZvLm91dHB1dC50ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvdXRwdXQgcHJvcGVydHkgcGFja2VkIGluY29uc2lzdGVudCcpO1xuICAgIH1cblxuICAgIHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5ydW4oYXJ0aWZhY3QsIGlucHV0cywgb3V0cHV0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBUZXh0dXJlRGF0YSBvYmplY3QgZnJvbSBhIHRlbnNvci5cbiAgICogVXNhZ2UgPSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seS5cbiAgICogSWYgYSByZWxhdGVkIHRleHR1cmUgZGF0YSBpcyBmb3VuZCBpbiBjYWNoZSwgcmV0dXJucyBpdDtcbiAgICogT3RoZXJ3aXNlOlxuICAgKiAgIENyZWF0ZXMgYSBuZXcgdGV4dHVyZSBsYXlvdXQgaWYgbm90IHByb3ZpZGVkO1xuICAgKiAgIENyZWF0ZXMgV2ViR0xUZXh0dXJlIHdpdGggdGhlIGxheW91dDtcbiAgICogICBVcGxvYWQgdGVuc29yIGRhdGEgdG8gdGhlIHRleHR1cmU7XG4gICAqICAgQ3JlYXRlcyBhIHRleHR1cmUgZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiB0ZW5zb3IuXG4gICAqIEBwYXJhbSB0ZW5zb3IgdGhlIHRlbnNvciB3aXRoIGRhdGEgdG8gdXBsb2FkXG4gICAqL1xuICBwcml2YXRlIGdldE9yQ3JlYXRlVGV4dHVyZURhdGEodGVuc29yOiBUZW5zb3IsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZSkge1xuICAgIGxldCB0ZCA9IHRoaXMuZ2V0VGV4dHVyZURhdGEodGVuc29yLmRhdGFJZCwgdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZCk7XG5cbiAgICBpZiAoIXRkKSB7XG4gICAgICAvLyBjaGVjayBpZiB3ZSBoYXZlIHRleHR1cmUgZGF0YSBpbiBkaWZmZXJlbnQgdHlwZVxuICAgICAgdGQgPSB0aGlzLmdldFRleHR1cmVEYXRhKHRlbnNvci5kYXRhSWQsIHRleHR1cmVUeXBlICE9PSBUZXh0dXJlVHlwZS5wYWNrZWQpO1xuICAgICAgaWYgKHRkKSB7XG4gICAgICAgIGlmICh0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucGFjayh0ZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudW5wYWNrKHRkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGQpIHtcbiAgICAgIGNvbnN0IGxheW91dCA9IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUodGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCB0ZW5zb3IuZGltcywgdGV4dHVyZVR5cGUpO1xuXG4gICAgICBpZiAodGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24pIHtcbiAgICAgICAgY29uc3QgZ3JvdXAgPSAxO1xuICAgICAgICBjb25zdCBjaGFubmVscyA9IDQ7XG4gICAgICAgIGNvbnN0IHNoYXBlID0gdGVuc29yLmRpbXM7XG4gICAgICAgIGlmIChzaGFwZS5sZW5ndGggPT09IDQpIHtcbiAgICAgICAgICAvLyBwcmUtcHJvY2Vzc2luZyBmb3Iga2VybmVsIGRhdGEgb2YgQ29udi5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIFRPRE86IGN1cnJlbnRseSB0aGlzIGlzIGEgaGFja2luZyB0byBvdmVyd3JpdGUgQ29udidzIHdlaWdodC4gVGhlIGNvcnJlY3Qgd2F5IHRvIGRvIHRoaXMgc2hvdWxkIGJlOlxuICAgICAgICAgIC8vIDEuIGltcGxlbWVudCB0ZXh0dXJlIGJhc2VkIGNvbnN0LWZvbGRpbmdcbiAgICAgICAgICAvLyAyLiBjcmVhdGUgYSBXZWJHTCBwcm9ncmFtIFwicHJlcHJvY2Vzc0NvbnZXZWlnaHRcIiB0byBkbyB0aGUgc2FtZSB3b3JrIGFzIGJlbG93XG4gICAgICAgICAgLy8gMy4gcnVuIHRoZSBwcm9ncmFtIGJlZm9yZSBkb3RQcm9kdWN0LlxuICAgICAgICAgIC8vXG4gICAgICAgICAgY29uc3QgYWRqdXN0ZWRLZXJuZWxTaGFwZSA9IFtzaGFwZVswXSwgTWF0aC5jZWlsKChzaGFwZVsxXSAqIHNoYXBlWzJdICogc2hhcGVbM10pIC8gY2hhbm5lbHMpXTtcbiAgICAgICAgICBjb25zdCBhZGp1c3RlZExheW91dCA9XG4gICAgICAgICAgICAgIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tVGV4dHVyZVR5cGUodGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCBhZGp1c3RlZEtlcm5lbFNoYXBlLCB0ZXh0dXJlVHlwZSk7XG4gICAgICAgICAgbGV0IGJ1ZmZlciA9IHRlbnNvci5udW1iZXJEYXRhO1xuICAgICAgICAgIGlmIChzaGFwZVsxXSAqIHNoYXBlWzJdICogc2hhcGVbM10gJSBjaGFubmVscyAhPT0gMCkge1xuICAgICAgICAgICAgY29uc3QgbnVtRmVhdHVyZU1hcHMgPSBzaGFwZVswXTtcbiAgICAgICAgICAgIGNvbnN0IG9sZFJvd1NpemUgPSBzaGFwZVsxXSAqIHNoYXBlWzJdICogc2hhcGVbM107XG4gICAgICAgICAgICBjb25zdCBuZXdSb3dTaXplID0gTWF0aC5jZWlsKG9sZFJvd1NpemUgKiBncm91cCAvIGNoYW5uZWxzKSAqIGNoYW5uZWxzO1xuICAgICAgICAgICAgY29uc3QgbmV3U2l6ZSA9IG51bUZlYXR1cmVNYXBzICogbmV3Um93U2l6ZTtcbiAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkobmV3U2l6ZSk7XG4gICAgICAgICAgICBmb3IgKGxldCBmID0gMDsgZiA8IG51bUZlYXR1cmVNYXBzOyArK2YpIHtcbiAgICAgICAgICAgICAgY29uc3Qgb2xkT2Zmc2V0ID0gZiAqIG9sZFJvd1NpemU7XG4gICAgICAgICAgICAgIGNvbnN0IG5ld09mZnNldCA9IGYgKiBuZXdSb3dTaXplICsgZiAlIGdyb3VwICogb2xkUm93U2l6ZTtcbiAgICAgICAgICAgICAgYnVmZmVyLnNldCh0ZW5zb3IubnVtYmVyRGF0YS5zdWJhcnJheShvbGRPZmZzZXQsIG9sZE9mZnNldCArIG9sZFJvd1NpemUpLCBuZXdPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShhZGp1c3RlZExheW91dCwgdGVuc29yLnR5cGUsIGJ1ZmZlciwgdGVuc29yLCBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpIHtcbiAgICAgICAgY29uc3QgdW5wYWNrZWRUZXh0dXJlTGF5b3V0ID1cbiAgICAgICAgICAgIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUodGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCB0ZW5zb3IuZGltcywgMSwgW10sIHtyZXZlcnNlV0g6IHRydWV9KTtcbiAgICAgICAgY29uc3QgdW5wYWNrZWRUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGEoXG4gICAgICAgICAgICB1bnBhY2tlZFRleHR1cmVMYXlvdXQsIHRlbnNvci50eXBlLCB0ZW5zb3IubnVtYmVyRGF0YSwgdGVuc29yLCBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSk7XG4gICAgICAgIHRkID0gdGhpcy5wYWNrKHVucGFja2VkVGV4dHVyZURhdGEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGQgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKGxheW91dCwgdGVuc29yLnR5cGUsIHRlbnNvci5udW1iZXJEYXRhLCB0ZW5zb3IsIEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRkO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIFRleHR1cmVEYXRhIG9iamVjdCB1c2luZyB0aGUgZ2l2ZW4gZGF0YSBhbmQgYmluZCB0byB0aGUgZ2l2ZW4gdGVuc29yLlxuICAgKiBVc2FnZSA9IEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5LlxuICAgKiBOT1RFOiB0aGlzIGZ1bmN0aW9uIGlzIGEgaGFjayBmb3IgQ29udiBpbXBsZW1lbnRhdGlvbi4gc2hvdWxkIHJlbW92ZSB0aGlzIGZ1bmN0aW9uLCBhZnRlciByZXdyaXRpbmcgQ29udlxuICAgKiBpbXBsZW1lbnRhdGlvbiBieSBHcmFwaC5UcmFuc2Zvcm1lclxuICAgKiBAcGFyYW0gZGF0YVR5cGUgdGhlIHRlbnNvciBkYXRhIHR5cGVcbiAgICogQHBhcmFtIGRhdGEgdGhlIGFjdHVhbCBkYXRhIHRvIHVwbG9hZFxuICAgKiBAcGFyYW0gdGVuc29yIHRoZSB0ZW5zb3IgdG8gYmluZC4gdGVuc29yJ3MgZGF0YSBpcyBpZ25vcmVkLlxuICAgKi9cbiAgY3JlYXRlVGV4dHVyZURhdGFGcm9tTGF5b3V0QmluZFRlbnNvcihcbiAgICAgIGxheW91dDogVGV4dHVyZUxheW91dCwgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgZGF0YTogVGVuc29yLk51bWJlclR5cGUsIHRlbnNvcjogVGVuc29yKTogVGV4dHVyZURhdGEge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKGxheW91dCwgZGF0YVR5cGUsIGRhdGEsIHRlbnNvciwgRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVUZXh0dXJlRGF0YShcbiAgICAgIGxheW91dDogVGV4dHVyZUxheW91dCwgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgZGF0YT86IFRlbnNvci5OdW1iZXJUeXBlLCB0ZW5zb3I/OiBUZW5zb3IsXG4gICAgICB1c2FnZT86IEVuY29kZXJVc2FnZSk6IFRleHR1cmVEYXRhIHtcbiAgICBMb2dnZXIudmVyYm9zZSgnSW5mZXJlbmNlSGFuZGxlcicsIGBDcmVhdGluZyBUZXh0dXJlRGF0YTogbGF5b3V0Olske0pTT04uc3RyaW5naWZ5KGxheW91dCl9XWApO1xuICAgIGNvbnN0IHRleHR1cmUgPSB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIuY3JlYXRlVGV4dHVyZUZyb21MYXlvdXQoZGF0YVR5cGUsIGxheW91dCwgZGF0YSwgdXNhZ2UpO1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUobGF5b3V0LCBkYXRhVHlwZSwgdGV4dHVyZSwgdGVuc29yKTtcbiAgfVxuXG4gIHJlc2hhcGVVbnBhY2tlZChpbnB1dDogVGVuc29yLCByZXNoYXBlZERpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yIHtcbiAgICBjb25zdCBpbnB1dFREID0gdGhpcy5nZXRPckNyZWF0ZVRleHR1cmVEYXRhKGlucHV0LCBUZXh0dXJlVHlwZS51bnBhY2tlZCk7XG4gICAgY29uc3QgbmV3VGV4dHVyZUxheW91dDogVGV4dHVyZUxheW91dCA9IHtcbiAgICAgIGNoYW5uZWxzOiBpbnB1dFRELmNoYW5uZWxzLFxuICAgICAgaGVpZ2h0OiBpbnB1dFRELmhlaWdodCxcbiAgICAgIHdpZHRoOiBpbnB1dFRELndpZHRoLFxuICAgICAgLy8gaGFuZGxlIHJlc2hhcGluZyBpbnRvIHNjYWxhciBUZW5zb3JzXG4gICAgICBzaGFwZTogcmVzaGFwZWREaW1zLmxlbmd0aCAhPT0gMCA/IHJlc2hhcGVkRGltcyA6IFsxXSxcbiAgICAgIHN0cmlkZXM6IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhyZXNoYXBlZERpbXMpLFxuICAgICAgdW5wYWNrZWRTaGFwZTogcmVzaGFwZWREaW1zLFxuICAgIH07XG4gICAgY29uc3QgbmV3VGV4dHVyZURhdGEgPSB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhRnJvbVRleHR1cmUobmV3VGV4dHVyZUxheW91dCwgaW5wdXQudHlwZSwgaW5wdXRURC50ZXh0dXJlKTtcbiAgICByZXR1cm4gbmV3VGV4dHVyZURhdGEudGVuc29yO1xuICB9XG5cbiAgcmVzaGFwZVBhY2tlZChpbnB1dDogVGVuc29yLCByZXNoYXBlZERpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogVGVuc29yIHtcbiAgICBjb25zdCBpbnB1dFREID0gdGhpcy5nZXRPckNyZWF0ZVRleHR1cmVEYXRhKGlucHV0LCBUZXh0dXJlVHlwZS5wYWNrZWQpO1xuXG4gICAgLy8gY2hlY2sgaWYgdGhlIHJlc2hhcGUgaXMgJ2NoZWFwJ1xuICAgIGlmIChpc1Jlc2hhcGVDaGVhcChpbnB1dC5kaW1zLCByZXNoYXBlZERpbXMpKSB7XG4gICAgICBjb25zdCBuZXdUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0ge1xuICAgICAgICBjaGFubmVsczogaW5wdXRURC5jaGFubmVscyxcbiAgICAgICAgaGVpZ2h0OiBpbnB1dFRELmhlaWdodCxcbiAgICAgICAgd2lkdGg6IGlucHV0VEQud2lkdGgsXG4gICAgICAgIC8vIGhhbmRsZSByZXNoYXBpbmcgaW50byBzY2FsYXIgVGVuc29yc1xuICAgICAgICBzaGFwZTogcmVzaGFwZWREaW1zLmxlbmd0aCAhPT0gMCA/IHJlc2hhcGVkRGltcyA6IFsxXSxcbiAgICAgICAgc3RyaWRlczogU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHJlc2hhcGVkRGltcyksXG4gICAgICAgIHVucGFja2VkU2hhcGU6IHJlc2hhcGVkRGltcyxcbiAgICAgICAgaXNQYWNrZWQ6IHRydWVcbiAgICAgIH07XG4gICAgICBjb25zdCBuZXdUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShuZXdUZXh0dXJlTGF5b3V0LCBpbnB1dC50eXBlLCBpbnB1dFRELnRleHR1cmUpO1xuICAgICAgcmV0dXJuIG5ld1RleHR1cmVEYXRhLnRlbnNvcjtcbiAgICB9XG5cbiAgICBjb25zdCBzcXVlZXplZElucHV0U2hhcGUgPSBwcm9jZXNzRGltczNEKGlucHV0LmRpbXMpO1xuICAgIGNvbnN0IHNxdWVlemVkT3V0cHV0U2hhcGUgPSBwcm9jZXNzRGltczNEKHJlc2hhcGVkRGltcyk7XG5cbiAgICBjb25zdCBzcXVlZXplZElucHV0VGVuc29yID0gdGhpcy5yZXNoYXBlUGFja2VkKGlucHV0LCBzcXVlZXplZElucHV0U2hhcGUpO1xuICAgIGNvbnN0IHNxdWVlemVkT3V0cHV0VGVuc29yID0gdGhpcy5ydW4oXG4gICAgICAgIGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvTG9hZGVyKHRoaXMsIHNxdWVlemVkSW5wdXRUZW5zb3IsIHNxdWVlemVkT3V0cHV0U2hhcGUpLCBbc3F1ZWV6ZWRJbnB1dFRlbnNvcl0pO1xuICAgIGNvbnN0IG91dHB1dFRlbnNvciA9IHRoaXMucmVzaGFwZVBhY2tlZChzcXVlZXplZE91dHB1dFRlbnNvciwgcmVzaGFwZWREaW1zKTtcbiAgICByZXR1cm4gb3V0cHV0VGVuc29yO1xuICB9XG5cbiAgY2FzdChpbnB1dDogVGVuc29yLCB0eXBlOiBUZW5zb3IuRGF0YVR5cGUpOiBUZW5zb3Ige1xuICAgIGNvbnN0IGlucHV0VEQgPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXQsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgICBjb25zdCBuZXdUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShpbnB1dFREIGFzIFRleHR1cmVMYXlvdXQsIHR5cGUsIGlucHV0VEQudGV4dHVyZSk7XG4gICAgcmV0dXJuIG5ld1RleHR1cmVEYXRhLnRlbnNvcjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShcbiAgICAgIGxheW91dDogVGV4dHVyZUxheW91dCwgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgdGV4dHVyZTogV2ViR0xUZXh0dXJlLCB0ZW5zb3I/OiBUZW5zb3IsIHRlbnNvcklkPzogVGVuc29yLklkKSB7XG4gICAgY29uc3QgdGV4dHVyZURhdGE6IFRleHR1cmVEYXRhID0ge1xuICAgICAgLi4ubGF5b3V0LFxuICAgICAgdGVuc29yOiB0ZW5zb3IgfHxcbiAgICAgICAgICBuZXcgVGVuc29yKFxuICAgICAgICAgICAgICAgICAgbGF5b3V0LnVucGFja2VkU2hhcGUsIGRhdGFUeXBlLCAoX2lkOiBUZW5zb3IuSWQpID0+IHRoaXMucmVhZFRleHR1cmUodGV4dHVyZURhdGEpLFxuICAgICAgICAgICAgICAgICAgYXN5bmMgKF9pZDogVGVuc29yLklkKSA9PiB0aGlzLnJlYWRUZXh0dXJlQXN5bmModGV4dHVyZURhdGEpLCB1bmRlZmluZWQsIHRlbnNvcklkKSxcbiAgICAgIHRleHR1cmVcbiAgICB9O1xuICAgIHRoaXMuc2V0VGV4dHVyZURhdGEodGV4dHVyZURhdGEudGVuc29yLmRhdGFJZCwgdGV4dHVyZURhdGEsIGxheW91dC5pc1BhY2tlZCk7XG4gICAgcmV0dXJuIHRleHR1cmVEYXRhO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZDogVGVuc29yLklkLCBpc1BhY2tlZCA9IGZhbHNlKTogVGV4dHVyZURhdGF8dW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIodGVuc29ySWQpID8gdGhpcy5zZXNzaW9uLmdldFRleHR1cmVEYXRhKHRlbnNvcklkLCBpc1BhY2tlZCkgOlxuICAgICAgICBpc1BhY2tlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmdldCh0ZW5zb3JJZCk7XG4gIH1cbiAgc2V0VGV4dHVyZURhdGEodGVuc29ySWQ6IFRlbnNvci5JZCwgdGQ6IFRleHR1cmVEYXRhLCBpc1BhY2tlZCA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2Vzc2lvbi5pc0luaXRpYWxpemVyKHRlbnNvcklkKSkge1xuICAgICAgdGhpcy5zZXNzaW9uLnNldFRleHR1cmVEYXRhKHRlbnNvcklkLCB0ZCwgaXNQYWNrZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAoaXNQYWNrZWQgPyB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgOiB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZSkuc2V0KHRlbnNvcklkLCB0ZCk7XG4gICAgfVxuICB9XG4gIGlzVGV4dHVyZUxheW91dENhY2hlZCh0ZW5zb3I6IFRlbnNvciwgaXNQYWNrZWQgPSBmYWxzZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuZ2V0VGV4dHVyZURhdGEodGVuc29yLmRhdGFJZCwgaXNQYWNrZWQpO1xuICB9XG5cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIuY2xlYXJBY3RpdmVUZXh0dXJlcygpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKHRkID0+IHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCkpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKHRkID0+IHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCkpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICB9XG5cbiAgcmVhZFRleHR1cmUodGV4dHVyZURhdGE6IFRleHR1cmVEYXRhKTogVGVuc29yLk51bWJlclR5cGUge1xuICAgIGlmICh0ZXh0dXJlRGF0YS5pc1BhY2tlZCkge1xuICAgICAgcmV0dXJuIHRoaXMucmVhZFRleHR1cmUodGhpcy51bnBhY2sodGV4dHVyZURhdGEpKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQuaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQoZW5jb2RlQXNVaW50OCh0aGlzLCB0ZXh0dXJlRGF0YSkpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlKHRleHR1cmVEYXRhLCB0ZXh0dXJlRGF0YS50ZW5zb3IudHlwZSwgdGV4dHVyZURhdGEuY2hhbm5lbHMpO1xuICB9XG5cbiAgYXN5bmMgcmVhZFRleHR1cmVBc3luYyh0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEpOiBQcm9taXNlPFRlbnNvci5OdW1iZXJUeXBlPiB7XG4gICAgaWYgKHRleHR1cmVEYXRhLmlzUGFja2VkKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWFkVGV4dHVyZUFzeW5jKHRoaXMudW5wYWNrKHRleHR1cmVEYXRhKSk7XG4gICAgfVxuICAgIGlmICghdGhpcy5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LmlzRmxvYXQzMkRvd25sb2FkU3VwcG9ydGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlYWRVaW50OFRleHR1cmVBc0Zsb2F0KGVuY29kZUFzVWludDgodGhpcywgdGV4dHVyZURhdGEpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWFkVGV4dHVyZUFzeW5jKHRleHR1cmVEYXRhLCB0ZXh0dXJlRGF0YS50ZW5zb3IudHlwZSwgdGV4dHVyZURhdGEuY2hhbm5lbHMpO1xuICB9XG5cbiAgcGFjayhpbnB1dDogVGV4dHVyZURhdGEpOiBUZXh0dXJlRGF0YSB7XG4gICAgY29uc3Qgb3V0cHV0VGV4dHVyZURhdGEgPSB0aGlzLmV4ZWN1dGVQcm9ncmFtKGNyZWF0ZVBhY2tQcm9ncmFtSW5mb0xvYWRlcih0aGlzLCBpbnB1dC50ZW5zb3IpLCBbaW5wdXQudGVuc29yXSk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhO1xuICB9XG5cbiAgdW5wYWNrKGlucHV0OiBUZXh0dXJlRGF0YSk6IFRleHR1cmVEYXRhIHtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuZXhlY3V0ZVByb2dyYW0oY3JlYXRlVW5wYWNrUHJvZ3JhbUluZm9Mb2FkZXIodGhpcywgaW5wdXQudGVuc29yKSwgW2lucHV0LnRlbnNvcl0pO1xuICAgIHJldHVybiBvdXRwdXRUZXh0dXJlRGF0YTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5jbGFzcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXlJbXBsIHtcbiAgY29uc3RydWN0b3IoYXR0cmlidXRlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcywgYXR0cmlidXRlKTtcbiAgfVxuXG4gIHByaXZhdGUga2V5OiBzdHJpbmc7XG4gIHB1YmxpYyBnZXQgY2FjaGVLZXkoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMua2V5KSB7XG4gICAgICB0aGlzLmtleSA9XG4gICAgICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGhpcykuc29ydCgpLm1hcChuYW1lID0+IGAkeyh0aGlzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtuYW1lXX1gKS5qb2luKCc7Jyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmtleTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGNhY2hlS2V5OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkgPSA8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+PihhdHRyaWJ1dGU6IFQpOiBUJkF0dHJpYnV0ZVdpdGhDYWNoZUtleSA9PlxuICAgIG5ldyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXlJbXBsKGF0dHJpYnV0ZSkgYXMgdW5rbm93biBhcyBUICYgQXR0cmlidXRlV2l0aENhY2hlS2V5O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge2dldEdsc2x9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBlcHNpbG9uOiBudW1iZXI7XG4gIG1vbWVudHVtOiBudW1iZXI7XG4gIHNwYXRpYWw6IG51bWJlcjtcbn1cblxuY29uc3QgYmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnQmF0Y2hOb3JtYWxpemF0aW9uJyxcbiAgaW5wdXROYW1lczogWydBJywgJ1NjYWxlJywgJ0InLCAnTWVhbicsICdWYXJpYW5jZSddLFxuICBpbnB1dFR5cGVzOlxuICAgICAgW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF1cbn07XG5cbmV4cG9ydCBjb25zdCBiYXRjaE5vcm1hbGl6YXRpb246IE9wZXJhdG9ySW1wbGVtZW50YXRpb248QmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4uYmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVCYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpbnB1dHMpO1xuICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248QmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyA9PiB7XG4gICAgICBjb25zdCBlcHNpbG9uID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdlcHNpbG9uJywgMWUtNSk7XG4gICAgICBjb25zdCBtb21lbnR1bSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnbW9tZW50dW0nLCAwLjkpO1xuICAgICAgY29uc3Qgc3BhdGlhbCA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3NwYXRpYWwnLCAxKTtcbiAgICAgIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe2Vwc2lsb24sIG1vbWVudHVtLCBzcGF0aWFsfSk7XG4gICAgfTtcblxuY29uc3QgY3JlYXRlQmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEJhdGNoTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXMpOlxuICAgICAgICBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICAgICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgICAgIGNvbnN0IHJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gICAgICAgICAgY29uc3QgW3NjYWxlV2lkdGgsIHNjYWxlSGVpZ2h0XSA9XG4gICAgICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KGlucHV0c1sxXS5kaW1zLCBUZXh0dXJlVHlwZS51bnBhY2tlZCk7XG4gICAgICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgdmVjMiBwb3NpdGlvbiA9IG9mZnNldFRvQ29vcmRzKGluZGljZXNbMV0sICR7c2NhbGVXaWR0aH0sICR7c2NhbGVIZWlnaHR9KTtcbiAgICBmbG9hdCBzY2FsZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShTY2FsZSwgcG9zaXRpb24pKTtcbiAgICBmbG9hdCBtZWFuID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KE1lYW4sIHBvc2l0aW9uKSk7XG4gICAgZmxvYXQgdmFyaWFuY2UgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oVmFyaWFuY2UsIHBvc2l0aW9uKSk7XG4gICAgZmxvYXQgYiA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShCLCBwb3NpdGlvbikpO1xuXG4gICAgcmV0dXJuIHNjYWxlICogKCAoX0EoaW5kaWNlcykgLSBtZWFuKSAvIHNxcnQodmFyaWFuY2UgKyBmbG9hdCgke2F0dHJpYnV0ZXMuZXBzaWxvbn0pKSApICsgYjtcbiAgfWA7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmJhdGNoTm9ybWFsaXphdGlvblByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICAgIG91dHB1dDoge2RpbXM6IGlucHV0c1swXS5kaW1zLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gNSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQmF0Y2hOb3JtYWxpemF0aW9uIHJlcXVpcmVzIDUgaW5wdXRzLicpO1xuICB9XG5cbiAgY29uc3QgWCA9IGlucHV0c1swXTtcbiAgY29uc3Qgc2NhbGUgPSBpbnB1dHNbMV07XG4gIGNvbnN0IEIgPSBpbnB1dHNbMl07XG4gIGNvbnN0IG1lYW4gPSBpbnB1dHNbM107XG4gIGNvbnN0IHZhcl8gPSBpbnB1dHNbNF07XG5cbiAgLy8gaW5wdXQgc2hvdWxkIGF0bGVhc3QgaGF2ZSB0aHJlZSBkaW1lbnNpb25zIC0gTixDLGRpbTEsLi4uLGRpbW5cbiAgLy8gb3RoZXIgaW5wdXRzIGNhbiBoYXZlIG9ubHkgb25lIGRpbWVuc2lvbnNcbiAgaWYgKFguZGltcy5sZW5ndGggPCAzIHx8IHNjYWxlLmRpbXMubGVuZ3RoICE9PSAxIHx8IEIuZGltcy5sZW5ndGggIT09IDEgfHwgbWVhbi5kaW1zLmxlbmd0aCAhPT0gMSB8fFxuICAgICAgdmFyXy5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoc2NhbGUuZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8IEIuZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8IG1lYW4uZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8XG4gICAgICB2YXJfLmRpbXNbMF0gIT09IFguZGltc1sxXSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoKFgudHlwZSAhPT0gJ2Zsb2F0MzInICYmIFgudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fCAoc2NhbGUudHlwZSAhPT0gJ2Zsb2F0MzInICYmIHNjYWxlLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAgIChCLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBCLnR5cGUgIT09ICdmbG9hdDY0JykgfHwgKG1lYW4udHlwZSAhPT0gJ2Zsb2F0MzInICYmIG1lYW4udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgICAgKHZhcl8udHlwZSAhPT0gJ2Zsb2F0MzInICYmIHZhcl8udHlwZSAhPT0gJ2Zsb2F0NjQnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCB0ZW5zb3IgdHlwZXMuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7UHJvZ3JhbUluZm8sIFRleHR1cmVMYXlvdXR9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtXZWJHTENvbnRleHR9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xuZXhwb3J0IGVudW0gRnVuY3Rpb25UeXBlIHtcbiAgVmFsdWVCYXNlZCxcbiAgUG9zaXRpb25hbFxufVxuZXhwb3J0IGludGVyZmFjZSBHbHNsRnVuY3Rpb248VCBleHRlbmRzIEZ1bmN0aW9uVHlwZT4ge1xuICBib2R5OiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogVDtcbn1cbmV4cG9ydCB0eXBlIEdsc2xWYWx1ZUZ1bmN0aW9uID0gR2xzbEZ1bmN0aW9uPEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkPjtcbmV4cG9ydCBpbnRlcmZhY2UgR2xzbFBvc2l0aW9uYWxGdW5jdGlvbiBleHRlbmRzIEdsc2xGdW5jdGlvbjxGdW5jdGlvblR5cGUuUG9zaXRpb25hbD4ge1xuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY2xhc3MgR2xzbENvbnRleHQge1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIHB1YmxpYyBnbENvbnRleHQ6IFdlYkdMQ29udGV4dCwgcHVibGljIHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbywgcHVibGljIGlucHV0VGV4dHVyZUxheW91dHM6IFRleHR1cmVMYXlvdXRbXSxcbiAgICAgIHB1YmxpYyBvdXRwdXRUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0KSB7fVxufVxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgY29udGV4dDogR2xzbENvbnRleHQpIHt9XG4gIGFic3RyYWN0IGdldEZ1bmN0aW9ucygpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfTtcbiAgYWJzdHJhY3QgZ2V0Q3VzdG9tVHlwZXMoKToge1tuYW1lOiBzdHJpbmddOiBzdHJpbmd9O1xufVxuXG4vLyBhYnN0cmFjdGlvbiB0byByZXByZXNlbnQgYSBHTFNMIGxpYnJhcnkgcm91dGluZSBhbmQgaXQncyBkZXBlbmRlbmNpZXNcbmV4cG9ydCBjbGFzcyBHbHNsTGliUm91dGluZSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyByb3V0aW5lQm9keTogc3RyaW5nLCBwdWJsaWMgZGVwZW5kZW5jaWVzPzogc3RyaW5nW10pIHt9XG59XG5cbi8vIGFic3RyYWN0aW9uIHRvIHJlcHJlc2VudCBhIEdMU0wgbGlicmFyeSByb3V0aW5lIGFuZCBpdCdzIGRlcGVuZGVuY2llcyBBUyBHUkFQSCBOb2Rlc1xuLy8gdGhpcyBsZXZlbCBvZiBhYnN0cmFjdGlvbiBpcyB1c2VkIHRvIHRvcG9sb2dpY2FsbHkgc29ydCByb3V0aW5lcyBiZWZvcmUgZnJhZ21lbnQgc2hhZGUgaW5jbHVzaW9uXG5leHBvcnQgY2xhc3MgR2xzbExpYlJvdXRpbmVOb2RlIHtcbiAgZGVwZW5kZW5jaWVzOiBHbHNsTGliUm91dGluZU5vZGVbXTtcbiAgcm91dGluZUJvZHk6IHN0cmluZztcbiAgY29uc3RydWN0b3IocHVibGljIG5hbWU6IHN0cmluZywgcm91dGluZUJvZHk/OiBzdHJpbmcsIGRlcGVuZGVuY2llcz86IEdsc2xMaWJSb3V0aW5lTm9kZVtdKSB7XG4gICAgaWYgKGRlcGVuZGVuY2llcykge1xuICAgICAgdGhpcy5kZXBlbmRlbmNpZXMgPSBkZXBlbmRlbmNpZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGVwZW5kZW5jaWVzID0gW107XG4gICAgfVxuXG4gICAgaWYgKHJvdXRpbmVCb2R5KSB7XG4gICAgICB0aGlzLnJvdXRpbmVCb2R5ID0gcm91dGluZUJvZHk7XG4gICAgfVxuICB9XG4gIGFkZERlcGVuZGVuY3kobm9kZTogR2xzbExpYlJvdXRpbmVOb2RlKSB7XG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIHRoaXMuZGVwZW5kZW5jaWVzLnB1c2gobm9kZSk7XG4gICAgfVxuICB9XG59XG5cbi8vIHRvcG9sb2dpY2FsbHkgc29ydCBHTFNMIGxpYnJhcnkgcm91dGluZXMgKGdyYXBoIG5vZGVzIGFic3RyYWN0aW9uKSBiZWZvcmUgc2hhZGVyIHNjcmlwdCBpbmNsdXNpb25cbmV4cG9ydCBjbGFzcyBUb3BvbG9naWNhbFNvcnRHbHNsUm91dGluZXMge1xuICBzdGF0aWMgcmV0dXJuT3JkZXJlZE5vZGVzKG5vZGVzOiBHbHNsTGliUm91dGluZU5vZGVbXSk6IEdsc2xMaWJSb3V0aW5lTm9kZVtdIHtcbiAgICBpZiAoIW5vZGVzIHx8IG5vZGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGlmIChub2Rlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBub2RlcztcbiAgICB9XG5cbiAgICBjb25zdCBjeWNsZUNoZWNrID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgYWxyZWFkeVRyYXZlcnNlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBBcnJheTxHbHNsTGliUm91dGluZU5vZGU+KCk7XG5cbiAgICB0aGlzLmNyZWF0ZU9yZGVyZWROb2Rlcyhub2RlcywgY3ljbGVDaGVjaywgYWxyZWFkeVRyYXZlcnNlZCwgcmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgY3JlYXRlT3JkZXJlZE5vZGVzKFxuICAgICAgZ3JhcGhOb2RlczogR2xzbExpYlJvdXRpbmVOb2RlW10sIGN5Y2xlQ2hlY2s6IFNldDxzdHJpbmc+LCBhbHJlYWR5VHJhdmVyc2VkOiBTZXQ8c3RyaW5nPixcbiAgICAgIHJlc3VsdDogR2xzbExpYlJvdXRpbmVOb2RlW10pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoTm9kZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHRoaXMuZGZzVHJhdmVyc2UoZ3JhcGhOb2Rlc1tpXSwgY3ljbGVDaGVjaywgYWxyZWFkeVRyYXZlcnNlZCwgcmVzdWx0KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBkZnNUcmF2ZXJzZShcbiAgICAgIHJvb3Q6IEdsc2xMaWJSb3V0aW5lTm9kZSwgY3ljbGVDaGVjazogU2V0PHN0cmluZz4sIGFscmVhZHlUcmF2ZXJzZWQ6IFNldDxzdHJpbmc+LCByZXN1bHQ6IEdsc2xMaWJSb3V0aW5lTm9kZVtdKSB7XG4gICAgLy8gaWYgdGhpcyByb290IGhhcyBhbHJlYWR5IGJlZW4gdHJhdmVyc2VkIHJldHVyblxuICAgIGlmICghcm9vdCB8fCBhbHJlYWR5VHJhdmVyc2VkLmhhcyhyb290Lm5hbWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gY3ljbGljIGRlcGVuZGVuY3kgaGFzIGJlZW4gZGV0ZWN0ZWRcbiAgICBpZiAoY3ljbGVDaGVjay5oYXMocm9vdC5uYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDeWNsaWMgZGVwZW5kZW5jeSBkZXRlY3RlZC4gQ2FuXFwndCB0b3BvbG9naWNhbGx5IHNvcnQgcm91dGluZXMgbmVlZGVkIGZvciBzaGFkZXIuJyk7XG4gICAgfVxuXG4gICAgLy8gaG9sZCB0aGlzIG5vZGUgdG8gZGV0ZWN0IGN5Y2xlcyBpZiBhbnlcbiAgICBjeWNsZUNoZWNrLmFkZChyb290Lm5hbWUpO1xuXG4gICAgLy8gdHJhdmVyc2UgY2hpbGRyZW4gaW4gYSBkZnMgZmFzaGlvblxuICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IHJvb3QuZGVwZW5kZW5jaWVzO1xuICAgIGlmIChkZXBlbmRlbmNpZXMgJiYgZGVwZW5kZW5jaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVwZW5kZW5jaWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHRoaXMuZGZzVHJhdmVyc2UoZGVwZW5kZW5jaWVzW2ldLCBjeWNsZUNoZWNrLCBhbHJlYWR5VHJhdmVyc2VkLCByZXN1bHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkZCB0byByZXN1bHQgaG9sZGVyXG4gICAgcmVzdWx0LnB1c2gocm9vdCk7XG5cbiAgICAvLyBtYXJrIHRoaXMgbm9kZSBhcyB0cmF2ZXJzZWQgc28gdGhhdCB3ZSBkb24ndCB0cmF2ZXJzZSBmcm9tIHRoaXMgYWdhaW5cbiAgICBhbHJlYWR5VHJhdmVyc2VkLmFkZChyb290Lm5hbWUpO1xuXG4gICAgLy8gcmVsZWFzZSB0aGUgaG9sZFxuICAgIGN5Y2xlQ2hlY2suZGVsZXRlKHJvb3QubmFtZSk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge0Jyb2FkY2FzdFV0aWwsIFNoYXBlVXRpbH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge0Z1bmN0aW9uVHlwZSwgR2xzbFZhbHVlRnVuY3Rpb259IGZyb20gJy4uL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQWRkKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdhZGRfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgKyBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxICsgdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbERpdigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnZGl2Xyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhIC8gYjtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2MSAvIHYyO1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xNdWwoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ211bF8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gYSAqIGI7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdjEgKiB2MjtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU3ViKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdzdWJfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgLSBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxIC0gdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEVxdWFsKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdlcXVhbF8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoYSA9PSBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2ZWM0KGVxdWFsKHYxLCB2MikpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xHcmVhdGVyKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdncmVhdGVyXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdChhID4gYik7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdmVjNCggdjEuciA+IHYyLnIgLFxuICAgICAgdjEuZyA+IHYyLmcsXG4gICAgICB2MS5iID4gdjIuYixcbiAgICAgIHYxLmEgPiB2Mi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbExlc3MoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2xlc3NfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KGEgPCBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2ZWM0KCB2MS5yIDwgdjIuciAsXG4gICAgICAgICAgICAgICAgdjEuZyA8IHYyLmcsXG4gICAgICAgICAgICAgICAgdjEuYiA8IHYyLmIsXG4gICAgICAgICAgICAgICAgdjEuYSA8IHYyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQW5kKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdhbmRfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KCBib29sKGEpICYmIGJvb2woYikgKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIGJ2ZWM0IGIxID0gYnZlYzQodjEpO1xuICAgIGJ2ZWM0IGIyID0gYnZlYzQodjIpO1xuICAgIHJldHVybiB2ZWM0KCBiMS5yICYmIGIyLnIgLFxuICAgICAgICAgICAgICAgIGIxLmcgJiYgYjIuZyxcbiAgICAgICAgICAgICAgICBiMS5iICYmIGIyLmIsXG4gICAgICAgICAgICAgICAgYjEuYSAmJiBiMi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbE9yKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdvcl8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoIGJvb2woYSkgfHwgYm9vbChiKSApO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgYnZlYzQgYjEgPSBidmVjNCh2MSk7XG4gICAgYnZlYzQgYjIgPSBidmVjNCh2Mik7XG4gICAgcmV0dXJuIHZlYzQoIGIxLnIgfHwgYjIuciAsXG4gICAgICAgICAgICAgICAgYjEuZyB8fCBiMi5nLFxuICAgICAgICAgICAgICAgIGIxLmIgfHwgYjIuYixcbiAgICAgICAgICAgICAgICBiMS5hIHx8IGIyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsWG9yKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICd4b3JfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KCBib29sKGEpIF5eIGJvb2woYikgKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIGJ2ZWM0IGIxID0gYnZlYzQodjEpO1xuICAgIGJ2ZWM0IGIyID0gYnZlYzQodjIpO1xuICAgIHJldHVybiB2ZWM0KCBiMS5yIF5eIGIyLnIgLFxuICAgICAgICAgICAgICAgIGIxLmcgXl4gYjIuZyxcbiAgICAgICAgICAgICAgICBiMS5iIF5eIGIyLmIsXG4gICAgICAgICAgICAgICAgYjEuYSBeXiBiMi5hICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFBvdygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpbkJpbmFyeSgncG93Jyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFBSZWx1KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdwcmVsdV8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gYSA8IDAuMCA/IGEgKiBiOiBhO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHZlYzQoXG4gICAgICB2MS5yIDwgMC4wID8gdjEuciAqIHYyLnI6IHYxLnIsXG4gICAgICB2MS5nIDwgMC4wID8gdjEuZyAqIHYyLmc6IHYxLmcsXG4gICAgICB2MS5iIDwgMC4wID8gdjEuYiAqIHYyLmI6IHYxLmIsXG4gICAgICB2MS5hIDwgMC4wID8gdjEuYSAqIHYyLmE6IHYxLmFcbiAgICAgICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5cbmZ1bmN0aW9uIGdsc2xCdWlsdGluQmluYXJ5KGZuYW1lOiBzdHJpbmcpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSBgJHtmbmFtZX1fYDtcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuICR7Zm5hbWV9KGEsIGIpO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuICR7Zm5hbWV9KHYxLCB2Mik7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5cbmNvbnN0IGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBnbHNsRnVuYzogR2xzbFZhbHVlRnVuY3Rpb24sXG4gICAgIG91dHB1dFRlbnNvclR5cGU6IFRlbnNvci5EYXRhVHlwZSA9IGlucHV0c1swXS50eXBlLCBjYWNoZUtleT86IHN0cmluZyk6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgICAgIGNvbnN0IHRleHR1cmVUeXBlID0gaGFuZGxlci5zZXNzaW9uLnBhY2sgPyBUZXh0dXJlVHlwZS5wYWNrZWQgOiBUZXh0dXJlVHlwZS51bnBhY2tlZDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IGdsc2xGdW5jLm5hbWUsXG4gICAgICAgIGlucHV0TmFtZXM6IFsnQScsICdCJ10sXG4gICAgICAgIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZSwgdGV4dHVyZVR5cGVdLFxuICAgICAgICBjYWNoZUhpbnQ6IGNhY2hlS2V5LFxuICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvKGhhbmRsZXIsIGlucHV0cywgZ2xzbEZ1bmMsIG91dHB1dFRlbnNvclR5cGUpXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBnbHNsRnVuYzogR2xzbFZhbHVlRnVuY3Rpb24sXG4gICAgIG91dHB1dFRlbnNvclR5cGU6IFRlbnNvci5EYXRhVHlwZSA9IGlucHV0c1swXS50eXBlKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgdGV4dHVyZVR5cGUgPSBoYW5kbGVyLnNlc3Npb24ucGFjayA/IFRleHR1cmVUeXBlLnBhY2tlZCA6IFRleHR1cmVUeXBlLnVucGFja2VkO1xuICAgICAgY29uc3QgaXNCcm9hZGNhc3QgPSAhU2hhcGVVdGlsLmFyZUVxdWFsKGlucHV0c1swXS5kaW1zLCBpbnB1dHNbMV0uZGltcyk7XG4gICAgICBsZXQgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcblxuICAgICAgY29uc3QgdXNlUGFja2VkVGV4dHVyZSA9IGhhbmRsZXIuc2Vzc2lvbi5wYWNrO1xuXG4gICAgICBpZiAoaXNCcm9hZGNhc3QpIHtcbiAgICAgICAgY29uc3QgY2FsY3VsYXRlZFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5kaW1zLCBmYWxzZSk7XG4gICAgICAgIGlmICghY2FsY3VsYXRlZFNoYXBlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXCd0IHBlcmZvcm0gYmluYXJ5IG9wIG9uIHRoZSBnaXZlbiB0ZW5zb3JzJyk7XG4gICAgICAgIH1cbiAgICAgICAgb3V0cHV0U2hhcGUgPSBjYWxjdWxhdGVkU2hhcGU7XG4gICAgICAgIGNvbnN0IG91dHB1dFJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGFSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSAwID8gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIDogMTtcbiAgICAgICAgY29uc3QgYlJhbmsgPSBpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDAgPyBpbnB1dHNbMV0uZGltcy5sZW5ndGggOiAxO1xuICAgICAgICBjb25zdCBhQmNhc3QgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDAgPyAnYmNhc3RJbmRpY2VzX0EoaW5kaWNlcywgYWluZGljZXMpOycgOiAnYWluZGljZXNbMF0gPSAwOyc7XG4gICAgICAgIGNvbnN0IGJCY2FzdCA9IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMCA/ICdiY2FzdEluZGljZXNfQihpbmRpY2VzLCBiaW5kaWNlcyk7JyA6ICdiaW5kaWNlc1swXSA9IDA7JztcblxuICAgICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IHVzZVBhY2tlZFRleHR1cmUgPyBgXG4gICAgICAke2dsc2xGdW5jLmJvZHl9XG4gICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgIHZlYzQgYSA9IGdldEFBdE91dENvb3JkcygpO1xuICAgICAgICB2ZWM0IGIgPSBnZXRCQXRPdXRDb29yZHMoKTtcbiAgICAgICAgdmVjNCByZXN1bHQgPSAke2dsc2xGdW5jLm5hbWV9KGEsIGIpO1xuICAgICAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgICAgIH1gIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBcbiAgICAgICR7Z2xzbEZ1bmMuYm9keX1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtvdXRwdXRSYW5rfV0pIHtcbiAgICAgICAgaW50IGFpbmRpY2VzWyR7YVJhbmt9XTtcbiAgICAgICAgaW50IGJpbmRpY2VzWyR7YlJhbmt9XTtcbiAgICAgICAgJHthQmNhc3R9XG4gICAgICAgICR7YkJjYXN0fVxuICAgICAgICByZXR1cm4gJHtnbHNsRnVuYy5uYW1lfShfQShhaW5kaWNlcyksIF9CKGJpbmRpY2VzKSk7XG4gICAgICB9YDtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG5hbWU6IGdsc2xGdW5jLm5hbWUsXG4gICAgICAgICAgaW5wdXROYW1lczogWydBJywgJ0InXSxcbiAgICAgICAgICBpbnB1dFR5cGVzOiBbdGV4dHVyZVR5cGUsIHRleHR1cmVUeXBlXSxcbiAgICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogb3V0cHV0VGVuc29yVHlwZSwgdGV4dHVyZVR5cGV9LFxuICAgICAgICAgIHNoYWRlclNvdXJjZSxcbiAgICAgICAgICBoYXNNYWluOiB1c2VQYWNrZWRUZXh0dXJlXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgJHtnbHNsRnVuYy5ib2R5fVxuICAgIHZvaWQgbWFpbigpIHtcbiAgICAgIHZlYzQgdjEgPSAke2dsc2wudGV4dHVyZTJEfShBLCBUZXhDb29yZHMpO1xuICAgICAgdmVjNCB2MiA9ICR7Z2xzbC50ZXh0dXJlMkR9KEIsIFRleENvb3Jkcyk7XG4gICAgICB2ZWM0IHJlc3VsdCA9ICR7Z2xzbEZ1bmMubmFtZX0odjEsIHYyKTtcbiAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgIH1cbiAgICBgO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBuYW1lOiBnbHNsRnVuYy5uYW1lLFxuICAgICAgICBpbnB1dE5hbWVzOiBbJ0EnLCAnQiddLFxuICAgICAgICBpbnB1dFR5cGVzOiBbdGV4dHVyZVR5cGUsIHRleHR1cmVUeXBlXSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogaW5wdXRzWzBdLmRpbXMsIHR5cGU6IG91dHB1dFRlbnNvclR5cGUsIHRleHR1cmVUeXBlfSxcbiAgICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgICBoYXNNYWluOiB0cnVlXG4gICAgICB9O1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBhZGQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsQWRkKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IGFuZCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xBbmQoKSwgJ2Jvb2wnKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBkaXYgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsRGl2KCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IGVxdWFsID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbEVxdWFsKCksICdib29sJyksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgZ3JlYXRlciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xHcmVhdGVyKCksICdib29sJyksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgbGVzcyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xMZXNzKCksICdib29sJyksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgbXVsID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbE11bCgpKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBvciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xPcigpLCAnYm9vbCcpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IHBvdyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xQb3coKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgcFJlbHUgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsUFJlbHUoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3Qgc3ViID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbFN1YigpKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCB4b3IgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsWG9yKCksICdib29sJyksIGlucHV0cyldO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7UHJvdG9VdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBjYXN0OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFRlbnNvci5EYXRhVHlwZT4gPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIHRvOiBUZW5zb3IuRGF0YVR5cGUpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICAgICAgcmV0dXJuIFtoYW5kbGVyLmNhc3QoaW5wdXRzWzBdLCB0byldO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNhc3RBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFRlbnNvci5EYXRhVHlwZT4gPSAobm9kZTogR3JhcGguTm9kZSk6IFRlbnNvci5EYXRhVHlwZSA9PlxuICAgIFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byhub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCd0bycpKTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYXN0IHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07IiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge2dldENvb3Jkc0RhdGFUeXBlLCBnZXRHbENoYW5uZWxzfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7Q29uY2F0QXR0cmlidXRlc30gZnJvbSAnLi9jb25jYXQnO1xuaW1wb3J0IHtnZXRDaGFubmVscywgdW5wYWNrRnJvbUNoYW5uZWx9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YSA9IChpbnB1dENvdW50OiBudW1iZXIsIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnQ29uY2F0IChwYWNrZWQpJyxcbiAgaW5wdXROYW1lczogQXJyYXkuZnJvbSh7bGVuZ3RoOiBpbnB1dENvdW50fSwgKF92LCBpKSA9PiBgWCR7aX1gKSxcbiAgaW5wdXRUeXBlczogQXJyYXkoaW5wdXRDb3VudCkuZmlsbChUZXh0dXJlVHlwZS5wYWNrZWQpLFxuICBjYWNoZUhpbnRcbn0pO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtSW5mbyA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gICAgICBpZiAoYXhpcyA+PSBpbnB1dFNoYXBlLmxlbmd0aCB8fCBheGlzIDwgKC0xICogaW5wdXRTaGFwZS5sZW5ndGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYXhpcyBzcGVjaWZpZWQgZm9yIGNvbmNhdCBkb2VzblxcJ3QgbWF0Y2ggaW5wdXQgZGltZW5zaW9uYWxpdHknKTtcbiAgICAgIH1cbiAgICAgIGlmIChheGlzIDwgMCkge1xuICAgICAgICBheGlzID0gaW5wdXRTaGFwZS5sZW5ndGggKyBheGlzO1xuICAgICAgfVxuICAgICAgLy8gZW5zdXJlIGFsbCBvZiB0aGUgbm9uLWNvbmNhdGVuYXRlZCBheGVzIG1hdGNoIGVhY2ggb3RoZXJcbiAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgc2hhcGUgb2YgdGhlIG91dHB1dCB0ZW5zb3Igd2hpbGUgd2UgZG8gdGhhdFxuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlLnNsaWNlKDApO1xuICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgZGF0YU5TaGFwZSA9IGlucHV0c1tpXS5kaW1zLnNsaWNlKCk7XG4gICAgICAgIGZvciAobGV0IGF4aXNJbmRleCA9IDA7IGF4aXNJbmRleCA8IGlucHV0U2hhcGUubGVuZ3RoOyBheGlzSW5kZXgrKykge1xuICAgICAgICAgIC8vIGFkZCB0byB0aGUgcGxhY2Vob2xkZXIgZm9yIGNvbXB1dGluZyBvdXRwdXQgc2hhcGVcbiAgICAgICAgICBpZiAoYXhpc0luZGV4ID09PSBheGlzKSB7XG4gICAgICAgICAgICBvdXRwdXRTaGFwZVtheGlzXSArPSBkYXRhTlNoYXBlW2F4aXNJbmRleF07XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIGVuc3VyZSBhbGwgbm9uLWNhbmNhdGVuYXRlZCBheGVzIG1hdGNoIGVhY2ggb3RoZXJcbiAgICAgICAgICBlbHNlIGlmIChpbnB1dFNoYXBlW2F4aXNJbmRleF0gIT09IGRhdGFOU2hhcGVbYXhpc0luZGV4XSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub24gY29uY2F0IGRpbWVuc2lvbnMgbXVzdCBtYXRjaCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3QgY29vcmRzID0gZ2V0Q2hhbm5lbHMoJ2Nvb3JkcycsIHJhbmspO1xuICAgICAgY29uc3QgZHR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShyYW5rKTtcbiAgICAgIGNvbnN0IHVucGFja0NoYW5uZWwgPSB1bnBhY2tGcm9tQ2hhbm5lbCgpO1xuXG4gICAgICBjb25zdCBzaGFwZXMgPSBpbnB1dHMubWFwKGkgPT4gaS5kaW1zKTtcbiAgICAgIGNvbnN0IGNoYW5uZWxzID0gZ2V0R2xDaGFubmVscyhyYW5rKTtcbiAgICAgIGNvbnN0IG9mZnNldHM6IG51bWJlcltdID0gbmV3IEFycmF5KHNoYXBlcy5sZW5ndGggLSAxKTtcblxuICAgICAgb2Zmc2V0c1swXSA9IHNoYXBlc1swXVtheGlzXTtcbiAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgb2Zmc2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBvZmZzZXRzW2ldID0gb2Zmc2V0c1tpIC0gMV0gKyBzaGFwZXNbaV1bYXhpc107XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNoYW5uZWwgPSBjaGFubmVsc1theGlzXTtcbiAgICAgIGNvbnN0IGxhc3RDaGFubmVscyA9IGNoYW5uZWxzLnNsaWNlKC0yKTtcbiAgICAgIGNvbnN0IGFsbENoYW5uZWxzID0gY2hhbm5lbHMuam9pbigpO1xuXG4gICAgICBsZXQgZ2V0VmFsdWVTbmlwcGV0ID0gYGlmICgke2NoYW5uZWx9IDwgJHtvZmZzZXRzWzBdfSkge1xuICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgIGdldFgwKCR7YWxsQ2hhbm5lbHN9KSwgdmVjMigke2xhc3RDaGFubmVscy5qb2luKCl9KSk7XG4gICAgICAgIH1gO1xuICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBvZmZzZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHNoaWZ0ID0gb2Zmc2V0c1tpIC0gMV07XG4gICAgICAgIGdldFZhbHVlU25pcHBldCArPSBgXG4gICAgICAgICAgICBpZiAoJHtjaGFubmVsfSA8ICR7b2Zmc2V0c1tpXX0gICYmICR7Y2hhbm5lbH0gPj0gJHtvZmZzZXRzW2kgLSAxXX0pIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGdldENoYW5uZWwoXG4gICAgICAgICAgICAgICAgZ2V0WCR7aX0oJHtnZXRTaGlmdGVkQ2hhbm5lbHNTbmlwcGV0KGNoYW5uZWxzLCBjaGFubmVsLCBzaGlmdCl9KSxcbiAgICAgICAgICAgICAgICB2ZWMyKCR7Z2V0U2hpZnRlZENoYW5uZWxzU25pcHBldChsYXN0Q2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pKTtcbiAgICAgICAgICAgIH1gO1xuICAgICAgfVxuICAgICAgY29uc3QgbGFzdEluZGV4ID0gb2Zmc2V0cy5sZW5ndGg7XG4gICAgICBjb25zdCBzaGlmdCA9IG9mZnNldHNbb2Zmc2V0cy5sZW5ndGggLSAxXTtcbiAgICAgIGdldFZhbHVlU25pcHBldCArPSBgXG4gICAgICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgICAgZ2V0WCR7bGFzdEluZGV4fSgke2dldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQoY2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pLFxuICAgICAgICAgICAgICB2ZWMyKCR7Z2V0U2hpZnRlZENoYW5uZWxzU25pcHBldChsYXN0Q2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pKTtgO1xuXG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgICAke3VucGFja0NoYW5uZWx9XG4gICAgICAgICAgZmxvYXQgZ2V0VmFsdWUoJHtjaGFubmVscy5tYXAoeCA9PiAnaW50ICcgKyB4KX0pIHtcbiAgICAgICAgICAgICR7Z2V0VmFsdWVTbmlwcGV0fVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAgICR7ZHR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAgICAgICAgICAgaW50IGxhc3REaW0gPSBjb29yZHMuJHtjaGFubmVsc1tyYW5rIC0gMV19O1xuICAgICAgICAgICAgY29vcmRzLiR7Y2hhbm5lbHNbcmFuayAtIDFdfSA9IGNvb3Jkcy4ke2NoYW5uZWxzW3JhbmsgLSAyXX07XG4gICAgICAgICAgICBjb29yZHMuJHtjaGFubmVsc1tyYW5rIC0gMl19ID0gbGFzdERpbTtcblxuICAgICAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KGdldFZhbHVlKCR7Y29vcmRzfSksIDAuLCAwLiwgMC4pO1xuXG4gICAgICAgICAgICAke2Nvb3Jkc1tyYW5rIC0gMV19ID0gJHtjb29yZHNbcmFuayAtIDFdfSArIDE7XG4gICAgICAgICAgICBpZiAoJHtjb29yZHNbcmFuayAtIDFdfSA8ICR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkge1xuICAgICAgICAgICAgICByZXN1bHQuZyA9IGdldFZhbHVlKCR7Y29vcmRzfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICR7Y29vcmRzW3JhbmsgLSAyXX0gPSAke2Nvb3Jkc1tyYW5rIC0gMl19ICsgMTtcbiAgICAgICAgICAgIGlmICgke2Nvb3Jkc1tyYW5rIC0gMl19IDwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMl19KSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5hID0gZ2V0VmFsdWUoJHtjb29yZHN9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgJHtjb29yZHNbcmFuayAtIDFdfSA9ICR7Y29vcmRzW3JhbmsgLSAxXX0gLSAxO1xuICAgICAgICAgICAgaWYgKCR7Y29vcmRzW3JhbmsgLSAyXX0gPCAke291dHB1dFNoYXBlW3JhbmsgLSAyXX0gJiZcbiAgICAgICAgICAgICAgICAke2Nvb3Jkc1tyYW5rIC0gMV19IDwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMV19KSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5iID0gZ2V0VmFsdWUoJHtjb29yZHN9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZH0sXG4gICAgICAgIHNoYWRlclNvdXJjZSxcbiAgICAgICAgaGFzTWFpbjogdHJ1ZSxcbiAgICAgIH07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb25jYXRBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVQYWNrZWRDb25jYXRQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCwgYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gICAgICByZXR1cm4gey4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMuYXhpcyl9O1xuICAgIH07XG5cbmNvbnN0IGdldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQgPSAoY2hhbm5lbHM6IHN0cmluZ1tdLCBjaGFubmVsOiBzdHJpbmcsIHNoaWZ0OiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjaGFubmVsSWR4ID0gY2hhbm5lbHMuaW5kZXhPZihjaGFubmVsKTtcbiAgY29uc3QgcmVzID0gY2hhbm5lbHMubWFwKChjLCBpZHgpID0+IHtcbiAgICBpZiAoaWR4ID09PSBjaGFubmVsSWR4KSB7XG4gICAgICByZXR1cm4gYCR7Y30gLSAke3NoaWZ0fWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXMuam9pbigpO1xufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleX0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7Y3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXJ9IGZyb20gJy4vY29uY2F0LXBhY2tlZCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uY2F0QXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4aXM6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGNvbmNhdDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb25jYXRBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29uY2F0QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gICAgICBpZiAoaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLnBhY2sgJiYgaW5wdXRzWzBdLmRpbXMubGVuZ3RoID4gMSkge1xuICAgICAgICBjb25zdCBvdXRwdXQgPVxuICAgICAgICAgICAgaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID1cbiAgICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgICAgfVxuICAgIH07XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbU1ldGFkYXRhID0gKGlucHV0Q291bnQ6IG51bWJlciwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdDb25jYXQnLFxuICBpbnB1dE5hbWVzOiBBcnJheS5mcm9tKHtsZW5ndGg6IGlucHV0Q291bnR9LCAoX3YsIGkpID0+IGBYJHtpfWApLFxuICBpbnB1dFR5cGVzOiBBcnJheShpbnB1dENvdW50KS5maWxsKFRleHR1cmVUeXBlLnVucGFja2VkKSxcbiAgY2FjaGVIaW50XG59KTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mbyA9XG4gICAgKF9oYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIGlucHV0czogVGVuc29yW10sIGF4aXM6IG51bWJlcik6IFByb2dyYW1JbmZvID0+IHtcbiAgICAgIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICAgICAgaWYgKGF4aXMgPj0gaW5wdXRTaGFwZS5sZW5ndGggfHwgYXhpcyA8ICgtMSAqIGlucHV0U2hhcGUubGVuZ3RoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2F4aXMgc3BlY2lmaWVkIGZvciBjb25jYXQgZG9lc25cXCd0IG1hdGNoIGlucHV0IGRpbWVuc2lvbmFsaXR5Jyk7XG4gICAgICB9XG4gICAgICBpZiAoYXhpcyA8IDApIHtcbiAgICAgICAgYXhpcyA9IGlucHV0U2hhcGUubGVuZ3RoICsgYXhpcztcbiAgICAgIH1cbiAgICAgIC8vIGVuc3VyZSBhbGwgb2YgdGhlIG5vbi1jb25jYXRlbmF0ZWQgYXhlcyBtYXRjaCBlYWNoIG90aGVyXG4gICAgICAvLyBjYWxjdWxhdGUgdGhlIHNoYXBlIG9mIHRoZSBvdXRwdXQgdGVuc29yIHdoaWxlIHdlIGRvIHRoYXRcbiAgICAgIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgwKTtcbiAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGRhdGFOU2hhcGUgPSBpbnB1dHNbaV0uZGltcy5zbGljZSgpO1xuICAgICAgICBmb3IgKGxldCBheGlzSW5kZXggPSAwOyBheGlzSW5kZXggPCBpbnB1dFNoYXBlLmxlbmd0aDsgYXhpc0luZGV4KyspIHtcbiAgICAgICAgICAvLyBhZGQgdG8gdGhlIHBsYWNlaG9sZGVyIGZvciBjb21wdXRpbmcgb3V0cHV0IHNoYXBlXG4gICAgICAgICAgaWYgKGF4aXNJbmRleCA9PT0gYXhpcykge1xuICAgICAgICAgICAgb3V0cHV0U2hhcGVbYXhpc10gKz0gZGF0YU5TaGFwZVtheGlzSW5kZXhdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBlbnN1cmUgYWxsIG5vbi1jYW5jYXRlbmF0ZWQgYXhlcyBtYXRjaCBlYWNoIG90aGVyXG4gICAgICAgICAgZWxzZSBpZiAoaW5wdXRTaGFwZVtheGlzSW5kZXhdICE9PSBkYXRhTlNoYXBlW2F4aXNJbmRleF0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbm9uIGNvbmNhdCBkaW1lbnNpb25zIG11c3QgbWF0Y2gnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICAgICAgY29uc3Qgc2l6ZUluQ29uY2F0QXhpcyA9IG5ldyBBcnJheTxudW1iZXI+KGlucHV0cy5sZW5ndGgpO1xuICAgICAgbGV0IHByZXZpb3VzU3VtID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZUluQ29uY2F0QXhpcy5sZW5ndGg7ICsraSkge1xuICAgICAgICBwcmV2aW91c1N1bSArPSBpbnB1dHNbaV0uZGltc1theGlzXTtcbiAgICAgICAgc2l6ZUluQ29uY2F0QXhpc1tpXSA9IHByZXZpb3VzU3VtO1xuICAgICAgfVxuXG4gICAgICBsZXQgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZCA9ICcnO1xuICAgICAgLy8gaW4gbW9zdCBjYXNlcyBsaW5lYXIgc2VhcmNoIGlzIHN1ZmZpY2llbnQsIGFzIGluIG1vc3Qgc2NlbmFyaW9zLCBvbmx5IDIgdGVuc29ycyBhcmUgY29uY2F0ZW5hdGVkXG4gICAgICBpZiAoaW5wdXRzLmxlbmd0aCA8IDUpIHtcbiAgICAgICAgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZCA9IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNMaW5lYXJTZWFyY2goc2l6ZUluQ29uY2F0QXhpcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kID0gZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0JpbmFyeVNlYXJjaChzaXplSW5Db25jYXRBeGlzKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlTWV0aG9kID0gZ2V0RmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlTWV0aG9kKGlucHV0cy5sZW5ndGgsIHJhbmspO1xuICAgICAgY29uc3QgZ2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4TWV0aG9kID0gZ2V0R2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4TWV0aG9kKHNpemVJbkNvbmNhdEF4aXMpO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAke2ZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZU1ldGhvZH1cbiAgICAgICAgJHtnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXhNZXRob2R9XG4gICAgICAgICR7Z2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc01ldGhvZH1cbiAgICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCB0ZXh0dXJlSW5kZXggPSBnZXRUZXh0dXJlV2hlcmVEYXRhUmVzaWRlcyAoaW5kaWNlc1ske2F4aXN9XSk7XG5cbiAgICAgICAgICBpZih0ZXh0dXJlSW5kZXggIT0gMCkge1xuICAgICAgICAgICAgaW5kaWNlc1ske2F4aXN9XSA9IGluZGljZXNbJHtheGlzfV0gLSBpbnQoZ2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4KHRleHR1cmVJbmRleC1pbnQoMSkpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlKHRleHR1cmVJbmRleCwgaW5kaWNlcyk7XG4gICAgICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgfTtcbiAgICB9O1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb25jYXRBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgICAgIHJldHVybiB7Li4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mbyhoYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzLmF4aXMpfTtcbiAgICB9O1xuXG5jb25zdCBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTGluZWFyU2VhcmNoID0gKHNpemVJbkNvbmNhdEF4aXM6IG51bWJlcltdKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc2VhcmNoQXhpcyA9IHNpemVJbkNvbmNhdEF4aXMubWFwKChzaXplLCBpKSA9PiBgaWYoaW5kZXg8JHtzaXplfSkge3JldHVybiAke2l9O31cbmApO1xuICByZXR1cm4gYGludCBnZXRUZXh0dXJlV2hlcmVEYXRhUmVzaWRlcyhpbnQgaW5kZXgpIHtcbiAgICAgICR7c2VhcmNoQXhpcy5qb2luKCcnKX1cbiAgICB9YDtcbn07XG5cbi8vIFRPRE86IEltcGxlbWVudCBCaW5hcnlTZWFyY2ggaW4gR0xTTFxuY29uc3QgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0JpbmFyeVNlYXJjaCA9IChzaXplSW5Db25jYXRBeGlzOiBudW1iZXJbXSk6IHN0cmluZyA9PlxuICAgIGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNMaW5lYXJTZWFyY2goc2l6ZUluQ29uY2F0QXhpcyk7XG5cbmNvbnN0IGdldEZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZU1ldGhvZCA9IChudW1iZXJPZlRlbnNvcnM6IG51bWJlciwgdGVuc29yUmFuazogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IGNvZGVMaW5lczogc3RyaW5nW10gPSBbYGZsb2F0IGZldGNoRGF0YUZyb21Db3JyZWN0VGV4dHVyZShpbnQgdGV4dHVyZUluZGV4LCBpbnQgaW5kaWNlc1ske3RlbnNvclJhbmt9XSkge2BdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mVGVuc29yczsgKytpKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgICAgICdcXHQnICtcbiAgICAgICAgICBgaWYgKHRleHR1cmVJbmRleCA9PSAke2l9KSB7IHJldHVybiBfWCR7aX0oaW5kaWNlcyk7IH1gKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IG51bWJlck9mVGVuc29ycyAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgICAgICdcXHQnICtcbiAgICAgICAgICBgZWxzZSB7IHJldHVybiBfWCR7aX0oaW5kaWNlcyk7IH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZUxpbmVzLnB1c2goXG4gICAgICAgICAgJ1xcdCcgK1xuICAgICAgICAgIGBlbHNlIGlmICh0ZXh0dXJlSW5kZXggPT0gJHtpfSkgeyByZXR1cm4gX1gke2l9KGluZGljZXMpOyB9YCk7XG4gICAgfVxuICB9XG4gIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgJ1xcdCcgK1xuICAgICAgJ30nKTtcbiAgcmV0dXJuIGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcbn07XG5cbmNvbnN0IGdldEdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleE1ldGhvZCA9IChzaXplSW5Db25jYXRBeGlzOiBudW1iZXJbXSk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNvZGVMaW5lczogc3RyaW5nW10gPSBbJ2ludCBnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXgoaW50IGluZGV4KSB7J107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZUluQ29uY2F0QXhpcy5sZW5ndGg7ICsraSkge1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBjb2RlTGluZXMucHVzaChcbiAgICAgICAgICAnXFx0JyArXG4gICAgICAgICAgYGlmIChpbmRleCA9PSAke2l9KSB7IHJldHVybiAke3NpemVJbkNvbmNhdEF4aXNbaV19OyB9YCk7XG4gICAgfSBlbHNlIGlmIChpID09PSBzaXplSW5Db25jYXRBeGlzLmxlbmd0aCAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgICAgICdcXHQnICtcbiAgICAgICAgICBgZWxzZSB7IHJldHVybiAke3NpemVJbkNvbmNhdEF4aXNbaV19OyB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgICAgICdcXHQnICtcbiAgICAgICAgICBgZWxzZSBpZiAoaW5kZXggPT0gJHtpfSkgeyByZXR1cm4gJHtzaXplSW5Db25jYXRBeGlzW2ldfTsgfWApO1xuICAgIH1cbiAgfVxuICBjb2RlTGluZXMucHVzaChcbiAgICAgICdcXHQnICtcbiAgICAgICd9Jyk7XG5cbiAgcmV0dXJuIGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNvbmNhdEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248Q29uY2F0QXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IENvbmNhdEF0dHJpYnV0ZXMgPT5cbiAgICBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe2F4aXM6IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnKX0pO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0b28gZmV3IGlucHV0cycpO1xuICB9XG5cbiAgY29uc3QgaW5wdXRUeXBlID0gaW5wdXRzWzBdLnR5cGU7XG4gIGNvbnN0IGlucHV0RGltZW5zaW9uYWxpdHkgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG5cbiAgLy8gVE9ETzogU3VwcG9ydCBzdHJpbmcgY29uY2F0XG4gIGlmIChpbnB1dFR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpbmcgdGVuc29yIGlzIG5vdCBzdXBwb3J0ZWQgeWV0Jyk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGlucHV0IG9mIGlucHV0cykge1xuICAgIC8vIG1ha2Ugc3VyZSB0eXBlcyBvZiBhbGwgaW5wdXRzIG1hdGNoXG4gICAgaWYgKGlucHV0LnR5cGUgIT09IGlucHV0VHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCB0ZW5zb3JzIHNob3VsZCBiZSBvbmUgdHlwZScpO1xuICAgIH1cblxuICAgIC8vIG1ha2Ugc3VyZSB0aGUgZGltZW5zaW9uYWxpdHkgb2YgYWxsIGlucHV0cyBhcmUgdGhlIHNhbWVcbiAgICBpZiAoaW5wdXQuZGltcy5sZW5ndGggIT09IGlucHV0RGltZW5zaW9uYWxpdHkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgdGVuc29ycyBzaG91bGQgaGF2ZSB0aGUgc2FtZSBzaGFwZScpO1xuICAgIH1cbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleX0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtNQVhfQ0xJUCwgTUlOX0NMSVB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtGdW5jdGlvblR5cGUsIEdsc2xWYWx1ZUZ1bmN0aW9ufSBmcm9tICcuLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQWJzKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2FicycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBY29zKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2Fjb3MnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQXNpbigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdhc2luJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEF0YW4oKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnYXRhbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xDZWlsKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2NlaWwnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQ29zKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2NvcycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xFbHUoYWxwaGE6IG51bWJlcik6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdlbHUnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBhbHBoYSA9IGZsb2F0KCR7YWxwaGF9KTtcblxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGEgPj0gMC4wID8gYTogKGV4cChhKSAtIDEuMCkgKiBhbHBoYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2ZWM0KCR7bmFtZX1fKHYueCksICR7bmFtZX1fKHYueSksICR7bmFtZX1fKHYueiksICR7bmFtZX1fKHYudykpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xFeHAoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnZXhwJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEZsb29yKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2Zsb29yJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbENsaXAobWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2NsaXAnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBtaW4gPSBmbG9hdCgke21pbn0pO1xuICBjb25zdCBmbG9hdCBtYXggPSBmbG9hdCgke21heH0pO1xuXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gY2xhbXAoYSwgbWluLCBtYXgpO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIGNsYW1wKHYsIG1pbiwgbWF4KTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsSWRlbnRpdHkoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2luZGVudGl0eSc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2O1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xMZWFreVJlbHUoYWxwaGE6IG51bWJlcik6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdsZWFreVJlbHUnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBhbHBoYSA9IGZsb2F0KCR7YWxwaGF9KTtcblxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGEgPCAwLjAgPyBhICogYWxwaGEgOiBhO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIHZlYzQoJHtuYW1lfV8odi54KSwgJHtuYW1lfV8odi55KSwgJHtuYW1lfV8odi56KSwgJHtuYW1lfV8odi53KSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbExvZygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdsb2cnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTmVnKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICduZWcnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIC1hO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIC12O1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xOb3QoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ25vdCc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gZmxvYXQoICEgYm9vbChhKSApO1xuICB9XG4gIGJvb2wgJHtuYW1lfV8oYm9vbCBhKSB7XG4gICAgcmV0dXJuICFhO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIHZlYzQoIWJvb2wodi54KSwgIWJvb2wodi55KSwgIWJvb2wodi56KSwgIWJvb2wodi53KSk7XG4gIH1cbiAgYnZlYzQgJHtuYW1lfV8oYnZlYzQgdikge1xuICAgIHJldHVybiBidmVjNCghdi54LCAhdi55LCAhdi56LCAhdi53KTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU2luKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ3NpbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xSZWx1KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdyZWx1JztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBtYXgoIGEsIDAuMCApO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIG1heCggdiwgMC4wICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFNpZ21vaWQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3NpZ21vaWQnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIDEuMCAvICgxLjAgKyBleHAoLWEpKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiAxLjAgLyAoMS4wICsgZXhwKC12KSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFNxcnQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnc3FydCcpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xUYW4oKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgndGFuJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFRhbmgoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3RhbmgnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgYSA9IGNsYW1wKGEsIC0xMC4sIDEwLik7XG4gICAgYSA9IGV4cCgyLiphKTtcbiAgICByZXR1cm4gKGEgLSAxLikgLyAoYSArIDEuKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHYgPSBjbGFtcCh2LCAtMTAuLCAxMC4pO1xuICAgIHYgPSBleHAoMi4qdik7XG4gICAgcmV0dXJuICh2IC0gMS4pIC8gKHYgKyAxLik7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5mdW5jdGlvbiBnbHNsQnVpbHRpblVuYXJ5KG5hbWU6IHN0cmluZyk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiAke25hbWV9KGEpO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuICR7bmFtZX0odik7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5cbi8vLy8vXG4vLy8vL1xuLy8vLy9cblxuY29uc3QgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXQ6IFRlbnNvciwgZ2xzbEZ1bmM6IEdsc2xWYWx1ZUZ1bmN0aW9uKTpcbiAgICAgICAgUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgICAgIGNvbnN0IHRleHR1cmVUeXBlID0gaGFuZGxlci5zZXNzaW9uLnBhY2sgPyBUZXh0dXJlVHlwZS5wYWNrZWQgOiBUZXh0dXJlVHlwZS51bnBhY2tlZDtcbiAgICAgICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICAgICAgb3V0cHV0OiB7ZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGV9LFxuICAgICAgICAgICAgc2hhZGVyU291cmNlOiBgXG4gICAgICR7Z2xzbEZ1bmMuYm9keX1cbiAgICAgdm9pZCBtYWluKCkge1xuICAgICAgIHZlYzQgdiA9ICR7Z2xzbC50ZXh0dXJlMkR9KEEsIFRleENvb3Jkcyk7XG4gICAgICAgdiA9ICR7Z2xzbEZ1bmMubmFtZX1fKHYpO1xuICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdjtcbiAgICAgfVxuICAgICBgLFxuICAgICAgICAgICAgaGFzTWFpbjogdHJ1ZVxuICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbmNvbnN0IGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIgPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbiwgY2FjaGVLZXk/OiBzdHJpbmcpOlxuICAgICAgICBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gICAgICAgICAgY29uc3QgdGV4dHVyZVR5cGUgPSBoYW5kbGVyLnNlc3Npb24ucGFjayA/IFRleHR1cmVUeXBlLnBhY2tlZCA6IFRleHR1cmVUeXBlLnVucGFja2VkO1xuICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0ge25hbWU6IGdsc2xGdW5jLm5hbWUsIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZV0sIGlucHV0TmFtZXM6IFsnQSddLCBjYWNoZUhpbnQ6IGNhY2hlS2V5fTtcbiAgICAgICAgICByZXR1cm4gey4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0LCBnbHNsRnVuYyl9O1xuICAgICAgICB9O1xuXG5leHBvcnQgY29uc3QgYWJzID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQWJzKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IGFjb3MgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBY29zKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IGFzaW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBc2luKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IGF0YW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBdGFuKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGludGVyZmFjZSBDbGlwQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IG1pbjogbnVtYmVyO1xuICByZWFkb25seSBtYXg6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGNsaXAgPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENsaXBBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKFxuICAgICAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKFxuICAgICAgICAgICAgaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQ2xpcChhdHRyaWJ1dGVzLm1pbiwgYXR0cmlidXRlcy5tYXgpLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KSxcbiAgICAgICAgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNsaXBBdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBDbGlwQXR0cmlidXRlcyA9PiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoXG4gICAge21pbjogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtaW4nLCBNSU5fQ0xJUCksIG1heDogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtYXgnLCBNQVhfQ0xJUCl9KTtcblxuZXhwb3J0IGNvbnN0IGNsaXBWMTEgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICBjb25zdCBhdHRyaWJ1dGVzID0gZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMoaGFuZGxlciwgaW5wdXRzKTtcbiAgcmV0dXJuIGNsaXAoaGFuZGxlciwgW2lucHV0c1swXV0sIGF0dHJpYnV0ZXMpO1xufTtcblxuY29uc3QgZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogQ2xpcEF0dHJpYnV0ZXMgPT4ge1xuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSAzICYmXG4gICAgICAoIWhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1sxXS5kYXRhSWQpIHx8ICFoYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMl0uZGF0YUlkKSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2R5bmFtaWMgY2xpcCBhdHRyaWJ1dGVzIGFyZSBub3QgYWxsb3dlZCcpO1xuICB9XG5cbiAgY29uc3QgbWluID0gKGlucHV0cy5sZW5ndGggPj0gMykgPyBpbnB1dHNbMV0ubnVtYmVyRGF0YVswXSA6IE1JTl9DTElQO1xuICBjb25zdCBtYXggPSAoaW5wdXRzLmxlbmd0aCA+PSAzKSA/IGlucHV0c1syXS5udW1iZXJEYXRhWzBdIDogTUFYX0NMSVA7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe21pbiwgbWF4fSk7XG59O1xuXG5leHBvcnQgY29uc3QgY2VpbCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbENlaWwoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgY29zID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQ29zKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGludGVyZmFjZSBFbHVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYWxwaGE6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGVsdSA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogRWx1QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihcbiAgICAgICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xFbHUoYXR0cmlidXRlcy5hbHBoYSksIGF0dHJpYnV0ZXMuY2FjaGVLZXkpLFxuICAgICAgICBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRWx1QXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlKTogRWx1QXR0cmlidXRlcyA9PlxuICAgIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7YWxwaGE6IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAxLjApfSk7XG5cbmV4cG9ydCBjb25zdCBleHAgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xFeHAoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgZmxvb3IgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xGbG9vcigpKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBpZGVudGl0eSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbElkZW50aXR5KCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGludGVyZmFjZSBMZWFreVJlbHVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYWxwaGE6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGxlYWt5UmVsdSA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogTGVha3lSZWx1QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihcbiAgICAgICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xMZWFreVJlbHUoYXR0cmlidXRlcy5hbHBoYSksIGF0dHJpYnV0ZXMuY2FjaGVLZXkpLFxuICAgICAgICBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTGVha3lSZWx1QXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlKTogTGVha3lSZWx1QXR0cmlidXRlcyA9PlxuICAgIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7YWxwaGE6IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAwLjAxKX0pO1xuXG5leHBvcnQgY29uc3QgbG9nID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsTG9nKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IG5lZyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbE5lZygpKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBub3QgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xOb3QoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgcmVsdSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFJlbHUoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3Qgc2lnbW9pZCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFNpZ21vaWQoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3Qgc2luID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsU2luKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IHNxcnQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xTcXJ0KCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IHRhbiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFRhbigpKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCB0YW5oID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsVGFuaCgpKSwgaW5wdXRzKV07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlfSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUnO1xuaW1wb3J0IHtNQVhfQ0xJUCwgTUlOX0NMSVB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtHbHNsVmFsdWVGdW5jdGlvbn0gZnJvbSAnLi4vZ2xzbC1kZWZpbml0aW9ucyc7XG5cbmltcG9ydCB7Z2xzbENsaXAsIGdsc2xSZWx1LCBnbHNsU2lnbW9pZH0gZnJvbSAnLi91bmFyeS1vcCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IGFjdGl2YXRpb246IHN0cmluZztcbiAgcmVhZG9ubHkgY2xpcE1pbj86IG51bWJlcjtcbiAgcmVhZG9ubHkgY2xpcE1heD86IG51bWJlcjtcbiAgcmVhZG9ubHkgYWN0aXZhdGlvbkNhY2hlS2V5OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBY3RpdmF0aW9uU25pcHBldChhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKSB7XG4gIGxldCBmdW5jOiBHbHNsVmFsdWVGdW5jdGlvbjtcbiAgc3dpdGNoIChhdHRyaWJ1dGVzLmFjdGl2YXRpb24pIHtcbiAgICBjYXNlICdSZWx1JzpcbiAgICAgIGZ1bmMgPSBnbHNsUmVsdSgpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnU2lnbW9pZCc6XG4gICAgICBmdW5jID0gZ2xzbFNpZ21vaWQoKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0NsaXAnOlxuICAgICAgZnVuYyA9IGdsc2xDbGlwKGF0dHJpYnV0ZXMuY2xpcE1pbiEsIGF0dHJpYnV0ZXMuY2xpcE1heCEpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gVE9ETzogYWRkaW5nIG90aGVyIGFjdGl2YXRpb25zIHRoYXQgY2FuIGJlIGZ1c2VkLlxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4ge2FjdGl2YXRpb25GdW5jdGlvbjogJycsIGFwcGx5QWN0aXZhdGlvbjogJyd9O1xuICB9XG5cbiAgY29uc3QgYWN0aXZhdGlvbk5hbWUgPSBmdW5jLm5hbWU7XG4gIGNvbnN0IGFjdGl2YXRpb25GdW5jdGlvbiA9IGZ1bmMuYm9keTtcbiAgY29uc3QgYXBwbHlBY3RpdmF0aW9uID0gYHZhbHVlID0gJHthY3RpdmF0aW9uTmFtZX1fKHZhbHVlKTtgO1xuICByZXR1cm4ge2FjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9ufTtcbn1cblxuZXhwb3J0IGNvbnN0IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyA9IChhdHRyaWJ1dGVzOiBBdHRyaWJ1dGUpOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYWN0aXZhdGlvbiA9IGF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhY3RpdmF0aW9uJywgJycpO1xuXG4gIGlmIChhY3RpdmF0aW9uID09PSAnQ2xpcCcpIHtcbiAgICBjb25zdCBbY2xpcE1pbiwgY2xpcE1heF0gPSBhdHRyaWJ1dGVzLmdldEZsb2F0cygnYWN0aXZhdGlvbl9wYXJhbXMnLCBbTUlOX0NMSVAsIE1BWF9DTElQXSk7XG4gICAgcmV0dXJuIHthY3RpdmF0aW9uLCBjbGlwTWF4LCBjbGlwTWluLCBhY3RpdmF0aW9uQ2FjaGVLZXk6IGAke2FjdGl2YXRpb259OiR7Y2xpcE1pbn0sJHtjbGlwTWF4fWB9O1xuICB9XG4gIHJldHVybiB7YWN0aXZhdGlvbiwgYWN0aXZhdGlvbkNhY2hlS2V5OiBhY3RpdmF0aW9ufTtcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuLi8uLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtjYWxjdWxhdGVPdXRwdXRTaGFwZSwgQ29udkF0dHJpYnV0ZXN9IGZyb20gJy4vY29udic7XG5pbXBvcnQge2dldEFjdGl2YXRpb25TbmlwcGV0fSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKTogUHJvZ3JhbU1ldGFkYXRhID0+ICh7XG4gIG5hbWU6ICdHcm91cGVkQ29udicsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ1gnLCAnVycsICdCaWFzJ10gOiBbJ1gnLCAnVyddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnRcbn0pO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gICAgIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICAgICAgY29uc3QgcHJvY2Vzc0JpYXMgPSBoYXNCaWFzID8gJ3ZhbHVlICs9IGdldEJpYXMob3V0cHV0X2NoYW5uZWwpOycgOiAnJztcbiAgICAgIGNvbnN0IHhTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gICAgICBjb25zdCB3U2hhcGUgPSBpbnB1dHNbMV0uZGltcy5zbGljZSgpO1xuICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbHNQZXJHcm91cCA9IHdTaGFwZVswXSAvIGF0dHJpYnV0ZXMuZ3JvdXA7XG4gICAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgICAgICAnR3JvdXBlZENvbnYnLFxuICAgICAgICAgIGBhdXRwUGFkOiR7YXR0cmlidXRlcy5hdXRvUGFkfSwgZGlsYXRpb25zOiR7YXR0cmlidXRlcy5kaWxhdGlvbnN9LCBncm91cDoke2F0dHJpYnV0ZXMuZ3JvdXB9LCBrZXJuZWxTaGFwZToke1xuICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlfSwgcGFkczoke2F0dHJpYnV0ZXMucGFkc30sIHN0cmlkZXM6JHthdHRyaWJ1dGVzLnN0cmlkZXN9YCk7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9XG4gICAgICAgICAgY2FsY3VsYXRlT3V0cHV0U2hhcGUoeFNoYXBlLCB3U2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICBjb25zdCB7YWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb259ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcyk7XG5cbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgY29uc3QgaXZlYzIgc3RyaWRlcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5zdHJpZGVzWzBdfSwgJHthdHRyaWJ1dGVzLnN0cmlkZXNbMV19KTtcbiAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5wYWRzWzBdfSwgJHthdHRyaWJ1dGVzLnBhZHNbMV19KTtcbiAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gIHZvaWQgbWFpbigpIHtcbiAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDtcbiAgICBpbnQgb3V0cHV0X2NoYW5uZWwgPSBjb29yZHMueTtcbiAgICBpdmVjMiB4UkNDb3JuZXIgPSBjb29yZHMuencgKiBzdHJpZGVzIC0gcGFkcztcbiAgICBpbnQgZ3JvdXBfaWQgPSBvdXRwdXRfY2hhbm5lbCAvICR7b3V0cHV0Q2hhbm5lbHNQZXJHcm91cH07XG5cbiAgICBmbG9hdCB2YWx1ZSA9IDAuMDtcbiAgICBmb3IgKGludCB3SW5DaGFubmVsID0gMDsgd0luQ2hhbm5lbCA8ICR7d1NoYXBlWzFdfTsgd0luQ2hhbm5lbCsrKSB7XG4gICAgICBpbnQgaW5wdXRfY2hhbm5lbCA9IGdyb3VwX2lkICogJHt3U2hhcGVbMV19ICsgd0luQ2hhbm5lbDtcbiAgICAgIGZvciAoaW50IHdIZWlnaHQgPSAwOyB3SGVpZ2h0IDwgJHt3U2hhcGVbMl19OyB3SGVpZ2h0KyspIHtcbiAgICAgICAgaW50IHhIZWlnaHQgPSB4UkNDb3JuZXIueCArIHdIZWlnaHQgKiAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzBdfTtcblxuICAgICAgICBpZiAoeEhlaWdodCA8IDAgfHwgeEhlaWdodCA+PSAke3hTaGFwZVsyXX0pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaW50IHdXaWR0aCA9IDA7IHdXaWR0aCA8ICR7d1NoYXBlWzNdfTsgd1dpZHRoKyspIHtcbiAgICAgICAgICBpbnQgeFdpZHRoID0geFJDQ29ybmVyLnkgKyB3V2lkdGggKiAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzFdfTtcbiAgICAgICAgICBpZiAoeFdpZHRoIDwgMCB8fCB4V2lkdGggPj0gJHt4U2hhcGVbM119KSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmbG9hdCB4VmFsID0gZ2V0WChiYXRjaCwgaW5wdXRfY2hhbm5lbCwgeFdpZHRoLCB4SGVpZ2h0KTtcbiAgICAgICAgICBmbG9hdCB3VmFsID0gZ2V0VyhvdXRwdXRfY2hhbm5lbCwgd0luQ2hhbm5lbCwgd1dpZHRoLCB3SGVpZ2h0KTtcbiAgICAgICAgICB2YWx1ZSArPSB4VmFsKndWYWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgJHtwcm9jZXNzQmlhc31cbiAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQodmFsdWUsIC4wLCAuMCwgLjApO1xuICB9XG5gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgICBoYXNNYWluOiB0cnVlLFxuICAgICAgfTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6XG4gICAgICAgIFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgICAgICAgICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgbWV0YWRhdGEsIGF0dHJpYnV0ZXMpXG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge2dldEdsc2x9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge0NvbnZBdHRyaWJ1dGVzfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHt1bnBhY2tGcm9tQ2hhbm5lbH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbU1ldGFkYXRhID0gKGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnSW0yQ29sIChwYWNrZWQpJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS5wYWNrZWRdLFxuICBjYWNoZUhpbnQsXG59KTtcblxuY29uc3QgY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIHg6IFRlbnNvciwgdzogVGVuc29yLFxuICAgICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgeHNoYXBlID0geC5kaW1zO1xuICAgICAgY29uc3Qgd3NoYXBlID0gdy5kaW1zO1xuICAgICAgY29uc3Qgcm93RGltID0gMjtcbiAgICAgIGNvbnN0IGNvbERpbSA9IDM7XG4gICAgICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3QgaW0yY29sU2hhcGUgPSBbd3NoYXBlWzFdICogd3NoYXBlWzJdICogd3NoYXBlWzNdLCBvdXRwdXRTaGFwZVsyXSAqIG91dHB1dFNoYXBlWzNdXTtcbiAgICAgIGNvbnN0IGtlcm5lbFNpemUgPSB3c2hhcGVbMl0gKiB3c2hhcGVbM107XG4gICAgICBjb25zdCB1bnBhY2tDaGFubmVsID0gdW5wYWNrRnJvbUNoYW5uZWwoKTtcbiAgICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAgIGxldCB1bnJvbGxlZCA9ICcnO1xuXG4gICAgICBmb3IgKGxldCByb3cgPSAwOyByb3cgPD0gMTsgcm93KyspIHtcbiAgICAgICAgZm9yIChsZXQgY29sID0gMDsgY29sIDw9IDE7IGNvbCsrKSB7XG4gICAgICAgICAgdW5yb2xsZWQgKz0gYFxuICAgICAgICAgICAgYmxvY2tJbmRleCA9IHJjLnggKyAke2NvbH07XG4gICAgICAgICAgICBwb3MgPSByYy55ICsgJHtyb3d9O1xuXG4gICAgICAgICAgICBpZihibG9ja0luZGV4IDwgJHtpbTJjb2xTaGFwZVsxXX0gJiYgcG9zIDwgJHtpbTJjb2xTaGFwZVswXX0pIHtcbiAgICAgICAgICAgICAgb2Zmc2V0WSA9IGludChibG9ja0luZGV4IC8gKCR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkpICogJHthdHRyaWJ1dGVzLnN0cmlkZXNbMF19IC1cbiAgICAgICAgICAgICAgICAke2F0dHJpYnV0ZXMucGFkc1swXX07XG4gICAgICAgICAgICAgIGQwID0gb2Zmc2V0WSArICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMF19ICogKGltb2QocG9zLCAke2tlcm5lbFNpemV9KSAvICR7d3NoYXBlWzJdfSk7XG5cbiAgICAgICAgICAgICAgaWYoZDAgPCAke3hzaGFwZVtyb3dEaW1dfSAmJiBkMCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0WCA9IGltb2QoYmxvY2tJbmRleCwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMV19KSAqICR7YXR0cmlidXRlcy5zdHJpZGVzWzFdfSAtXG4gICAgICAgICAgICAgICAgICAke2F0dHJpYnV0ZXMucGFkc1sxXX07XG4gICAgICAgICAgICAgICAgZDEgPSBvZmZzZXRYICsgJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX0gKiBpbW9kKGltb2QocG9zLCAke2tlcm5lbFNpemV9KSwgJHt3c2hhcGVbMl19KTtcblxuICAgICAgICAgICAgICAgIGlmKGQxIDwgJHt4c2hhcGVbY29sRGltXX0gJiYgZDEgPj0gMCkge1xuXG4gICAgICAgICAgICAgICAgICBjaCA9IGludChmbG9hdChwb3MpLyAke2tlcm5lbFNpemV9Lik7XG4gICAgICAgICAgICAgICAgICAgIGlubmVyRGltcyA9IHZlYzIoZDAsIGQxKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0WyR7cm93ICogMiArIGNvbH1dID0gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgICAgICAgICAgICBnZXRBKDAsIGNoLCBpbnQoaW5uZXJEaW1zLngpLFxuICAgICAgICAgICAgICAgICAgICAgIGludChpbm5lckRpbXMueSkpLCBpbm5lckRpbXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgYDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke3VucGFja0NoYW5uZWx9XG5cbiAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgaXZlYzIgcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMC4wKTtcbiAgICAgICAgICBpbnQgYmxvY2tJbmRleCwgcG9zLCBvZmZzZXRZLCBkMCwgb2Zmc2V0WCwgZDEsIGNoO1xuICAgICAgICAgIHZlYzIgaW5uZXJEaW1zO1xuICAgICAgICAgICR7dW5yb2xsZWR9XG4gICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICB9XG4gICAgICAgICAgICBgO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IGltMmNvbFNoYXBlLCB0eXBlOiB4LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2UsXG4gICAgICAgIGhhc01haW46IHRydWVcbiAgICAgIH07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCB4OiBUZW5zb3IsIHc6IFRlbnNvciwgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbU1ldGFkYXRhKGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIGdldDogKCkgPT4gY3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIHgsIHcsIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKVxuICAgICAgfTtcbiAgICB9O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7QnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHtnZXRDb29yZHNEYXRhVHlwZSwgZ2V0R2xDaGFubmVsc30gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQge2dldEFjdGl2YXRpb25TbmlwcGV0LCBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXN9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQge2NyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyfSBmcm9tICcuL21hdG11bC1wYWNrJztcblxuZXhwb3J0IGNvbnN0IG1hdE11bDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgICAgIGlmIChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24ucGFjaykge1xuICAgICAgICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgICAgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyKGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyldO1xuICAgICAgfVxuICAgIH07XG5cbmV4cG9ydCBjb25zdCBwYXJzZU1hdE11bEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248SW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyA9PiBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMobm9kZS5hdHRyaWJ1dGVzKTtcblxuY29uc3QgY3JlYXRlTWF0bXVsUHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnTWF0TXVsJyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnQScsICdCJywgJ0JpYXMnXSA6IFsnQScsICdCJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXMgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0gOlxuICAgICAgICAgICAgICAgICAgICAgICAgW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludFxufSk7XG5cbmZ1bmN0aW9uIGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvKFxuICAgIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIGlucHV0czogVGVuc29yW10sIGFjdGl2YXRpb25BdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8ge1xuICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoYVNoYXBlLCBiU2hhcGUsIHRydWUpO1xuICBpZiAoIW91dHB1dFNoYXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXCd0IHVzZSBtYXRtdWwgb24gdGhlIGdpdmVuIHRlbnNvcnMnKTtcbiAgfVxuICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gIGNvbnN0IGFsbEdsQ2hhbm5lbHMgPSBnZXRHbENoYW5uZWxzKCk7XG4gIGNvbnN0IHthY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbn0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhY3RpdmF0aW9uQXR0cmlidXRlcyk7XG5cbiAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICBjb25zdCBwcm9jZXNzQmlhcyA9IGhhc0JpYXMgPyAndmFsdWUgKz0gZ2V0Qmlhc0Zvck1hdG11bCgpOycgOiAnJztcbiAgY29uc3QgZ2V0Qmlhc0Zvck1hdG11bFNuaXBwZXQgPVxuICAgICAgaGFzQmlhcyA/IGAke2dldEJpYXNGb3JNYXRtdWwoY29vcmRzRGF0YVR5cGUsIGFsbEdsQ2hhbm5lbHMsIGlucHV0c1syXS5kaW1zLCBvdXRwdXRTaGFwZSwgZmFsc2UpfWAgOiAnJztcblxuICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICBjb25zdCBhcmFuayA9IGFTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGJyYW5rID0gYlNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgc2hhcmVkRGltID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAxXTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICR7YWN0aXZhdGlvbkZ1bmN0aW9ufVxuICAgICR7Z2V0Qmlhc0Zvck1hdG11bFNuaXBwZXR9XG4gICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICBpbnQgYVske2FyYW5rfV07XG4gICAgICAgIGludCBiWyR7YnJhbmt9XTtcbiAgICAgICAgYmNhc3RNYXRtdWxJbmRpY2VzX0EoaW5kaWNlcywgYSk7XG4gICAgICAgIGJjYXN0TWF0bXVsSW5kaWNlc19CKGluZGljZXMsIGIpO1xuXG4gICAgICAgIGZsb2F0IHZhbHVlO1xuICAgICAgICBmb3IgKGludCBrPTA7IGs8JHtzaGFyZWREaW19OyArK2spIHtcbiAgICAgICAgICAgIGFbJHthcmFuayAtIDF9XSA9IGs7XG4gICAgICAgICAgICBiWyR7YnJhbmsgLSAyfV0gPSBrO1xuICAgICAgICAgICAgdmFsdWUgKz0gX0EoYSkgKiBfQihiKTtcbiAgICAgICAgfVxuICAgICAgICAke3Byb2Nlc3NCaWFzfVxuICAgICAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICBzaGFkZXJTb3VyY2UsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihcbiAgICBpbnB1dHM6IFRlbnNvcltdLCBhY3RpdmF0aW9uQXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvTG9hZGVyIHtcbiAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVNYXRtdWxQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGFjdGl2YXRpb25BdHRyaWJ1dGVzLmFjdGl2YXRpb25DYWNoZUtleSk7XG4gIHJldHVybiB7Li4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm8obWV0YWRhdGEsIGlucHV0cywgYWN0aXZhdGlvbkF0dHJpYnV0ZXMpfTtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNYXRNdWwgcmVxdWlyZXMgMiBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLmRpbXNbaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMV0gIT09IGlucHV0c1sxXS5kaW1zW2lucHV0c1sxXS5kaW1zLmxlbmd0aCAtIDJdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzaGFyZWQgZGltZW5zaW9uIGRvZXMgbm90IG1hdGNoLicpO1xuICB9XG5cbiAgaWYgKChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgICAoaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0NjQnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXRzIHNob3VsZCBiZSBmbG9hdCB0eXBlJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1sxXS50eXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dHMgdHlwZXMgc2hvdWxkIG1hdGNoJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCaWFzRm9yTWF0bXVsKFxuICAgIGNvb3Jkc0RhdGFUeXBlOiBzdHJpbmcsIGFsbEdsQ2hhbm5lbHM6IHJlYWRvbmx5IHN0cmluZ1tdLCBpblNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgb3V0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgIGlzUGFja2VkOiBib29sZWFuKTogc3RyaW5nIHtcbiAgbGV0IHVucGFja2VkQ29vcmRzU25pcHBldCA9ICcnO1xuICBjb25zdCBpblJhbmsgPSBpblNoYXBlLmxlbmd0aDtcbiAgY29uc3Qgb3V0UmFuayA9IG91dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgcmFua0RpZmYgPSBvdXRSYW5rIC0gaW5SYW5rO1xuICBpZiAob3V0UmFuayA8IDIgJiYgaW5SYW5rID4gMCkge1xuICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9ICdjb29yZHMnO1xuICB9IGVsc2Uge1xuICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9IGluU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbaSArIHJhbmtEaWZmXX1gKS5qb2luKCcsICcpO1xuICB9XG4gIGNvbnN0IGJyb2FkY2FzdERpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5TaGFwZSwgb3V0U2hhcGUpO1xuICBjb25zdCBjb29yZHNTbmlwcGV0ID0gYnJvYWRjYXN0RGltcy5tYXAoZCA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tkICsgcmFua0RpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gIGNvbnN0IGluU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGluU2hhcGUpO1xuICBjb25zdCBpc0lucHV0U2NhbGFyID0gaW5TaXplID09PSAxO1xuICBsZXQgb3V0cHV0ID0gJ3ZlYzQob3V0cHV0VmFsdWUueHgsIG91dHB1dFZhbHVlLnl5KSc7XG4gIGlmIChpc0lucHV0U2NhbGFyKSB7XG4gICAgb3V0cHV0ID0gJ3ZlYzQob3V0cHV0VmFsdWUueCknO1xuICB9XG4gIGNvbnN0IGdldEJpYXNGb3JNYXRtdWxTb3VyY2UgPSBpc1BhY2tlZCA/IGBcbnZlYzQgZ2V0Qmlhc0Zvck1hdG11bCgpIHtcbiAgJHtjb29yZHNEYXRhVHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICR7Y29vcmRzU25pcHBldH1cbiAgdmVjNCBvdXRwdXRWYWx1ZSA9IGdldEJpYXMoJHt1bnBhY2tlZENvb3Jkc1NuaXBwZXR9KTtcbiAgcmV0dXJuICR7b3V0cHV0fTtcbn1gIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFxuZmxvYXQgZ2V0Qmlhc0Zvck1hdG11bCgpIHtcbiAgJHtjb29yZHNEYXRhVHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICR7Y29vcmRzU25pcHBldH1cbiAgcmV0dXJuIGdldEJpYXMoY29vcmRzLngpO1xufWA7XG5cbiAgcmV0dXJuIGdldEJpYXNGb3JNYXRtdWxTb3VyY2U7XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtCcm9hZGNhc3RVdGlsLCBTaGFwZVV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7Z2V0Q29vcmRzRGF0YVR5cGUsIGdldEdsQ2hhbm5lbHN9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHtnZXRBY3RpdmF0aW9uU25pcHBldCwgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlc30gZnJvbSAnLi9mdXNlLXV0aWxzJztcbmltcG9ydCB7Z2V0Qmlhc0Zvck1hdG11bH0gZnJvbSAnLi9tYXRtdWwnO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdNYXRNdWwgKHBhY2tlZCknLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydBJywgJ0InLCAnQmlhcyddIDogWydBJywgJ0InXSxcbiAgaW5wdXRUeXBlczogaGFzQmlhcyA/IFtUZXh0dXJlVHlwZS5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkXSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBbVGV4dHVyZVR5cGUucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWRdLFxuICBjYWNoZUhpbnRcbn0pO1xuXG5jb25zdCBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mbyA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXRzOiBUZW5zb3JbXSxcbiAgICAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gICAgICBjb25zdCBwcm9jZXNzQmlhcyA9IGhhc0JpYXMgPyAndmFsdWUgKz0gZ2V0Qmlhc0Zvck1hdG11bCgpOycgOiAnJztcbiAgICAgIGNvbnN0IGFTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICAgICAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IEJyb2FkY2FzdFV0aWwuY2FsY1NoYXBlKGFTaGFwZSwgYlNoYXBlLCB0cnVlKTtcbiAgICAgIGNvbnN0IGlzQnJvYWRjYXN0ID0gIVNoYXBlVXRpbC5hcmVFcXVhbChpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMpO1xuXG4gICAgICBpZiAoIW91dHB1dFNoYXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuXFwndCB1c2UgbWF0bXVsIG9uIHRoZSBnaXZlbiB0ZW5zb3JzJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBzaGFyZWREaW0gPSBhU2hhcGVbYVNoYXBlLmxlbmd0aCAtIDFdO1xuICAgICAgY29uc3Qgc2hhcmVkRGltSW5kZXggPSBNYXRoLmNlaWwoc2hhcmVkRGltIC8gMik7XG4gICAgICBjb25zdCBhUmFuayA9IGFTaGFwZS5sZW5ndGg7XG4gICAgICBjb25zdCBiUmFuayA9IGJTaGFwZS5sZW5ndGg7XG5cbiAgICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAgIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgICAgIGNvbnN0IG91dFJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gICAgICBjb25zdCBhbGxHbENoYW5uZWxzID0gZ2V0R2xDaGFubmVscygpO1xuICAgICAgY29uc3Qge2FjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9ufSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGFjdGl2YXRpb25BdHRyaWJ1dGVzKTtcblxuICAgICAgY29uc3QgZ2V0Qmlhc0Zvck1hdG11bFNuaXBwZXQgPVxuICAgICAgICAgIGhhc0JpYXMgPyBgJHtnZXRCaWFzRm9yTWF0bXVsKGNvb3Jkc0RhdGFUeXBlLCBhbGxHbENoYW5uZWxzLCBpbnB1dHNbMl0uZGltcywgb3V0cHV0U2hhcGUsIHRydWUpfWAgOiAnJztcblxuICAgICAgY29uc3QgZ2V0QmNhc3RlZFNhbXBsZXJGb3JNYXRtdWxTbmlwcGV0ID1cbiAgICAgICAgICBpc0Jyb2FkY2FzdCA/IGAke2dldEJjYXN0U2FtcGxlckZvck1hdG11bChjb29yZHNEYXRhVHlwZSwgYWxsR2xDaGFubmVscywgaW5wdXRzLCBvdXRwdXRTaGFwZSl9YCA6ICcnO1xuXG4gICAgICBjb25zdCBnZXRTYW1wbGVyQUluTG9vcFNuaXBwZXQgPSBpc0Jyb2FkY2FzdCA/ICdnZXRBQXRPdXRDb29yZHNNYXRtdWwoaSknIDogYGdldEEoJHtnZXRBKGFsbEdsQ2hhbm5lbHMsIGFSYW5rKX0pYDtcbiAgICAgIGNvbnN0IGdldFNhbXBsZXJCSW5Mb29wU25pcHBldCA9IGlzQnJvYWRjYXN0ID8gJ2dldEJBdE91dENvb3Jkc01hdG11bChpKScgOiBgZ2V0Qigke2dldEIoYWxsR2xDaGFubmVscywgYlJhbmspfSlgO1xuICAgICAgY29uc3QgZ2V0T3V0cHV0Q29vcmRzU25pcHBldCA9IGlzQnJvYWRjYXN0ID8gJycgOiBgJHtjb29yZHNEYXRhVHlwZX0gcmMgPVxuICAgICAgICAgIGdldE91dHB1dENvb3JkcygpOyBpbnQgbGFzdERpbSA9IHJjLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMV19OyByYy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDFdfSA9XG4gICAgICAgICAgcmMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAyXX07IHJjLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMl19ID0gbGFzdERpbTtcbiAgICAgIGA7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICAgICAke2dldEJjYXN0ZWRTYW1wbGVyRm9yTWF0bXVsU25pcHBldH1cbiAgICAgICAgICAgICR7Z2V0Qmlhc0Zvck1hdG11bFNuaXBwZXR9XG4gICAgICAgICAgICAke2FjdGl2YXRpb25GdW5jdGlvbn1cbiAgICAgICAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgICAgICAgJHtnZXRPdXRwdXRDb29yZHNTbmlwcGV0fVxuXG4gICAgICAgICAgICAgIHZlYzQgdmFsdWUgPSB2ZWM0KDApO1xuICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7c2hhcmVkRGltSW5kZXh9OyBpKyspIHtcbiAgICAgICAgICAgICAgICB2ZWM0IGEgPSAke2dldFNhbXBsZXJBSW5Mb29wU25pcHBldH07XG4gICAgICAgICAgICAgICAgdmVjNCBiID0gJHtnZXRTYW1wbGVyQkluTG9vcFNuaXBwZXR9O1xuXG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gKGEucnJiYiAqIGIucmdyZyk7XG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gKGEuZ2dhYSAqIGIuYmFiYSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgJHtwcm9jZXNzQmlhc31cbiAgICAgICAgICAgICAgJHthcHBseUFjdGl2YXRpb259XG4gICAgICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmFsdWU7XG4gICAgICAgICAgICB9YDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2UsXG4gICAgICAgIGhhc01haW46IHRydWVcbiAgICAgIH07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLFxuICAgICBhY3RpdmF0aW9uQXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhY3RpdmF0aW9uQXR0cmlidXRlcy5hY3RpdmF0aW9uQ2FjaGVLZXkpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIGdldDogKCkgPT4gY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYWN0aXZhdGlvbkF0dHJpYnV0ZXMpXG4gICAgICB9O1xuICAgIH07XG5cbmZ1bmN0aW9uIGdldEJjYXN0U2FtcGxlckZvck1hdG11bChcbiAgICBjb29yZHNEYXRhVHlwZTogc3RyaW5nLCBhbGxHbENoYW5uZWxzOiByZWFkb25seSBzdHJpbmdbXSwgaW5wdXRzOiBUZW5zb3JbXSwgb3V0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogc3RyaW5nIHtcbiAgbGV0IHVucGFja2VkQUNvb3Jkc1NuaXBwZXQgPSBbXTtcbiAgbGV0IHVucGFja2VkQkNvb3Jkc1NuaXBwZXQgPSBbXTtcblxuICBjb25zdCBpbkFTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBpbkJTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuXG4gIGNvbnN0IGluQVJhbmsgPSBpbkFTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGluQlJhbmsgPSBpbkJTaGFwZS5sZW5ndGg7XG5cbiAgY29uc3Qgb3V0UmFuayA9IG91dFNoYXBlLmxlbmd0aDtcbiAgY29uc3QgcmFua0FEaWZmID0gb3V0UmFuayAtIGluQVJhbms7XG4gIGNvbnN0IHJhbmtCRGlmZiA9IG91dFJhbmsgLSBpbkJSYW5rO1xuXG4gIHVucGFja2VkQUNvb3Jkc1NuaXBwZXQgPSBpbkFTaGFwZS5tYXAoKF9zLCBpKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tpICsgcmFua0FEaWZmXX1gKTtcbiAgdW5wYWNrZWRBQ29vcmRzU25pcHBldFtpbkFSYW5rIC0gMV0gPSAnaSoyJztcbiAgdW5wYWNrZWRBQ29vcmRzU25pcHBldC5qb2luKCcsICcpO1xuICB1bnBhY2tlZEJDb29yZHNTbmlwcGV0ID0gaW5CU2hhcGUubWFwKChfcywgaSkgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbaSArIHJhbmtCRGlmZl19YCk7XG4gIHVucGFja2VkQkNvb3Jkc1NuaXBwZXRbaW5CUmFuayAtIDJdID0gJ2kqMic7XG4gIHVucGFja2VkQkNvb3Jkc1NuaXBwZXQuam9pbignLCAnKTtcblxuICBjb25zdCBicm9hZGNhc3RBRGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpbkFTaGFwZSwgb3V0U2hhcGUpO1xuICBjb25zdCBicm9hZGNhc3RCRGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpbkJTaGFwZSwgb3V0U2hhcGUpO1xuXG4gIGNvbnN0IGNvb3Jkc0FTbmlwcGV0ID0gYnJvYWRjYXN0QURpbXMubWFwKGQgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbZCArIHJhbmtBRGlmZl19ID0gMDtgKS5qb2luKCdcXG4nKTtcbiAgY29uc3QgY29vcmRzQlNuaXBwZXQgPSBicm9hZGNhc3RCRGltcy5tYXAoZCA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tkICsgcmFua0JEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICBjb25zdCBzd2FwRGltU25pcHBldCA9IGBpbnQgbGFzdERpbSA9IGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDFdfTtcbiAgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMV19ID0gY29vcmRzLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMl19O1xuICBjb29yZHMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAyXX0gPSBsYXN0RGltO2A7XG5cbiAgY29uc3QgZ2V0QmNhc3RTYW1wbGVyTWF0bXVsU291cmNlID0gYFxudmVjNCBnZXRBQXRPdXRDb29yZHNNYXRtdWwoaW50IGkpIHtcbiAgJHtjb29yZHNEYXRhVHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICR7c3dhcERpbVNuaXBwZXR9XG4gICR7Y29vcmRzQVNuaXBwZXR9XG4gIHZlYzQgb3V0cHV0VmFsdWUgPSBnZXRBKCR7dW5wYWNrZWRBQ29vcmRzU25pcHBldH0pO1xuICByZXR1cm4gb3V0cHV0VmFsdWU7XG59XG5cbnZlYzQgZ2V0QkF0T3V0Q29vcmRzTWF0bXVsKGludCBpKSB7XG4gICR7Y29vcmRzRGF0YVR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAke3N3YXBEaW1TbmlwcGV0fVxuICAke2Nvb3Jkc0JTbmlwcGV0fVxuICB2ZWM0IG91dHB1dFZhbHVlID0gZ2V0Qigke3VucGFja2VkQkNvb3Jkc1NuaXBwZXR9KTtcbiAgcmV0dXJuIG91dHB1dFZhbHVlO1xufWA7XG5cbiAgcmV0dXJuIGdldEJjYXN0U2FtcGxlck1hdG11bFNvdXJjZTtcbn1cblxuZnVuY3Rpb24gZ2V0QShhbGxHbENoYW5uZWxzOiBzdHJpbmdbXSwgcmFuazogbnVtYmVyKTogc3RyaW5nIHtcbiAgbGV0IHJlcyA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAyOyBpKyspIHtcbiAgICByZXMgKz0gYHJjLiR7YWxsR2xDaGFubmVsc1tpXX0sIGA7XG4gIH1cbiAgcmVzICs9IGByYy4ke2FsbEdsQ2hhbm5lbHNbcmFuayAtIDJdfSwgYCArXG4gICAgICAnaSoyJztcbiAgcmV0dXJuIHJlcztcbn1cblxuZnVuY3Rpb24gZ2V0QihhbGxHbENoYW5uZWxzOiBzdHJpbmdbXSwgcmFuazogbnVtYmVyKTogc3RyaW5nIHtcbiAgbGV0IHJlcyA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAyOyBpKyspIHtcbiAgICByZXMgKz0gYHJjLiR7YWxsR2xDaGFubmVsc1tpXX0sIGA7XG4gIH1cbiAgcmVzICs9ICdpKjIsICcgK1xuICAgICAgYHJjLiR7YWxsR2xDaGFubmVsc1tyYW5rIC0gMV19YDtcbiAgcmV0dXJuIHJlcztcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5pbXBvcnQge2NhbGN1bGF0ZU91dHB1dFNoYXBlLCBDb252QXR0cmlidXRlc30gZnJvbSAnLi9jb252JztcbmltcG9ydCB7Y3JlYXRlUGFja2VkSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXJ9IGZyb20gJy4vaW0yY29sLXBhY2snO1xuaW1wb3J0IHtjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcn0gZnJvbSAnLi9tYXRtdWwtcGFjayc7XG5cbmV4cG9ydCBjb25zdCBjb252MkRQYWNrZWRQb2ludHdpc2UgPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogVGVuc29yID0+IHtcbiAgICAgIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICAgICAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9XG4gICAgICAgICAgY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gICAgICBjb25zdCByZXNoYXBlZFggPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzBdLCBbeHNoYXBlWzFdLCB4c2hhcGVbMl0gKiB4c2hhcGVbM11dKTtcbiAgICAgIGNvbnN0IHJlc2hhcGVkSyA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChpbnB1dHNbMV0sIFtrc2hhcGVbMF0sIGtzaGFwZVsxXV0pO1xuXG4gICAgICBjb25zdCBtYXRtdWxJbnB1dHMgPSBpbnB1dHMubGVuZ3RoID4gMiA/IFtyZXNoYXBlZEssIHJlc2hhcGVkWCwgaW5wdXRzWzJdXSA6IFtyZXNoYXBlZEssIHJlc2hhcGVkWF07XG4gICAgICBjb25zdCBtYXRtdWxPdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBtYXRtdWxJbnB1dHMsIGF0dHJpYnV0ZXMpLCBtYXRtdWxJbnB1dHMpO1xuICAgICAgcmV0dXJuIGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChtYXRtdWxPdXRwdXQsIG91dHB1dFNoYXBlKTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgY29udjJEUGFja2VkID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IFRlbnNvciA9PiB7XG4gICAgICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgICAgIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPVxuICAgICAgICAgIGNhbGN1bGF0ZU91dHB1dFNoYXBlKHhzaGFwZSwga3NoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMpO1xuXG4gICAgICAvLyBydW4gaW0yY29sXG4gICAgICBjb25zdCBpbTJjb2xPdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGlucHV0c1sxXSwgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLFxuICAgICAgICAgIFtpbnB1dHNbMF1dKTtcblxuICAgICAgLy8gcmVzaGFwZSBrZXJuZWxcbiAgICAgIGNvbnN0IGtlcm5lbFJlc2hhcGVkID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKGlucHV0c1sxXSwgW2tzaGFwZVswXSwga3NoYXBlWzFdICoga3NoYXBlWzJdICoga3NoYXBlWzNdXSk7XG5cbiAgICAgIC8vIHJ1biBtYXRtdWxcbiAgICAgIGNvbnN0IG1hdG11bElucHV0cyA9XG4gICAgICAgICAgKGlucHV0cy5sZW5ndGggPT09IDMpID8gW2tlcm5lbFJlc2hhcGVkLCBpbTJjb2xPdXRwdXQsIGlucHV0c1syXV0gOiBba2VybmVsUmVzaGFwZWQsIGltMmNvbE91dHB1dF07XG4gICAgICBjb25zdCBtYXRtdWxPdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBtYXRtdWxJbnB1dHMsIGF0dHJpYnV0ZXMpLCBtYXRtdWxJbnB1dHMpO1xuXG4gICAgICAvLyByZXNoYXBlIG91dHB1dFxuICAgICAgY29uc3Qgb3V0cHV0UmVzaGFwZWQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQobWF0bXVsT3V0cHV0LCBvdXRwdXRTaGFwZSk7XG4gICAgICByZXR1cm4gb3V0cHV0UmVzaGFwZWQ7XG4gICAgfTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtDb252QXR0cmlidXRlc30gZnJvbSAnLi9jb252JztcblxuY29uc3QgY3JlYXRlSW0yQ29sUHJvZ3JhbU1ldGFkYXRhID0gKGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnSW0yQ29sJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludCxcbn0pO1xuXG5jb25zdCBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mbyA9XG4gICAgKF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIHg6IFRlbnNvciwgdzogVGVuc29yLFxuICAgICBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgeHNoYXBlID0geC5kaW1zO1xuICAgICAgY29uc3Qgd3NoYXBlID0gdy5kaW1zO1xuXG4gICAgICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3QgaW0yY29sRGltcyA9IGNhbGN1bGF0ZUltMkNvbERpbXMoeHNoYXBlLCB3c2hhcGUsIG91dHB1dFNoYXBlLCA0KTtcblxuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICBjb25zdCBpbnQgWEMgPSAke3hzaGFwZVsxXX07XG4gICAgICAgIGNvbnN0IGludCBYSCA9ICR7eHNoYXBlWzJdfTtcbiAgICAgICAgY29uc3QgaW50IFhXID0gJHt4c2hhcGVbM119O1xuICAgICAgICBjb25zdCBpbnQgS0ggPSAke2F0dHJpYnV0ZXMua2VybmVsU2hhcGVbMF19O1xuICAgICAgICBjb25zdCBpbnQgS1cgPSAke2F0dHJpYnV0ZXMua2VybmVsU2hhcGVbMV19O1xuICAgICAgICBjb25zdCBpbnQgZGlsYXRpb25IID0gJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1swXX07XG4gICAgICAgIGNvbnN0IGludCBkaWxhdGlvblcgPSAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzFdfTtcbiAgICAgICAgY29uc3QgaW50IHN0cmlkZUggPSAke2F0dHJpYnV0ZXMuc3RyaWRlc1swXX07XG4gICAgICAgIGNvbnN0IGludCBzdHJpZGVXID0gJHthdHRyaWJ1dGVzLnN0cmlkZXNbMV19O1xuICAgICAgICBjb25zdCBpbnQgcGFkSCA9ICR7YXR0cmlidXRlcy5wYWRzWzBdfTtcbiAgICAgICAgY29uc3QgaW50IHBhZFcgPSAke2F0dHJpYnV0ZXMucGFkc1sxXX07XG4gICAgICAgIGNvbnN0IGludCBLSEtXID0gS0gqS1c7XG4gICAgICAgIGNvbnN0IGludCBYQ0tIS1cgPSBYQyAqIEtIS1c7XG4gICAgICAgIGNvbnN0IGludCBvdXRwdXRDaGFubmVscyA9IDQ7XG4gICAgICAgIHZlYzQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBiICA9IGluZGljZXNbMF07IC8vIGJhdGNoIHNpemVcbiAgICAgICAgICBpbnQgb2ggPSBpbmRpY2VzWzFdICogc3RyaWRlSCAtIHBhZEg7IC8vb3V0cHV0IGhlaWdodFxuICAgICAgICAgIGludCBvdyA9IGluZGljZXNbMl0gKiBzdHJpZGVXIC0gcGFkVzsgLy9vdXRwdXQgd2lkdGhcbiAgICAgICAgICBpbnQgcCA9IGluZGljZXNbM10gKiBvdXRwdXRDaGFubmVsczsgLy9wYXRjaFxuICAgICAgICAgIHZlYzQgdmFsdWUgPSB2ZWM0KDAuMCk7XG4gICAgICAgICAgZm9yKGludCBpPTA7IGkgPCBvdXRwdXRDaGFubmVsczsgKytpKSB7XG4gICAgICAgICAgICBpZihwIDwgWENLSEtXKSB7XG4gICAgICAgICAgICAgIGludCBwYXRjaEMgPSBwIC8gS0hLVztcbiAgICAgICAgICAgICAgaW50IHBhdGNoSCA9IChwIC0gcGF0Y2hDKktIS1cpIC8gS1c7XG4gICAgICAgICAgICAgIGludCBwYXRjaFcgPSAocCAtIHBhdGNoQypLSEtXKSAtIHBhdGNoSCAqIEtXO1xuICAgICAgICAgICAgICBpbnQgeGgyID0gb2ggKyBwYXRjaEggKiBkaWxhdGlvbkg7XG4gICAgICAgICAgICAgIGludCB4dzIgPSBvdyArIHBhdGNoVyAqIGRpbGF0aW9uVztcbiAgICAgICAgICAgICAgaW50IHhbJHt4c2hhcGUubGVuZ3RofV07XG4gICAgICAgICAgICAgIHhbMF0gPSBiO1xuICAgICAgICAgICAgICB4WzFdID0gcGF0Y2hDO1xuICAgICAgICAgICAgICB4WzJdID0geGgyO1xuICAgICAgICAgICAgICB4WzNdID0geHcyO1xuICAgICAgICAgICAgICBpZih4aDIgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgeGgyIDwgWEggJiZcbiAgICAgICAgICAgICAgICAgIHh3MiA+PSAwICYmXG4gICAgICAgICAgICAgICAgICB4dzIgPCBYVykge1xuICAgICAgICAgICAgICAgIHZhbHVlW2ldID0gX1goeCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICsrcDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogaW0yY29sRGltcywgdHlwZTogeC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbn0sXG4gICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgfTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIgPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIHg6IFRlbnNvciwgdzogVGVuc29yLCBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVJbTJDb2xQcm9ncmFtTWV0YWRhdGEoYXR0cmlidXRlcy5jYWNoZUtleSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YSwgeCwgdywgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpXG4gICAgICB9O1xuICAgIH07XG5cblxuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZUltMkNvbERpbXMgPVxuICAgIChpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGNoYW5uZWxzID0gNCk6XG4gICAgICAgIG51bWJlcltdID0+XG4gICAgICAgICAgICBbb3V0cHV0U2hhcGVbMF0sIG91dHB1dFNoYXBlWzJdLCBvdXRwdXRTaGFwZVszXSxcbiAgICAgICAgICAgICBNYXRoLmNlaWwoaW5wdXRTaGFwZVsxXSAqIGtlcm5lbFNoYXBlWzJdICoga2VybmVsU2hhcGVbM10gLyBjaGFubmVscyldO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7Z2V0QWN0aXZhdGlvblNuaXBwZXQsIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXN9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQge2NhbGN1bGF0ZUltMkNvbERpbXN9IGZyb20gJy4vaW0yY29sJztcblxuY29uc3QgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1NZXRhZGF0YSA9IChoYXNCaWFzOiBib29sZWFuLCBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKSA9PiAoe1xuICBuYW1lOiAnQ29udkRvdFByb2R1Y3QnLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydJbTJDb2wnLCAnSycsICdCJ10gOiBbJ0ltMkNvbCcsICdLJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXMgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sIFRleHR1cmVUeXBlLnVucGFja2VkXSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb25dLFxuICBjYWNoZUtleTogYXR0cmlidXRlcy5hY3RpdmF0aW9uQ2FjaGVLZXlcbn0pO1xuXG5jb25zdCBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gICAgIG91dHB1dFNoYXBlOiBudW1iZXJbXSwgYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvID0+IHtcbiAgICAgIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICAgICAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gICAgICBjb25zdCBhZGp1c3RlZEtlcm5lbFNoYXBlID0gW2tzaGFwZVswXSwgTWF0aC5jZWlsKCh4c2hhcGVbMV0gKiBrc2hhcGVbMl0gKiBrc2hhcGVbM10pIC8gNCldO1xuICAgICAgY29uc3QgaW0yY29sU2hhcGUgPSBjYWxjdWxhdGVJbTJDb2xEaW1zKHhzaGFwZSwga3NoYXBlLCBvdXRwdXRTaGFwZSk7XG4gICAgICBjb25zdCBba1dpZHRoLCBrSGVpZ2h0XSA9XG4gICAgICAgICAgaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoYWRqdXN0ZWRLZXJuZWxTaGFwZSwgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbik7XG5cbiAgICAgIGNvbnN0IGltMmNvbFN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoaW0yY29sU2hhcGUpO1xuICAgICAgY29uc3QgW2ltMmNvbFdpZHRoLCBpbTJjb2xIZWlnaHRdID1cbiAgICAgICAgICBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChpbTJjb2xTaGFwZSwgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbik7XG4gICAgICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gICAgICBjb25zdCBpbml0VmFsdWUgPSAoaW5wdXRzLmxlbmd0aCA8IDMpID8gJzAuMCcgOiAnX0IoYiknO1xuICAgICAgY29uc3Qgc2hhcmVkRGltID0gTWF0aC5jZWlsKHhzaGFwZVsxXSAqIGtzaGFwZVsyXSAqIGtzaGFwZVszXSAvIDQpO1xuICAgICAgY29uc3Qge2FjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9ufSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMpO1xuICAgICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuJHthY3RpdmF0aW9uRnVuY3Rpb259XG5mbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gIGludCBiWzFdO1xuICBiWzBdID0gaW5kaWNlc1sxXTtcbiAgaW50IGltMmNvbFs0XTtcbiAgaW0yY29sWzBdID0gaW5kaWNlc1swXTtcbiAgaW0yY29sWzFdID0gaW5kaWNlc1syXTtcbiAgaW0yY29sWzJdID0gaW5kaWNlc1szXTtcbiAgaW50IGltMmNvbE9mZnNldCA9IGltMmNvbFswXSAqICR7aW0yY29sU3RyaWRlc1swXX0gKyBpbTJjb2xbMV0gKiAke2ltMmNvbFN0cmlkZXNbMV19ICsgaW0yY29sWzJdICogJHtcbiAgICAgICAgICBpbTJjb2xTdHJpZGVzWzJdfTtcbiAgaW50IGtlcm5lbE9mZnNldCA9IGluZGljZXNbMV0gKiAke2FkanVzdGVkS2VybmVsU2hhcGVbMV19O1xuICBmbG9hdCB2YWx1ZSA9ICR7aW5pdFZhbHVlfTtcbiAgZm9yIChpbnQgaSA9IDA7IGkgPCAke3NoYXJlZERpbX07ICsraSkge1xuICAgIHZlYzIgaW0yY29sQ29vcmRzID0gb2Zmc2V0VG9Db29yZHMoaW0yY29sT2Zmc2V0LCAke2ltMmNvbFdpZHRofSwgJHtpbTJjb2xIZWlnaHR9KTtcbiAgICB2ZWMyIGtlcm5lbENvb3JkcyA9IG9mZnNldFRvQ29vcmRzKGtlcm5lbE9mZnNldCwgJHtrV2lkdGh9LCAke2tIZWlnaHR9KTtcbiAgICB2YWx1ZSArPSBkb3QoJHtnbHNsLnRleHR1cmUyRH0oSW0yQ29sLCBpbTJjb2xDb29yZHMpLCAke2dsc2wudGV4dHVyZTJEfShLLCBrZXJuZWxDb29yZHMpKTtcbiAgICArK2ltMmNvbE9mZnNldDtcbiAgICArK2tlcm5lbE9mZnNldDtcbiAgfVxuICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgcmV0dXJuIHZhbHVlO1xufWA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mb0xvYWRlciA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSwgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuICAgICBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhdHRyaWJ1dGVzKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcylcbiAgICAgIH07XG4gICAgfTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleX0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7SW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vLi4vLi4vYmFja2VuZCc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7UG9vbENvbnZVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmltcG9ydCB7Y3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvTG9hZGVyfSBmcm9tICcuL2NvbnYtZ3JvdXBlZCc7XG5pbXBvcnQge2NvbnYyRFBhY2tlZH0gZnJvbSAnLi9jb252LXBhY2snO1xuaW1wb3J0IHtjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm9Mb2FkZXJ9IGZyb20gJy4vZG90LXByb2R1Y3QnO1xuaW1wb3J0IHtJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXN9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQge2NyZWF0ZUltMkNvbFByb2dyYW1JbmZvTG9hZGVyfSBmcm9tICcuL2ltMmNvbCc7XG5pbXBvcnQge2NyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyfSBmcm9tICcuL21hdG11bCc7XG5cblxuZXhwb3J0IGNvbnN0IGNhbGN1bGF0ZU91dHB1dFNoYXBlID1cbiAgICAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICAgYWRqdXN0UGFkczogcmVhZG9ubHkgbnVtYmVyW10sIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyW10gPT4ge1xuICAgICAgY29uc3QgYmF0Y2hTaXplID0gaW5wdXRTaGFwZVswXTtcbiAgICAgIGNvbnN0IGlucHV0U3BhdGlhbFNoYXBlID0gaW5wdXRTaGFwZS5zbGljZSgyKTtcbiAgICAgIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRTcGF0aWFsU2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3Qgb3V0Q2hhbm5lbHMgPSBrZXJuZWxTaGFwZVswXTtcbiAgICAgIGNvbnN0IGtlcm5lbFNwYXRpYWxTaGFwZSA9IGtlcm5lbFNoYXBlLnNsaWNlKDIpO1xuICAgICAgY29uc3QgZGlsYXRlZEtlcm5lbFNoYXBlID0ga2VybmVsU3BhdGlhbFNoYXBlLm1hcCgodiwgaSkgPT4gdiArICh2IC0gMSkgKiAoZGlsYXRpb25zW2ldIC0gMSkpO1xuICAgICAgY29uc3QgaW5wdXRTcGF0aWFsU2hhcGVXaXRoUGFkID0gaW5wdXRTcGF0aWFsU2hhcGUubWFwKCh2LCBpKSA9PiB2ICsgYWRqdXN0UGFkc1tpXSArIGFkanVzdFBhZHNbaSArIHNwYXRpYWxSYW5rXSk7XG4gICAgICBjb25zdCBvdXRwdXRTcGF0aWFsU2hhcGUgPVxuICAgICAgICAgIGlucHV0U3BhdGlhbFNoYXBlV2l0aFBhZC5tYXAoKHYsIGkpID0+IE1hdGguZmxvb3IoKHYgLSBkaWxhdGVkS2VybmVsU2hhcGVbaV0gKyBzdHJpZGVzW2ldKSAvIHN0cmlkZXNbaV0pKTtcbiAgICAgIGNvbnN0IG91dHB1dFNoYXBlID0gW2JhdGNoU2l6ZSwgb3V0Q2hhbm5lbHNdLmNvbmNhdCguLi5vdXRwdXRTcGF0aWFsU2hhcGUpO1xuICAgICAgcmV0dXJuIG91dHB1dFNoYXBlO1xuICAgIH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udkF0dHJpYnV0ZXMgZXh0ZW5kcyBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzLCBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBhdXRvUGFkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IGdyb3VwOiBudW1iZXI7XG4gIHJlYWRvbmx5IGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgcGFkczogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgY29udjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb252QXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7ICAvLyBjdXJyZW50bHkgd2lsbCBmYWlsIGlmIG5vdCBjb252MkRcbiAgICAgIHJldHVybiBjb252MmQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgICB9O1xuXG5jb25zdCBjb252MmQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29udkF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIGNvbnN0IGFkanVzdGVkQXR0cmlidXRlcyA9IGdldEFkanVzdGVkQ29udkF0dHJpYnV0ZXMoYXR0cmlidXRlcywgaW5wdXRzKTtcbiAgICAgIGNvbnN0IHBhY2tNb2RlID0gaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLnBhY2s7XG4gICAgICBjb25zdCBpc1BvaW50d2lzZSA9IGFkanVzdGVkQXR0cmlidXRlcy5rZXJuZWxTaGFwZVswXSA9PT0gMSAmJiBhZGp1c3RlZEF0dHJpYnV0ZXMua2VybmVsU2hhcGVbMV0gPT09IDE7XG4gICAgICBpZiAoYWRqdXN0ZWRBdHRyaWJ1dGVzLmdyb3VwID4gMSkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICAgIGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyksIGlucHV0cyk7XG4gICAgICAgIHJldHVybiBbcmVzdWx0XTtcbiAgICAgIH0gZWxzZSBpZiAoaXNQb2ludHdpc2UgJiYgcGFja01vZGUpIHtcbiAgICAgICAgcmV0dXJuIFtjb252MkRVbnBhY2tlZFBvaW50d2lzZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyldO1xuICAgICAgfSBlbHNlIGlmIChwYWNrTW9kZSAmJiBpbnB1dHNbMF0uZGltcy5sZW5ndGggPT09IDQgJiYgaW5wdXRzWzBdLmRpbXNbMF0gPT09IDEgJiYgIWlzUG9pbnR3aXNlKSB7XG4gICAgICAgIHJldHVybiBbY29udjJEUGFja2VkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gW2NvbnYyRFVucGFja2VkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYWRqdXN0ZWRBdHRyaWJ1dGVzKV07XG4gICAgICB9XG4gICAgfTtcblxuY29uc3QgY29udjJEVW5wYWNrZWRQb2ludHdpc2UgPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogVGVuc29yID0+IHtcbiAgICAgIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICAgICAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9XG4gICAgICAgICAgY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gICAgICBjb25zdCByZXNoYXBlZFggPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIFt4c2hhcGVbMV0sIHhzaGFwZVsyXSAqIHhzaGFwZVszXV0pO1xuICAgICAgY29uc3QgcmVzaGFwZWRLID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzFdLCBba3NoYXBlWzBdLCBrc2hhcGVbMV1dKTtcblxuICAgICAgY29uc3QgbWF0bXVsSW5wdXRzID0gaW5wdXRzLmxlbmd0aCA+IDIgPyBbcmVzaGFwZWRLLCByZXNoYXBlZFgsIGlucHV0c1syXV0gOiBbcmVzaGFwZWRLLCByZXNoYXBlZFhdO1xuICAgICAgY29uc3QgbWF0bXVsT3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIobWF0bXVsSW5wdXRzLCBhdHRyaWJ1dGVzKSwgbWF0bXVsSW5wdXRzKTtcbiAgICAgIHJldHVybiBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChtYXRtdWxPdXRwdXQsIG91dHB1dFNoYXBlKTtcbiAgICB9O1xuXG5jb25zdCBjb252MkRVbnBhY2tlZCA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMpOiBUZW5zb3IgPT4ge1xuICAgICAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gICAgICBjb25zdCBrc2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgICAgIGNvbnN0IG91dHB1dFNoYXBlID1cbiAgICAgICAgICBjYWxjdWxhdGVPdXRwdXRTaGFwZSh4c2hhcGUsIGtzaGFwZSwgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy5zdHJpZGVzKTtcbiAgICAgIGNvbnN0IHhJbTJDb2wgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICBjcmVhdGVJbTJDb2xQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGlucHV0c1sxXSwgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLCBbaW5wdXRzWzBdXSk7XG5cbiAgICAgIGNvbnN0IGRvdFByb2R1Y3RJbnB1dHMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gW3hJbTJDb2wsIGlucHV0c1sxXSwgaW5wdXRzWzJdXSA6IFt4SW0yQ29sLCBpbnB1dHNbMV1dO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgb3V0cHV0U2hhcGUsIGF0dHJpYnV0ZXMpLCBkb3RQcm9kdWN0SW5wdXRzKTtcbiAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRDb252QXR0cmlidXRlcyA9IDxUIGV4dGVuZHMgQ29udkF0dHJpYnV0ZXM+KGF0dHJpYnV0ZXM6IFQsIGlucHV0czogVGVuc29yW10pOiBUID0+IHtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnNsaWNlKCk7XG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGF0dHJpYnV0ZXMgb2YgdGhpcyBvcCwgaW5mZXIgaXQgZnJvbSB0aGUgd2VpZ2h0IHRlbnNvciBkaW1zXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAobGV0IGkgPSAyOyBpIDwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGtlcm5lbFNoYXBlLnB1c2goaW5wdXRzWzFdLmRpbXNbaV0pO1xuICAgIH1cbiAgfVxuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzLnNsaWNlKCk7XG4gIFBvb2xDb252VXRpbC5hZGp1c3RQYWRzQmFzZWRPbkF1dG9QYWQoXG4gICAgICBpbnB1dHNbMF0uZGltcywgYXR0cmlidXRlcy5zdHJpZGVzLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywga2VybmVsU2hhcGUsIHBhZHMsIGF0dHJpYnV0ZXMuYXV0b1BhZCk7XG5cbiAgLy8gYWx3YXlzIHJldHVybiBhIG5ldyBvYmplY3Qgc28gZG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBhdHRyaWJ1dGVzXG4gIGNvbnN0IG5ld0F0dHJpYnV0ZXM6IFQgPSBPYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzKTtcbiAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7a2VybmVsU2hhcGUsIHBhZHMsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5fSk7XG4gIHJldHVybiBuZXdBdHRyaWJ1dGVzO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ29udkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248Q29udkF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBDb252QXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBub2RlLmF0dHJpYnV0ZXM7XG4gIGNvbnN0IGFjdGl2YXRpb25BdHRyaWJ1dGVzID0gcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpO1xuICAvLyBUT0RPIDogTWFrZSB0aGlzIGdlbmVyaWMgZW5vdWdoIHRvIGNvbXB1dGUgZGVmYXVsdCBhdHRyaWJ1dGVzIGZvciBtdWx0aS1kaW1lbnNpb25hbCBjb252XG4gIGNvbnN0IGF1dG9QYWQgPSBhdHRyaWJ1dGVzLmdldFN0cmluZygnYXV0b19wYWQnLCAnTk9UU0VUJyk7XG4gIGNvbnN0IGRpbGF0aW9ucyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnZGlsYXRpb25zJywgWzEsIDFdKTtcbiAgY29uc3QgZ3JvdXAgPSBhdHRyaWJ1dGVzLmdldEludCgnZ3JvdXAnLCAxKTtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmdldEludHMoJ2tlcm5lbF9zaGFwZScsIFtdKTtcbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygncGFkcycsIFswLCAwLCAwLCAwXSk7XG4gIGNvbnN0IHN0cmlkZXMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ3N0cmlkZXMnLCBbMSwgMV0pO1xuXG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe2F1dG9QYWQsIGRpbGF0aW9ucywgZ3JvdXAsIGtlcm5lbFNoYXBlLCBwYWRzLCBzdHJpZGVzLCAuLi5hY3RpdmF0aW9uQXR0cmlidXRlc30pO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgLy8gUmVmZXIgdG8gdGhlIGJlbG93IGxpbmsgZm9yIGFsbCBpbnB1dCBjaGVja3NcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjQ29udlxuICBpZiAoIWlucHV0cyB8fCAoaW5wdXRzLmxlbmd0aCAhPT0gMiAmJiBpbnB1dHMubGVuZ3RoICE9PSAzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udiByZXF1aXJlcyAyIG9yIDMgaW5wdXRzJyk7XG4gIH1cblxuICAvLyBUT0RPIDogTmVlZCB0byBhZGQgc3VwcG9ydCBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0IHx8IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudGx5IG9ubHkgc3VwcG9ydCAyLWRpbWVuc2lvbmFsIGNvbnYnKTtcbiAgfVxuXG4gIC8vIEZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUxcbiAgY29uc3QgZGF0YUNoYW5uZWwgPSBpbnB1dHNbMF0uZGltc1sxXTtcbiAgY29uc3QgZmlsdGVySW5DaGFubmVsID0gaW5wdXRzWzFdLmRpbXNbMV0gKiBhdHRyaWJ1dGVzLmdyb3VwO1xuICBpZiAoZGF0YUNoYW5uZWwgIT09IGZpbHRlckluQ2hhbm5lbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTCcpO1xuICB9XG5cbiAgLy8gaWYgYmlhcyBpcyBwcm92aWRlZCBpdCBzaG91bGQgYmUgMUQgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgZmVhdHVyZSBtYXBzXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIChpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEgfHwgaW5wdXRzWzFdLmRpbXNbMF0gIT09IGlucHV0c1syXS5kaW1zWzBdKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBiaWFzJyk7XG4gIH1cblxuICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAtIDI7XG4gIC8vIHdyb25nIGRpbGF0aW9ucyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuZGlsYXRpb25zLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRpbGF0aW9ucyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBzdHJpZGVzIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5zdHJpZGVzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHN0cmlkZXMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3JvbmcgcGFkcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMucGFkcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rICogMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgcGFkcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFuayAqIDJ9RGApO1xuICB9XG5cbiAgLy8gaWYga2VybmVsU2hhcGUgaXMgc3BlY2lmaWVkLCBpdCdzIGRhdGEgbGVuZ3RoIG11c3QgYmUgMiBsZXNzIHRoYW4gZGltcyBsZW5ndGggb2YgdGhlIHdlaWdodHMgdGVuc29yXG4gIC8vICh0aGUgZmlyc3QgMiBkaW1zIGFyZSBiYXRjaF9zaXplIGFuZCBjaGFubmVscylcbiAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSAwICYmIGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoICE9PSBpbnB1dHNbMV0uZGltcy5sZW5ndGggLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGtlcm5lbCBzaGFwZScpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIGZsb2F0NjRcbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgfHwgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udiBpbnB1dChYLFcpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxuXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgaW5wdXQoYmlhcykgc2hvdWxkIGJlIGZsb2F0IHRlbnNvcicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge2NyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleX0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7SW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vLi4vLi4vYmFja2VuZCc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7Q29udkF0dHJpYnV0ZXN9IGZyb20gJy4vY29udic7XG5pbXBvcnQge2dldEFjdGl2YXRpb25TbmlwcGV0LCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXN9IGZyb20gJy4vZnVzZS11dGlscyc7XG5cbmNvbnN0IGNvbXB1dGVUb3RhbFBhZCA9XG4gICAgKGluRGltOiBudW1iZXIsIHN0cmlkZTogbnVtYmVyLCBhZGo6IG51bWJlciwga2VybmVsOiBudW1iZXIsIGRpbGF0aW9uOiBudW1iZXIsIG91dFNpemU6IG51bWJlcikgPT5cbiAgICAgICAgKGluRGltIC0gMSkgKiBzdHJpZGUgKyBhZGogKyAoa2VybmVsIC0gMSkgKiBkaWxhdGlvbiArIDEgLSBvdXRTaXplO1xuXG5jb25zdCBkaXN0cmlidXRlUGFkZGluZyA9ICh0b3RhbFBhZDogbnVtYmVyLCBhdXRvUGFkOiBzdHJpbmcsIHBhZHM6IG51bWJlcltdLCBoZWFkOiBudW1iZXIsIHRhaWw6IG51bWJlcikgPT4ge1xuICBjb25zdCBzbWFsbFBhZCA9IE1hdGguZmxvb3IodG90YWxQYWQgLyAyKTtcbiAgaWYgKGF1dG9QYWQgPT09ICdTQU1FX1VQUEVSJykge1xuICAgIHBhZHNbaGVhZF0gPSBzbWFsbFBhZDtcbiAgICBwYWRzW3RhaWxdID0gdG90YWxQYWQgLSBzbWFsbFBhZDtcbiAgfSBlbHNlIGlmIChhdXRvUGFkID09PSAnU0FNRV9MT1dFUicpIHtcbiAgICBwYWRzW2hlYWRdID0gdG90YWxQYWQgLSBzbWFsbFBhZDtcbiAgICBwYWRzW3RhaWxdID0gc21hbGxQYWQ7XG4gIH1cbn07XG5cbmNvbnN0IGNhbGN1bGF0ZU91dHB1dFNoYXBlQW5kUGFkcyA9XG4gICAgKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sIGF1dG9QYWQ6IHN0cmluZyxcbiAgICAgcGFkczogbnVtYmVyW10sIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLCBvdXRwdXRQYWRkaW5nOiByZWFkb25seSBudW1iZXJbXSwgb3V0cHV0U2hhcGU6IG51bWJlcltdKSA9PiB7XG4gICAgICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0U2hhcGUubGVuZ3RoIC0gMjtcbiAgICAgIGNvbnN0IHVwZGF0ZVNoYXBlID0gb3V0cHV0U2hhcGUubGVuZ3RoID09PSAwO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGF0aWFsUmFuazsgKytpKSB7XG4gICAgICAgIGNvbnN0IG91dFNpemUgPSB1cGRhdGVTaGFwZSA/IGlucHV0U2hhcGVbaSArIDJdICogc3RyaWRlc1tpXSA6IG91dHB1dFNoYXBlW2ldO1xuICAgICAgICBjb25zdCB0b3RhbFBhZCA9IGNvbXB1dGVUb3RhbFBhZChpbnB1dFNoYXBlW2kgKyAyXSwgc3RyaWRlc1tpXSwgcGFkc1tpXSwga2VybmVsU2hhcGVbaV0sIGRpbGF0aW9uc1tpXSwgb3V0U2l6ZSk7XG4gICAgICAgIGRpc3RyaWJ1dGVQYWRkaW5nKHRvdGFsUGFkLCBhdXRvUGFkLCBwYWRzLCBpLCBpICsgc3BhdGlhbFJhbmspO1xuICAgICAgICBpZiAodXBkYXRlU2hhcGUpIHtcbiAgICAgICAgICBvdXRwdXRTaGFwZS5wdXNoKFxuICAgICAgICAgICAgICBzdHJpZGVzW2ldICogKGlucHV0U2hhcGVbaSArIDJdIC0gMSkgKyBvdXRwdXRQYWRkaW5nW2ldICsgKGtlcm5lbFNoYXBlW2ldIC0gMSkgKiBkaWxhdGlvbnNbaV0gKyAxIC1cbiAgICAgICAgICAgICAgcGFkc1tpXSAtIHBhZHNbaSArIHNwYXRpYWxSYW5rXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzIGV4dGVuZHMgQ29udkF0dHJpYnV0ZXMge1xuICByZWFkb25seSBvdXRwdXRQYWRkaW5nOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgY29udlRyYW5zcG9zZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb252VHJhbnNwb3NlQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7ICAvLyBjdXJyZW50bHkgd2lsbCBmYWlsIGlmIG5vdCBjb252VHJhbnNwb3NlMkRcbiAgICAgIHJldHVybiBjb252VHJhbnNwb3NlMmQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgICB9O1xuXG5jb25zdCBjb252VHJhbnNwb3NlMmQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29udlRyYW5zcG9zZUF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIGNvbnN0IGFkanVzdGVkQXR0cmlidXRlcyA9IGdldEFkanVzdGVkQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMoYXR0cmlidXRlcywgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbY29udlRyYW5zcG9zZTJEVW5wYWNrZWQoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpXTtcbiAgICB9O1xuXG5jb25zdCBjcmVhdGVDb252VHJhbnNwb3NlUHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnQ29udlRyYW5zcG9zZScsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ1gnLCAnVycsICdCJ10gOiBbJ1gnLCAnVyddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnRcbn0pO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbnZUcmFuc3Bvc2VQcm9ncmFtSW5mbyA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSxcbiAgICAgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gICAgICBjb25zdCB2YWx1ZUluaXQgPSBoYXNCaWFzID8gJ2dldEIob3V0cHV0X2NoYW5uZWwpJyA6ICcwLjAnO1xuICAgICAgY29uc3QgeFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gICAgICBjb25zdCB3U2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxzUGVyR3JvdXAgPSB3U2hhcGVbMV07XG4gICAgICBjb25zdCBpbnB1dENoYW5uZWxzUGVyR3JvdXAgPSB3U2hhcGVbMF0gLyBhdHRyaWJ1dGVzLmdyb3VwO1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBbaW5wdXRzWzBdLmRpbXNbMF0sIGlucHV0c1sxXS5kaW1zWzFdICogYXR0cmlidXRlcy5ncm91cCwgLi4uYXR0cmlidXRlcy5vdXRwdXRTaGFwZV07XG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICBjb25zdCB7YWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb259ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcyk7XG5cbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgY29uc3QgaXZlYzIgc3RyaWRlcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5zdHJpZGVzWzBdfSwgJHthdHRyaWJ1dGVzLnN0cmlkZXNbMV19KTtcbiAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5wYWRzWzBdfSwgJHthdHRyaWJ1dGVzLnBhZHNbMV19KTtcbiAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gIHZvaWQgbWFpbigpIHtcbiAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDtcbiAgICBpbnQgb3V0cHV0X2NoYW5uZWwgPSBjb29yZHMueTtcblxuICAgIGl2ZWMyIGxvYyA9IGNvb3Jkcy56dyArIHBhZHM7XG5cbiAgICBpbnQgZ3JvdXBfaWQgPSBvdXRwdXRfY2hhbm5lbCAvICR7b3V0cHV0Q2hhbm5lbHNQZXJHcm91cH07XG4gICAgaW50IHdPdXRDaGFubmVsID0gb3V0cHV0X2NoYW5uZWwgLSBncm91cF9pZCAqICR7b3V0cHV0Q2hhbm5lbHNQZXJHcm91cH07XG5cbiAgICBmbG9hdCB2YWx1ZSA9ICR7dmFsdWVJbml0fTtcbiAgICBmb3IgKGludCBpbkNoYW5uZWxPZmZzZXQgPSAwOyBpbkNoYW5uZWxPZmZzZXQgPCAke2lucHV0Q2hhbm5lbHNQZXJHcm91cH07IGluQ2hhbm5lbE9mZnNldCsrKSB7XG4gICAgICBpbnQgaW5wdXRfY2hhbm5lbCA9IGdyb3VwX2lkICogJHtpbnB1dENoYW5uZWxzUGVyR3JvdXB9ICsgaW5DaGFubmVsT2Zmc2V0O1xuICAgICAgZm9yIChpbnQgd1dPZmYgPSAwOyB3V09mZiA8ICR7d1NoYXBlWzJdfTsgd1dPZmYrKykge1xuICAgICAgICBmb3IgKGludCB3SE9mZiA9IDA7IHdIT2ZmIDwgJHt3U2hhcGVbM119OyB3SE9mZisrKSB7XG4gICAgICAgICAgaXZlYzIgd09mZiA9IGl2ZWMyKHdXT2ZmICogJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1swXX0sIHdIT2ZmICogJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX0pO1xuICAgICAgICAgIGl2ZWMyIHdMb2MgPSBsb2MgLSB3T2ZmO1xuICAgICAgICAgIGl2ZWMyIHdMb2NJbiA9IHdMb2MgLyBzdHJpZGVzO1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHdMb2NJbiAqIHN0cmlkZXMgPT0gd0xvYyAmJlxuICAgICAgICAgICAgd0xvY0luLnggPj0gMCAmJiB3TG9jSW4ueCA8ICR7eFNoYXBlWzJdfSAmJlxuICAgICAgICAgICAgd0xvY0luLnkgPj0gMCAmJiB3TG9jSW4ueSA8ICR7eFNoYXBlWzNdfVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgZmxvYXQgeFZhbCA9IGdldFgoYmF0Y2gsIGlucHV0X2NoYW5uZWwsIHdMb2NJbi55LCB3TG9jSW4ueCk7XG4gICAgICAgICAgICBmbG9hdCB3VmFsID0gZ2V0VyhpbnB1dF9jaGFubmVsLCB3T3V0Q2hhbm5lbCwgd0hPZmYsIHdXT2ZmKTtcbiAgICAgICAgICAgIHZhbHVlICs9IHhWYWwgKiB3VmFsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQodmFsdWUsIC4wLCAuMCwgLjApO1xuICB9XG5gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgICBoYXNNYWluOiB0cnVlLFxuICAgICAgfTtcbiAgICB9O1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbnZUcmFuc3Bvc2VQcm9ncmFtSW5mb0xvYWRlciA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMpOlxuICAgICAgICBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gICAgICAgICAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVDb252VHJhbnNwb3NlUHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZVVucGFja2VkQ29udlRyYW5zcG9zZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgbWV0YWRhdGEsIGF0dHJpYnV0ZXMpXG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcblxuXG5jb25zdCBjb252VHJhbnNwb3NlMkRVbnBhY2tlZCA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMpOlxuICAgICAgICBUZW5zb3IgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgICAgICBjcmVhdGVVbnBhY2tlZENvbnZUcmFuc3Bvc2VQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpO1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG5cbmNvbnN0IGdldEFkanVzdGVkQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgPSA8VCBleHRlbmRzIENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzPihhdHRyaWJ1dGVzOiBULCBpbnB1dHM6IFRlbnNvcltdKTogVCA9PiB7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgb3AsIGluZmVyIGl0IGZyb20gdGhlIHdlaWdodCB0ZW5zb3IgZGltc1xuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGxldCBpID0gMjsgaSA8IGlucHV0c1sxXS5kaW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICBrZXJuZWxTaGFwZS5wdXNoKGlucHV0c1sxXS5kaW1zW2ldKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzLnNsaWNlKCk7XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gYXR0cmlidXRlcy5vdXRwdXRTaGFwZS5zbGljZSgpO1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gIC8vIElmIG91dHB1dFNoYXBlIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGF0dHJpYnV0ZXMgb2YgdGhpcyBvcCwgaW5mZXIgaXQgZnJvbSB0aGUgcGFyYW1ldGVyc1xuICAvLyBTaW1pbGFybHksIGF1dG9tYXRpY2FsbHkgaW5mZXIgcGFkcyBpZiBub3Qgc3BlY2lmaWVkXG4gIGNhbGN1bGF0ZU91dHB1dFNoYXBlQW5kUGFkcyhcbiAgICAgIGlucHV0U2hhcGUsIGtlcm5lbFNoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5hdXRvUGFkLCBwYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMsXG4gICAgICBhdHRyaWJ1dGVzLm91dHB1dFBhZGRpbmcsIG91dHB1dFNoYXBlKTtcblxuICAvLyBhbHdheXMgcmV0dXJuIGEgbmV3IG9iamVjdCBzbyBkb2VzIG5vdCBtb2RpZnkgdGhlIG9yaWdpbmFsIGF0dHJpYnV0ZXNcbiAgY29uc3QgbmV3QXR0cmlidXRlczogVCA9IE9iamVjdC5hc3NpZ24oe30sIGF0dHJpYnV0ZXMpO1xuICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHtrZXJuZWxTaGFwZSwgcGFkcywgb3V0cHV0U2hhcGUsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5fSk7XG4gIHJldHVybiBuZXdBdHRyaWJ1dGVzO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248Q29udlRyYW5zcG9zZUF0dHJpYnV0ZXM+ID1cbiAgICAobm9kZTogR3JhcGguTm9kZSk6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzID0+IHtcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBub2RlLmF0dHJpYnV0ZXM7XG4gICAgICBjb25zdCBhY3RpdmF0aW9uQXR0cmlidXRlcyA9IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTtcbiAgICAgIC8vIFRPRE8gOiBNYWtlIHRoaXMgZ2VuZXJpYyBlbm91Z2ggdG8gY29tcHV0ZSBkZWZhdWx0IGF0dHJpYnV0ZXMgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgICAgIGNvbnN0IGF1dG9QYWQgPSBhdHRyaWJ1dGVzLmdldFN0cmluZygnYXV0b19wYWQnLCAnTk9UU0VUJyk7XG4gICAgICBjb25zdCBkaWxhdGlvbnMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ2RpbGF0aW9ucycsIFsxLCAxXSk7XG4gICAgICBjb25zdCBncm91cCA9IGF0dHJpYnV0ZXMuZ2V0SW50KCdncm91cCcsIDEpO1xuICAgICAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmdldEludHMoJ2tlcm5lbF9zaGFwZScsIFtdKTtcbiAgICAgIGNvbnN0IG91dHB1dFBhZGRpbmcgPSBhdHRyaWJ1dGVzLmdldEludHMoJ291dHB1dF9wYWRkaW5nJywgWzAsIDBdKTtcbiAgICAgIGNvbnN0IG91dHB1dFNoYXBlID0gYXR0cmlidXRlcy5nZXRJbnRzKCdvdXRwdXRfc2hhcGUnLCBbXSk7XG4gICAgICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJywgWzAsIDAsIDAsIDBdKTtcbiAgICAgIGNvbnN0IHN0cmlkZXMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ3N0cmlkZXMnLCBbMSwgMV0pO1xuXG4gICAgICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KFxuICAgICAgICAgIHthdXRvUGFkLCBkaWxhdGlvbnMsIGdyb3VwLCBrZXJuZWxTaGFwZSwgb3V0cHV0UGFkZGluZywgb3V0cHV0U2hhcGUsIHBhZHMsIHN0cmlkZXMsIC4uLmFjdGl2YXRpb25BdHRyaWJ1dGVzfSk7XG4gICAgfTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMpOiB2b2lkID0+IHtcbiAgLy8gUmVmZXIgdG8gdGhlIGJlbG93IGxpbmsgZm9yIGFsbCBpbnB1dCBjaGVja3NcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjQ29udlxuICBpZiAoIWlucHV0cyB8fCAoaW5wdXRzLmxlbmd0aCAhPT0gMiAmJiBpbnB1dHMubGVuZ3RoICE9PSAzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udiByZXF1aXJlcyAyIG9yIDMgaW5wdXRzJyk7XG4gIH1cblxuICAvLyBUT0RPIDogTmVlZCB0byBhZGQgc3VwcG9ydCBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0IHx8IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY3VycmVudGx5IG9ubHkgc3VwcG9ydCAyLWRpbWVuc2lvbmFsIGNvbnYnKTtcbiAgfVxuXG4gIC8vIEZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUxcbiAgY29uc3QgZGF0YUNoYW5uZWwgPSBpbnB1dHNbMF0uZGltc1sxXTtcbiAgY29uc3QgZmlsdGVySW5DaGFubmVsID0gaW5wdXRzWzFdLmRpbXNbMF07XG4gIGlmIChkYXRhQ2hhbm5lbCAhPT0gZmlsdGVySW5DaGFubmVsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMJyk7XG4gIH1cblxuICBjb25zdCBmZWF0dXJlTWFwcyA9IGlucHV0c1sxXS5kaW1zWzFdICogYXR0cmlidXRlcy5ncm91cDtcblxuICAvLyBpZiBiaWFzIGlzIHByb3ZpZGVkIGl0IHNob3VsZCBiZSAxRCBhbmQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBzaG91bGQgYmUgZXF1YWwgdG8gdGhlIG51bWJlciBvZiBmZWF0dXJlIG1hcHNcbiAgaWYgKGlucHV0cy5sZW5ndGggPT09IDMgJiYgKGlucHV0c1syXS5kaW1zLmxlbmd0aCAhPT0gMSB8fCBpbnB1dHNbMl0uZGltc1swXSAhPT0gZmVhdHVyZU1hcHMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGJpYXMnKTtcbiAgfVxuXG4gIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMjtcbiAgLy8gd3JvbmcgZGlsYXRpb25zIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5kaWxhdGlvbnMubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgZGlsYXRpb25zIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHN0cmlkZXMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoICE9PSBzcGF0aWFsUmFuaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgc3RyaWRlcyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBwYWRzIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmsgKiAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBwYWRzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rICogMn1EYCk7XG4gIH1cblxuICAvLyBXcm9uZyBvdXRwdXQgcGFkZGluZyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMub3V0cHV0UGFkZGluZy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXRfcGFkZGluZyBzaG91bGQgYmUgJHtzcGF0aWFsUmFua31EYCk7XG4gIH1cblxuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBzcGVjaWZpZWQsIGl0J3MgZGF0YSBsZW5ndGggbXVzdCBiZSAyIGxlc3MgdGhhbiBkaW1zIGxlbmd0aCBvZiB0aGUgd2VpZ2h0cyB0ZW5zb3JcbiAgLy8gKHRoZSBmaXJzdCAyIGRpbXMgYXJlIGJhdGNoX3NpemUgYW5kIGNoYW5uZWxzKVxuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggIT09IDAgJiYgYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggIT09IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAtIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQga2VybmVsIHNoYXBlJyk7XG4gIH1cblxuICAvLyBhcyB3aXRoIGtlcm5lbFNoYXBlLCBtdXN0IGhhdmUgc2FtZSBudW1iZXIgb2Ygc3BhdGlhbCBkaW1zIGFzIGlucHV0XG4gIGlmIChhdHRyaWJ1dGVzLm91dHB1dFNoYXBlLmxlbmd0aCAhPT0gMCAmJiBhdHRyaWJ1dGVzLm91dHB1dFNoYXBlLmxlbmd0aCAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBvdXRwdXQgc2hhcGUnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBmbG9hdDY0XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInIHx8IGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnZUcmFuc3Bvc2UgaW5wdXQoWCxXKSBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0udHlwZSAhPT0gJ2Zsb2F0MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252VHJhbnNwb3NlIGlucHV0KGJpYXMpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleX0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtTaGFwZVV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNwb3NlQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IHBlcm06IG51bWJlcltdO1xufVxuXG5jb25zdCB0cmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdUcmFuc3Bvc2UnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXVxufTtcblxuZXhwb3J0IGNvbnN0IHRyYW5zcG9zZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogVHJhbnNwb3NlQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gICAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi50cmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcy5wZXJtKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFRyYW5zcG9zZUF0dHJpYnV0ZXM+ID1cbiAgICAobm9kZTogR3JhcGguTm9kZSk6IFRyYW5zcG9zZUF0dHJpYnV0ZXMgPT4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtwZXJtOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygncGVybScsIFtdKX0pO1xuXG5jb25zdCBjcmVhdGVUcmFuc3Bvc2VQcm9ncmFtSW5mbyA9XG4gICAgKF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIHBlcm06IG51bWJlcltdKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0LmRpbXM7XG4gICAgICBwZXJtID0gZ2V0QWRqdXN0ZWRQZXJtKGlucHV0U2hhcGUsIHBlcm0pO1xuICAgICAgY29uc3QgdW5wYWNrZWRPdXRwdXRTaGFwZSA9IGdldE91dHB1dFNoYXBlKGlucHV0U2hhcGUsIHBlcm0pO1xuICAgICAgY29uc3QgcmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICAgICAgLy8gQSBkaW1zPVske2lucHV0c1swXS5kaW1zLnRvU3RyaW5nKCl9XVxuICAgICAgLy8gb3V0IERpbXM9WyR7dW5wYWNrZWRPdXRwdXRTaGFwZS50b1N0cmluZygpfV1cbiAgICAgIC8vIGJhc2VkIG9uIHBlcm09WyR7cGVybS50b1N0cmluZygpfV1cbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7Z2V0UGVybUZ1bmN0aW9uQm9keSgncGVybScsIHBlcm0sIHJhbmspfVxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICBpbnQgYVske3Jhbmt9XTtcbiAgICAgICAgcGVybShhLCBpbmRpY2VzKTtcbiAgICAgICAgcmV0dXJuIF9BKGEpO1xuICAgICAgfWA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi50cmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IHVucGFja2VkT3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZH0sXG4gICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgfTtcbiAgICB9O1xuXG5jb25zdCBnZXRBZGp1c3RlZFBlcm0gPSAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHBlcm06IG51bWJlcltdKTogbnVtYmVyW10gPT4ge1xuICBpZiAocGVybSAmJiBwZXJtLmxlbmd0aCAhPT0gaW5wdXRTaGFwZS5sZW5ndGgpIHtcbiAgICBwZXJtID0gWy4uLihpbnB1dFNoYXBlLmtleXMoKSldLnJldmVyc2UoKTtcbiAgfVxuICByZXR1cm4gcGVybTtcbn07XG5cbmNvbnN0IGdldE91dHB1dFNoYXBlID0gKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwZXJtOiBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdID0+IHtcbiAgcGVybSA9IGdldEFkanVzdGVkUGVybShpbnB1dFNoYXBlLCBwZXJtKTtcbiAgcmV0dXJuIFNoYXBlVXRpbC5zb3J0QmFzZWRPblBlcm0oaW5wdXRTaGFwZSwgcGVybSk7XG59O1xuXG5jb25zdCBnZXRQZXJtRnVuY3Rpb25Cb2R5ID0gKG5hbWU6IHN0cmluZywgcGVybTogbnVtYmVyW10sIHJhbms6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHJldmVyc2VGdW5jID0gW107XG4gIHJldmVyc2VGdW5jLnB1c2goYHZvaWQgJHtuYW1lfShvdXQgaW50IGFbJHtyYW5rfV0sIGludCBzcmNbJHtyYW5rfV0pIHtgKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICByZXZlcnNlRnVuYy5wdXNoKGBcXHRhWyR7cGVybVtpXX1dPXNyY1ske2l9XTtgKTtcbiAgfVxuICByZXZlcnNlRnVuYy5wdXNoKCdcXHR9Jyk7XG4gIHJldHVybiByZXZlcnNlRnVuYy5qb2luKCdcXG4nKTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVHJhbnNwb3NlIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuaW1wb3J0IHt0cmFuc3Bvc2UsIFRyYW5zcG9zZUF0dHJpYnV0ZXN9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuZXhwb3J0IGludGVyZmFjZSBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzIHtcbiAgbW9kZTogJ0RDUid8J0NSRCc7XG4gIGJsb2Nrc2l6ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgZGVwdGhUb1NwYWNlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPERlcHRoVG9TcGFjZUF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgICAgIGNvbnN0IGJsb2Nrc2l6ZSA9IGF0dHJpYnV0ZXMuYmxvY2tzaXplO1xuICAgICAgY29uc3QgYmxvY2tzaXplU3FyID0gYmxvY2tzaXplICogYmxvY2tzaXplO1xuICAgICAgY29uc3QgdHJhbnNwb3NlUGVybSA9IGF0dHJpYnV0ZXMubW9kZSA9PT0gJ0RDUicgPyBbMCwgMywgNCwgMSwgNSwgMl0gOiBbMCwgMSwgNCwgMiwgNSwgM107XG4gICAgICBjb25zdCBmaXJzdFJlc2hhcGVTaGFwZSA9IGF0dHJpYnV0ZXMubW9kZSA9PT0gJ0RDUicgP1xuICAgICAgICAgIFtcbiAgICAgICAgICAgIGlucHV0c1swXS5kaW1zWzBdLCBibG9ja3NpemUsIGJsb2Nrc2l6ZSwgaW5wdXRzWzBdLmRpbXNbMV0gLyBibG9ja3NpemVTcXIsIGlucHV0c1swXS5kaW1zWzJdLFxuICAgICAgICAgICAgaW5wdXRzWzBdLmRpbXNbM11cbiAgICAgICAgICBdIDpcbiAgICAgICAgICBbXG4gICAgICAgICAgICBpbnB1dHNbMF0uZGltc1swXSwgaW5wdXRzWzBdLmRpbXNbMV0gLyBibG9ja3NpemVTcXIsIGJsb2Nrc2l6ZSwgYmxvY2tzaXplLCBpbnB1dHNbMF0uZGltc1syXSxcbiAgICAgICAgICAgIGlucHV0c1swXS5kaW1zWzNdXG4gICAgICAgICAgXTtcblxuICAgICAgLy8gY29uc3QgdHJhbnNwb3NlID0gbmV3IFdlYkdMVHJhbnNwb3NlKCk7XG4gICAgICAvLyBjb25zdCBhdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZSh1bmRlZmluZWQpO1xuICAgICAgLy8gYXR0cmlidXRlcy5zZXQoJ3Blcm0nLCAnaW50cycsIHRyYW5zcG9zZVBlcm0pO1xuICAgICAgLy8gdHJhbnNwb3NlLmluaXRpYWxpemUoYXR0cmlidXRlcyk7XG5cbiAgICAgIC8vIEZpcnN0IHJlc2hhcGVcbiAgICAgIGNvbnN0IGZpcnN0UmVzaGFwZWRUZW5zb3IgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIGZpcnN0UmVzaGFwZVNoYXBlKTtcblxuICAgICAgLy8gdHJhbnNwb3NlXG4gICAgICBjb25zdCB0cmFuc3Bvc2VBdHRyaWJ1dGVzOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzID0ge3Blcm06IHRyYW5zcG9zZVBlcm0sIGNhY2hlS2V5OiBgJHt0cmFuc3Bvc2VQZXJtfWB9O1xuICAgICAgY29uc3QgW3RyYW5zcG9zZU91dHB1dF0gPSB0cmFuc3Bvc2UoaW5mZXJlbmNlSGFuZGxlciwgW2ZpcnN0UmVzaGFwZWRUZW5zb3JdLCB0cmFuc3Bvc2VBdHRyaWJ1dGVzKTtcblxuICAgICAgLy8gU2Vjb25kIHJlc2hhcGVcbiAgICAgIGNvbnN0IHNlY29uZFJlc2hhcGVTaGFwZSA9IFtcbiAgICAgICAgaW5wdXRzWzBdLmRpbXNbMF0sIGlucHV0c1swXS5kaW1zWzFdIC8gYmxvY2tzaXplU3FyLCBpbnB1dHNbMF0uZGltc1syXSAqIGJsb2Nrc2l6ZSxcbiAgICAgICAgaW5wdXRzWzBdLmRpbXNbM10gKiBibG9ja3NpemVcbiAgICAgIF07XG4gICAgICBjb25zdCByZXN1bHQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZCh0cmFuc3Bvc2VPdXRwdXQsIHNlY29uZFJlc2hhcGVTaGFwZSk7XG4gICAgICByZXR1cm4gW3Jlc3VsdF07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRGVwdGhUb1NwYWNlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzPiA9XG4gICAgKG5vZGU6IEdyYXBoLk5vZGUpOiBEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzID0+IHtcbiAgICAgIC8vIHByb2Nlc3Npbmcgbm9kZSBhdHRyaWJ1dGVzXG4gICAgICBjb25zdCBibG9ja3NpemUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdibG9ja3NpemUnKTtcbiAgICAgIGlmIChibG9ja3NpemUgPCAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgYmxvY2tzaXplIG11c3QgYmUgPj0gMSwgYnV0IGdvdCA6ICR7YmxvY2tzaXplfSBmb3IgRGVwdGhUb1NwYWNlYCk7XG4gICAgICB9XG4gICAgICBjb25zdCBtb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICdEQ1InKTtcbiAgICAgIGlmIChtb2RlICE9PSAnRENSJyAmJiBtb2RlICE9PSAnQ1JEJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVjb2duaXplZCBtb2RlOiAke21vZGV9IGZvciBEZXB0aFRvU3BhY2VgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7bW9kZSwgYmxvY2tzaXplfTtcbiAgICB9O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmIChpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBEZXB0aFRvU3BhY2UgZXhwZWN0IDEgaW5wdXRzLCBidXQgZ290ICR7aW5wdXRzLmxlbmd0aH1gKTtcbiAgfVxuXG4gIC8vIElucHV0IGhhcyB0byBiZSBhIDQtRCB0ZW5zb3JcbiAgLy8gVE9ETzogU3VwcG9ydCBzdHJpbmcgZGVwdGgtdG8tc3BhY2UuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycgfHwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRGVwdGhUb1NwYWNlIGlucHV0IHNob3VsZCBiZSBhIDQtRCBudW1lcmljIHRlbnNvcicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBmbGF0dGVuOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcj4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF4aXM6IG51bWJlcik6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXhpcyk7XG5cbiAgICAgIGNvbnN0IG91dHB1dERpbXMgPSBTaGFwZVV0aWwuZmxhdHRlblNoYXBlKGlucHV0c1swXS5kaW1zLCBheGlzKTtcbiAgICAgIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBvdXRwdXREaW1zKV07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRmxhdHRlbkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248bnVtYmVyPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogbnVtYmVyID0+XG4gICAgbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDEpOyAgLy8gZGVmYXVsdCBheGlzIGlzIDFcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXR0ZW4gcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGNvbnN0IHIgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGlmIChyID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzY2FsYXIgdGVuc29yIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gIH1cblxuICBpZiAoYXhpcyA8IC1yIHx8IGF4aXMgPiByKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGF4aXMnKTtcbiAgfVxuXG4gIC8vIFRPRE86IFN1cHBvcnQgc3RyaW5nIHR5cGVcbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignc3RyaW5nIHRlbnNvciBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICB9XG59OyIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi90ZW5zb3InO1xuXG5leHBvcnQgdHlwZSBPcGVyYXRvckltcGxlbWVudGF0aW9uPFQ+ID0gKGluZmVyZW5jZUhhbmRsZXI6IEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGNvbnRleHQ6IFQpID0+IFRlbnNvcltdO1xuZXhwb3J0IHR5cGUgT3BlcmF0b3JJbml0aWFsaXphdGlvbjxUPiA9IChub2RlOiBHcmFwaC5Ob2RlLCBncmFwaDogR3JhcGgpID0+IFQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlcmF0b3Ige1xuICByZWFkb25seSBpbXBsOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPHVua25vd24+O1xuICByZWFkb25seSBjb250ZXh0OiBHcmFwaC5Ob2RlfHVua25vd247XG59XG5cbmV4cG9ydCBjb25zdCBOVU1CRVJfVFlQRVM6IHJlYWRvbmx5IFRlbnNvci5EYXRhVHlwZVtdID1cbiAgICBbJ2Zsb2F0MzInLCAnZmxvYXQ2NCcsICdpbnQzMicsICdpbnQxNicsICdpbnQ4JywgJ3VpbnQxNicsICd1aW50MzInLCAndWludDgnXTtcbmV4cG9ydCBjb25zdCBJTlRfVFlQRVM6IHJlYWRvbmx5IFRlbnNvci5EYXRhVHlwZVtdID0gWydpbnQzMicsICdpbnQxNicsICdpbnQ4JywgJ3VpbnQxNicsICd1aW50MzInLCAndWludDgnXTtcbmV4cG9ydCBjb25zdCBGTE9BVF9UWVBFUzogcmVhZG9ubHkgVGVuc29yLkRhdGFUeXBlW10gPSBbJ2Zsb2F0MzInLCAnZmxvYXQ2NCddO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtOVU1CRVJfVFlQRVMsIE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbnRlcmZhY2UgR2F0aGVyQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4aXM6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGdhdGhlcjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxHYXRoZXJBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2F0aGVyQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcy5heGlzKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZUdhdGhlclByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyk7XG4gICAgICByZXR1cm4gW291dHB1dF07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2F0aGVyQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxHYXRoZXJBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogR2F0aGVyQXR0cmlidXRlcyA9PlxuICAgIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7YXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDApfSk7XG5cbmNvbnN0IGdhdGhlclByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0dhdGhlcicsXG4gIGlucHV0TmFtZXM6IFsnQScsICdCJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3QgY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm8gPVxuICAgIChfaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLCBpbnB1dHM6IFRlbnNvcltdLCBheGlzOiBudW1iZXIpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgICAgIGNvbnN0IGluZGV4RGF0YVNoYXBlID0gaW5wdXRzWzFdLmRpbXMuc2xpY2UoKTtcbiAgICAgIGNvbnN0IG91dHB1dFNoYXBlID0gbmV3IEFycmF5KGlucHV0U2hhcGUubGVuZ3RoICsgaW5kZXhEYXRhU2hhcGUubGVuZ3RoIC0gMSk7XG5cbiAgICAgIGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhheGlzLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG4gICAgICBjb25zdCBpbmRleENvcHlPcHM6IHN0cmluZ1tdID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dFNoYXBlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIC8vIG91dHB1dFNoYXBlIGlzIGRpdmlkZWQgaW50byB0aHJlZSBwYXJ0czogQSwgQiwgQ1xuICAgICAgICAvLyB8MCAgICAgICAgYXhpc3wgIGF4aXMgKyBpbmRleERhdGFTaGFwZS5sZW5ndGggfCAgICAgICAgICBlbmR8XG4gICAgICAgIC8vIHwgICAgIEEgICAgICAgfCAgICAgICAgICAgICBCICAgICAgICAgICAgICAgICB8ICAgICAgQyAgICAgIHxcbiAgICAgICAgLy9cbiAgICAgICAgLy8gaW5wdXRJZHg6IFtBLCBpbnB1dHNbMV1bQl0sIENdXG4gICAgICAgIGlmIChpIDwgYXhpcykgeyAgLy8gQVxuICAgICAgICAgIG91dHB1dFNoYXBlW2ldID0gaW5wdXRTaGFwZVtpXTtcbiAgICAgICAgICBpbmRleENvcHlPcHMucHVzaChgaW5wdXRJZHhbJHtpfV0gPSBvdXRwdXRJZHhbJHtpfV07YCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGkgPCBheGlzICsgaW5kZXhEYXRhU2hhcGUubGVuZ3RoKSB7ICAvLyBCXG4gICAgICAgICAgICBvdXRwdXRTaGFwZVtpXSA9IGluZGV4RGF0YVNoYXBlW2kgLSBheGlzXTtcbiAgICAgICAgICAgIGluZGV4Q29weU9wcy5wdXNoKGBpbmRleERhdGFJZHhbJHtpIC0gYXhpc31dID0gb3V0cHV0SWR4WyR7aX1dO2ApO1xuICAgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENcbiAgICAgICAgICAgIG91dHB1dFNoYXBlW2ldID0gaW5wdXRTaGFwZVtpIC0gaW5kZXhEYXRhU2hhcGUubGVuZ3RoICsgMV07ICAvLyBza2lwIDEgZm9yIGF4aXNcbiAgICAgICAgICAgIGluZGV4Q29weU9wcy5wdXNoKGBpbnB1dElkeFske2kgLSBpbmRleERhdGFTaGFwZS5sZW5ndGggKyAxfV0gPSBvdXRwdXRJZHhbJHtpfV07YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9yYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoIHx8IDE7XG4gICAgICBjb25zdCBpcmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3QgaURyYW5rID0gaW5kZXhEYXRhU2hhcGUubGVuZ3RoIHx8IDE7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtvcmFua31dKSB7XG4gICAgICAgIGludCBpbnB1dElkeFske2lyYW5rfV07XG4gICAgICAgIGludCBpbmRleERhdGFJZHhbJHtpRHJhbmt9XTtcbiAgICAgICAgaW5kZXhEYXRhSWR4WzBdID0gMDtcbiAgICAgICAgJHtpbmRleENvcHlPcHMuam9pbignXFxuICAgICAgICAnKX1cbiAgICAgICAgaW50IGlkeCA9IGludChfQihpbmRleERhdGFJZHgpKTtcbiAgICAgICAgaW5wdXRJZHhbJHtheGlzfV0gPSBpZHggPCAwID8gaWR4ICsgJHtpbnB1dFNoYXBlW2F4aXNdfSA6IGlkeDtcbiAgICAgICAgcmV0dXJuIF9BKGlucHV0SWR4KTtcbiAgICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZUdhdGhlclByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBHYXRoZXJBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSB7Li4uZ2F0aGVyUHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXl9O1xuICAgICAgcmV0dXJuIHsuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVHYXRoZXJQcm9ncmFtSW5mbyhoYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzLmF4aXMpfTtcbiAgICB9O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBheGlzOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignR2F0aGVyIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG4gIGNvbnN0IHRlbnNvclJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGlmICh0ZW5zb3JSYW5rIDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoYXhpcyA8IC10ZW5zb3JSYW5rIHx8IGF4aXMgPiB0ZW5zb3JSYW5rIC0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBheGlzLicpO1xuICB9XG4gIGlmIChOVU1CRVJfVFlQRVMuaW5kZXhPZihpbnB1dHNbMF0udHlwZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicgJiYgaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQxNicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge0dlbW1VdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEdlbW1BdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgdHJhbnNBOiBib29sZWFuO1xuICB0cmFuc0I6IGJvb2xlYW47XG4gIGFscGhhOiBudW1iZXI7XG4gIGJldGE6IG51bWJlcjtcbiAgaXNPcHRpb25hbEM6IGJvb2xlYW47ICAvLyBpbiBvcHNldCAxMSwgQyBiZWNvbWVzIG9wdGlvbmFsXG59XG5cbmV4cG9ydCBjb25zdCBnZW1tOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEdlbW1BdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlR2VtbVByb2dyYW1JbmZvTG9hZGVyKGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyk7XG4gICAgICByZXR1cm4gW291dHB1dF07XG4gICAgfTtcblxuY29uc3QgcGFyc2VHZW1tQXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlLCBpc09wdGlvbmFsQzogYm9vbGVhbik6IEdlbW1BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgdHJhbnNBID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgndHJhbnNBJywgMCkgIT09IDA7XG4gIGNvbnN0IHRyYW5zQiA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3RyYW5zQicsIDApICE9PSAwO1xuICBjb25zdCBhbHBoYSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAxLjApO1xuICBjb25zdCBiZXRhID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdiZXRhJywgMS4wKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7dHJhbnNBLCB0cmFuc0IsIGFscGhhLCBiZXRhLCBpc09wdGlvbmFsQ30pO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2VtbUF0dHJpYnV0ZXNWNzogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxHZW1tQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IEdlbW1BdHRyaWJ1dGVzID0+XG4gICAgcGFyc2VHZW1tQXR0cmlidXRlcyhub2RlLCBmYWxzZSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjExOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEdlbW1BdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogR2VtbUF0dHJpYnV0ZXMgPT5cbiAgICBwYXJzZUdlbW1BdHRyaWJ1dGVzKG5vZGUsIHRydWUpO1xuXG5jb25zdCBjcmVhdGVHZW1tUHJvZ3JhbUluZm9Mb2FkZXIgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdHZW1tJyxcbiAgICBpbnB1dE5hbWVzOiBpbnB1dHMubGVuZ3RoID09PSAzID8gWydBJywgJ0InLCAnQyddIDogWydBJywgJ0InXSxcbiAgICBpbnB1dFR5cGVzOiBpbnB1dHMubGVuZ3RoID09PSAzID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAga2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5XG4gIH07XG5cbiAgcmV0dXJuIHsuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVHZW1tUHJvZ3JhbUluZm8obWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcyl9O1xufTtcblxuY29uc3QgY3JlYXRlR2VtbVByb2dyYW1JbmZvID1cbiAgICAobWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICAgICAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXMuc2xpY2UoKTtcbiAgICAgIGNvbnN0IFtNLCBOXSA9IEdlbW1VdGlsLmdldFNoYXBlT2ZHZW1tUmVzdWx0KFxuICAgICAgICAgIGFTaGFwZSwgYXR0cmlidXRlcy50cmFuc0EsIGJTaGFwZSwgYXR0cmlidXRlcy50cmFuc0IsIGlucHV0cy5sZW5ndGggPT09IDMgPyBpbnB1dHNbMl0uZGltcyA6IHVuZGVmaW5lZCk7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IFtNLCBOXTtcbiAgICAgIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXCd0IHVzZSBnZW1tIG9uIHRoZSBnaXZlbiB0ZW5zb3JzJyk7XG4gICAgICB9XG4gICAgICBsZXQgc2hhcmVkRGltID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAxXTtcbiAgICAgIGxldCBsaW5lID0gJyc7XG4gICAgICBpZiAoYXR0cmlidXRlcy50cmFuc0EpIHtcbiAgICAgICAgc2hhcmVkRGltID0gYVNoYXBlWzBdO1xuICAgICAgfVxuICAgICAgaWYgKGF0dHJpYnV0ZXMudHJhbnNBICYmIGF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgICAgIGxpbmUgPSAndmFsdWUgKz0gX0FfVChhKSAqIF9CX1QoYik7JztcbiAgICAgIH0gZWxzZSBpZiAoYXR0cmlidXRlcy50cmFuc0EgJiYgIWF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgICAgIGxpbmUgPSAndmFsdWUgKz0gX0FfVChhKSAqIF9CKGIpOyc7XG4gICAgICB9IGVsc2UgaWYgKCFhdHRyaWJ1dGVzLnRyYW5zQSAmJiBhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgICAgICBsaW5lID0gJ3ZhbHVlICs9IF9BKGEpICogX0JfVChiKTsnO1xuICAgICAgfSBlbHNlIGlmICghYXR0cmlidXRlcy50cmFuc0EgJiYgIWF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgICAgIGxpbmUgPSAndmFsdWUgKz0gX0EoYSkgKiBfQihiKTsnO1xuICAgICAgfVxuICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IGRlY2xhcmVDID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/IGBpbnQgY1ske2lucHV0c1syXS5kaW1zLmxlbmd0aH1dO2AgOiAnJztcbiAgICAgIGNvbnN0IGJyb2FkY2FzdEMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gJ2JjYXN0SW5kaWNlc19DKGluZGljZXMsIGMpOycgOiAnJztcbiAgICAgIGNvbnN0IGNhbGN1bGF0ZUMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gJ3ZhbHVlICs9IGJldGEgKiBfQyhjKTsnIDogJyc7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IGFbJHtyYW5rfV07XG4gICAgICAgICAgaW50IGJbJHtyYW5rfV07XG4gICAgICAgICAgJHtkZWNsYXJlQ31cblxuICAgICAgICAgIGNvcHlWZWMoaW5kaWNlcywgYSk7XG4gICAgICAgICAgY29weVZlYyhpbmRpY2VzLCBiKTtcbiAgICAgICAgICAke2Jyb2FkY2FzdEN9XG5cbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9IDAuMDtcbiAgICAgICAgICBmb3IgKGludCBrPTA7IGs8JHtzaGFyZWREaW19OyArK2spIHtcbiAgICAgICAgICAgICAgYVske3JhbmsgLSAxfV0gPSBrO1xuICAgICAgICAgICAgICBiWyR7cmFuayAtIDJ9XSA9IGs7XG4gICAgICAgICAgICAgICR7bGluZX1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlICogYWxwaGE7XG4gICAgICAgICAgJHtjYWxjdWxhdGVDfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgdmFyaWFibGVzOiBbXG4gICAgICAgICAge25hbWU6ICdhbHBoYScsIHR5cGU6ICdmbG9hdCcsIGRhdGE6IGF0dHJpYnV0ZXMuYWxwaGF9LCB7bmFtZTogJ2JldGEnLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBhdHRyaWJ1dGVzLmJldGF9XG4gICAgICAgIF0sXG4gICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgfTtcbiAgICB9O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBHZW1tQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgaXMgbWlzc2luZycpO1xuICB9XG4gIGlmIChhdHRyaWJ1dGVzLmlzT3B0aW9uYWxDICYmIChpbnB1dHMubGVuZ3RoIDwgMiB8fCBpbnB1dHMubGVuZ3RoID4gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoIWF0dHJpYnV0ZXMuaXNPcHRpb25hbEMgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignR2VtbSByZXF1aXJlcyAzIGlucHV0cycpO1xuICB9XG5cbiAgLy8gJ0MnIGNhbiBiZSBvZiBkaW1lbnNpb25hbGl0eSAxIG9yIDIgb25seVxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEgJiYgaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlIG9mIEMnKTtcbiAgfVxuXG4gIGlmICgoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgICAgKGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAgIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzJdLnR5cGUgIT09ICdmbG9hdDY0JykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuXG4gIGlmICgoaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1sxXS50eXBlKSB8fCAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzWzJdLnR5cGUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCB0eXBlcyBhcmUgbWlzbWF0Y2hlZCcpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBJbWFnZVNjYWxlckF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBzY2FsZTogbnVtYmVyO1xuICBiaWFzOiBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGltYWdlU2NhbGVyOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEltYWdlU2NhbGVyQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEltYWdlU2NhbGVyQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gICAgICBjb25zdCBvdXRwdXQgPVxuICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZUltYWdlU2NhbGVyUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VJbWFnZVNjYWxlckF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248SW1hZ2VTY2FsZXJBdHRyaWJ1dGVzPiA9XG4gICAgKG5vZGU6IEdyYXBoLk5vZGUpOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMgPT4ge1xuICAgICAgY29uc3Qgc2NhbGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ3NjYWxlJyk7XG4gICAgICBjb25zdCBiaWFzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0cygnYmlhcycpO1xuICAgICAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7c2NhbGUsIGJpYXN9KTtcbiAgICB9O1xuXG5jb25zdCBpbWFnZVNjYWxlclByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0ltYWdlU2NhbGVyJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVJbWFnZVNjYWxlclByb2dyYW1JbmZvID1cbiAgICAoX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzKTpcbiAgICAgICAgUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgICAgIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgICAgICAgICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgICAgICAgIGNvbnN0IGdldEJpYXNNZXRob2QgPSBjcmVhdGVHZXRCaWFzTWV0aG9kKGF0dHJpYnV0ZXMuYmlhcy5sZW5ndGgpO1xuICAgICAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICR7Z2V0Qmlhc01ldGhvZH1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgcmV0dXJuIF9YKGluZGljZXMpICogc2NhbGUgKyBnZXRCaWFzKGJpYXMsIGluZGljZXNbMV0pO1xuICAgICAgfWA7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICAgICAgdmFyaWFibGVzOiBbXG4gICAgICAgICAgICAgIHtuYW1lOiAnYmlhcycsIHR5cGU6ICdmbG9hdCcsIGFycmF5TGVuZ3RoOiBhdHRyaWJ1dGVzLmJpYXMubGVuZ3RoLCBkYXRhOiBhdHRyaWJ1dGVzLmJpYXN9LFxuICAgICAgICAgICAgICB7bmFtZTogJ3NjYWxlJywgdHlwZTogJ2Zsb2F0JywgZGF0YTogYXR0cmlidXRlcy5zY2FsZX1cbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuXG5jb25zdCBjcmVhdGVJbWFnZVNjYWxlclByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IHsuLi5pbWFnZVNjYWxlclByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5fTtcbiAgICAgIHJldHVybiB7Li4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlSW1hZ2VTY2FsZXJQcm9ncmFtSW5mbyhoYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBhdHRyaWJ1dGVzKX07XG4gICAgfTtcblxuY29uc3QgY3JlYXRlR2V0Qmlhc01ldGhvZCA9IChudW1DaGFubmVsczogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3QgY29kZUxpbmVzOiBzdHJpbmdbXSA9IFtgZmxvYXQgZ2V0QmlhcyhmbG9hdCBiaWFzWyR7bnVtQ2hhbm5lbHN9XSwgaW50IGNoYW5uZWwpIHtgXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1DaGFubmVsczsgKytpKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgICAgICdcXHQnICtcbiAgICAgICAgICBgaWYgKGNoYW5uZWwgPT0gJHtpfSkgeyByZXR1cm4gYmlhc1ske2l9XTsgfWApO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gbnVtQ2hhbm5lbHMgLSAxKSB7XG4gICAgICBjb2RlTGluZXMucHVzaChcbiAgICAgICAgICAnXFx0JyArXG4gICAgICAgICAgYGVsc2UgeyByZXR1cm4gYmlhc1ske2l9XTsgfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlTGluZXMucHVzaChcbiAgICAgICAgICAnXFx0JyArXG4gICAgICAgICAgYGVsc2UgaWYgKGNoYW5uZWwgPT0gJHtpfSkgeyByZXR1cm4gYmlhc1ske2l9XTsgfWApO1xuICAgIH1cbiAgfVxuICBjb2RlTGluZXMucHVzaChcbiAgICAgICdcXHQnICtcbiAgICAgICd9Jyk7XG4gIHJldHVybiBjb2RlTGluZXMuam9pbignXFxuJyk7XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ltYWdlU2NhbGVyIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGluc3RhbmNlTm9ybWFsaXphdGlvbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxudW1iZXI+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBlcHNpbG9uOiBudW1iZXIpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gICAgICBjb25zdCBtZWFuQW5kVmFyaWFuY2UgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mb0xvYWRlcihpbnB1dHNbMF0pLCBpbnB1dHMpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgY3JlYXRlQ29tcHV0ZU91dHB1dFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgZXBzaWxvbiwgbWVhbkFuZFZhcmlhbmNlLmRpbXMpLFxuICAgICAgICAgIFtpbnB1dHNbMF0sIG1lYW5BbmRWYXJpYW5jZSwgaW5wdXRzWzFdLCBpbnB1dHNbMl1dKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VJbnN0YW5jZU5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPG51bWJlcj4gPSAobm9kZTogR3JhcGguTm9kZSk6IG51bWJlciA9PlxuICAgIG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnZXBzaWxvbicsIDFlLTUpO1xuXG5jb25zdCBtZWFuQW5kVmFyaWFuY2VQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdJbnN0YW5jZU5vcm1hbGl6YXRpb25fTWVhbkFuZFZhcmlhbmNlJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mbyA9IChtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLCBpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm8gPT4ge1xuICBjb25zdCB4RGltcyA9IGlucHV0LmRpbXMuc2xpY2UoKTtcbiAgY29uc3QgY2hhbm5lbCA9IHhEaW1zWzFdO1xuICBjb25zdCBjaGFubmVsU2l6ZSA9IHhEaW1zWzJdICogeERpbXNbM107XG4gIGNvbnN0IG91dHB1dFNoYXBlID0gW3hEaW1zWzBdLCBjaGFubmVsXTtcblxuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICB2ZWM0IHByb2Nlc3MoaW50WzJdIGluZGljZXMpIHtcbiAgICAgICAgdmVjNCB2ID0gdmVjNCgwLjApO1xuICAgICAgICBpbnQgYVs0XTtcbiAgICAgICAgYVswXSA9IGluZGljZXNbMF07XG4gICAgICAgIGFbMV0gPSBpbmRpY2VzWzFdO1xuICAgICAgICBmbG9hdCB0ZW1wID0gMC4wO1xuICAgICAgICBmb3IoaW50IGEyPTA7IGEyPCR7eERpbXNbMl19OyBhMisrKSB7XG4gICAgICAgICAgYVsyXSA9IGEyO1xuICAgICAgICAgIGZvcihpbnQgYTM9MDsgYTM8JHt4RGltc1szXX07IGEzKyspIHtcbiAgICAgICAgICAgIGFbM10gPSBhMztcbiAgICAgICAgICAgIGZsb2F0IHggPSBfWChhKTtcbiAgICAgICAgICAgIHRlbXAgKz0geDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZmxvYXQgbWVhbiA9IHRlbXAgLyBmbG9hdCgke2NoYW5uZWxTaXplfSk7XG4gICAgICAgIHRlbXAgPSAwLjA7XG4gICAgICAgIGZvcihpbnQgYTI9MDsgYTI8JHt4RGltc1syXX07IGEyKyspIHtcbiAgICAgICAgICBhWzJdID0gYTI7XG4gICAgICAgICAgZm9yKGludCBhMz0wOyBhMzwke3hEaW1zWzNdfTsgYTMrKykge1xuICAgICAgICAgICAgYVszXSA9IGEzO1xuICAgICAgICAgICAgZmxvYXQgeCA9IF9YKGEpO1xuICAgICAgICAgICAgdGVtcCArPSAoeCAtIG1lYW4pICogKHggLSBtZWFuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdi5yID0gbWVhbjtcbiAgICAgICAgdi5nID0gdGVtcCAvIGZsb2F0KCR7Y2hhbm5lbFNpemV9KTtcblxuICAgICAgICByZXR1cm4gdjtcbiAgICAgIH1gO1xuICByZXR1cm4ge1xuICAgIC4uLm1ldGFkYXRhLFxuICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbn0sXG4gICAgc2hhZGVyU291cmNlXG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mb0xvYWRlciA9IChpbnB1dDogVGVuc29yKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4gKHtcbiAgLi4ubWVhbkFuZFZhcmlhbmNlUHJvZ3JhbU1ldGFkYXRhLFxuICBnZXQ6ICgpID0+IGNyZWF0ZU1lYW5BbmRWYXJpYW5jZVByb2dyYW1JbmZvKG1lYW5BbmRWYXJpYW5jZVByb2dyYW1NZXRhZGF0YSwgaW5wdXQpXG59KTtcblxuY29uc3QgY29tcHV0ZU91dHB1dFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0luc3RhbmNlTm9ybWFsaXphdGlvbl9Db21wdXRlT3V0cHV0JyxcbiAgaW5wdXROYW1lczogWydYJywgJ01lYW5BbmRWYXJpYW5jZScsICdTY2FsZScsICdCJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbiwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmNvbnN0IGNyZWF0ZUNvbXB1dGVPdXRwdXRQcm9ncmFtSW5mbyA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXQ6IFRlbnNvciwgZXBzaWxvbjogbnVtYmVyLFxuICAgICBtZWFuQW5kVmFyaWFuY2VTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9XG4gICAgICAgICAgaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQobWVhbkFuZFZhcmlhbmNlU2hhcGUsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24pO1xuICAgICAgY29uc3QgW21lYW5BbmRWYXJpYW5jZVdpZHRoLCBtZWFuQW5kVmFyaWFuY2VIZWlnaHRdID0gW3RleHR1cmVXaWR0aCAvIDQsIHRleHR1cmVIZWlnaHRdO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgdmVjNCBnZXRfTWVhbkFuZFZhcmlhbmNlKGludFsyXSBtdikge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gaW5kaWNlc1RvT2Zmc2V0X01lYW5BbmRWYXJpYW5jZShtdik7XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke21lYW5BbmRWYXJpYW5jZVdpZHRofSwgJHttZWFuQW5kVmFyaWFuY2VIZWlnaHR9KTtcbiAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KE1lYW5BbmRWYXJpYW5jZSwgY29vcmRzKTtcbiAgICAgIH1cblxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbNF0gaW5kaWNlcykge1xuICAgICAgICBpbnQgbXZbMl07XG4gICAgICAgIG12WzBdID0gaW5kaWNlc1swXTtcbiAgICAgICAgbXZbMV0gPSBpbmRpY2VzWzFdO1xuICAgICAgICB2ZWM0IG1lYW5fYW5kX3ZhcmlhbmNlID0gZ2V0X01lYW5BbmRWYXJpYW5jZShtdik7XG4gICAgICAgIGZsb2F0IG1lYW4gPSBtZWFuX2FuZF92YXJpYW5jZS5yO1xuICAgICAgICBmbG9hdCB2YXJpYW5jZSA9IG1lYW5fYW5kX3ZhcmlhbmNlLmc7XG5cbiAgICAgICAgaW50IHNiWzFdO1xuICAgICAgICBzYlswXSA9IGluZGljZXNbMV07XG4gICAgICAgIGZsb2F0IHNjYWxlID0gX1NjYWxlKHNiKTtcbiAgICAgICAgZmxvYXQgYiA9IF9CKHNiKTtcblxuICAgICAgICByZXR1cm4gc2NhbGUgKiAoX1goaW5kaWNlcykgLSBtZWFuKSAvIHNxcnQodmFyaWFuY2UgKyBlcHNpbG9uKSArIGI7XG4gICAgICB9YDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBpbnB1dC5kaW1zLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICB2YXJpYWJsZXM6IFt7bmFtZTogJ2Vwc2lsb24nLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBlcHNpbG9ufV0sXG4gICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgfTtcbiAgICB9O1xuXG5jb25zdCBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm9Mb2FkZXIgPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIGVwc2lsb246IG51bWJlciwgbWVhbkFuZFZhcmlhbmNlU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTpcbiAgICAgICAgUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0gey4uLmNvbXB1dGVPdXRwdXRQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYCR7ZXBzaWxvbn1gfTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZUNvbXB1dGVPdXRwdXRQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXQsIGVwc2lsb24sIG1lYW5BbmRWYXJpYW5jZVNoYXBlKVxuICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5zdGFuY2VOb3JtYWxpemF0aW9uIHJlcXVpcmVzIDMgaW5wdXRzLicpO1xuICB9XG5cbiAgY29uc3QgWCA9IGlucHV0c1swXTtcbiAgY29uc3Qgc2NhbGUgPSBpbnB1dHNbMV07XG4gIGNvbnN0IEIgPSBpbnB1dHNbMl07XG5cbiAgLy8gaW5wdXQgc2hvdWxkIGF0IGxlYXN0IGhhdmUgdGhyZWUgZGltZW5zaW9ucyAtIE4sQyxkaW0xLC4uLixkaW1uXG4gIC8vIG90aGVyIGlucHV0cyBjYW4gaGF2ZSBvbmx5IG9uZSBkaW1lbnNpb25zXG4gIGlmIChYLmRpbXMubGVuZ3RoIDwgMyB8fCBzY2FsZS5kaW1zLmxlbmd0aCAhPT0gMSB8fCBCLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChzY2FsZS5kaW1zWzBdICE9PSBYLmRpbXNbMV0gfHwgQi5kaW1zWzBdICE9PSBYLmRpbXNbMV0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IHNoYXBlcyBhcmUgbWlzbWF0Y2hlZC4nKTtcbiAgfVxuICBpZiAoKFgudHlwZSAhPT0gJ2Zsb2F0MzInICYmIFgudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fCAoc2NhbGUudHlwZSAhPT0gJ2Zsb2F0MzInICYmIHNjYWxlLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAgIChCLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBCLnR5cGUgIT09ICdmbG9hdDY0JykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IHN1cHBvcnQgNC1EIGlucHV0IHNoYXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTHJuQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGFscGhhOiBudW1iZXI7XG4gIGJldGE6IG51bWJlcjtcbiAgYmlhczogbnVtYmVyO1xuICBzaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBscm46IE9wZXJhdG9ySW1wbGVtZW50YXRpb248THJuQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IExybkF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gICAgICAvLyBpZiAoaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLnBhY2spIHtcbiAgICAgIC8vICAgcmV0dXJuIFtpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVQYWNrZWRMcm5Qcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLFxuICAgICAgLy8gICBpbnB1dHMpXTtcbiAgICAgIC8vIH0gZWxzZSB7XG4gICAgICByZXR1cm4gW2luZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZUxyblByb2dyYW1JbmZvTG9hZGVyKGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyldO1xuICAgICAgLy99XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTHJuQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxMcm5BdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogTHJuQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGFscGhhID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdhbHBoYScsIDAuMDAwMSk7XG4gIGNvbnN0IGJldGEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2JldGEnLCAwLjc1KTtcbiAgY29uc3QgYmlhcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYmlhcycsIDEuMCk7XG4gIGNvbnN0IHNpemUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdzaXplJyk7XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7YWxwaGEsIGJldGEsIGJpYXMsIHNpemV9KTtcbn07XG5cbmNvbnN0IGxyblByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0xSTicsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdXG59O1xuXG5mdW5jdGlvbiBjcmVhdGVMcm5Qcm9ncmFtSW5mbyhpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBMcm5BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8ge1xuICBjb25zdCBDID0gaW5wdXRzWzBdLmRpbXNbMV07XG4gIGNvbnN0IHJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGNvbnN0IGZyb20gPSAtTWF0aC5mbG9vcigoYXR0cmlidXRlcy5zaXplIC0gMSkgLyAyKTtcbiAgY29uc3QgdG8gPSBNYXRoLmNlaWwoKGF0dHJpYnV0ZXMuc2l6ZSAtIDEpIC8gMik7XG4gIGNvbnN0IGFscGhhID0gYGZsb2F0KCR7YXR0cmlidXRlcy5hbHBoYX0pIC8gZmxvYXQoJHthdHRyaWJ1dGVzLnNpemV9KWA7XG4gIGNvbnN0IGJpYXMgPSBgZmxvYXQoJHthdHRyaWJ1dGVzLmJpYXN9KWA7XG4gIGNvbnN0IGJldGEgPSBgZmxvYXQoJHthdHRyaWJ1dGVzLmJldGF9KWA7XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGMgPSBpbmRpY2VzWzFdO1xuICAgICAgICBmbG9hdCB4ID0gX1goaW5kaWNlcyk7XG4gICAgICAgIGZsb2F0IHNxdWFyZV9zdW0gPSAwLjA7XG5cbiAgICAgICAgZm9yIChpbnQgaSA9ICR7ZnJvbX07IGkgPD0gJHt0b307IGkrKykge1xuICAgICAgICAgIGludCBpZHggPSBjICsgaTtcbiAgICAgICAgICBpZiAoYyA+PSAwICYmIGMgPCAke0N9KSB7XG4gICAgICAgICAgICBpbmRpY2VzWzFdID0gaWR4O1xuICAgICAgICAgICAgZmxvYXQgaiA9IF9YKGluZGljZXMpO1xuICAgICAgICAgICAgc3F1YXJlX3N1bSArPSBqICogajtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggLyBwb3coJHtiaWFzfSArICR7YWxwaGF9ICogc3F1YXJlX3N1bSwgJHtiZXRhfSk7XG4gICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubHJuUHJvZ3JhbU1ldGFkYXRhLFxuICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICBvdXRwdXQ6IHtkaW1zOiBpbnB1dHNbMF0uZGltcywgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZH0sXG4gICAgc2hhZGVyU291cmNlLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTHJuUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogTHJuQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvTG9hZGVyIHtcbiAgcmV0dXJuIHsuLi5scm5Qcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBjcmVhdGVMcm5Qcm9ncmFtSW5mbyhpbnB1dHMsIGF0dHJpYnV0ZXMpfTtcbn1cblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdMUk4gcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgb25seSBzdXBwb3J0IExSTiBmb3IgaW5wdXQgd2l0aCBcIk5DSFdcIiBmb3JtYXQnKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hvdWxkIGJlIGZsb2F0IHR5cGUnKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleX0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtTaGFwZVV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtnZXRHbHNsLCBHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBQYWRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgbW9kZTogc3RyaW5nO1xuICByZWFkb25seSBwYWRzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgdmFsdWU6IG51bWJlcjtcbn1cblxuY29uc3QgcGFkUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnUGFkJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgcGFkVjI6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UGFkQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFBhZEF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0c1YyKGlucHV0cyk7XG4gICAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5wYWRQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZVBhZFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcylcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlucHV0cyk7XG4gICAgICByZXR1cm4gW291dHB1dF07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUGFkQXR0cmlidXRlc1YyOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFBhZEF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBQYWRBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgbW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnY29uc3RhbnQnKTtcbiAgY29uc3QgdmFsdWUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ3ZhbHVlJywgMC4wKTtcbiAgY29uc3QgcGFkcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJyk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe21vZGUsIHZhbHVlLCBwYWRzfSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFkVjExOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPHN0cmluZz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIG1vZGU6IHN0cmluZyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzVjExKGlucHV0cyk7XG4gICAgICBjb25zdCBhdHRydWJ1dGVzID0gZ2VuZXJhdGVQYWRBdHRyaWJ1dGVzRnJvbUlucHV0cyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIG1vZGUpO1xuICAgICAgcmV0dXJuIHBhZFYyKGluZmVyZW5jZUhhbmRsZXIsIFtpbnB1dHNbMF1dLCBhdHRydWJ1dGVzKTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VQYWRBdHRyaWJ1dGVzVjExOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPHN0cmluZz4gPSAobm9kZTogR3JhcGguTm9kZSk6IHN0cmluZyA9PlxuICAgIG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnY29uc3RhbnQnKTtcblxuY29uc3QgZ2VuZXJhdGVQYWRBdHRyaWJ1dGVzRnJvbUlucHV0cyA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgbW9kZTogc3RyaW5nKTogUGFkQXR0cmlidXRlcyA9PiB7XG4gICAgICBpZiAoIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1sxXS5kYXRhSWQpIHx8XG4gICAgICAgICAgKGlucHV0cy5sZW5ndGggPj0gMyAmJiAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzJdLmRhdGFJZCkpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZHluYW1pYyBwYWQgYXR0cmlidXRlcyBhcmUgbm90IGFsbG93ZWQnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFkcyA9IEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKTtcbiAgICAgIGNvbnN0IHZhbHVlID0gKGlucHV0cy5sZW5ndGggPj0gMykgPyBpbnB1dHNbMl0uZmxvYXREYXRhWzBdIDogMC4wO1xuXG4gICAgICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHttb2RlLCBwYWRzLCB2YWx1ZX0pO1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZVBhZFByb2dyYW1JbmZvID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yLCBhdHRyaWJ1dGVzOiBQYWRBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwucGFkU2hhcGUoaW5wdXQuZGltcy5zbGljZSgpLCBhdHRyaWJ1dGVzLnBhZHMpO1xuICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IHBhZEZ1bmN0aW9uID0gZ2V0UGFkRnVuY3Rpb24oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXQsIGF0dHJpYnV0ZXMpO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtwYWRGdW5jdGlvbn1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICAgICAgICByZXR1cm4gcGFkQShpbmRpY2VzKTtcbiAgICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogJ1BhZCcsXG4gICAgICAgIGlucHV0TmFtZXM6IFsnQSddLFxuICAgICAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjIgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQYWQgcmVxdWlyZXMgMSBpbnB1dCcpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMTEgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCAoaW5wdXRzLmxlbmd0aCAhPT0gMiAmJiBpbnB1dHMubGVuZ3RoICE9PSAzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGFkIHJlcXVpcmVzIDIgb3IgMyBpbnB1dHMnKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSAzICYmIGlucHV0c1syXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5jb25zdCBnZXRQYWRGdW5jdGlvbiA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIGF0dHJpYnV0ZXM6IFBhZEF0dHJpYnV0ZXMpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIGNvbnN0IFt3aWR0aCwgaGVpZ2h0XSA9IGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KGlucHV0LmRpbXMsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgY29uc3Qgc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhpbnB1dC5kaW1zKTtcblxuICBzd2l0Y2ggKGF0dHJpYnV0ZXMubW9kZSkge1xuICAgIGNhc2UgJ2NvbnN0YW50JzpcbiAgICAgIHJldHVybiBnZXRQYWRDb25zdGFudChnbHNsLCBpbnB1dC5kaW1zLCBzdHJpZGVzLCB3aWR0aCwgaGVpZ2h0LCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMudmFsdWUpO1xuICAgIGNhc2UgJ3JlZmxlY3QnOlxuICAgICAgcmV0dXJuIGdldFBhZFJlZmxlY3QoZ2xzbCwgaW5wdXQuZGltcywgc3RyaWRlcywgd2lkdGgsIGhlaWdodCwgYXR0cmlidXRlcy5wYWRzKTtcbiAgICBjYXNlICdlZGdlJzpcbiAgICAgIHJldHVybiBnZXRQYWRFZGdlKGdsc2wsIGlucHV0LmRpbXMsIHN0cmlkZXMsIHdpZHRoLCBoZWlnaHQsIGF0dHJpYnV0ZXMucGFkcyk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBtb2RlJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdldFBhZENvbnN0YW50ID1cbiAgICAoZ2xzbDogR2xzbCwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIHBhZHM6IG51bWJlcltdLFxuICAgICB2YWx1ZTogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICBsZXQgYmxvY2sgPSAnJztcbiAgICAgIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBrID0gbVske2l9XSAtICR7cGFkc1tpXX07XG4gICAgICAgIGlmIChrIDwgMCkgIHJldHVybiBjb25zdGFudDtcbiAgICAgICAgaWYgKGsgPj0gJHtzaGFwZVtpXX0pIHJldHVybiBjb25zdGFudDtcbiAgICAgICAgb2Zmc2V0ICs9IGsgKiAke3N0cmlkZXNbaV19O1xuICAgICAgICBgO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGBcbiAgICAgIGZsb2F0IHBhZEEoaW50IG1bJHtyYW5rfV0pIHtcbiAgICAgICAgY29uc3QgZmxvYXQgY29uc3RhbnQgPSBmbG9hdCgke3ZhbHVlfSk7XG4gICAgICAgIGludCBvZmZzZXQgPSAwO1xuICAgICAgICBpbnQgayA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgY29vcmRzKSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGA7XG4gICAgfTtcblxuY29uc3QgZ2V0UGFkUmVmbGVjdCA9XG4gICAgKGdsc2w6IEdsc2wsIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBwYWRzOiBudW1iZXJbXSk6XG4gICAgICAgIHN0cmluZyA9PiB7XG4gICAgICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAgICAgICAgIGxldCBibG9jayA9ICcnO1xuICAgICAgICAgIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgayA9IG1bJHtpfV0gLSAke3BhZHNbaV19O1xuICAgICAgICBpZiAoayA8IDApIHsgayA9IC1rOyB9XG4gICAgICAgIHtcbiAgICAgICAgICBjb25zdCBpbnQgXzJuXzEgPSAkezIgKiAoc2hhcGVbaV0gLSAxKX07XG4gICAgICAgICAgayA9IGludCggbW9kKCBmbG9hdChrKSwgZmxvYXQoXzJuXzEpICkgKSA7XG4gICAgICAgICAgaWYoayA+PSAke3NoYXBlW2ldfSkgeyBrID0gXzJuXzEgLSBrOyB9XG4gICAgICAgIH1cbiAgICAgICAgb2Zmc2V0ICs9IGsgKiAke3N0cmlkZXNbaV19O1xuICAgICAgICBgO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYFxuICAgICAgZmxvYXQgcGFkQShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gMDtcbiAgICAgICAgaW50IGsgPSAwO1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIGNvb3JkcykpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBgO1xuICAgICAgICB9O1xuXG5jb25zdCBnZXRQYWRFZGdlID1cbiAgICAoZ2xzbDogR2xzbCwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIHBhZHM6IG51bWJlcltdKTpcbiAgICAgICAgc3RyaW5nID0+IHtcbiAgICAgICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgICAgICAgbGV0IGJsb2NrID0gJyc7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IHJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBrID0gbVske2l9XSAtICR7cGFkc1tpXX07XG4gICAgICAgIGlmIChrIDwgMCkgIGsgPSAwO1xuICAgICAgICBpZiAoayA+PSAke3NoYXBlW2ldfSkgayA9ICR7c2hhcGVbaV0gLSAxfTtcbiAgICAgICAgb2Zmc2V0ICs9IGsgKiAke3N0cmlkZXNbaV19O1xuICAgICAgYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGBcbiAgICAgIGZsb2F0IHBhZEEoaW50IG1bJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IG9mZnNldCA9IDA7XG4gICAgICAgIGludCBrID0gMDtcbiAgICAgICAgJHtibG9ja31cbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7d2lkdGh9LCAke2hlaWdodH0pO1xuICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBjb29yZHMpKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgYDtcbiAgICAgICAgfTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleX0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtQb29sQ29udlV0aWwsIFNoYXBlVXRpbH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF2ZXJhZ2VQb29sQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF1dG9QYWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgY2VpbE1vZGU6IG51bWJlcjtcbiAgcmVhZG9ubHkgY291bnRJbmNsdWRlUGFkOiBib29sZWFuO1xuICByZWFkb25seSBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBwYWRzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGF2ZXJhZ2VQb29sOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEF2ZXJhZ2VQb29sQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9XG4gICAgICAgICAge25hbWU6ICdBdmVyYWdlUG9vbCcsIGlucHV0TmFtZXM6IFsnWCddLCBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXl9O1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgey4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUF2ZXJhZ2VQb29sUHJvZ3JhbUluZm8oaW5wdXRzLCBtZXRhZGF0YSwgZmFsc2UsIGF0dHJpYnV0ZXMpfSwgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248QXZlcmFnZVBvb2xBdHRyaWJ1dGVzPiA9XG4gICAgKG5vZGU6IEdyYXBoLk5vZGUpOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgPT4ge1xuICAgICAgY29uc3QgYXV0b1BhZCA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2F1dG9fcGFkJywgJ05PVFNFVCcpO1xuICAgICAgY29uc3QgY2VpbE1vZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdjZWlsX21vZGUnLCAwKTtcbiAgICAgIGNvbnN0IGNvdW50SW5jbHVkZVBhZCA9IChub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdjb3VudF9pbmNsdWRlX3BhZCcsIDApID09PSAwID8gZmFsc2UgOiB0cnVlKTtcbiAgICAgIGNvbnN0IGtlcm5lbFNoYXBlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2tlcm5lbF9zaGFwZScpO1xuICAgICAgY29uc3Qgc3RyaWRlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgW10pO1xuICAgICAgY29uc3QgcGFkcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJywgW10pO1xuXG4gICAgICAvLyBUT0RPOiBzdXBwb3J0IGF0dHJpYnV0ZSAnY2VpbF9tb2RlJ1xuICAgICAgaWYgKGNlaWxNb2RlICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndXNpbmcgY2VpbCgpIGluIHNoYXBlIGNvbXB1dGF0aW9uIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciBBdmVyYWdlUG9vbCcpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHthdXRvUGFkLCBjZWlsTW9kZSwgY291bnRJbmNsdWRlUGFkLCBrZXJuZWxTaGFwZSwgc3RyaWRlcywgcGFkc30pO1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZUF2ZXJhZ2VQb29sUHJvZ3JhbUluZm8gPVxuICAgIChpbnB1dHM6IFRlbnNvcltdLCBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLCBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLCBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMpOlxuICAgICAgICBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICAgICAgY29uc3QgW2FkanVzdGVkQXR0cmlidXRlcywgb3V0cHV0U2hhcGVdID1cbiAgICAgICAgICAgICAgZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlKGlucHV0cywgYXR0cmlidXRlcywgaXNHbG9iYWxPcGVyYXRvcik7XG4gICAgICAgICAgY29uc3Qga2VybmVsU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGFkanVzdGVkQXR0cmlidXRlcy5rZXJuZWxTaGFwZSk7XG4gICAgICAgICAgY29uc3Qgb3AxID0gJ3ZhbHVlICs9IF9YKHgpOyc7XG4gICAgICAgICAgbGV0IG9wMiA9ICcnO1xuICAgICAgICAgIGlmIChhZGp1c3RlZEF0dHJpYnV0ZXMuY291bnRJbmNsdWRlUGFkKSB7XG4gICAgICAgICAgICBvcDIgKz0gYHZhbHVlIC89IGZsb2F0KCR7a2VybmVsU2l6ZX0pO2A7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9wMiArPSBgdmFsdWUgLz0gZmxvYXQoJHtrZXJuZWxTaXplfSAtIHBhZCk7YDtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgcG9vbGluZ0NvZGUgPSBnZW5lcmF0ZVBvb2xpbmdDb2RlKGlucHV0c1swXS5kaW1zLCBhZGp1c3RlZEF0dHJpYnV0ZXMsIG9wMSwgb3AyLCAnMC4wJyk7XG4gICAgICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAke3Bvb2xpbmdDb2RlfVxuICAgICAgYDtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZH0sXG4gICAgICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuXG5leHBvcnQgY29uc3QgZ2xvYmFsQXZlcmFnZVBvb2w6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248QXZlcmFnZVBvb2xBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0ge1xuICAgICAgICBuYW1lOiAnR2xvYmFsQXZlcmFnZVBvb2wnLFxuICAgICAgICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgICAgICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgICAgICAgY2FjaGVIaW50OiBgJHthdHRyaWJ1dGVzLmNvdW50SW5jbHVkZVBhZH1gXG4gICAgICB9O1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgey4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUF2ZXJhZ2VQb29sUHJvZ3JhbUluZm8oaW5wdXRzLCBtZXRhZGF0YSwgdHJ1ZSwgYXR0cmlidXRlcyl9LCBpbnB1dHMpO1xuICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM+ID1cbiAgICAobm9kZTogR3JhcGguTm9kZSk6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyA9PiB7XG4gICAgICBjb25zdCBjb3VudEluY2x1ZGVQYWQgPSAobm9kZS5hdHRyaWJ1dGVzLmdldEludCgnY291bnRfaW5jbHVkZV9wYWQnLCAwKSA9PT0gMCA/IGZhbHNlIDogdHJ1ZSk7XG4gICAgICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KFxuICAgICAgICAgIHthdXRvUGFkOiAnJywgY2VpbE1vZGU6IDAsIGNvdW50SW5jbHVkZVBhZCwga2VybmVsU2hhcGU6IFtdLCBzdHJpZGVzOiBbXSwgcGFkczogW119KTtcbiAgICB9O1xuXG5leHBvcnQgaW50ZXJmYWNlIE1heFBvb2xBdHRyaWJ1dGVzIGV4dGVuZHMgQXZlcmFnZVBvb2xBdHRyaWJ1dGVzIHtcbiAgcmVhZG9ubHkgc3RvcmFnZU9yZGVyOiBudW1iZXI7XG4gIHJlYWRvbmx5IGRpbGF0aW9uczogbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBtYXhQb29sOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPE1heFBvb2xBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogTWF4UG9vbEF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICAgICAgY29uc3QgbWV0YWRhdGEgPVxuICAgICAgICAgIHtuYW1lOiAnTWF4UG9vbCcsIGlucHV0TmFtZXM6IFsnWCddLCBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXl9O1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgey4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZU1heFBvb2xQcm9ncmFtSW5mbyhpbnB1dHMsIG1ldGFkYXRhLCBmYWxzZSwgYXR0cmlidXRlcyl9LCBpbnB1dHMpO1xuICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBwYXJzZU1heFBvb2xBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPE1heFBvb2xBdHRyaWJ1dGVzPiA9XG4gICAgKG5vZGU6IEdyYXBoLk5vZGUpOiBNYXhQb29sQXR0cmlidXRlcyA9PiB7XG4gICAgICBjb25zdCBhdXRvUGFkID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnYXV0b19wYWQnLCAnTk9UU0VUJyk7XG4gICAgICBjb25zdCBjZWlsTW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2NlaWxfbW9kZScsIDApO1xuICAgICAgY29uc3Qga2VybmVsU2hhcGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygna2VybmVsX3NoYXBlJyk7XG4gICAgICBjb25zdCBzdHJpZGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3N0cmlkZXMnLCBbXSk7XG4gICAgICBjb25zdCBwYWRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbXSk7XG4gICAgICBjb25zdCBzdG9yYWdlT3JkZXIgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdzdG9yYWdlX29yZGVyJywgMCk7XG4gICAgICBjb25zdCBkaWxhdGlvbnMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnZGlsYXRpb25zJywgW10pO1xuXG4gICAgICAvLyBUT0RPOiBzdXBwb3J0IGF0dHJpYnV0ZSAnY2VpbF9tb2RlJyBhbmQgJ3N0b3JhZ2Vfb3JkZXInXG4gICAgICBpZiAoc3RvcmFnZU9yZGVyICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY29sdW1uIG1ham9yIHN0b3JhZ2Ugb3JkZXIgaXMgbm90IHlldCBzdXBwb3J0ZWQgZm9yIE1heFBvb2wnKTtcbiAgICAgIH1cbiAgICAgIGlmIChjZWlsTW9kZSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzaW5nIGNlaWwoKSBpbiBzaGFwZSBjb21wdXRhdGlvbiBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgTWF4UG9vbCcpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KFxuICAgICAgICAgIHthdXRvUGFkLCBjZWlsTW9kZSwgY291bnRJbmNsdWRlUGFkOiBmYWxzZSwga2VybmVsU2hhcGUsIHN0cmlkZXMsIHBhZHMsIHN0b3JhZ2VPcmRlciwgZGlsYXRpb25zfSk7XG4gICAgfTtcblxuY29uc3QgY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvID1cbiAgICAoaW5wdXRzOiBUZW5zb3JbXSwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbiwgYXR0cmlidXRlczogTWF4UG9vbEF0dHJpYnV0ZXMpOlxuICAgICAgICBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICAgICAgY29uc3QgW2FkanVzdGVkQXR0cmlidXRlcywgb3V0cHV0U2hhcGVdID1cbiAgICAgICAgICAgICAgZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlKGlucHV0cywgYXR0cmlidXRlcywgaXNHbG9iYWxPcGVyYXRvcik7XG4gICAgICAgICAgY29uc3Qgb3AxID0gYFxuICAgICAgdmFsdWUgPSBtYXgoX1goeCksIHZhbHVlKTtcbiAgICBgO1xuICAgICAgICAgIGNvbnN0IG9wMiA9ICcnO1xuICAgICAgICAgIGNvbnN0IHBvb2xpbmdDb2RlID0gZ2VuZXJhdGVQb29saW5nQ29kZShpbnB1dHNbMF0uZGltcywgYWRqdXN0ZWRBdHRyaWJ1dGVzLCBvcDEsIG9wMiwgJy0xZTUnKTtcbiAgICAgICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke3Bvb2xpbmdDb2RlfVxuICAgIGA7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRQb29sQXR0cmlidXRlc0FuZE91dHB1dFNoYXBlID1cbiAgICAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzfE1heFBvb2xBdHRyaWJ1dGVzLCBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuKTpcbiAgICAgICAgW0F2ZXJhZ2VQb29sQXR0cmlidXRlc3xNYXhQb29sQXR0cmlidXRlcywgbnVtYmVyW11dID0+IHtcbiAgICAgICAgICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgICAgICAgICBjb25zdCBoYXNEaWxhdGlvbnMgPSBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChhdHRyaWJ1dGVzLCAnZGlsYXRpb25zJyk7XG4gICAgICAgICAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnNsaWNlKCk7XG4gICAgICAgICAgY29uc3Qgc3RyaWRlcyA9IGF0dHJpYnV0ZXMuc3RyaWRlcy5zbGljZSgpO1xuICAgICAgICAgIGNvbnN0IGRpbGF0aW9uczogbnVtYmVyW10gPSBoYXNEaWxhdGlvbnMgPyAoYXR0cmlidXRlcyBhcyBNYXhQb29sQXR0cmlidXRlcykuZGlsYXRpb25zLnNsaWNlKCkgOiBbXTtcbiAgICAgICAgICBjb25zdCBwYWRzID0gYXR0cmlidXRlcy5wYWRzLnNsaWNlKCk7XG4gICAgICAgICAgUG9vbENvbnZVdGlsLmFkanVzdFBvb2xBdHRyaWJ1dGVzKGlzR2xvYmFsT3BlcmF0b3IsIGlucHV0U2hhcGUsIGtlcm5lbFNoYXBlLCBzdHJpZGVzLCBkaWxhdGlvbnMsIHBhZHMpO1xuXG4gICAgICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBQb29sQ29udlV0aWwuY29tcHV0ZVBvb2xPdXRwdXRTaGFwZShcbiAgICAgICAgICAgICAgaXNHbG9iYWxPcGVyYXRvciwgaW5wdXRTaGFwZSwgc3RyaWRlcywgZGlsYXRpb25zLCBrZXJuZWxTaGFwZSwgcGFkcywgYXR0cmlidXRlcy5hdXRvUGFkKTtcblxuICAgICAgICAgIGNvbnN0IG5ld0F0dHJpYnV0ZXMgPSBPYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzKTtcbiAgICAgICAgICBpZiAoaGFzRGlsYXRpb25zKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHtrZXJuZWxTaGFwZSwgc3RyaWRlcywgcGFkcywgZGlsYXRpb25zLCBjYWNoZUtleTogYXR0cmlidXRlcy5jYWNoZUtleX0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKG5ld0F0dHJpYnV0ZXMsIHtrZXJuZWxTaGFwZSwgc3RyaWRlcywgcGFkcywgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXl9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFtuZXdBdHRyaWJ1dGVzLCBvdXRwdXRTaGFwZV07XG4gICAgICAgIH07XG5cbmNvbnN0IGdsb2JhbE1heFBvb2xBdHRyaWJ1dGVzID0ge1xuICBhdXRvUGFkOiAnJyxcbiAgY2VpbE1vZGU6IDAsXG4gIGNvdW50SW5jbHVkZVBhZDogZmFsc2UsXG4gIGtlcm5lbFNoYXBlOiBbXSxcbiAgc3RyaWRlczogW10sXG4gIHBhZHM6IFtdLFxuICBzdG9yYWdlT3JkZXI6IDAsXG4gIGRpbGF0aW9uczogW10sXG4gIGNhY2hlS2V5OiAnJ1xufTtcblxuY29uc3QgZ2xvYmFsTWF4UG9vbE1ldGFkYXRhID0ge1xuICBuYW1lOiAnR2xvYmFsTWF4UG9vbCcsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdXG59O1xuXG5leHBvcnQgY29uc3QgZ2xvYmFsTWF4UG9vbCA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAge1xuICAgICAgICAuLi5nbG9iYWxNYXhQb29sTWV0YWRhdGEsXG4gICAgICAgIGdldDogKCkgPT4gY3JlYXRlTWF4UG9vbFByb2dyYW1JbmZvKGlucHV0cywgZ2xvYmFsTWF4UG9vbE1ldGFkYXRhLCB0cnVlLCBnbG9iYWxNYXhQb29sQXR0cmlidXRlcylcbiAgICAgIH0sXG4gICAgICBpbnB1dHMpO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bvb2wgb3BzIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5jb25zdCBnZW5lcmF0ZVBvb2xpbmdDb2RlID1cbiAgICAoaW5wdXREaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLCBvcDE6IHN0cmluZywgb3AyOiBzdHJpbmcsIHN0YXJ0OiBzdHJpbmcpOlxuICAgICAgICBzdHJpbmcgPT4ge1xuICAgICAgICAgIGNvbnN0IHJhbmsgPSBpbnB1dERpbXMubGVuZ3RoO1xuICAgICAgICAgIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA8PSAyKSB7XG4gICAgICAgICAgICBjb25zdCBrdyA9IGF0dHJpYnV0ZXMua2VybmVsU2hhcGVbYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgIGNvbnN0IHN3ID0gYXR0cmlidXRlcy5zdHJpZGVzW2F0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgIGNvbnN0IHB3U3RhcnQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAvIDIgLSAxXTtcbiAgICAgICAgICAgIGNvbnN0IHB3RW5kID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgIGNvbnN0IGRpbVcgPSBpbnB1dERpbXNbcmFuayAtIDFdO1xuICAgICAgICAgICAgbGV0IGNvZGVXID0gJyc7XG4gICAgICAgICAgICBsZXQgY29kZUggPSAnJztcbiAgICAgICAgICAgIGxldCBjb2RlSEVuZCA9ICcnO1xuICAgICAgICAgICAgaWYgKHB3U3RhcnQgKyBwd0VuZCAhPT0gMCkge1xuICAgICAgICAgICAgICBjb2RlVyA9IGBcbiAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7a3d9OyBpKyspIHtcbiAgICAgICAgICAgIHhbJHtyYW5rfSAtIDFdID0gaW5kaWNlc1ske3Jhbmt9IC0gMV0gKiAke3N3fSAtICR7cHdTdGFydH0gKyBpO1xuICAgICAgICAgICAgaWYgKHhbJHtyYW5rfSAtIDFdIDwgMCB8fCB4WyR7cmFua30gLSAxXSA+PSAke2RpbVd9KSB7XG4gICAgICAgICAgICAgIHBhZCsrO1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgICR7b3AxfVxuICAgICAgICAgIH1gO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY29kZVcgPSBgXG4gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke2t3fTsgaSsrKSB7XG4gICAgICAgICAgICB4WyR7cmFua30gLSAxXSA9IGluZGljZXNbJHtyYW5rfSAtIDFdICogJHtzd30gLSAke3B3U3RhcnR9ICsgaTtcbiAgICAgICAgICAgICR7b3AxfVxuICAgICAgICAgIH1gO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgICAgY29uc3Qga2ggPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlW2F0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIC0gMl07XG4gICAgICAgICAgICAgIGNvbnN0IHNoID0gYXR0cmlidXRlcy5zdHJpZGVzW2F0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggLSAyXTtcbiAgICAgICAgICAgICAgY29uc3QgcGhTdGFydCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC8gMiAtIDJdO1xuICAgICAgICAgICAgICBjb25zdCBwaEVuZCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC0gMl07XG4gICAgICAgICAgICAgIGNvbnN0IGRpbUggPSBpbnB1dERpbXNbcmFuayAtIDJdO1xuICAgICAgICAgICAgICBpZiAocGhTdGFydCArIHBoRW5kICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgY29kZUggPSBgXG4gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8ICR7a2h9OyBqKyspIHtcbiAgICAgICAgICAgICAgeFske3Jhbmt9IC0gMl0gPSBpbmRpY2VzWyR7cmFua30gLSAyXSAqICR7c2h9IC0gJHtwaFN0YXJ0fSArIGo7XG4gICAgICAgICAgICAgIGlmICh4WyR7cmFua30gLSAyXSA8IDAgfHwgeFske3Jhbmt9IC0gMl0gPj0gJHtkaW1IfSkge1xuICAgICAgICAgICAgICAgIHBhZCs9ICR7a3d9O1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgYDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb2RlSCA9IGBcbiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgJHtraH07IGorKykge1xuICAgICAgICAgICAgICB4WyR7cmFua30gLSAyXSA9IGluZGljZXNbJHtyYW5rfSAtIDJdICogJHtzaH0gLSAke3BoU3RhcnR9ICsgajtcbiAgICAgICAgICAgIGA7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY29kZUhFbmQgPSBgXG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBwb29saW5nQ29kZSA9IGBcbiAgICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCB4WyR7cmFua31dO1xuICAgICAgICAgIGNvcHlWZWMoaW5kaWNlcywgeCk7XG5cbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9ICR7c3RhcnR9O1xuICAgICAgICAgIGludCBwYWQgPSAwO1xuICAgICAgICAgICR7Y29kZUh9XG4gICAgICAgICAgJHtjb2RlV31cbiAgICAgICAgICAke2NvZGVIRW5kfVxuICAgICAgICAgICR7b3AyfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICAgICAgICAgIHJldHVybiBwb29saW5nQ29kZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qga2VybmVsU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUpO1xuICAgICAgICAgICAgY29uc3Qga2VybmVsU3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlKTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmlkZXNSYW5rID0ga2VybmVsU3RyaWRlcy5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBwYWRzUmFuayA9IGF0dHJpYnV0ZXMucGFkcy5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBvZmZzZXRUb0luZGljZXNGdW5jdGlvbiA9IG9mZnNldFRvSW5kaWNlcyhzdHJpZGVzUmFuayk7XG4gICAgICAgICAgICBjb25zdCBjb3B5SW5wdXREaW1zID0gY29weUFycmF5KGlucHV0RGltcywgJ2lucHV0RGltcycpO1xuICAgICAgICAgICAgY29uc3QgY29weVBhZHMgPSBjb3B5QXJyYXkoYXR0cmlidXRlcy5wYWRzLCAncGFkcycpO1xuICAgICAgICAgICAgY29uc3QgY29weUtlcm5lbFN0cmlkZXMgPSBjb3B5QXJyYXkoa2VybmVsU3RyaWRlcywgJ2tlcm5lbFN0cmlkZXMnKTtcbiAgICAgICAgICAgIGNvbnN0IGNvcHlTdHJpZGVzID0gY29weUFycmF5KGF0dHJpYnV0ZXMuc3RyaWRlcywgJ3N0cmlkZXMnKTtcbiAgICAgICAgICAgIGNvbnN0IGhhc1BhZHMgPSBhdHRyaWJ1dGVzLnBhZHMucmVkdWNlKChzdW0sIGN1cikgPT4gc3VtICsgY3VyKTtcbiAgICAgICAgICAgIGxldCBwYWRDb2RlID0gJyc7XG4gICAgICAgICAgICBpZiAoaGFzUGFkcykge1xuICAgICAgICAgICAgICBwYWRDb2RlID0gYFxuICAgICAgICAgICAgaWYgKHhbal0gPj0gaW5wdXREaW1zW2pdIHx8IHhbal0gPCAwKSB7XG4gICAgICAgICAgICAgIHBhZCsrO1xuICAgICAgICAgICAgICBpc1BhZCA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWlzUGFkKSB7XG4gICAgICAgICAgICAke29wMX1cbiAgICAgICAgICB9YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBhZENvZGUgPSBgXG4gICAgICAgICAgfVxuICAgICAgICAgICR7b3AxfVxuICAgICAgICBgO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcG9vbGluZ0NvZGUgPSBgXG4gICAgICAgICR7b2Zmc2V0VG9JbmRpY2VzRnVuY3Rpb259XG4gICAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgeFske3Jhbmt9XTtcbiAgICAgICAgICBjb3B5VmVjKGluZGljZXMsIHgpO1xuICAgICAgICAgIGludCBvZmZzZXRbJHtzdHJpZGVzUmFua31dO1xuICAgICAgICAgIGludCBwYWRzWyR7cGFkc1Jhbmt9XTtcbiAgICAgICAgICBpbnQgaW5wdXREaW1zWyR7cmFua31dO1xuICAgICAgICAgIGludCBrZXJuZWxTdHJpZGVzWyR7c3RyaWRlc1Jhbmt9XTtcbiAgICAgICAgICBpbnQgc3RyaWRlc1ske3N0cmlkZXNSYW5rfV07XG4gICAgICAgICAgJHtjb3B5UGFkc31cbiAgICAgICAgICAke2NvcHlJbnB1dERpbXN9XG4gICAgICAgICAgJHtjb3B5U3RyaWRlc31cbiAgICAgICAgICAke2NvcHlLZXJuZWxTdHJpZGVzfVxuXG4gICAgICAgICAgZmxvYXQgdmFsdWUgPSAke3N0YXJ0fTtcbiAgICAgICAgICBpbnQgcGFkID0gMDtcbiAgICAgICAgICBib29sIGlzUGFkID0gZmFsc2U7XG4gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke2tlcm5lbFNpemV9OyBpKyspIHtcbiAgICAgICAgICAgIG9mZnNldFRvSW5kaWNlcyhpLCBrZXJuZWxTdHJpZGVzLCBvZmZzZXQpO1xuICAgICAgICAgICAgaXNQYWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAoaW50IGogPSAke3Jhbmt9IC0gJHtzdHJpZGVzUmFua307IGogPCAke3Jhbmt9OyBqKyspIHtcbiAgICAgICAgICAgICAgeFtqXSA9IGluZGljZXNbal0gKiBzdHJpZGVzW2ogLSAke3Jhbmt9ICsgJHtzdHJpZGVzUmFua31dXG4gICAgICAgICAgICAgICAgKyBvZmZzZXRbaiAtICR7cmFua30gKyAke3N0cmlkZXNSYW5rfV0gLSBwYWRzW2ogLSAyXTtcbiAgICAgICAgICAgICAgJHtwYWRDb2RlfVxuICAgICAgICAgIH1cbiAgICAgICAgICAke29wMn1cblxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICAgICAgICAgIHJldHVybiBwb29saW5nQ29kZTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbmNvbnN0IGNvcHlBcnJheSA9IChhcnJheTogcmVhZG9ubHkgbnVtYmVyW10sIGFycmF5TmFtZTogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgbGV0IGJsb2NrID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICBibG9jayArPSBgXG4gICAgICAke2FycmF5TmFtZX1bJHtpfV0gPSAke2FycmF5W2ldfTtcbiAgICBgO1xuICB9XG4gIHJldHVybiBibG9jaztcbn07XG5cbmNvbnN0IG9mZnNldFRvSW5kaWNlcyA9IChyYW5rOiBudW1iZXIpOiBzdHJpbmcgPT4gYFxuICB2b2lkIG9mZnNldFRvSW5kaWNlcyhpbnQgb2Zmc2V0LCBpbnRbJHtyYW5rfV0gc3RyaWRlcywgb3V0IGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG4gICAgaWYgKCR7cmFua30gPT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGludCBpID0gMDsgaSA8ICR7cmFua30gLSAxOyArK2kpIHtcbiAgICAgIGluZGljZXNbaV0gPSBvZmZzZXQgLyBzdHJpZGVzW2ldO1xuICAgICAgb2Zmc2V0IC09IGluZGljZXNbaV0gKiBzdHJpZGVzW2ldO1xuICAgIH1cbiAgICBpbmRpY2VzWyR7cmFua30gLSAxXSA9IG9mZnNldDtcbiAgfWA7XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge05VTUJFUl9UWVBFUywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtTaGFwZVV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBSZWR1Y2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhlczogbnVtYmVyW107XG4gIHJlYWRvbmx5IGtlZXBEaW1zOiBib29sZWFuO1xufVxuXG4vLyByZXR1cm4gW2luaXQgb3BzLCByZWR1Y2Ugb3BzLCBmaW5hbCBvcHNdXG50eXBlIFJlZHVjZU9wID0gKGlucHV0czogVGVuc29yW10sIGF4ZXM6IG51bWJlcltdKSA9PiBzdHJpbmdbXTtcblxuY29uc3QgcmVkdWNlID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLCBuYW1lOiBzdHJpbmcsXG4gICAgIHJlZHVjZU9wOiBSZWR1Y2VPcCk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgICAgIGNvbnN0IHJlZHVjZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgaW5wdXROYW1lczogWydBJ10sXG4gICAgICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5yZWR1Y2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICAgICAgICBnZXQ6ICgpID0+XG4gICAgICAgICAgICAgICAgY3JlYXRlUmVkdWNlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCBuYW1lLCByZWR1Y2VPcCwgcmVkdWNlUHJvZ3JhbU1ldGFkYXRhKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBSZWR1Y2VBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXhlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJywgW10pO1xuICBjb25zdCBrZWVwRGltcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2tlZXBkaW1zJywgMSkgPT09IDE7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe2F4ZXMsIGtlZXBEaW1zfSk7XG59O1xuXG5jb25zdCBjcmVhdGVSZWR1Y2VQcm9ncmFtSW5mbyA9XG4gICAgKF9oYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMsIF9uYW1lOiBzdHJpbmcsIHJlZHVjZU9wOiBSZWR1Y2VPcCxcbiAgICAgcmVkdWNlUHJvZ3JhbU1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgICAgIGNvbnN0IGlSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoIHx8IDE7XG5cbiAgICAgIGNvbnN0IGlkeENvcHkgPSBbXTsgIC8vIGNvcHkgb3V0cHV0IGluZGV4ZXMgdG8gaW5wdXQgaW5kZXhlc1xuXG4gICAgICBjb25zdCBheGVzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4ZXMoYXR0cmlidXRlcy5heGVzLCBpbnB1dHNbMF0uZGltcy5sZW5ndGgpO1xuICAgICAgY29uc3Qgb3BzID0gcmVkdWNlT3AoaW5wdXRzLCBheGVzKTtcbiAgICAgIGxldCByZWR1Y2VPcHMgPSBvcHNbMV07XG5cbiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgLy8gaWYgdGhpcyBheGlzIGlzIHJlZHVjZWRcbiAgICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgaWYgKGF0dHJpYnV0ZXMua2VlcERpbXMpIHtcbiAgICAgICAgICAgIG91dHB1dFNoYXBlLnB1c2goMSk7XG4gICAgICAgICAgfSAgLy8gZWxzZSB7IHJlbW92ZSB0aGUgYXhpcyBmcm9tIG91dHB1dFNoYXBlOyB9XG5cbiAgICAgICAgICAvLyBsb29wIG92ZXIgdGhlIGQtdGggYXhpc1xuICAgICAgICAgIHJlZHVjZU9wcyA9IGBcbiAgICAgICAgICBmb3IoaW50IGoke2t9ID0gMDsgaiR7a30gPCAke2lucHV0c1swXS5kaW1zW2tdfTsgaiR7a30rKykge1xuICAgICAgICAgICAgaW5wdXRJZHhbJHtrfV0gPSBqJHtrfTtcbiAgICAgICAgICAgICR7cmVkdWNlT3BzfVxuICAgICAgICAgIH1gO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlkeENvcHkucHVzaChgaW5wdXRJZHhbJHtrfV0gPSBvdXRwdXRJZHhbJHtvdXRwdXRTaGFwZS5sZW5ndGh9XTtgKTtcblxuICAgICAgICAgIG91dHB1dFNoYXBlLnB1c2goaW5wdXRzWzBdLmRpbXNba10pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9SYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoIHx8IDE7XG5cbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IG91dHB1dElkeFske29SYW5rfV0pIHtcbiAgICAgICAgZmxvYXQgdmFsdWU7ICAgICAgICAgICAgICAgICAvLyBmaW5hbCByZXN1bHRcbiAgICAgICAgaW50IGlucHV0SWR4WyR7aVJhbmt9XTsgICAgICAvLyBhZGRyZXNzaW5nIGlucHV0IGRhdGFcbiAgICAgICAgJHtpZHhDb3B5LmpvaW4oJ1xcbicpfVxuICAgICAgICAke29wc1swXX0gICAgICAgLy8gaW5pdCBvcHMgZm9yIHJlZHVjZSBtYXgvbWluXG4gICAgICAgICR7cmVkdWNlT3BzfVxuICAgICAgICAke29wc1syXX0gICAgICAgLy8gZmluYWwgY29tcHV0YXRpb24gZm9yIHJlZHVjZSBtZWFuXG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1gO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5yZWR1Y2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgLy8gVE9ETzogc3VwcG9ydCBSZWR1Y2UqIG9wZXJhdG9ycyB3aXRoIDIgaW5wdXRzLlxuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZWR1Y2Ugb3AgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChOVU1CRVJfVFlQRVMuaW5kZXhPZihpbnB1dHNbMF0udHlwZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VTdW06IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoKTogc3RyaW5nW10gPT4gWyd2YWx1ZSA9IDAuMDsnLCAndmFsdWUgKz0gX0EoaW5wdXRJZHgpOycsICcnXTtcbiAgICAgIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlU3VtJywgcmVkdWNlT3ApO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VNZWFuOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0czogVGVuc29yW10sIGF4ZXM6IG51bWJlcltdKTogc3RyaW5nW10gPT4ge1xuICAgICAgICBsZXQgc2l6ZSA9IDEuMDtcbiAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgc2l6ZSAqPSBpbnB1dHNbMF0uZGltc1trXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gWyd2YWx1ZSA9IDAuMDsnLCAndmFsdWUgKz0gX0EoaW5wdXRJZHgpOycsIGB2YWx1ZSAvPSAke3NpemV9LjtgXTsgIC8vIGVuc3VyZSByZWFsIG51bWJlciB3aXRoIGAuYFxuICAgICAgfTtcbiAgICAgIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTWVhbicsIHJlZHVjZU9wKTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTWF4OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKGlucHV0czogVGVuc29yW10sIGF4ZXM6IG51bWJlcltdKTogc3RyaW5nW10gPT4ge1xuICAgICAgICBjb25zdCBpZHhaZXJvID0gW107XG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgaW5wdXRzWzBdLmRpbXMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICBpZiAoYXhlcy5pbmRleE9mKGspID49IDAgfHwgYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGlkeFplcm8ucHVzaChgaW5wdXRJZHhbJHtrfV0gPSAwO2ApOyAgLy8gZmlyc3QgZWxlbWVudFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbYCR7aWR4WmVyby5qb2luKCdcXG4nKX1cXG52YWx1ZSA9IF9BKGlucHV0SWR4KTtgLCAndmFsdWUgPSBtYXgodmFsdWUsIF9BKGlucHV0SWR4KSk7JywgJyddO1xuICAgICAgfTtcbiAgICAgIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTWF4JywgcmVkdWNlT3ApO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VNaW46IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBzdHJpbmdbXSA9PiB7XG4gICAgICAgIGNvbnN0IGlkeFplcm8gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgaWR4WmVyby5wdXNoKGBpbnB1dElkeFske2t9XSA9IDA7YCk7ICAvLyBmaXJzdCBlbGVtZW50XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFtgJHtpZHhaZXJvLmpvaW4oJ1xcbicpfVxcbnZhbHVlID0gX0EoaW5wdXRJZHgpO2AsICd2YWx1ZSA9IG1pbih2YWx1ZSwgX0EoaW5wdXRJZHgpKTsnLCAnJ107XG4gICAgICB9O1xuICAgICAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VNaW4nLCByZWR1Y2VPcCk7XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZVByb2Q6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoKTogc3RyaW5nW10gPT4gWyd2YWx1ZSA9IDEuMDsnLCAndmFsdWUgKj0gX0EoaW5wdXRJZHgpOycsICcnXTtcbiAgICAgIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlUHJvZCcsIHJlZHVjZU9wKTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKCk6IHN0cmluZ1tdID0+IFsndmFsdWUgPSAwLjA7JywgJ3ZhbHVlICs9IF9BKGlucHV0SWR4KTsnLCAndmFsdWUgPSBsb2codmFsdWUpOyddO1xuICAgICAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VMb2dTdW0nLCByZWR1Y2VPcCk7XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZUxvZ1N1bVNxdWFyZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ2Zsb2F0IHQ7IHZhbHVlID0gMC4wOycsICd0ID0gX0EoaW5wdXRJZHgpOyB2YWx1ZSArPSB0ICogdDsnLCAnJ107XG4gICAgICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZUxvZ1N1bVNxdWFyZScsIHJlZHVjZU9wKTtcbiAgICB9O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCByZXNoYXBlID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgY29uc3QgcmVzaGFwZWREaW1zID0gU2hhcGVVdGlsLmNhbGN1bGF0ZVJlc2hhcGVkRGltcyhpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmludGVnZXJEYXRhKTtcbiAgaWYgKGhhbmRsZXIuc2Vzc2lvbi5wYWNrKSB7XG4gICAgcmV0dXJuIFtoYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzBdLCByZXNoYXBlZERpbXMpXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW2hhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgcmVzaGFwZWREaW1zKV07XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXBzYW1wbGVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgb3BzZXQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgaXNSZXNpemU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IG1vZGU6IHN0cmluZztcbiAgcmVhZG9ubHkgc2NhbGVzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgZXh0cmFwb2xhdGlvblZhbHVlOiBudW1iZXI7XG4gIHJlYWRvbmx5IGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHVzZUV4dHJhcG9sYXRpb246IGJvb2xlYW47XG4gIHJlYWRvbmx5IG5lZWRSb2lJbnB1dDogYm9vbGVhbjtcbiAgcmVhZG9ubHkgbmVhcmVzdE1vZGU6IHN0cmluZztcbiAgcmVhZG9ubHkgY3ViaWNDb2VmZmljaWVudEE6IG51bWJlcjtcbiAgcmVhZG9ubHkgZXhjbHVkZU91dHNpZGU6IGJvb2xlYW47XG4gIHJlYWRvbmx5IHVzZU5lYXJlc3QyeE9wdGltaXphdGlvbjogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcm9pSW5wdXRJZHg6IG51bWJlcjtcbiAgcmVhZG9ubHkgc2NhbGVzSW5wdXRJZHg6IG51bWJlcjtcbiAgcmVhZG9ubHkgc2l6ZXNJbnB1dElkeDogbnVtYmVyO1xufVxuXG5jb25zdCB1cHNhbXBsZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1Vwc2FtcGxlJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3QgdXBzYW1wbGU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnVwc2FtcGxlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVVcHNhbXBsZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcylcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlucHV0cyk7XG4gICAgICByZXR1cm4gW291dHB1dF07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjc6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9XG4gICAgKG5vZGU6IEdyYXBoLk5vZGUpOiBVcHNhbXBsZUF0dHJpYnV0ZXMgPT4gcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMobm9kZSwgNyk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y5OiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzKG5vZGUsIDkpO1xuXG5leHBvcnQgY29uc3QgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMgPSAobm9kZTogR3JhcGguTm9kZSwgb3BzZXQ6IG51bWJlcik6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGlzUmVzaXplID0gKG9wc2V0ID49IDEwKTtcblxuICAvLyBwcm9jZXNzaW5nIG5vZGUgYXR0cmlidXRlc1xuICBjb25zdCBtb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICduZWFyZXN0Jyk7XG4gIGlmIChtb2RlICE9PSAnbmVhcmVzdCcgJiYgbW9kZSAhPT0gJ2xpbmVhcicgJiYgKG9wc2V0IDwgMTEgfHwgbW9kZSAhPT0gJ2N1YmljJykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVjb2duaXplZCBtb2RlOiAke21vZGV9YCk7XG4gIH1cblxuICBsZXQgc2NhbGVzOiBudW1iZXJbXSA9IFtdO1xuICBpZiAob3BzZXQgPCA5KSB7XG4gICAgc2NhbGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0cygnc2NhbGVzJyk7XG4gICAgc2NhbGVzVmFsaWRhdGlvbihzY2FsZXMsIG1vZGUsIGlzUmVzaXplKTtcbiAgfVxuXG4gIGNvbnN0IGV4dHJhcG9sYXRpb25WYWx1ZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnZXh0cmFwb2xhdGlvbl92YWx1ZScsIDAuMCk7XG5cbiAgY29uc3QgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPVxuICAgICAgb3BzZXQgPiAxMCA/IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2Nvb3JkaW5hdGVfdHJhbnNmb3JtYXRpb25fbW9kZScsICdoYWxmX3BpeGVsJykgOiAnYXN5bW1ldHJpYyc7XG4gIGlmIChbXG4gICAgICAgICdhc3ltbWV0cmljJywgJ3B5dG9yY2hfaGFsZl9waXhlbCcsICd0Zl9oYWxmX3BpeGVsX2Zvcl9ubicsICdhbGlnbl9jb3JuZXJzJywgJ3RmX2Nyb3BfYW5kX3Jlc2l6ZScsICdoYWxmX3BpeGVsJ1xuICAgICAgXS5pbmRleE9mKGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGNvb3JkaW5hdGVfdHJhbnNmb3JtX21vZGUgJyR7Y29vcmRpbmF0ZVRyYW5zZm9ybU1vZGV9JyBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gIH1cbiAgY29uc3QgbmVlZFJvaUlucHV0ID0gKGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlID09PSAndGZfY3JvcF9hbmRfcmVzaXplJyk7XG4gIGNvbnN0IHVzZUV4dHJhcG9sYXRpb24gPSBuZWVkUm9pSW5wdXQ7XG5cbiAgY29uc3QgbmVhcmVzdE1vZGUgPVxuICAgICAgKG1vZGUgPT09ICduZWFyZXN0JyAmJiBvcHNldCA+PSAxMSkgPyBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCduZWFyZXN0X21vZGUnLCAncm91bmRfcHJlZmVyX2Zsb29yJykgOiAnJztcbiAgaWYgKFsncm91bmRfcHJlZmVyX2Zsb29yJywgJ3JvdW5kX3ByZWZlcl9jZWlsJywgJ2Zsb29yJywgJ2NlaWwnLCAnJ10uaW5kZXhPZihuZWFyZXN0TW9kZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBuZWFyZXN0X21vZGUgJyR7bmVhcmVzdE1vZGV9JyBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gIH1cblxuICBjb25zdCBjdWJpY0NvZWZmaWNpZW50QSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnY3ViaWNfY29lZmZfYScsIC0wLjc1KTtcbiAgY29uc3QgZXhjbHVkZU91dHNpZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdleGNsdWRlX291dHNpZGUnLCAwKSAhPT0gMDtcbiAgaWYgKGV4Y2x1ZGVPdXRzaWRlICYmIG1vZGUgIT09ICdjdWJpYycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4Y2x1ZGVfb3V0c2lkZSBjYW4gYmUgc2V0IHRvIDEgb25seSB3aGVuIG1vZGUgaXMgQ1VCSUMuJyk7XG4gIH1cblxuICBjb25zdCB1c2VOZWFyZXN0MnhPcHRpbWl6YXRpb24gPVxuICAgICAgKG9wc2V0IDwgMTEpID8gdHJ1ZSA6IChtb2RlID09PSAnbmVhcmVzdCcgJiYgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgPT09ICdhc3ltbWV0cmljJyAmJiBuZWFyZXN0TW9kZSA9PT0gJ2Zsb29yJyk7XG5cbiAgbGV0IHJvaUlucHV0SWR4ID0gMDtcbiAgbGV0IHNjYWxlc0lucHV0SWR4ID0gMDtcbiAgbGV0IHNpemVzSW5wdXRJZHggPSAwO1xuXG4gIGlmIChvcHNldCA+IDEwKSB7XG4gICAgLy8gaGFuZGxlIHdoZW4gcm9pSW5wdXQgaXMgbm90IGdpdmVuXG4gICAgaWYgKG5vZGUuaW5wdXRzLmxlbmd0aCA+IDIpIHtcbiAgICAgIHJvaUlucHV0SWR4ID0gMTtcbiAgICAgIHNjYWxlc0lucHV0SWR4ID0gMjtcbiAgICAgIHNpemVzSW5wdXRJZHggPSAzO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZXNJbnB1dElkeCA9IDE7XG4gICAgICBzaXplc0lucHV0SWR4ID0gMjtcbiAgICB9XG4gIH0gZWxzZSBpZiAob3BzZXQgPT09IDkpIHtcbiAgICBzY2FsZXNJbnB1dElkeCA9IDE7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtcbiAgICBvcHNldCxcbiAgICBpc1Jlc2l6ZSxcbiAgICBtb2RlLFxuICAgIHNjYWxlcyxcbiAgICBleHRyYXBvbGF0aW9uVmFsdWUsXG4gICAgY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUsXG4gICAgdXNlRXh0cmFwb2xhdGlvbixcbiAgICBuZWVkUm9pSW5wdXQsXG4gICAgbmVhcmVzdE1vZGUsXG4gICAgY3ViaWNDb2VmZmljaWVudEEsXG4gICAgZXhjbHVkZU91dHNpZGUsXG4gICAgdXNlTmVhcmVzdDJ4T3B0aW1pemF0aW9uLFxuICAgIHJvaUlucHV0SWR4LFxuICAgIHNjYWxlc0lucHV0SWR4LFxuICAgIHNpemVzSW5wdXRJZHhcbiAgfSk7XG59O1xuXG5jb25zdCBjcmVhdGVVcHNhbXBsZVByb2dyYW1JbmZvID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICBjb25zdCBbaW5wdXRXaWR0aCwgaW5wdXRIZWlnaHRdID1cbiAgICAgICAgICBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChpbnB1dHNbMF0uZGltcywgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuXG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLm1hcCgoZGltLCBpKSA9PiBNYXRoLmZsb29yKGRpbSAqIGF0dHJpYnV0ZXMuc2NhbGVzW2ldKSk7XG4gICAgICBjb25zdCBbb3V0cHV0V2lkdGgsIG91dHB1dEhlaWdodF0gPVxuICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KG91dHB1dFNoYXBlLCBUZXh0dXJlVHlwZS51bnBhY2tlZCk7XG4gICAgICBjb25zdCBkaW0gPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgICAgIGNvbnN0IG91dHB1dFBpdGNoZXMgPSBuZXcgQXJyYXk8bnVtYmVyPihkaW0pO1xuICAgICAgY29uc3QgaW5wdXRQaXRjaGVzID0gbmV3IEFycmF5PG51bWJlcj4oZGltKTtcbiAgICAgIGxldCBwcmVjYWxjdWxhdGVkUGl0Y2hlcyA9IGBcbiAgICAgIGludCBvdXRwdXRfcGl0Y2hlc1ske2RpbX1dO1xuICAgICAgaW50IGlucHV0X3BpdGNoZXNbJHtkaW19XTtcbiAgICAgIGA7XG4gICAgICBmb3IgKGxldCBkID0gZGltIC0gMTsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgb3V0cHV0UGl0Y2hlc1tkXSA9IChkID09PSBkaW0gLSAxKSA/IDEgOiBvdXRwdXRQaXRjaGVzW2QgKyAxXSAqIG91dHB1dFNoYXBlW2QgKyAxXTtcbiAgICAgICAgaW5wdXRQaXRjaGVzW2RdID0gKGQgPT09IGRpbSAtIDEpID8gMSA6IGlucHV0UGl0Y2hlc1tkICsgMV0gKiBpbnB1dHNbMF0uZGltc1tkICsgMV07XG5cbiAgICAgICAgcHJlY2FsY3VsYXRlZFBpdGNoZXMgKz0gYFxuICAgICAgICBvdXRwdXRfcGl0Y2hlc1ske2R9XSA9ICR7b3V0cHV0UGl0Y2hlc1tkXX07XG4gICAgICAgIGlucHV0X3BpdGNoZXNbJHtkfV0gPSAke2lucHV0UGl0Y2hlc1tkXX07XG4gICAgICAgIGA7XG4gICAgICB9XG4gICAgICBjb25zdCBnZXRJbnB1dEZsb2F0RnVuY3Rpb24gPSBgXG4gICAgICBmbG9hdCBnZXRJbnB1dEZsb2F0KGludCBpbmRleCkge1xuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKGluZGV4LCAke2lucHV0V2lkdGh9LCAke2lucHV0SGVpZ2h0fSk7XG4gICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KFgsIGNvb3JkcykpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBgO1xuXG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBhdHRyaWJ1dGVzLm1vZGUgPT09ICduZWFyZXN0JyA/XG4gICAgICAgICAgLy8gbmVhcmVzdFxuICAgICAgICAgIGBcbiAgICAke2dldElucHV0RmxvYXRGdW5jdGlvbn1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7ZGltfV0pIHtcbiAgICAgIGludCBpbnB1dF9pbmRleCA9IDA7XG4gICAgICBpbnQgb3V0cHV0X2luZGV4ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke291dHB1dFdpZHRofSwgJHtvdXRwdXRIZWlnaHR9KTtcblxuICAgICAgJHtwcmVjYWxjdWxhdGVkUGl0Y2hlc31cblxuICAgICAgaW50IGQsIG07XG4gICAgICBmb3IgKGludCBkaW0gPSAwOyBkaW0gPCAke2RpbX07ICsrZGltKSB7XG4gICAgICAgIGQgPSBvdXRwdXRfaW5kZXggLyBvdXRwdXRfcGl0Y2hlc1tkaW1dO1xuICAgICAgICBtID0gb3V0cHV0X2luZGV4IC0gZCAqIG91dHB1dF9waXRjaGVzW2RpbV07XG4gICAgICAgIG91dHB1dF9pbmRleCA9IG07XG5cbiAgICAgICAgaWYgKHNjYWxlc1tkaW1dICE9IDEgJiYgZCA+IDApIHtcbiAgICAgICAgICBpbnQgZDIgPSBkIC8gc2NhbGVzW2RpbV07XG4gICAgICAgICAgbSA9IGQgLSBkMiAqIHNjYWxlc1tkaW1dO1xuICAgICAgICAgIGQgPSBkMjtcbiAgICAgICAgfVxuICAgICAgICBpbnB1dF9pbmRleCArPSBpbnB1dF9waXRjaGVzW2RpbV0gKiBkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCk7XG4gICAgfWAgOlxuICAgICAgICAgIGRpbSA9PT0gNCA/XG4gICAgICAgICAgLy8gYmlsaW5lYXIgNERcbiAgICAgICAgICAgICAgYFxuICAgICR7Z2V0SW5wdXRGbG9hdEZ1bmN0aW9ufVxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbNF0pIHtcbiAgICAgIGludCBpbnB1dF9pbmRleCA9IDA7XG4gICAgICBpbnQgb3V0cHV0X2luZGV4ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke291dHB1dFdpZHRofSwgJHtvdXRwdXRIZWlnaHR9KTtcblxuICAgICAgJHtwcmVjYWxjdWxhdGVkUGl0Y2hlc31cblxuICAgICAgaW50IG07XG4gICAgICBpbnQgaW5kZXhfb2ZfZGltMCwgaW5kZXhfb2ZfZGltMSwgaW5kZXhfb2ZfZGltMiwgaW5kZXhfb2ZfZGltMztcbiAgICAgIGluZGV4X29mX2RpbTAgPSBvdXRwdXRfaW5kZXggLyBvdXRwdXRfcGl0Y2hlc1swXTtcbiAgICAgIG0gPSBvdXRwdXRfaW5kZXggLSBpbmRleF9vZl9kaW0wICogb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBpbmRleF9vZl9kaW0xID0gbSAvIG91dHB1dF9waXRjaGVzWzFdO1xuICAgICAgbSA9IG0gLSBpbmRleF9vZl9kaW0xICogb3V0cHV0X3BpdGNoZXNbMV07XG4gICAgICBpbmRleF9vZl9kaW0yID0gbSAvIG91dHB1dF9waXRjaGVzWzJdO1xuICAgICAgbSA9IG0gLSBpbmRleF9vZl9kaW0yICogb3V0cHV0X3BpdGNoZXNbMl07XG4gICAgICBpbmRleF9vZl9kaW0zID0gbTtcblxuICAgICAgaW50IGluZGV4X29mX2lucHV0X2RpbTIsIGluZGV4X29mX2lucHV0X2RpbTMsIHhfb2Zmc2V0LCB5X29mZnNldDtcbiAgICAgIGluZGV4X29mX2lucHV0X2RpbTIgPSBpbmRleF9vZl9kaW0yIC8gc2NhbGVzWzJdO1xuICAgICAgeV9vZmZzZXQgPSBpbmRleF9vZl9kaW0yIC0gaW5kZXhfb2ZfaW5wdXRfZGltMiAqIHNjYWxlc1syXTtcbiAgICAgIGluZGV4X29mX2lucHV0X2RpbTMgPSBpbmRleF9vZl9kaW0zIC8gc2NhbGVzWzNdO1xuICAgICAgeF9vZmZzZXQgPSBpbmRleF9vZl9kaW0zIC0gaW5kZXhfb2ZfaW5wdXRfZGltMyAqIHNjYWxlc1szXTtcblxuICAgICAgaW5wdXRfaW5kZXggPSBpbmRleF9vZl9kaW0wICogaW5wdXRfcGl0Y2hlc1swXSArXG4gICAgICAgICAgICBpbmRleF9vZl9kaW0xICogaW5wdXRfcGl0Y2hlc1sxXSArXG4gICAgICAgICAgICBpbmRleF9vZl9pbnB1dF9kaW0yICogaW5wdXRfcGl0Y2hlc1syXSArXG4gICAgICAgICAgICBpbmRleF9vZl9pbnB1dF9kaW0zO1xuXG4gICAgICBmbG9hdCB4MDAgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4KTtcbiAgICAgIGZsb2F0IHgxMCwgeDAxLCB4MTE7XG5cbiAgICAgIGJvb2wgZW5kX29mX2RpbTIgPSBmYWxzZTtcbiAgICAgIGlmIChpbmRleF9vZl9pbnB1dF9kaW0yID09ICgke2lucHV0c1swXS5kaW1zWzJdfSAtIDEpKSB7XG4gICAgICAgIC8vIEl0J3MgdGhlIGVuZCBpbiBkaW1lbnNpb24gMlxuICAgICAgICB4MDEgPSB4MDA7XG4gICAgICAgIGVuZF9vZl9kaW0yID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHgwMSA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyBpbnB1dF9waXRjaGVzWzJdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluZGV4X29mX2lucHV0X2RpbTMgPT0gKGlucHV0X3BpdGNoZXNbMl0gLSAxKSkge1xuICAgICAgICAvLyBJdCdzIHRoZSBlbmQgaW4gZGltZW5zaW9uIDNcbiAgICAgICAgeDEwID0geDAwO1xuICAgICAgICB4MTEgPSB4MDE7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgeDEwID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIDEpO1xuICAgICAgICB4MTEgPSBlbmRfb2ZfZGltMiA/IHgxMCA6IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyBpbnB1dF9waXRjaGVzWzJdICsgMSk7XG4gICAgICB9XG5cbiAgICAgIGZsb2F0IHkwID0geDAwICsgZmxvYXQoeV9vZmZzZXQpICogKHgwMSAtIHgwMCkgLyBmbG9hdChzY2FsZXNbMl0pO1xuICAgICAgZmxvYXQgeTEgPSB4MTAgKyBmbG9hdCh5X29mZnNldCkgKiAoeDExIC0geDEwKSAvIGZsb2F0KHNjYWxlc1syXSk7XG4gICAgICByZXR1cm4geTAgKyBmbG9hdCh4X29mZnNldCkgKiAoeTEgLSB5MCkgLyBmbG9hdChzY2FsZXNbM10pO1xuICAgIH1gIDpcbiAgICAgICAgICAgICAgLy8gYmlsaW5lYXIgMkRcbiAgICAgICAgICAgICAgYFxuICAgICR7Z2V0SW5wdXRGbG9hdEZ1bmN0aW9ufVxuICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbMl0pIHtcbiAgICAgIGludCBpbnB1dF9pbmRleCA9IDA7XG4gICAgICBpbnQgb3V0cHV0X2luZGV4ID0gY29vcmRzVG9PZmZzZXQoVGV4Q29vcmRzLCAke291dHB1dFdpZHRofSwgJHtvdXRwdXRIZWlnaHR9KTtcblxuICAgICAgJHtwcmVjYWxjdWxhdGVkUGl0Y2hlc31cblxuICAgICAgaW50IG07XG4gICAgICBpbnQgaW5kZXhfb2ZfZGltMCwgaW5kZXhfb2ZfZGltMTtcbiAgICAgIGluZGV4X29mX2RpbTAgPSBvdXRwdXRfaW5kZXggLyBvdXRwdXRfcGl0Y2hlc1swXTtcbiAgICAgIG0gPSBvdXRwdXRfaW5kZXggLSBpbmRleF9vZl9kaW0wICogb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBpbmRleF9vZl9kaW0xID0gbTtcblxuICAgICAgaW50IGluZGV4X29mX2lucHV0X2RpbTAsIGluZGV4X29mX2lucHV0X2RpbTEsIHhfb2Zmc2V0LCB5X29mZnNldDtcbiAgICAgIGluZGV4X29mX2lucHV0X2RpbTAgPSBpbmRleF9vZl9kaW0wIC8gc2NhbGVzWzBdO1xuICAgICAgeV9vZmZzZXQgPSBpbmRleF9vZl9kaW0wIC0gaW5kZXhfb2ZfaW5wdXRfZGltMCAqIHNjYWxlc1swXTtcbiAgICAgIGluZGV4X29mX2lucHV0X2RpbTEgPSBpbmRleF9vZl9kaW0xIC8gc2NhbGVzWzFdO1xuICAgICAgeF9vZmZzZXQgPSBpbmRleF9vZl9kaW0xIC0gaW5kZXhfb2ZfaW5wdXRfZGltMSAqIHNjYWxlc1sxXTtcblxuICAgICAgaW5wdXRfaW5kZXggPSBpbmRleF9vZl9pbnB1dF9kaW0wICogaW5wdXRfcGl0Y2hlc1swXSArIGluZGV4X29mX2lucHV0X2RpbTE7XG5cbiAgICAgIGZsb2F0IHgwMCA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXgpO1xuICAgICAgZmxvYXQgeDEwLCB4MDEsIHgxMTtcblxuICAgICAgYm9vbCBlbmRfb2ZfZGltMCA9IGZhbHNlO1xuICAgICAgaWYgKGluZGV4X29mX2lucHV0X2RpbTAgPT0gKCR7aW5wdXRzWzBdLmRpbXNbMF19IC0gMSkpIHtcbiAgICAgICAgLy8gSXQncyB0aGUgZW5kIGluIGRpbWVuc2lvbiAwXG4gICAgICAgIHgwMSA9IHgwMDtcbiAgICAgICAgZW5kX29mX2RpbTAgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeDAxID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIGlucHV0X3BpdGNoZXNbMF0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5kZXhfb2ZfaW5wdXRfZGltMSA9PSAoaW5wdXRfcGl0Y2hlc1swXSAtIDEpKSB7XG4gICAgICAgIC8vIEl0J3MgdGhlIGVuZCBpbiBkaW1lbnNpb24gMVxuICAgICAgICB4MTAgPSB4MDA7XG4gICAgICAgIHgxMSA9IHgwMTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB4MTAgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgMSk7XG4gICAgICAgIHgxMSA9IGVuZF9vZl9kaW0wID8geDEwIDogZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIGlucHV0X3BpdGNoZXNbMF0gKyAxKTtcbiAgICAgIH1cblxuICAgICAgZmxvYXQgeTAgPSB4MDAgKyBmbG9hdCh5X29mZnNldCkgKiAoeDAxIC0geDAwKSAvIGZsb2F0KHNjYWxlc1swXSk7XG4gICAgICBmbG9hdCB5MSA9IHgxMCArIGZsb2F0KHlfb2Zmc2V0KSAqICh4MTEgLSB4MTApIC8gZmxvYXQoc2NhbGVzWzBdKTtcbiAgICAgIHJldHVybiB5MCArIGZsb2F0KHhfb2Zmc2V0KSAqICh5MSAtIHkwKSAvIGZsb2F0KHNjYWxlc1sxXSk7XG4gICAgfWA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi51cHNhbXBsZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2UsXG4gICAgICAgIHZhcmlhYmxlczogW3tcbiAgICAgICAgICBuYW1lOiAnc2NhbGVzJyxcbiAgICAgICAgICB0eXBlOiAnaW50JyxcbiAgICAgICAgICBhcnJheUxlbmd0aDogYXR0cmlidXRlcy5zY2FsZXMubGVuZ3RoLFxuICAgICAgICAgIGRhdGE6IGF0dHJpYnV0ZXMuc2NhbGVzLm1hcCh4ID0+IE1hdGguY2VpbCh4KSlcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZTogVXBzYW1wbGVBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IChhdHRyaWJ1dGUub3BzZXQgPCA5ICYmIGlucHV0cy5sZW5ndGggIT09IDEpIHx8XG4gICAgICAoYXR0cmlidXRlLm9wc2V0ID49IDkgJiYgYXR0cmlidXRlLm9wc2V0IDwgMTEgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMikgfHxcbiAgICAgIChhdHRyaWJ1dGUub3BzZXQgPj0gMTEgJiYgaW5wdXRzLmxlbmd0aCA8IDIpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChhdHRyaWJ1dGUuc2NhbGVzLmxlbmd0aCA+IDAgJiYgaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSBhdHRyaWJ1dGUuc2NhbGVzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdGVuc29yIHR5cGVzLicpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2NhbGVzVmFsaWRhdGlvbiA9IChzY2FsZXM6IG51bWJlcltdLCBtb2RlOiBzdHJpbmcsIGlzUmVzaXplOiBib29sZWFuKTogdm9pZCA9PiB7XG4gIGlmICghaXNSZXNpemUpIHtcbiAgICBmb3IgKGNvbnN0IHNjYWxlIG9mIHNjYWxlcykge1xuICAgICAgaWYgKHNjYWxlIDwgMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjYWxlIHZhbHVlIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMS4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yIChjb25zdCBzY2FsZSBvZiBzY2FsZXMpIHtcbiAgICAgIGlmIChzY2FsZSA8PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU2NhbGUgdmFsdWUgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwLicpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAobW9kZSA9PT0gJ2xpbmVhcicgfHwgbW9kZSA9PT0gJ2N1YmljJykge1xuICAgIGlmIChzY2FsZXMubGVuZ3RoICE9PSAyICYmIChzY2FsZXMubGVuZ3RoICE9PSA0IHx8IHNjYWxlc1swXSAhPT0gMSB8fCBzY2FsZXNbMV0gIT09IDEpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCdMaW5lYXInIG1vZGUgYW5kICdDdWJpYycgbW9kZSBvbmx5IHN1cHBvcnQgMi1EIGlucHV0cyAoJ0JpbGluZWFyJywgJ0JpY3ViaWMnKSBcXFxuICAgICAgICBvciA0LUQgaW5wdXRzIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgb3V0ZXJtb3N0IDIgc2NhbGUgdmFsdWVzIGJlaW5nIDEgXFxcbiAgICAgICAgaW4gdGhlICR7aXNSZXNpemUgPyAnUmVzaXplJyA6ICdVcHNhbXBsZSd9IG9wZWFydG9yLmApO1xuICAgIH1cbiAgfVxufTsiLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7Z2V0Q29vcmRzRGF0YVR5cGV9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHt1bnBhY2tGcm9tQ2hhbm5lbH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcbmltcG9ydCB7cGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMsIHNjYWxlc1ZhbGlkYXRpb24sIFVwc2FtcGxlQXR0cmlidXRlcywgdmFsaWRhdGVJbnB1dHN9IGZyb20gJy4vdXBzYW1wbGUnO1xuXG5jb25zdCByZXNpemVQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdSZXNpemUnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnBhY2tlZF1cbn07XG5cbmV4cG9ydCBjb25zdCByZXNpemU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnJlc2l6ZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gY3JlYXRlUGFja2VkUmVzaXplUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjEwOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzKG5vZGUsIDEwKTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMTogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID1cbiAgICAobm9kZTogR3JhcGguTm9kZSk6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCAxMSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZFJlc2l6ZVByb2dyYW1JbmZvID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICBjb25zdCBbc2NhbGVzLCBvdXRwdXRTaGFwZV0gPSBwcmVwYXJlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7XG5cbiAgICAgIGNvbnN0IGlzU2FtZSA9XG4gICAgICAgICAgc2NhbGVzLmV2ZXJ5KChzOiBudW1iZXIpID0+IHMgPT09IDEpICYmIGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgIT09ICd0Zl9jcm9wX2FuZF9yZXNpemUnO1xuICAgICAgaWYgKGlzU2FtZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnJlc2l6ZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWR9LFxuICAgICAgICAgIGhhc01haW46IHRydWUsXG4gICAgICAgICAgc2hhZGVyU291cmNlOiBgdm9pZCBtYWluKCkge1xuICAgICAgICAgICAgICAgICAgICB2ZWM0IHYgPSAke2dsc2wudGV4dHVyZTJEfShYLCBUZXhDb29yZHMpO1xuICAgICAgICAgICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHY7XG4gICAgICAgICAgICAgICAgfWBcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGltID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgICAgaWYgKGRpbSA8IDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXQgZGltZW5zaW9uIHNob3VsZCBiZSBhdCBsZWFzdCAyLCBidXQgZ290ICR7ZGltfWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvdXRwdXRIZWlnaHQgPSBvdXRwdXRTaGFwZVtkaW0gLSAyXTtcbiAgICAgIGNvbnN0IG91dHB1dFdpZHRoID0gb3V0cHV0U2hhcGVbZGltIC0gMV07XG5cbiAgICAgIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgICAgIGlmIChkaW0gIT09IGlucHV0U2hhcGUubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgb3V0cHV0IGRpbWVuc2lvbiBzaG91bGQgbWF0Y2ggaW5wdXQgJHtpbnB1dFNoYXBlLmxlbmd0aH0sIGJ1dCBnb3QgJHtkaW19YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBpbnB1dEhlaWdodCA9IGlucHV0U2hhcGVbZGltIC0gMl07XG4gICAgICBjb25zdCBpbnB1dFdpZHRoID0gaW5wdXRTaGFwZVtkaW0gLSAxXTtcblxuICAgICAgY29uc3Qgc2NhbGVzSGVpZ2h0ID0gc2NhbGVzW2RpbSAtIDJdO1xuICAgICAgY29uc3Qgc2NhbGVzV2lkdGggPSBzY2FsZXNbZGltIC0gMV07XG5cbiAgICAgIGxldCBnZXRTb3VyY2VGcmFjSW5kZXggPSAnJztcblxuICAgICAgaWYgKGF0dHJpYnV0ZXMubW9kZSAhPT0gJ2xpbmVhcicpIHtcbiAgICAgICAgLy8gVE9ETzogc3VwcG9ydCBvdGhlciBtb2Rlc1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHJlc2l6ZSAocGFja2VkKSBkb2VzIG5vdCBzdXBwb3J0IG1vZGU6ICcke2F0dHJpYnV0ZXMubW9kZX0nYCk7XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUpIHtcbiAgICAgICAgY2FzZSAnYXN5bW1ldHJpYyc6XG4gICAgICAgICAgZ2V0U291cmNlRnJhY0luZGV4ID0gYFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IGdldFNvdXJjZUZyYWNJbmRleChpdmVjNCBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0KGNvb3JkcykgLyBzY2FsZVdIV0g7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdoYWxmX3BpeGVsJzpcbiAgICAgICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh2ZWM0KGNvb3JkcykgKyAwLjUpIC8gc2NhbGVXSFdIIC0gMC41O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAncHl0b3JjaF9oYWxmX3BpeGVsJzpcbiAgICAgICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCBmY29vcmRzID0gdmVjNChjb29yZHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZlYzQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRXaWR0aH0uMCA+IDEuMCA/IChmY29vcmRzLnggKyAwLjUpIC8gc2NhbGVXSFdILnggLSAwLjUgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRIZWlnaHR9LjAgPiAxLjAgPyAoZmNvb3Jkcy55ICsgMC41KSAvIHNjYWxlV0hXSC55IC0gMC41IDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0V2lkdGh9LjAgPiAxLjAgPyAoZmNvb3Jkcy56ICsgMC41KSAvIHNjYWxlV0hXSC56IC0gMC41IDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0SGVpZ2h0fS4wID4gMS4wID8gKGZjb29yZHMudyArIDAuNSkgLyBzY2FsZVdIV0gudyAtIDAuNSA6IDAuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnYWxpZ25fY29ybmVycyc6XG4gICAgICAgICAgZ2V0U291cmNlRnJhY0luZGV4ID0gYFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IGdldFNvdXJjZUZyYWNJbmRleChpdmVjNCBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQgcmVzaXplZCA9IHZlYzQoJHtvdXRwdXRXaWR0aH0uMCAtIDEuMCwgJHtvdXRwdXRIZWlnaHR9LjAgLSAxLjAsICR7b3V0cHV0V2lkdGh9LjAgLSAxLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRIZWlnaHR9LjAgLSAxLjApO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCBvcmlnaW5hbCA9IHZlYzQoJHtpbnB1dFdpZHRofS4wIC0gMS4wLCAke2lucHV0SGVpZ2h0fS4wIC0gMS4wLCAke2lucHV0V2lkdGh9LjAgLSAxLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpbnB1dEhlaWdodH0uMCAtIDEuMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWM0IG5ld19zY2FsZSA9IG9yaWdpbmFsIC8gcmVzaXplZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0KGNvb3JkcykgKiBuZXdfc2NhbGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIFRPRE86c3VwcG9ydGluZyBvdGhlciBjb29yZGluYXRlVHJhbnNmb3JtTW9kZXNcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHJlc2l6ZSAocGFja2VkKSBkb2VzIG5vdCBzdXBwb3J0IGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlOiBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnJHthdHRyaWJ1dGVzLmNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlfSdgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShkaW0pO1xuICAgICAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICAgICBjb25zdCB2ZWMyIGlucHV0V0ggPSB2ZWMyKCR7aW5wdXRIZWlnaHR9LjAsICR7aW5wdXRXaWR0aH0uMCk7XG4gICAgICAgICAgICBjb25zdCB2ZWM0IHNjYWxlV0hXSCA9IHZlYzQoZmxvYXQoJHtzY2FsZXNIZWlnaHR9KSwgZmxvYXQoJHtzY2FsZXNXaWR0aH0pLCBmbG9hdCgke3NjYWxlc0hlaWdodH0pLCBmbG9hdCgke1xuICAgICAgICAgIHNjYWxlc1dpZHRofSkpO1xuICAgICAgICAgICAgJHt1bnBhY2tDaGFubmVsfVxuICAgICAgICAgICAgJHtnZXRTb3VyY2VGcmFjSW5kZXh9XG4gICAgICAgICAgICBmbG9hdCBnZXRBVmFsdWUoaW50IHgxMCwgaW50IHIsIGludCBjLCBpbnQgZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsKGdldEEoeDEwLCByLCBjLCBkKSwgdmVjMihjLCBkKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAgICAgJHtjb29yZHNEYXRhVHlwZX0gcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcblxuICAgICAgICAgICAgICAgIGludCBiYXRjaCA9IHJjWzBdO1xuICAgICAgICAgICAgICAgIGludCBkZXB0aCA9IHJjWzFdO1xuXG4gICAgICAgICAgICAgICAgLy8gcmV0cmlldmUgdGhlIDQgY29vcmRpbmF0ZXMgdGhhdCBpcyB1c2VkIGluIHRoZSA0IHBhY2tlZCBvdXRwdXQgdmFsdWVzLlxuICAgICAgICAgICAgICAgIGl2ZWM0IGNvb3JkcyA9IGl2ZWM0KHJjLnd6LCByYy53ICsgMSwgcmMueiArIDEpO1xuXG4gICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBzb3VyY2UgaW5kZXggaW4gZnJhY3Rpb25cbiAgICAgICAgICAgICAgICB2ZWM0IHNvdXJjZUZyYWMgPSBnZXRTb3VyY2VGcmFjSW5kZXgoY29vcmRzKTtcblxuICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgbG93ZXIgYW5kIHVwcGVyIGJvdW5kIG9mIHRoZSA0IHZhbHVlcyB0aGF0IHdpbGwgYmUgcGFja2VkIGludG8gb25lIHRleGVsLlxuICAgICAgICAgICAgICAgIGl2ZWM0IHgwMCA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnh5LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnh5KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgwMSA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnh3LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnh3KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgxMCA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnp5LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnp5KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgxMSA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnp3LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnp3KSkpO1xuXG4gICAgICAgICAgICAgICAgYm9vbCBoYXNOZXh0Um93ID0gcmMudyA8ICR7b3V0cHV0SGVpZ2h0IC0gMX07XG4gICAgICAgICAgICAgICAgYm9vbCBoYXNOZXh0Q29sID0gcmMueiA8ICR7b3V0cHV0V2lkdGggLSAxfTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgdG9wLWxlZnQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCB0b3BMZWZ0ID0gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAwLngsIHgwMC55KSxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMS54LCB4MDEueSkgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTAueCwgeDEwLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMS54LCB4MTEueSkgOiAwLjApO1xuXG4gICAgICAgICAgICAgICAgLy8gcGFjayB4MDAsIHgwMSwgeDEwLCB4MTEncyB0b3AtcmlnaHQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCB0b3BSaWdodCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC54LCB4MDAudyksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueCwgeDAxLncpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLngsIHgxMC53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueCwgeDExLncpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgYm90dG9tLWxlZnQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b21MZWZ0ID0gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAwLnosIHgwMC55KSxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMS56LCB4MDEueSkgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTAueiwgeDEwLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMS56LCB4MTEueSkgOiAwLjApO1xuXG4gICAgICAgICAgICAgICAgLy8gcGFjayB4MDAsIHgwMSwgeDEwLCB4MTEncyBib3R0b20tcmlnaHQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b21SaWdodCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC56LCB4MDAudyksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueiwgeDAxLncpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLnosIHgxMC53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueiwgeDExLncpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgaW50ZXJwb2xhdGlvbiBmcmFjdGlvbiBvbiB1IGFuZCB2IGRpcmVjdGlvblxuICAgICAgICAgICAgICAgIHZlYzQgZnJhYyA9IHZlYzQoc291cmNlRnJhYykgLSBmbG9vcihzb3VyY2VGcmFjKTtcbiAgICAgICAgICAgICAgICB2ZWM0IGNsYW1wRnJhYyA9IGNsYW1wKGZyYWMsIHZlYzQoMC4wKSwgdmVjNCgxLjApKTtcblxuICAgICAgICAgICAgICAgIHZlYzQgdG9wID0gbWl4KHRvcExlZnQsIHRvcFJpZ2h0LCBjbGFtcEZyYWMueXd5dyk7XG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b20gPSBtaXgoYm90dG9tTGVmdCwgYm90dG9tUmlnaHQsIGNsYW1wRnJhYy55d3l3KTtcbiAgICAgICAgICAgICAgICB2ZWM0IG5ld1ZhbHVlID0gbWl4KHRvcCwgYm90dG9tLCBjbGFtcEZyYWMueHh6eik7XG5cbiAgICAgICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQobmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucmVzaXplUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWR9LFxuICAgICAgICBoYXNNYWluOiB0cnVlLFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuXG5jb25zdCBwcmVwYXJlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyk6IFtyZWFkb25seSBudW1iZXJbXSwgcmVhZG9ubHkgbnVtYmVyW11dID0+IHtcbiAgY29uc3QgeCA9IGlucHV0c1swXTtcbiAgY29uc3QgeERpbXMgPSB4LmRpbXM7XG5cbiAgbGV0IHNjYWxlcyA9IGF0dHJpYnV0ZXMuc2NhbGVzO1xuICBsZXQgb3V0cHV0U2l6ZXM6IG51bWJlcltdfHVuZGVmaW5lZDtcbiAgaWYgKHNjYWxlcy5sZW5ndGggPT09IDApIHtcbiAgICBjb25zdCBzY2FsZXNUZW5zb3IgPSBpbnB1dHNbYXR0cmlidXRlcy5zY2FsZXNJbnB1dElkeF07XG4gICAgaWYgKHNjYWxlc1RlbnNvciAmJiBzY2FsZXNUZW5zb3Iuc2l6ZSAhPT0gMCkge1xuICAgICAgaWYgKGlucHV0c1thdHRyaWJ1dGVzLnNpemVzSW5wdXRJZHhdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2Ygc2NhbGVzIG9yIHNpemVzIG11c3QgYmUgcHJvdmlkZWQgYXMgaW5wdXQuJyk7XG4gICAgICB9XG4gICAgICBzY2FsZXMgPSBwYXJzZVNjYWxlc0RhdGEoc2NhbGVzVGVuc29yLCBhdHRyaWJ1dGVzLm1vZGUsIGF0dHJpYnV0ZXMuaXNSZXNpemUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzaXplc1RlbnNvciA9IGlucHV0c1thdHRyaWJ1dGVzLnNpemVzSW5wdXRJZHhdO1xuICAgICAgaWYgKCFzaXplc1RlbnNvciB8fCBzaXplc1RlbnNvci5zaXplID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRWl0aGVyIHNjYWxlcyBvciBzaXplcyBNVVNUIGJlIHByb3ZpZGVkIGFzIGlucHV0LicpO1xuICAgICAgfVxuXG4gICAgICBvdXRwdXRTaXplcyA9IEFycmF5LmZyb20oc2l6ZXNUZW5zb3IuaW50ZWdlckRhdGEpO1xuICAgICAgc2NhbGVzID0gcGFyc2VTY2FsZXNEYXRhRnJvbU91dHB1dFNpemUob3V0cHV0U2l6ZXMsIHhEaW1zLCBhdHRyaWJ1dGVzLm1vZGUsIGF0dHJpYnV0ZXMuaXNSZXNpemUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoaW5wdXRzW2F0dHJpYnV0ZXMuc2l6ZXNJbnB1dElkeF0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2Ygc2NhbGVzIG9yIHNpemVzIG11c3QgYmUgcHJvdmlkZWQgYXMgaW5wdXQuJyk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgeURpbXMgPSBvdXRwdXRTaXplcyB8fCAoeERpbXMubWFwKChkaW0sIGkpID0+IE1hdGguZmxvb3IoZGltICogc2NhbGVzW2ldKSkpO1xuXG4gIHJldHVybiBbc2NhbGVzLCB5RGltc107XG59O1xuXG5jb25zdCBwYXJzZVNjYWxlc0RhdGEgPSAoc2NhbGU6IFRlbnNvciwgbW9kZTogc3RyaW5nLCBpc1Jlc2l6ZTogYm9vbGVhbik6IG51bWJlcltdID0+IHtcbiAgY29uc3Qgc2NhbGVzID0gQXJyYXkuZnJvbShzY2FsZS5mbG9hdERhdGEpO1xuICBzY2FsZXNWYWxpZGF0aW9uKHNjYWxlcywgbW9kZSwgaXNSZXNpemUpO1xuICByZXR1cm4gc2NhbGVzO1xufTtcblxuY29uc3QgcGFyc2VTY2FsZXNEYXRhRnJvbU91dHB1dFNpemUgPVxuICAgICh5RGltczogcmVhZG9ubHkgbnVtYmVyW10sIHhEaW1zOiByZWFkb25seSBudW1iZXJbXSwgbW9kZTogc3RyaW5nLCBpc1Jlc2l6ZTogYm9vbGVhbik6IG51bWJlcltdID0+IHtcbiAgICAgIGNvbnN0IGxlbmd0aCA9IHhEaW1zLmxlbmd0aDtcbiAgICAgIGNvbnN0IHNjYWxlcyA9IG5ldyBBcnJheTxudW1iZXI+KGxlbmd0aCk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBlbmQgPSBsZW5ndGg7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgICBpZiAoeERpbXNbaV0gPT09IDApIHtcbiAgICAgICAgICBpZiAoeURpbXNbaV0gIT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgZGltIGlzIHplcm8gYnV0IHJlcXVpcmVkIG91dHB1dCBkaW0gaXMgbm9uLXplcm8uJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNjYWxlc1tpXSA9IDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2NhbGVzW2ldID0geURpbXNbaV0gLyB4RGltc1tpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc2NhbGVzVmFsaWRhdGlvbihzY2FsZXMsIG1vZGUsIGlzUmVzaXplKTtcbiAgICAgIHJldHVybiBzY2FsZXM7XG4gICAgfTtcblxuLy8gcm9pIGRhdGEgaXMgbm90IHVzZWQgeWV0LiBidXQgbGVhdmUgaGVyZSBmb3IgZnV0dXJlIHVzYWdlLlxuLy8gY29uc3QgZ2V0Um9pID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcykgOiBudW1iZXJbXSA9PiB7XG4vLyAgICAgbGV0IHJvaTogbnVtYmVyW10gPSBbXTtcbi8vICAgICBpZiAoYXR0cmlidXRlcy5uZWVkUm9pSW5wdXQpIHtcbi8vICAgICAgICAgaWYgKGF0dHJpYnV0ZXMucm9pSW5wdXRJZHggPD0gMCkge1xuLy8gICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHJvaSBpbnB1dCBpbmRleC4nKTtcbi8vICAgICAgICAgfVxuLy8gICAgICAgICBjb25zdCByb2lUZW5zb3IgPSBpbnB1dHNbYXR0cmlidXRlcy5yb2lJbnB1dElkeF07XG4vLyAgICAgICAgIHJvaSA9IHJvaVRlbnNvci5zaXplID4gMCA/IEFycmF5LmZyb20ocm9pVGVuc29yLmZsb2F0RGF0YSkgOiBbXTtcbi8vICAgICB9IGVsc2Uge1xuLy8gICAgICAgICByb2kgPSBuZXcgQXJyYXkoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICogMikuZmlsbCgwKTtcbi8vICAgICB9XG4vLyAgICAgcmV0dXJuIHJvaTtcbi8vIH07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IHNoYXBlID0gKF9pbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gIHJldHVybiBbbmV3IFRlbnNvcihbaW5wdXRzWzBdLmRpbXMubGVuZ3RoXSwgJ2ludDMyJywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIG5ldyBJbnQzMkFycmF5KGlucHV0c1swXS5kaW1zKSldO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtOVU1CRVJfVFlQRVMsIE9wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNsaWNlQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IGF4ZXM6IG51bWJlcltdO1xuICByZWFkb25seSBlbmRzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgc3RhcnRzOiBudW1iZXJbXTtcbn1cblxuY29uc3Qgc2xpY2VQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTbGljZScsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdXG59O1xuXG5leHBvcnQgY29uc3Qgc2xpY2U6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248U2xpY2VBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogU2xpY2VBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnNsaWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVTbGljZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcylcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlucHV0cyk7XG4gICAgICByZXR1cm4gW291dHB1dF07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU2xpY2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFNsaWNlQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IFNsaWNlQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IHN0YXJ0cyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdzdGFydHMnKTtcbiAgY29uc3QgZW5kcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdlbmRzJyk7XG4gIGNvbnN0IGF4ZXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnYXhlcycsIFtdKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7c3RhcnRzLCBlbmRzLCBheGVzfSk7XG59O1xuXG5jb25zdCBjcmVhdGVTbGljZVByb2dyYW1JbmZvID1cbiAgICAoX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvciwgYXR0cmlidXRlczogU2xpY2VBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgYXhlcyA9IChhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID09PSAwKSA/IGlucHV0LmRpbXMuc2xpY2UoMCkubWFwKChfdmFsLCBpKSA9PiBpKSA6IGF0dHJpYnV0ZXMuYXhlcztcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRBeGVzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4ZXMoYXhlcywgaW5wdXQuZGltcy5sZW5ndGgpO1xuICAgICAgY29uc3Qgc3RhcnRzID0gYXR0cmlidXRlcy5zdGFydHMubWFwKChzdGFydCwgaSkgPT4ge1xuICAgICAgICBpZiAoc3RhcnQgPiBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXSAtIDEpIHtcbiAgICAgICAgICByZXR1cm4gaW5wdXQuZGltc1tub3JtYWxpemVkQXhlc1tpXV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKHN0YXJ0LCBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXSk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGVuZHMgPSBhdHRyaWJ1dGVzLmVuZHMubWFwKChlbmQsIGkpID0+IHtcbiAgICAgICAgaWYgKGVuZCA+IGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dIC0gMSkge1xuICAgICAgICAgIHJldHVybiBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoZW5kLCBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXSk7XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dC5kaW1zLnNsaWNlKCk7XG5cbiAgICAgIGNvbnN0IHNsaWNlT3BzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub3JtYWxpemVkQXhlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBvdXRwdXRTaGFwZVtub3JtYWxpemVkQXhlc1tpXV0gPSBlbmRzW2ldIC0gc3RhcnRzW2ldO1xuICAgICAgICBpZiAoc3RhcnRzW2ldID4gMCkge1xuICAgICAgICAgIHNsaWNlT3BzLnB1c2goYG91dHB1dElkeFske25vcm1hbGl6ZWRBeGVzW2ldfV0gKz0gJHtzdGFydHNbaV19O2ApO1xuICAgICAgICB9ICAvLyBlbHNlIHsgc2xpY2VPcHMucHVzaChgb3V0cHV0SWR4WyR7bm9ybWFsaXplZEF4ZXNbaV19XSArPSAwO2ApOyB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtyYW5rfV0pIHtcbiAgICAgICAgJHtzbGljZU9wcy5qb2luKCdcXG4gICAgICAnKX1cbiAgICAgICAgcmV0dXJuIF9BKG91dHB1dElkeCk7XG4gICAgICB9YDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnNsaWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2xpY2UgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2xpY2VWMTAgPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0c1YxMChpbnB1dHMpO1xuICBjb25zdCBhdHRyaWJ1dGVzID0gZ2VuZXJhdGVTbGljZUF0dHJpYnV0ZXNGcm9tSW5wdXRzKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cyk7XG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAge1xuICAgICAgICAuLi5zbGljZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LFxuICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZVNsaWNlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzKVxuICAgICAgfSxcbiAgICAgIFtpbnB1dHNbMF1dKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgZ2VuZXJhdGVTbGljZUF0dHJpYnV0ZXNGcm9tSW5wdXRzID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogU2xpY2VBdHRyaWJ1dGVzID0+IHtcbiAgICAgIGlmICghaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzFdLmRhdGFJZCkgfHxcbiAgICAgICAgICAhaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzJdLmRhdGFJZCkgfHxcbiAgICAgICAgICAoaW5wdXRzLmxlbmd0aCA+PSA0ICYmICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbM10uZGF0YUlkKSkgfHxcbiAgICAgICAgICAoaW5wdXRzLmxlbmd0aCA+PSA1ICYmICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbNF0uZGF0YUlkKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkeW5hbWljIHNsaWNlIGF0dHJpYnV0ZXMgYXJlIG5vdCBhbGxvd2VkJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbnB1dHMubGVuZ3RoID49IDUgJiYgaW5wdXRzWzRdLmludGVnZXJEYXRhLnNvbWUoKGk6IG51bWJlcikgPT4gaSAhPT0gMSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgbm9uLTEgc3RlcHMgaXMgbm90IHN1cHBvcnRlZCBmb3IgU2xpY2UnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhcnRzID0gQXJyYXkuZnJvbShpbnB1dHNbMV0uaW50ZWdlckRhdGEpO1xuICAgICAgY29uc3QgZW5kcyA9IEFycmF5LmZyb20oaW5wdXRzWzJdLmludGVnZXJEYXRhKTtcbiAgICAgIGNvbnN0IGF4ZXMgPSBpbnB1dHMubGVuZ3RoID49IDQgPyBBcnJheS5mcm9tKGlucHV0c1szXS5pbnRlZ2VyRGF0YSkgOiBbXTtcbiAgICAgIGNvbnN0IGNhY2hlS2V5ID0gYCR7YXhlc307JHtzdGFydHN9OyR7ZW5kc31gO1xuICAgICAgcmV0dXJuIHtzdGFydHMsIGVuZHMsIGF4ZXMsIGNhY2hlS2V5fTtcbiAgICB9O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YxMCA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggPCAzIHx8IGlucHV0cy5sZW5ndGggPiA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IG51bWJlci4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicgfHwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1syXS50eXBlICE9PSAnaW50MzInIHx8IGlucHV0c1syXS5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHMubGVuZ3RoID49IDQgJiYgKGlucHV0c1szXS50eXBlICE9PSAnaW50MzInIHx8IGlucHV0c1szXS5kaW1zLmxlbmd0aCAhPT0gMSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSA1ICYmIChpbnB1dHNbNF0udHlwZSAhPT0gJ2ludDMyJyB8fCBpbnB1dHNbNF0uZGltcy5sZW5ndGggIT09IDEpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7dHJhbnNwb3NlLCBUcmFuc3Bvc2VBdHRyaWJ1dGVzfSBmcm9tICcuL3RyYW5zcG9zZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU29mdG1heEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG59XG5cbmNvbnN0IHNvZnRtYXhDb21wdXRlTWF4UHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU29mdG1heENvbXB1dGVNYXgnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmNvbnN0IHNvZnRtYXhDb21wdXRlU2NhbGVQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTb2Z0bWF4Q29tcHV0ZVNjYWxlJyxcbiAgaW5wdXROYW1lczogWydBJywgJ01heCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmNvbnN0IHNvZnRtYXhQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTb2Z0TWF4JyxcbiAgaW5wdXROYW1lczogWydBJywgJ01heCcsICdOb3JtJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBzb2Z0bWF4OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNvZnRtYXhBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogU29mdG1heEF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gICAgICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgICAgIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0U2hhcGUubGVuZ3RoKTtcbiAgICAgIGNvbnN0IGxvZ2ljYWxSb3dDb3VudCA9IFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24oaW5wdXRTaGFwZSwgYXhpcyk7XG4gICAgICBjb25zdCBmZWF0dXJlQ291bnQgPSBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oaW5wdXRTaGFwZSwgYXhpcyk7XG5cbiAgICAgIGNvbnN0IG91dHB1dCA9IGNvbXB1dGVTb2Z0bWF4KGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgbG9naWNhbFJvd0NvdW50LCBmZWF0dXJlQ291bnQpO1xuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTb2Z0bWF4QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxTb2Z0bWF4QXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogU29mdG1heEF0dHJpYnV0ZXMgPT4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtheGlzOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJywgMSl9KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU29mdG1heEF0dHJpYnV0ZXNWMTM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID1cbiAgICAobm9kZTogR3JhcGguTm9kZSk6IFNvZnRtYXhBdHRyaWJ1dGVzID0+IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7YXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIC0xKX0pO1xuXG4vLyBUaGUgXCJzZW1hbnRpY1wiIG1lYW5pbmcgb2YgYXhpcyBoYXMgY2hhbmdlZCBpbiBvcHNldC0xMy5cbi8vIFBsZWFzZSBjb21wYXJlOiBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL09wZXJhdG9ycy5tZCNTb2Z0bWF4XG4vLyB3aXRoIGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvQ2hhbmdlbG9nLm1kI1NvZnRtYXgtMTEgZm9yIGRldGFpbGVkIGV4cGxhbmF0aW9uc1xuLy8gVG8gYWNjb3VudCBmb3IgdGhlIG9wc2V0LTEzIGJlaGF2aW9yLCBvdXIgcGxhbiB3aWxsIGJlIHRvIHRyYW5zcG9zZSB0aGUgXCJheGlzXCIgZGltIHRvIHRoZSBpbm5lcm1vc3QgZGltXG4vLyBhbmQgcGVyZm9ybSBzb2Z0bWF4IGFuZCB0aGVuIHJldmVyc2UgdGhlIHRyYW5zcG9zZS4gV2UgY2FuIHNraXAgdGhlIHRyYW5zcG9zaW5nIGFzcGVjdCBpZiB0aGUgYXhpcyBpcyBhbHJlYWR5XG4vLyB0aGUgaW5uZXJtb3N0IGRpbVxuZXhwb3J0IGNvbnN0IHNvZnRtYXhWMTM6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBTb2Z0bWF4QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgICAgIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICAgICAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF0dHJpYnV0ZXMuYXhpcywgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICAgICAgY29uc3QgcmFuayA9IGlucHV0U2hhcGUubGVuZ3RoO1xuXG4gICAgICBjb25zdCBpc1RyYW5zcG9zZVJlcXVpcmVkID0gKGF4aXMgIT09IHJhbmsgLSAxKSA/IHRydWUgOiBmYWxzZTtcbiAgICAgIGNvbnN0IHRyYW5zcG9zZWRJbnB1dFNoYXBlOiBudW1iZXJbXSA9IFtdO1xuICAgICAgbGV0IHBlcm06IG51bWJlcltdID0gW107XG4gICAgICBsZXQgdHJhbnNwb3NlZElucHV0czogVGVuc29yW10gPSBbXTtcbiAgICAgIGxldCB0cmFuc3Bvc2VBdHRyaWJ1dGU6IFRyYW5zcG9zZUF0dHJpYnV0ZXM7XG5cbiAgICAgIGlmIChpc1RyYW5zcG9zZVJlcXVpcmVkKSB7XG4gICAgICAgIHBlcm0gPSBBcnJheS5mcm9tKHtsZW5ndGg6IHJhbmt9KS5tYXAoKF8sIGkpID0+IGkpO1xuXG4gICAgICAgIC8vIHN3YXAgdGhlIGlubmVybW9zdCBkaW0gd2l0aCB0aGUgZGltIGNvcnJlc3BvbmRpbmcgdG8gYXhpc1xuICAgICAgICBwZXJtW2F4aXNdID0gcmFuayAtIDE7XG4gICAgICAgIHBlcm1bcmFuayAtIDFdID0gYXhpcztcblxuICAgICAgICBwZXJtLm1hcChwID0+IHRyYW5zcG9zZWRJbnB1dFNoYXBlLnB1c2goaW5wdXRTaGFwZVtwXSkpO1xuXG4gICAgICAgIHRyYW5zcG9zZUF0dHJpYnV0ZSA9IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7cGVybX0pO1xuICAgICAgICB0cmFuc3Bvc2VkSW5wdXRzID0gdHJhbnNwb3NlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgdHJhbnNwb3NlQXR0cmlidXRlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbG9naWNhbFJvd0NvdW50ID0gaXNUcmFuc3Bvc2VSZXF1aXJlZCA/IFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24odHJhbnNwb3NlZElucHV0U2hhcGUsIHJhbmsgLSAxKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2hhcGVVdGlsLnNpemVUb0RpbWVuc2lvbihpbnB1dFNoYXBlLCByYW5rIC0gMSk7XG4gICAgICBjb25zdCBmZWF0dXJlQ291bnQgPSBpc1RyYW5zcG9zZVJlcXVpcmVkID8gU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKHRyYW5zcG9zZWRJbnB1dFNoYXBlLCByYW5rIC0gMSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbihpbnB1dFNoYXBlLCByYW5rIC0gMSk7XG5cbiAgICAgIGNvbnN0IG91dHB1dCA9IGNvbXB1dGVTb2Z0bWF4KFxuICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIsIGlzVHJhbnNwb3NlUmVxdWlyZWQgPyB0cmFuc3Bvc2VkSW5wdXRzIDogaW5wdXRzLCBhdHRyaWJ1dGVzLCBsb2dpY2FsUm93Q291bnQsIGZlYXR1cmVDb3VudCk7XG5cbiAgICAgIGlmIChpc1RyYW5zcG9zZVJlcXVpcmVkKSB7XG4gICAgICAgIGNvbnN0IHJldmVyc2VkT3V0cHV0ID0gdHJhbnNwb3NlKGluZmVyZW5jZUhhbmRsZXIsIG91dHB1dCwgdHJhbnNwb3NlQXR0cmlidXRlISk7XG4gICAgICAgIHJldHVybiByZXZlcnNlZE91dHB1dDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgICB9XG4gICAgfTtcblxuY29uc3QgY29tcHV0ZVNvZnRtYXggPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFNvZnRtYXhBdHRyaWJ1dGVzLCBsb2dpY2FsUm93Q291bnQ6IG51bWJlcixcbiAgICAgZmVhdHVyZUNvdW50OiBudW1iZXIpOiBUZW5zb3JbXSA9PiB7XG4gICAgICBjb25zdCBjb21wdXRlTWF4UHJvZ3JhbUluZm8gPVxuICAgICAgICAgIGNyZWF0ZUNvbXB1dGVNYXhQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGxvZ2ljYWxSb3dDb3VudCwgZmVhdHVyZUNvdW50LCBbbG9naWNhbFJvd0NvdW50XSk7XG4gICAgICBjb25zdCBtYXggPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICB7Li4uc29mdG1heENvbXB1dGVNYXhQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBjb21wdXRlTWF4UHJvZ3JhbUluZm99LFxuICAgICAgICAgIGlucHV0cyk7XG5cbiAgICAgIGNvbnN0IGNvbXB1dGVTY2FsZVByb2dyYW1JbmZvID0gY3JlYXRlQ29tcHV0U2NhbGVQcm9ncmFtSW5mbyhcbiAgICAgICAgICBpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGxvZ2ljYWxSb3dDb3VudCwgZmVhdHVyZUNvdW50LCBjb21wdXRlTWF4UHJvZ3JhbUluZm8ub3V0cHV0LmRpbXMsXG4gICAgICAgICAgW2xvZ2ljYWxSb3dDb3VudF0pO1xuICAgICAgY29uc3Qgc2NhbGUgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICB7Li4uc29mdG1heENvbXB1dGVTY2FsZVByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LCBnZXQ6ICgpID0+IGNvbXB1dGVTY2FsZVByb2dyYW1JbmZvfSxcbiAgICAgICAgICBbaW5wdXRzWzBdLCBtYXhdKTtcblxuICAgICAgY29uc3Qgc29mdE1heFByb2dyYW1JbmZvID0gY3JlYXRlU29mdE1heFByb2dyYW1JbmZvKFxuICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgbG9naWNhbFJvd0NvdW50LCBmZWF0dXJlQ291bnQsIGNvbXB1dGVNYXhQcm9ncmFtSW5mby5vdXRwdXQuZGltcyxcbiAgICAgICAgICBjb21wdXRlU2NhbGVQcm9ncmFtSW5mby5vdXRwdXQuZGltcyk7XG4gICAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICB7Li4uc29mdG1heFByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5LCBnZXQ6ICgpID0+IHNvZnRNYXhQcm9ncmFtSW5mb30sXG4gICAgICAgICAgW2lucHV0c1swXSwgbWF4LCBzY2FsZV0pO1xuICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgIH07XG5cbi8qKlxuICogQ3JlYXRlIGEgdGV4dHVyZSB0aGF0IGNvbnRhaW5zIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGVhY2ggb2YgdGhlICdOJyByb3dzXG4gKi9cbmNvbnN0IGNyZWF0ZUNvbXB1dGVNYXhQcm9ncmFtSW5mbyA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvciwgbG9naWNhbFJvd0NvdW50OiBudW1iZXIsIGZlYXR1cmVDb3VudDogbnVtYmVyLFxuICAgICBvdXRwdXRTaGFwZTogbnVtYmVyW10pOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9XG4gICAgICAgICAgaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoaW5wdXQuZGltcywgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICAgICAgaWYgKGxvZ2ljYWxSb3dDb3VudCA8IDEgfHwgZmVhdHVyZUNvdW50IDwgMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvZ2ljYWwgcm93IGNvdW50IE4gYW5kIGZlYXR1cmUgY291bnQgRCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvdXRwdXRTaGFwZS5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb25hbGl0eSBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSAxJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvdXRwdXRTaGFwZVswXSAhPT0gbG9naWNhbFJvd0NvdW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIG91dHB1dCBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgICAgICBpbnQgbG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ID0gaW5kaWNlc1swXSAqICR7ZmVhdHVyZUNvdW50fTtcblxuICAgICAgICBmbG9hdCBtYXggPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgb2Zmc2V0VG9Db29yZHMobG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0LCAke3RleHR1cmVXaWR0aH0sXG4gICAgICAgICR7dGV4dHVyZUhlaWdodH0gKSkpO1xuICAgICAgICBmb3IoaW50IGk9MTsgaTwke2ZlYXR1cmVDb3VudH07ICsraSlcbiAgICAgICAge1xuICAgICAgICAgIGZsb2F0IGN1cnJlbnQgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgb2Zmc2V0VG9Db29yZHMobG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ICsgaSxcbiAgICAgICAgICAgICR7dGV4dHVyZVdpZHRofSwgJHt0ZXh0dXJlSGVpZ2h0fSkpKTtcbiAgICAgICAgICBpZihjdXJyZW50ID4gbWF4KVxuICAgICAgICAgIG1heCA9IGN1cnJlbnQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWF4O1xuICAgICAgfWA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5zb2Z0bWF4Q29tcHV0ZU1heFByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZH0sXG4gICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgfTtcbiAgICB9O1xuXG4vKipcbiAqIENyZWF0ZSBhIHRleHR1cmUgdGhhdCBjb250YWlucyB0aGUgbm9ybWFsaXphdGlvbiBmYWN0b3IgZm9yIGVhY2ggb2YgdGhlICdOJyByb3dzXG4gKi9cbmNvbnN0IGNyZWF0ZUNvbXB1dFNjYWxlUHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIGxvZ2ljYWxSb3dDb3VudDogbnVtYmVyLCBmZWF0dXJlQ291bnQ6IG51bWJlcixcbiAgICAgbWF4RWxlbWVudFBlckxvZ2ljYWxSb3c6IHJlYWRvbmx5IG51bWJlcltdLCBvdXRwdXRTaGFwZTogbnVtYmVyW10pOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9XG4gICAgICAgICAgaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoaW5wdXQuZGltcywgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcblxuICAgICAgaWYgKGxvZ2ljYWxSb3dDb3VudCA8IDEgfHwgZmVhdHVyZUNvdW50IDwgMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvZ2ljYWwgcm93IGNvdW50IE4gYW5kIGZlYXR1cmUgY291bnQgRCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvdXRwdXRTaGFwZS5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb25hbGl0eSBvZiB0aGUgb3V0cHV0IHNob3VsZCBiZSAxJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvdXRwdXRTaGFwZVswXSAhPT0gbG9naWNhbFJvd0NvdW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIG91dHB1dCBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93Lmxlbmd0aCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgMScpO1xuICAgICAgfVxuXG4gICAgICBpZiAobWF4RWxlbWVudFBlckxvZ2ljYWxSb3dbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NoYXBlIG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgICAgICBpbnQgbG9naWNhbF9yb3dfc3RhcnRfb2Zmc2V0ID0gaW5kaWNlc1swXSAqICR7ZmVhdHVyZUNvdW50fTtcblxuICAgICAgICBmbG9hdCBub3JtX2ZhY3RvciA9IDAuMDtcbiAgICAgICAgZmxvYXQgbWF4ID0gX01heChpbmRpY2VzKTtcbiAgICAgICAgZm9yKGludCBpPTA7IGk8JHtmZWF0dXJlQ291bnR9OyArK2kpXG4gICAgICAgIHtcbiAgICAgICAgICBub3JtX2ZhY3RvciArPSBleHAoZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIG9mZnNldFRvQ29vcmRzKGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCArIGksXG4gICAgICAgICAgICAke3RleHR1cmVXaWR0aH0sICR7dGV4dHVyZUhlaWdodH0pKSkgLSBtYXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vcm1fZmFjdG9yO1xuICAgICAgfWA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5zb2Z0bWF4Q29tcHV0ZVNjYWxlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZVNvZnRNYXhQcm9ncmFtSW5mbyA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvciwgbG9naWNhbFJvd0NvdW50OiBudW1iZXIsIGZlYXR1cmVDb3VudDogbnVtYmVyLFxuICAgICBtYXhFbGVtZW50UGVyTG9naWNhbFJvdzogcmVhZG9ubHkgbnVtYmVyW10sIG5vcm1hbGl6YXRpb25QZXJMb2dpY2FsUm93OiByZWFkb25seSBudW1iZXJbXSk6IFByb2dyYW1JbmZvID0+IHtcbiAgICAgIGNvbnN0IFt0ZXh0dXJlV2lkdGgsIHRleHR1cmVIZWlnaHRdID1cbiAgICAgICAgICBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChpbnB1dC5kaW1zLCBUZXh0dXJlVHlwZS51bnBhY2tlZCk7XG4gICAgICBjb25zdCByYW5rID0gaW5wdXQuZGltcy5sZW5ndGg7XG5cbiAgICAgIGlmIChsb2dpY2FsUm93Q291bnQgPCAxIHx8IGZlYXR1cmVDb3VudCA8IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMb2dpY2FsIHJvdyBjb3VudCBOIGFuZCBmZWF0dXJlIGNvdW50IEQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgfVxuXG4gICAgICBpZiAobWF4RWxlbWVudFBlckxvZ2ljYWxSb3cubGVuZ3RoICE9PSAxIHx8IG5vcm1hbGl6YXRpb25QZXJMb2dpY2FsUm93Lmxlbmd0aCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbWVuc2lvbmFsaXR5IG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgMScpO1xuICAgICAgfVxuXG4gICAgICBpZiAobWF4RWxlbWVudFBlckxvZ2ljYWxSb3dbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCB8fCBub3JtYWxpemF0aW9uUGVyTG9naWNhbFJvd1swXSAhPT0gbG9naWNhbFJvd0NvdW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgb2YgdGhlIGludGVybWVkaWF0ZSByZXN1bHRzIHNob3VsZCBiZSBlcXVhbCB0byBsb2dpY2FsIHJvdyBjb3VudCcpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludFske3Jhbmt9XSBpbmRpY2VzKSB7XG5cbiAgICAgIC8vIGdldCBvZmZzZXQgb2YgY3VycmVudCBsb2dpY2FsIHRlbnNvciBpbmRleCBmcm9tIHRoZSAyLUQgdGV4dHVyZSBjb29yZGluYXRlcyAoVGV4Q29vcmRzKVxuICAgICAgaW50IG9mZnNldCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXh0dXJlV2lkdGh9LCAke3RleHR1cmVIZWlnaHR9KTtcblxuICAgICAgLy9kZXRlcm1pbmUgdGhlIGxvZ2ljYWwgcm93IGZvciB0aGlzIGluZGV4XG4gICAgICBpbnQgbG9naWNhbF9yb3dfaW5kZXhbMV07XG4gICAgICBsb2dpY2FsX3Jvd19pbmRleFswXSA9IG9mZnNldCAvICR7ZmVhdHVyZUNvdW50fTtcblxuICAgICAgZmxvYXQgbm9ybV9mYWN0b3IgPSBfTm9ybShsb2dpY2FsX3Jvd19pbmRleCk7XG5cbiAgICAgIC8vIGF2b2lkIHBvc3NpYmxlIGRpdmlzaW9uIGJ5IDBcbiAgICAgIC8vIGlmIG5vcm1fZmFjb3IgaXMgMCwgYWxsIGVsZW1lbnRzIGFyZSB6ZXJvXG4gICAgICAvLyBpZiBzbywgcmV0dXJuIDBcbiAgICAgIGlmKG5vcm1fZmFjdG9yID09IDAuMClcbiAgICAgICAgcmV0dXJuIDAuMDtcblxuICAgICAgcmV0dXJuIGV4cChfQShpbmRpY2VzKSAtIF9NYXgobG9naWNhbF9yb3dfaW5kZXgpKSAvIG5vcm1fZmFjdG9yO1xuICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uc29mdG1heFByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU29mdG1heCByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsLCBTcGxpdFV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3BsaXRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xuICByZWFkb25seSBzcGxpdDogbnVtYmVyW107XG4gIHJlYWRvbmx5IG51bU91dHB1dHM6IG51bWJlcjtcbn1cblxuY29uc3Qgc3BsaXRQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTcGxpdCcsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHNwbGl0OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNwbGl0QXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFNwbGl0QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgICAgIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG4gICAgICBjb25zdCBjb3VudCA9IGdldFByb2dyYW1Db3VudChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF4aXMsIGF0dHJpYnV0ZXMpO1xuICAgICAgY29uc3Qgb3V0cHV0OiBUZW5zb3JbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7XG4gICAgICAgIG91dHB1dC5wdXNoKGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAuLi5zcGxpdFByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICAgICAgY2FjaGVIaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fTske2l9YCxcbiAgICAgICAgICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVTcGxpdFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcywgYXhpcywgaSlcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbnB1dHMpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTcGxpdEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U3BsaXRBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogU3BsaXRBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXhpcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAwKTtcbiAgY29uc3Qgc3BsaXQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3BsaXQnLCBbXSk7XG4gIGNvbnN0IG51bU91dHB1dHMgPSBub2RlLm91dHB1dHMubGVuZ3RoO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtheGlzLCBzcGxpdCwgbnVtT3V0cHV0c30pO1xufTtcblxuY29uc3QgZ2V0UHJvZ3JhbUNvdW50ID1cbiAgICAoX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyLCBhdHRyaWJ1dGVzOiBTcGxpdEF0dHJpYnV0ZXMpOiBudW1iZXIgPT4ge1xuICAgICAgY29uc3QgWywgb2Zmc2V0c10gPSBTcGxpdFV0aWwuc3BsaXRTaGFwZShpbnB1dHNbMF0uZGltcywgYXhpcywgYXR0cmlidXRlcy5zcGxpdCwgYXR0cmlidXRlcy5udW1PdXRwdXRzKTtcbiAgICAgIHJldHVybiBvZmZzZXRzLmxlbmd0aDtcbiAgICB9O1xuXG5jb25zdCBjcmVhdGVTcGxpdFByb2dyYW1JbmZvID1cbiAgICAoX2luZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvciwgYXR0cmlidXRlczogU3BsaXRBdHRyaWJ1dGVzLCBheGlzOiBudW1iZXIsIGluZGV4OiBudW1iZXIpOlxuICAgICAgICBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICAgICAgY29uc3QgW3NoYXBlcywgb2Zmc2V0c10gPSBTcGxpdFV0aWwuc3BsaXRTaGFwZShpbnB1dC5kaW1zLCBheGlzLCBhdHRyaWJ1dGVzLnNwbGl0LCBhdHRyaWJ1dGVzLm51bU91dHB1dHMpO1xuICAgICAgICAgIGNvbnN0IG9mZnNldCA9IG9mZnNldHNbaW5kZXhdO1xuICAgICAgICAgIGNvbnN0IG91dHB1dFNoYXBlID0gc2hhcGVzW2luZGV4XTtcbiAgICAgICAgICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgICAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW5kaWNlc1ske2F4aXN9XSArPSAke29mZnNldH07XG4gICAgICAgIHJldHVybiBfQShpbmRpY2VzKTtcbiAgICAgIH1cbiAgICBgO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5zcGxpdFByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICAgIGNhY2hlSGludDogYCR7YXR0cmlidXRlcy5jYWNoZUtleX06JHtpbmRleH1gLFxuICAgICAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZH0sXG4gICAgICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NwbGl0IHJlcXVpcmVzIG9uZSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2ludDgnICYmIGlucHV0c1swXS50eXBlICE9PSAndWludDgnICYmIGlucHV0c1swXS50eXBlICE9PSAnaW50MTYnICYmXG4gICAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ3VpbnQxNicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdpbnQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICd1aW50MzInICYmXG4gICAgICBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdib29sJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBzcXVlZXplOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcltdPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwuc3F1ZWV6ZVNoYXBlKGlucHV0c1swXS5kaW1zLCBheGVzKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgb3V0cHV0U2hhcGUpO1xuICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBzcXVlZXplVjEzID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHNWMTMoaW5wdXRzKTtcbiAgcmV0dXJuIHNxdWVlemUoaW5mZXJlbmNlSGFuZGxlciwgW2lucHV0c1swXV0sIEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTcXVlZXplQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxudW1iZXJbXT4gPSAobm9kZTogR3JhcGguTm9kZSk6IG51bWJlcltdID0+XG4gICAgbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2F4ZXMnKTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTcXVlZXplIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMTMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTcXVlZXplIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07IiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IHN1bSA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgY29uc3Qgc3VtUHJvZ3JhbU1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdTdW0nLFxuICAgIGlucHV0TmFtZXM6IGlucHV0cy5tYXAoKF92LCBpKSA9PiBgWCR7aX1gKSxcbiAgICBpbnB1dFR5cGVzOiBuZXcgQXJyYXkoaW5wdXRzLmxlbmd0aCkuZmlsbChUZXh0dXJlVHlwZS51bnBhY2tlZClcbiAgfTtcblxuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgIHsuLi5zdW1Qcm9ncmFtTWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlU3VtUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBzdW1Qcm9ncmFtTWV0YWRhdGEpfSwgaW5wdXRzKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgY3JlYXRlU3VtUHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIHN1bVByb2dyYW1NZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICAgICAgY29uc3Qgc3VtTGluZSA9IGlucHV0cy5tYXAoKF92LCBpKSA9PiBgJHtnbHNsLnRleHR1cmUyRH0oWCR7aX0sVGV4Q29vcmRzKWApLmpvaW4oJyArICcpO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICB2ZWM0IHJlc3VsdCA9ICR7c3VtTGluZX07XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfVxuICAgIGA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5zdW1Qcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgaGFzTWFpbjogdHJ1ZSxcbiAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3VtIHJlcXVpcmVzIGlucHV0cy4nKTtcbiAgfVxuXG4gIGNvbnN0IGxlbmd0aCA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAobGVuZ3RoICE9PSBpbnB1dHNbaV0uZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgc2hhcGVzIGFyZSBtaXNtYXRjaGVkLicpO1xuICAgIH1cblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGVuZ3RoOyBqKyspIHtcbiAgICAgIGlmIChpbnB1dHNbMF0uZGltc1tqXSAhPT0gaW5wdXRzW2ldLmRpbXNbal0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBzaGFwZXMgYXJlIG5vdCBtYXRjaGVkLicpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBmb3IgKGxldCBpID0gMTsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzW2ldLnR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgdHlwZXMgYXJlIG5vdCBtYXRjaGVkLicpO1xuICAgIH1cbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtOVU1CRVJfVFlQRVN9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCB0aWxlID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCB0aWxlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdUaWxlJyxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICB9O1xuXG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgey4uLnRpbGVQcm9ncmFtTWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlVGlsZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgdGlsZVByb2dyYW1NZXRhZGF0YSl9LFxuICAgICAgaW5wdXRzKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgY3JlYXRlVGlsZVByb2dyYW1JbmZvID1cbiAgICAoX2hhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgdGlsZVByb2dyYW1NZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IG5ldyBBcnJheShpbnB1dFNoYXBlLmxlbmd0aCk7XG5cbiAgICAgIGNvbnN0IHRpbGVPcHM6IHN0cmluZ1tdID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0U2hhcGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgb3V0cHV0U2hhcGVbaV0gPSBpbnB1dFNoYXBlW2ldICogaW5wdXRzWzFdLm51bWJlckRhdGFbaV07XG4gICAgICAgIHRpbGVPcHMucHVzaChgaW5wdXRJZHhbJHtpfV0gPSBpbnQobW9kKGZsb2F0KG91dHB1dElkeFske2l9XSksICR7aW5wdXRTaGFwZVtpXX0uKSk7YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGlucHV0SWR4WyR7cmFua31dO1xuICAgICAgICAke3RpbGVPcHMuam9pbignXFxuJyl9XG4gICAgICAgIHJldHVybiBfQShpbnB1dElkeCk7XG4gICAgICB9XG4gICAgYDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnRpbGVQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignVGlsZSByZXF1aXJlcyAyIGlucHV0LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBzZWNvbmQgaW5wdXQgc2hhcGUgbXVzdCAxIGRpbWVuc2lvbi4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzFdLmRpbXNbMF0gIT09IGlucHV0c1swXS5kaW1zLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJyAmJiBpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDE2Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCByZXBlYXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1NoYXBlVXRpbH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgdW5zcXVlZXplOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcltdPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwudW5zcXVlZXplU2hhcGUoaW5wdXRzWzBdLmRpbXMsIGF4ZXMpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBvdXRwdXRTaGFwZSk7XG4gICAgICByZXR1cm4gW291dHB1dF07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHVuc3F1ZWV6ZVYxMyA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjEzKGlucHV0cyk7XG4gIHJldHVybiB1bnNxdWVlemUoaW5mZXJlbmNlSGFuZGxlciwgW2lucHV0c1swXV0sIEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VVbnNxdWVlemVBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPG51bWJlcltdPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogbnVtYmVyW10gPT5cbiAgICBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnYXhlcycpO1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3F1ZWV6ZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dCB0ZW5zb3IgdHlwZXMuJyk7XG4gIH1cbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjEzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5zcXVlZXplIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7T3BTZXR9IGZyb20gJy4uLy4uL29wc2V0JztcblxuaW1wb3J0IHtiYXRjaE5vcm1hbGl6YXRpb24sIHBhcnNlQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlc30gZnJvbSAnLi9vcHMvYmF0Y2gtbm9ybWFsaXphdGlvbic7XG5pbXBvcnQgKiBhcyBiaW5hcnlPcHMgZnJvbSAnLi9vcHMvYmluYXJ5LW9wJztcbmltcG9ydCB7Y2FzdCwgcGFyc2VDYXN0QXR0cmlidXRlc30gZnJvbSAnLi9vcHMvY2FzdCc7XG5pbXBvcnQge2NvbmNhdCwgcGFyc2VDb25jYXRBdHRyaWJ1dGVzfSBmcm9tICcuL29wcy9jb25jYXQnO1xuaW1wb3J0IHtjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzfSBmcm9tICcuL29wcy9jb252JztcbmltcG9ydCB7Y29udlRyYW5zcG9zZSwgcGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlc30gZnJvbSAnLi9vcHMvY29udi10cmFuc3Bvc2UnO1xuaW1wb3J0IHtkZXB0aFRvU3BhY2UsIHBhcnNlRGVwdGhUb1NwYWNlQXR0cmlidXRlc30gZnJvbSAnLi9vcHMvZGVwdGgtdG8tc3BhY2UnO1xuaW1wb3J0IHtmbGF0dGVuLCBwYXJzZUZsYXR0ZW5BdHRyaWJ1dGVzfSBmcm9tICcuL29wcy9mbGF0dGVuJztcbmltcG9ydCB7Z2F0aGVyLCBwYXJzZUdhdGhlckF0dHJpYnV0ZXN9IGZyb20gJy4vb3BzL2dhdGhlcic7XG5pbXBvcnQge2dlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXNWMTEsIHBhcnNlR2VtbUF0dHJpYnV0ZXNWN30gZnJvbSAnLi9vcHMvZ2VtbSc7XG5pbXBvcnQge2ltYWdlU2NhbGVyLCBwYXJzZUltYWdlU2NhbGVyQXR0cmlidXRlc30gZnJvbSAnLi9vcHMvaW1hZ2Utc2NhbGVyJztcbmltcG9ydCB7aW5zdGFuY2VOb3JtYWxpemF0aW9uLCBwYXJzZUluc3RhbmNlTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXN9IGZyb20gJy4vb3BzL2luc3RhbmNlLW5vcm1hbGl6YXRpb24nO1xuaW1wb3J0IHtscm4sIHBhcnNlTHJuQXR0cmlidXRlc30gZnJvbSAnLi9vcHMvbHJuJztcbmltcG9ydCB7bWF0TXVsLCBwYXJzZU1hdE11bEF0dHJpYnV0ZXN9IGZyb20gJy4vb3BzL21hdG11bCc7XG5pbXBvcnQge3BhZFYxMSwgcGFkVjIsIHBhcnNlUGFkQXR0cmlidXRlc1YxMSwgcGFyc2VQYWRBdHRyaWJ1dGVzVjJ9IGZyb20gJy4vb3BzL3BhZCc7XG5pbXBvcnQge2F2ZXJhZ2VQb29sLCBnbG9iYWxBdmVyYWdlUG9vbCwgZ2xvYmFsTWF4UG9vbCwgbWF4UG9vbCwgcGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXMsIHBhcnNlR2xvYmFsQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLCBwYXJzZU1heFBvb2xBdHRyaWJ1dGVzfSBmcm9tICcuL29wcy9wb29sJztcbmltcG9ydCB7cGFyc2VSZWR1Y2VBdHRyaWJ1dGVzLCByZWR1Y2VMb2dTdW0sIHJlZHVjZUxvZ1N1bVNxdWFyZSwgcmVkdWNlTWF4LCByZWR1Y2VNZWFuLCByZWR1Y2VNaW4sIHJlZHVjZVByb2QsIHJlZHVjZVN1bX0gZnJvbSAnLi9vcHMvcmVkdWNlJztcbmltcG9ydCB7cmVzaGFwZX0gZnJvbSAnLi9vcHMvcmVzaGFwZSc7XG5pbXBvcnQge3BhcnNlUmVzaXplQXR0cmlidXRlc1YxMCwgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjExLCByZXNpemV9IGZyb20gJy4vb3BzL3Jlc2l6ZS1wYWNrZWQnO1xuaW1wb3J0IHtzaGFwZX0gZnJvbSAnLi9vcHMvc2hhcGUnO1xuaW1wb3J0IHtwYXJzZVNsaWNlQXR0cmlidXRlcywgc2xpY2UsIHNsaWNlVjEwfSBmcm9tICcuL29wcy9zbGljZSc7XG5pbXBvcnQge3BhcnNlU29mdG1heEF0dHJpYnV0ZXMsIHBhcnNlU29mdG1heEF0dHJpYnV0ZXNWMTMsIHNvZnRtYXgsIHNvZnRtYXhWMTN9IGZyb20gJy4vb3BzL3NvZnRtYXgnO1xuaW1wb3J0IHtwYXJzZVNwbGl0QXR0cmlidXRlcywgc3BsaXR9IGZyb20gJy4vb3BzL3NwbGl0JztcbmltcG9ydCB7cGFyc2VTcXVlZXplQXR0cmlidXRlcywgc3F1ZWV6ZSwgc3F1ZWV6ZVYxM30gZnJvbSAnLi9vcHMvc3F1ZWV6ZSc7XG5pbXBvcnQge3N1bX0gZnJvbSAnLi9vcHMvc3VtJztcbmltcG9ydCB7dGlsZX0gZnJvbSAnLi9vcHMvdGlsZSc7XG5pbXBvcnQge3BhcnNlVHJhbnNwb3NlQXR0cmlidXRlcywgdHJhbnNwb3NlfSBmcm9tICcuL29wcy90cmFuc3Bvc2UnO1xuaW1wb3J0ICogYXMgdW5hcnlPcHMgZnJvbSAnLi9vcHMvdW5hcnktb3AnO1xuaW1wb3J0IHtwYXJzZVVuc3F1ZWV6ZUF0dHJpYnV0ZXMsIHVuc3F1ZWV6ZSwgdW5zcXVlZXplVjEzfSBmcm9tICcuL29wcy91bnNxdWVlemUnO1xuaW1wb3J0IHtwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y3LCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y5LCB1cHNhbXBsZX0gZnJvbSAnLi9vcHMvdXBzYW1wbGUnO1xuXG5leHBvcnQgY29uc3QgV0VCR0xfT1BfUkVTT0xWRV9SVUxFUzogcmVhZG9ubHkgT3BTZXQuUmVzb2x2ZVJ1bGVbXSA9IFtcbiAgWydBYnMnLCAnJywgJzYrJywgdW5hcnlPcHMuYWJzXSxcbiAgWydBY29zJywgJycsICc3KycsIHVuYXJ5T3BzLmFjb3NdLFxuICBbJ0FkZCcsICcnLCAnNysnLCBiaW5hcnlPcHMuYWRkXSxcbiAgWydBbmQnLCAnJywgJzcrJywgYmluYXJ5T3BzLmFuZF0sXG4gIFsnQXNpbicsICcnLCAnNysnLCB1bmFyeU9wcy5hc2luXSxcbiAgWydBdGFuJywgJycsICc3KycsIHVuYXJ5T3BzLmF0YW5dLFxuICAvLyBUT0RPOiBzdXBwb3J0IG5ldyBhdHRyaWJ1dGVzIGZvciBBdmVyYWdlUG9vbC0xMFxuICBbJ0F2ZXJhZ2VQb29sJywgJycsICc3KycsIGF2ZXJhZ2VQb29sLCBwYXJzZUF2ZXJhZ2VQb29sQXR0cmlidXRlc10sXG4gIFsnQmF0Y2hOb3JtYWxpemF0aW9uJywgJycsICc3KycsIGJhdGNoTm9ybWFsaXphdGlvbiwgcGFyc2VCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzXSxcbiAgWydDYXN0JywgJycsICc2KycsIGNhc3QsIHBhcnNlQ2FzdEF0dHJpYnV0ZXNdLFxuICBbJ0NlaWwnLCAnJywgJzYrJywgdW5hcnlPcHMuY2VpbF0sXG4gIFsnQ2xpcCcsICcnLCAnNi0xMCcsIHVuYXJ5T3BzLmNsaXAsIHVuYXJ5T3BzLnBhcnNlQ2xpcEF0dHJpYnV0ZXNdLFxuICBbJ0NsaXAnLCAnJywgJzExKycsIHVuYXJ5T3BzLmNsaXBWMTFdLFxuICBbJ0NvbmNhdCcsICcnLCAnNCsnLCBjb25jYXQsIHBhcnNlQ29uY2F0QXR0cmlidXRlc10sXG4gIFsnQ29udicsICcnLCAnMSsnLCBjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzXSxcbiAgWydDb252VHJhbnNwb3NlJywgJycsICcxKycsIGNvbnZUcmFuc3Bvc2UsIHBhcnNlQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXNdLFxuICBbJ0NvcycsICcnLCAnNysnLCB1bmFyeU9wcy5jb3NdLFxuICBbJ0RpdicsICcnLCAnNysnLCBiaW5hcnlPcHMuZGl2XSxcbiAgWydEcm9wb3V0JywgJycsICc3KycsIHVuYXJ5T3BzLmlkZW50aXR5XSxcbiAgWydEZXB0aFRvU3BhY2UnLCAnJywgJzErJywgZGVwdGhUb1NwYWNlLCBwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXNdLFxuICBbJ0VxdWFsJywgJycsICc3KycsIGJpbmFyeU9wcy5lcXVhbF0sXG4gIFsnRWx1JywgJycsICc2KycsIHVuYXJ5T3BzLmVsdSwgdW5hcnlPcHMucGFyc2VFbHVBdHRyaWJ1dGVzXSxcbiAgWydFeHAnLCAnJywgJzYrJywgdW5hcnlPcHMuZXhwXSxcbiAgWydGbGF0dGVuJywgJycsICcxKycsIGZsYXR0ZW4sIHBhcnNlRmxhdHRlbkF0dHJpYnV0ZXNdLFxuICBbJ0Zsb29yJywgJycsICc2KycsIHVuYXJ5T3BzLmZsb29yXSxcbiAgWydGdXNlZENvbnYnLCAnY29tLm1pY3Jvc29mdCcsICcxKycsIGNvbnYsIHBhcnNlQ29udkF0dHJpYnV0ZXNdLFxuICBbJ0dhdGhlcicsICcnLCAnMSsnLCBnYXRoZXIsIHBhcnNlR2F0aGVyQXR0cmlidXRlc10sXG4gIFsnR2VtbScsICcnLCAnNy0xMCcsIGdlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXNWN10sXG4gIFsnR2VtbScsICcnLCAnMTErJywgZ2VtbSwgcGFyc2VHZW1tQXR0cmlidXRlc1YxMV0sXG4gIFsnR2xvYmFsQXZlcmFnZVBvb2wnLCAnJywgJzErJywgZ2xvYmFsQXZlcmFnZVBvb2wsIHBhcnNlR2xvYmFsQXZlcmFnZVBvb2xBdHRyaWJ1dGVzXSxcbiAgWydHbG9iYWxNYXhQb29sJywgJycsICcxKycsIGdsb2JhbE1heFBvb2xdLFxuICBbJ0dyZWF0ZXInLCAnJywgJzcrJywgYmluYXJ5T3BzLmdyZWF0ZXJdLFxuICBbJ0lkZW50aXR5JywgJycsICcxKycsIHVuYXJ5T3BzLmlkZW50aXR5XSxcbiAgWydJbWFnZVNjYWxlcicsICcnLCAnMSsnLCBpbWFnZVNjYWxlciwgcGFyc2VJbWFnZVNjYWxlckF0dHJpYnV0ZXNdLFxuICBbJ0luc3RhbmNlTm9ybWFsaXphdGlvbicsICcnLCAnNisnLCBpbnN0YW5jZU5vcm1hbGl6YXRpb24sIHBhcnNlSW5zdGFuY2VOb3JtYWxpemF0aW9uQXR0cmlidXRlc10sXG4gIFsnTGVha3lSZWx1JywgJycsICc2KycsIHVuYXJ5T3BzLmxlYWt5UmVsdSwgdW5hcnlPcHMucGFyc2VMZWFreVJlbHVBdHRyaWJ1dGVzXSxcbiAgWydMZXNzJywgJycsICc3KycsIGJpbmFyeU9wcy5sZXNzXSxcbiAgWydMUk4nLCAnJywgJzErJywgbHJuLCBwYXJzZUxybkF0dHJpYnV0ZXNdLFxuICBbJ0xvZycsICcnLCAnNisnLCB1bmFyeU9wcy5sb2ddLFxuICBbJ01hdE11bCcsICcnLCAnMSsnLCBtYXRNdWwsIHBhcnNlTWF0TXVsQXR0cmlidXRlc10sXG4gIC8vIFRPRE86IHN1cHBvcnQgbmV3IGF0dHJpYnV0ZXMgZm9yIE1heFBvb2wtOCBhbmQgTWF4UG9vbC0xMFxuICBbJ01heFBvb2wnLCAnJywgJzErJywgbWF4UG9vbCwgcGFyc2VNYXhQb29sQXR0cmlidXRlc10sXG4gIFsnTXVsJywgJycsICc3KycsIGJpbmFyeU9wcy5tdWxdLFxuICBbJ05lZycsICcnLCAnNisnLCB1bmFyeU9wcy5uZWddLFxuICBbJ05vdCcsICcnLCAnMSsnLCB1bmFyeU9wcy5ub3RdLFxuICBbJ09yJywgJycsICc3KycsIGJpbmFyeU9wcy5vcl0sXG4gIFsnUGFkJywgJycsICcyLTEwJywgcGFkVjIsIHBhcnNlUGFkQXR0cmlidXRlc1YyXSxcbiAgWydQYWQnLCAnJywgJzExKycsIHBhZFYxMSwgcGFyc2VQYWRBdHRyaWJ1dGVzVjExXSxcbiAgWydQb3cnLCAnJywgJzcrJywgYmluYXJ5T3BzLnBvd10sXG4gIFsnUFJlbHUnLCAnJywgJzcrJywgYmluYXJ5T3BzLnBSZWx1XSxcbiAgWydSZWR1Y2VMb2dTdW0nLCAnJywgJzErJywgcmVkdWNlTG9nU3VtLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZU1heCcsICcnLCAnMSsnLCByZWR1Y2VNYXgsIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlTWVhbicsICcnLCAnMSsnLCByZWR1Y2VNZWFuLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZU1pbicsICcnLCAnMSsnLCByZWR1Y2VNaW4sIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlUHJvZCcsICcnLCAnMSsnLCByZWR1Y2VQcm9kLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZVN1bScsICcnLCAnMS0xMicsIHJlZHVjZVN1bSwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VTdW1TcXVhcmUnLCAnJywgJzErJywgcmVkdWNlTG9nU3VtU3F1YXJlLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlbHUnLCAnJywgJzYrJywgdW5hcnlPcHMucmVsdV0sXG4gIFsnUmVzaGFwZScsICcnLCAnNSsnLCByZXNoYXBlXSxcbiAgWydSZXNpemUnLCAnJywgJzEwJywgcmVzaXplLCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTBdLFxuICBbJ1Jlc2l6ZScsICcnLCAnMTErJywgcmVzaXplLCBwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTFdLFxuICBbJ1NoYXBlJywgJycsICcxKycsIHNoYXBlXSxcbiAgWydTaWdtb2lkJywgJycsICc2KycsIHVuYXJ5T3BzLnNpZ21vaWRdLFxuICBbJ1NpbicsICcnLCAnNysnLCB1bmFyeU9wcy5zaW5dLFxuICBbJ1NsaWNlJywgJycsICcxMCsnLCBzbGljZVYxMF0sICAvLyBUT0RPOiBzdXBwb3J0ICdzdGVwcycgZm9yIFNsaWNlLTEwXG4gIFsnU2xpY2UnLCAnJywgJzEtOScsIHNsaWNlLCBwYXJzZVNsaWNlQXR0cmlidXRlc10sXG4gIC8vIFRoZSBcInNlbWFudGljXCIgbWVhbmluZyBvZiBheGlzIGhhcyBjaGFuZ2VkIGluIG9wc2V0LTEzLlxuICBbJ1NvZnRtYXgnLCAnJywgJzEtMTInLCBzb2Z0bWF4LCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzXSxcbiAgWydTb2Z0bWF4JywgJycsICcxMysnLCBzb2Z0bWF4VjEzLCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzVjEzXSxcbiAgLy8gJ1NwbGl0JyBvcGVyYXRvciBoYXMgYW4gb3B0aW9uYWwgYXR0cmlidXRlICdzcGxpdCdcbiAgLy8gdGhpcyBhdHRyaWJ1dGUgZGV0ZXJtaW5lcyBob3cgdGhlIHNwZWNpZmllZCBheGlzIG9mIGlucHV0IGRhdGEgaXMgc3BsaXQuXG4gIC8vIFdoZW4gdGhlIGF0dHJpYnV0ZSBpcyBtaXNzaW5nLCB3ZSBuZWVkIHRoZSBjb3VudCBvZiBudW1iZXIgb2Ygb3V0cHV0c1xuICAvLyBzbyB0aGF0IHdlIGNhbiBkZXRlcm1pbmUgdGhlICdzcGxpdCcgYXR0cmlidXRlIGZyb20gdGhlIHJ1bnRpbWUgaW5wdXQgdG8gdGhlIE9wZXJhdG9yXG4gIFsnU3BsaXQnLCAnJywgJzItMTInLCBzcGxpdCwgcGFyc2VTcGxpdEF0dHJpYnV0ZXNdLFxuICBbJ1NxcnQnLCAnJywgJzYrJywgdW5hcnlPcHMuc3FydF0sXG4gIFsnU3F1ZWV6ZScsICcnLCAnMS0xMicsIHNxdWVlemUsIHBhcnNlU3F1ZWV6ZUF0dHJpYnV0ZXNdLFxuICBbJ1NxdWVlemUnLCAnJywgJzEzKycsIHNxdWVlemVWMTNdLFxuICBbJ1N1YicsICcnLCAnNysnLCBiaW5hcnlPcHMuc3ViXSxcbiAgWydTdW0nLCAnJywgJzYrJywgc3VtXSxcbiAgWydUYW4nLCAnJywgJzcrJywgdW5hcnlPcHMudGFuXSxcbiAgWydUYW5oJywgJycsICc2KycsIHVuYXJ5T3BzLnRhbmhdLFxuICBbJ1RpbGUnLCAnJywgJzYrJywgdGlsZV0sXG4gIFsnVHJhbnNwb3NlJywgJycsICcxKycsIHRyYW5zcG9zZSwgcGFyc2VUcmFuc3Bvc2VBdHRyaWJ1dGVzXSxcbiAgWydVcHNhbXBsZScsICcnLCAnNy04JywgdXBzYW1wbGUsIHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjddLFxuICBbJ1Vwc2FtcGxlJywgJycsICc5JywgdXBzYW1wbGUsIHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzVjldLFxuICBbJ1Vuc3F1ZWV6ZScsICcnLCAnMS0xMicsIHVuc3F1ZWV6ZSwgcGFyc2VVbnNxdWVlemVBdHRyaWJ1dGVzXSxcbiAgWydVbnNxdWVlemUnLCAnJywgJzEzKycsIHVuc3F1ZWV6ZVYxM10sXG4gIFsnWG9yJywgJycsICc3KycsIGJpbmFyeU9wcy54b3JdLFxuXTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuY29uc3QgSU5MSU5FX0ZVTkNfREVGX1JFR0VYID0gL0BpbmxpbmVbXFxzXFxuXFxyXSsoXFx3KylbXFxzXFxuXFxyXSsoWzAtOWEtekEtWl9dKylcXHMqXFwoKFteKV0qKVxcKVxccyp7KChbXn1dfFtcXG5cXHJdKSopfS9nbTtcbmNvbnN0IEZVTkNfQ0FMTF9SRUdFWCA9ICcoXFxcXHcrKT9cXFxccysoW18wLTlhLXpBLVpdKylcXFxccys9XFxcXHMrX19GVU5DX19cXFxcKCguKilcXFxcKVxcXFxzKjsnO1xuLyoqXG4gKiBHTFNMIHByZXByb2Nlc3NvciByZXNwb25zaWJsZSBmb3IgcmVzb2x2aW5nIEBpbmxpbmUgZGlyZWN0aXZlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZUlubGluZXMoc2NyaXB0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBpbmxpbmVEZWZzOiB7W25hbWU6IHN0cmluZ106IHtwYXJhbXM6IEFycmF5PHt0eXBlOiBzdHJpbmc7IG5hbWU6IHN0cmluZ318bnVsbD47IGJvZHk6IHN0cmluZ319ID0ge307XG4gIGxldCBtYXRjaDtcbiAgd2hpbGUgKChtYXRjaCA9IElOTElORV9GVU5DX0RFRl9SRUdFWC5leGVjKHNjcmlwdCkpICE9PSBudWxsKSB7XG4gICAgY29uc3QgcGFyYW1zID0gbWF0Y2hbM11cbiAgICAgICAgICAgICAgICAgICAgICAgLnNwbGl0KCcsJylcbiAgICAgICAgICAgICAgICAgICAgICAgLm1hcChzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0b2tlbnMgPSBzLnRyaW0oKS5zcGxpdCgnICcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0b2tlbnMgJiYgdG9rZW5zLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHt0eXBlOiB0b2tlbnNbMF0sIG5hbWU6IHRva2Vuc1sxXX07XG4gICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKHYgPT4gdiAhPT0gbnVsbCk7XG4gICAgaW5saW5lRGVmc1ttYXRjaFsyXV0gPSB7cGFyYW1zLCBib2R5OiBtYXRjaFs0XX07XG4gIH1cbiAgZm9yIChjb25zdCBuYW1lIGluIGlubGluZURlZnMpIHtcbiAgICBjb25zdCByZWdleFN0cmluZyA9IEZVTkNfQ0FMTF9SRUdFWC5yZXBsYWNlKCdfX0ZVTkNfXycsIG5hbWUpO1xuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChyZWdleFN0cmluZywgJ2dtJyk7XG4gICAgd2hpbGUgKChtYXRjaCA9IHJlZ2V4LmV4ZWMoc2NyaXB0KSkgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IHR5cGUgPSBtYXRjaFsxXTtcbiAgICAgIGNvbnN0IHZhcmlhYmxlID0gbWF0Y2hbMl07XG4gICAgICBjb25zdCBwYXJhbXMgPSBtYXRjaFszXS5zcGxpdCgnLCcpO1xuICAgICAgY29uc3QgZGVjbExpbmUgPSAodHlwZSkgPyBgJHt0eXBlfSAke3ZhcmlhYmxlfTtgIDogJyc7XG4gICAgICBsZXQgbmV3Qm9keTogc3RyaW5nID0gaW5saW5lRGVmc1tuYW1lXS5ib2R5O1xuICAgICAgbGV0IHBhcmFtUmVkZWNMaW5lID0gJyc7XG4gICAgICBpbmxpbmVEZWZzW25hbWVdLnBhcmFtcy5mb3JFYWNoKCh2LCBpKSA9PiB7XG4gICAgICAgIGlmICh2KSB7XG4gICAgICAgICAgcGFyYW1SZWRlY0xpbmUgKz0gYCR7di50eXBlfSAke3YubmFtZX0gPSAke3BhcmFtc1tpXX07XFxuYDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBuZXdCb2R5ID0gYCR7cGFyYW1SZWRlY0xpbmV9XFxuICR7bmV3Qm9keX1gO1xuICAgICAgbmV3Qm9keSA9IG5ld0JvZHkucmVwbGFjZSgncmV0dXJuJywgYCR7dmFyaWFibGV9ID0gYCk7XG4gICAgICBjb25zdCByZXBsYWNlbWVudCA9IGBcbiAgICAgICR7ZGVjbExpbmV9XG4gICAgICB7XG4gICAgICAgICR7bmV3Qm9keX1cbiAgICAgIH1cbiAgICAgIGA7XG4gICAgICBzY3JpcHQgPSBzY3JpcHQucmVwbGFjZShtYXRjaFswXSwgcmVwbGFjZW1lbnQpO1xuICAgIH1cbiAgfVxuICBzY3JpcHQgPSBzY3JpcHQucmVwbGFjZShJTkxJTkVfRlVOQ19ERUZfUkVHRVgsICcnKTtcbiAgcmV0dXJuIHNjcmlwdDtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtMb2dnZXJ9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuaW1wb3J0IHthc3NlcnR9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG4vKiogTGF5b3V0IHByZWZlcmVuY2VzICovXG5leHBvcnQgaW50ZXJmYWNlIFdpZHRoSGVpZ2h0UHJlZnMge1xuICBicmVha0F4aXM/OiBudW1iZXI7XG4gIGlzUGFja2VkPzogYm9vbGVhbjtcbiAgcmV2ZXJzZVdIPzogYm9vbGVhbjtcbn1cbi8qKlxuICogVGV4dHVyZUxheW91dFN0cmF0ZWd5IGlzIGFuIGFic3RyYWN0aW9uIGZvciBkaWZmZXJlbnQgcGxhbnNcbiAqIGZvciBtYXBwaW5nIG4tZGltZW5zaW9uYWwgYXJyYXlzIHRvIDJEIHRleHR1cmVzIChhbmQgYmFjaylcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kge1xuICBjb21wdXRlVGV4dHVyZVdIKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzKTogW251bWJlciwgbnVtYmVyXTtcbn1cblxuLyoqXG4gKiBUaGlzIHN0cmF0ZWd5IHRyeSB0byBmaW5kIHRoZSBtaW5pbWFsIG1heChXLEgpIHRoYXQgZnVsZmlsbHMgKFcgKiBIID09IHRvdGFsU2l6ZSlcbiAqL1xuZXhwb3J0IGNsYXNzIEFsd2F5c0tlZXBPcmlnaW5hbFNpemVTdHJhdGVneSBpbXBsZW1lbnRzIFRleHR1cmVMYXlvdXRTdHJhdGVneSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBtYXhUZXh0dXJlU2l6ZTogbnVtYmVyKSB7fVxuICBjb21wdXRlVGV4dHVyZVdIKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgLy8gc2NhbGFyIHRlbnNvclxuICAgIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbMSwgMV07XG4gICAgfVxuICAgIGNvbnN0IG1heFRleHR1cmVTaXplID0gdGhpcy5tYXhUZXh0dXJlU2l6ZTtcbiAgICBpZiAocHJlZnMgJiYgcHJlZnMuYnJlYWtBeGlzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIGNoZWNrIHRvIHNlZSBpZiBkaW1zIGZpdFxuICAgICAgY29uc3Qgd3NpemUgPSBwcmVmcy5icmVha0F4aXMgPj0gc2hhcGUubGVuZ3RoID8gMSA6IHNoYXBlLnNsaWNlKHByZWZzLmJyZWFrQXhpcykucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBjb25zdCBoc2l6ZSA9IHByZWZzLmJyZWFrQXhpcyA8PSAwID8gMSA6IHNoYXBlLnNsaWNlKDAsIHByZWZzLmJyZWFrQXhpcykucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBpZiAod3NpemUgPiBtYXhUZXh0dXJlU2l6ZSB8fCBoc2l6ZSA+IG1heFRleHR1cmVTaXplKSB7XG4gICAgICAgIC8vIGlnbm9yZSBwcmVmZXJlbmNlc1xuICAgICAgICAvLyBjb250aW51ZSB3aXRoIGRlZmF1bHQgbGF5b3V0XG4gICAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICAgJ1RleHR1cmVMYXlvdXQnLFxuICAgICAgICAgICAgYEdpdmVuIHdpZHRoL2hlaWdodCBwcmVmZXJlbmNlcyB3ZXJlIHVuYXR0YWluYWJsZTogc2hhcGU6JHtzaGFwZX0sIGJyZWFrQXhpczoke3ByZWZzLmJyZWFrQXhpc31gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbd3NpemUsIGhzaXplXTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgdG90YWxTaXplID0gc2hhcGUucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG5cbiAgICBsZXQgd2lkdGggPSBNYXRoLmZsb29yKE1hdGguc3FydCh0b3RhbFNpemUpKTtcblxuICAgIGZvciAoOyB3aWR0aCA8IG1heFRleHR1cmVTaXplICYmIHdpZHRoIDwgdG90YWxTaXplOyB3aWR0aCsrKSB7XG4gICAgICBpZiAodG90YWxTaXplICUgd2lkdGggPT09IDApIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdpZHRoID49IG1heFRleHR1cmVTaXplIHx8IHRvdGFsU2l6ZSAlIHdpZHRoICE9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBnaXZlbiBkaW1lbnNpb25zIGFyZSBvdXRzaWRlIHRoaXMgR1BVJ3MgYm91bmRhcmllczogJHtzaGFwZX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIFt3aWR0aCwgdG90YWxTaXplIC8gd2lkdGhdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQcmVmZXJMb2dpY2FsU3RyYXRlZ3kgaW1wbGVtZW50cyBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgbWF4VGV4dHVyZVNpemU6IG51bWJlcikge31cbiAgY29tcHV0ZVRleHR1cmVXSChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHByZWZzPzogV2lkdGhIZWlnaHRQcmVmcyk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGNvbnN0IHdoID0gdGhpcy5jb21wdXRlVGV4dHVyZShzaGFwZSwgcHJlZnMpO1xuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5pc1BhY2tlZCkge1xuICAgICAgd2hbMF0gLz0gMjtcbiAgICAgIHdoWzFdIC89IDI7XG4gICAgfVxuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5yZXZlcnNlV0gpIHtcbiAgICAgIHJldHVybiBbd2hbMV0sIHdoWzBdXTtcbiAgICB9XG4gICAgcmV0dXJuIHdoO1xuICB9XG5cbiAgY29tcHV0ZVRleHR1cmUoc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCBpc1BhY2tlZCA9IHByZWZzICYmIHByZWZzLmlzUGFja2VkO1xuICAgIC8vIHNjYWxhciB0ZW5zb3JcbiAgICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gaXNQYWNrZWQgPyBbMiwgMl0gOiBbMSwgMV07XG4gICAgfVxuICAgIGxldCBtYXhUZXh0dXJlU2l6ZSA9IHRoaXMubWF4VGV4dHVyZVNpemU7XG4gICAgaWYgKHByZWZzICYmIHByZWZzLmJyZWFrQXhpcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBjaGVjayB0byBzZWUgaWYgZGltcyBmaXRcbiAgICAgIGNvbnN0IHdzaXplID0gcHJlZnMuYnJlYWtBeGlzID49IHNoYXBlLmxlbmd0aCA/IDEgOiBzaGFwZS5zbGljZShwcmVmcy5icmVha0F4aXMpLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgY29uc3QgaHNpemUgPSBwcmVmcy5icmVha0F4aXMgPD0gMCA/IDEgOiBzaGFwZS5zbGljZSgwLCBwcmVmcy5icmVha0F4aXMpLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgaWYgKHdzaXplID4gbWF4VGV4dHVyZVNpemUgfHwgaHNpemUgPiBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgICAvLyBpZ25vcmUgcHJlZmVyZW5jZXNcbiAgICAgICAgLy8gY29udGludWUgd2l0aCBkZWZhdWx0IGxheW91dFxuICAgICAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgICAgICAgICdUZXh0dXJlTGF5b3V0JyxcbiAgICAgICAgICAgIGBHaXZlbiB3aWR0aC9oZWlnaHQgcHJlZmVyZW5jZXMgd2VyZSB1bmF0dGFpbmFibGU6IHNoYXBlOiR7c2hhcGV9LCBicmVha0F4aXM6JHtwcmVmcy5icmVha0F4aXN9YCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gW3dzaXplLCBoc2l6ZV07XG4gICAgICB9XG4gICAgfVxuICAgIGxldCBsb2dTaGFwZSA9IHNoYXBlLnNsaWNlKDApO1xuICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgbWF4VGV4dHVyZVNpemUgPSBtYXhUZXh0dXJlU2l6ZSAqIDI7XG5cbiAgICAgIC8vIFRoaXMgbG9naWMgZW5zdXJlcyB3ZSBhY2N1cmF0ZWx5IGNvdW50IHRoZSBudW1iZXIgb2YgcGFja2VkIHRleGVscyBuZWVkZWRcbiAgICAgIC8vIHRvIGFjY29tbW9kYXRlIHRoZSB0ZW5zb3IuIFdlIGNhbiBvbmx5IHBhY2sgdmFsdWVzIGluIHRoZSBzYW1lIHRleGVsIGlmXG4gICAgICAvLyB0aGV5IGFyZSBmcm9tIGFkamFjZW50IHBhaXJzIG9mIHJvd3MvY29scyB3aXRoaW4gdGhlIHNhbWUgYmF0Y2guIFNvIGlmIGFcbiAgICAgIC8vIHRlbnNvciBoYXMgMyByb3dzLCB3ZSBwcmV0ZW5kIGl0IGhhcyA0IHJvd3MgaW4gb3JkZXIgdG8gYWNjb3VudCBmb3IgdGhlXG4gICAgICAvLyBmYWN0IHRoYXQgdGhlIHRleGVscyBjb250YWluaW5nIHRoZSB0aGlyZCByb3cgYXJlIGhhbGYgZW1wdHkuXG4gICAgICBsb2dTaGFwZSA9IGxvZ1NoYXBlLm1hcChcbiAgICAgICAgICAoX2QsIGkpID0+IGkgPj0gbG9nU2hhcGUubGVuZ3RoIC0gMiA/IChsb2dTaGFwZVtpXSAlIDIgPT09IDAgPyBsb2dTaGFwZVtpXSA6IGxvZ1NoYXBlW2ldICsgMSkgOiBsb2dTaGFwZVtpXSk7XG5cbiAgICAgIC8vIFBhY2tlZCB0ZXh0dXJlIGhlaWdodCBpcyBhdCBsZWFzdCAyICh0aGUgY2hhbm5lbCBoZWlnaHQgb2YgYSBzaW5nbGVcbiAgICAgIC8vIHRleGVsKS5cbiAgICAgIGlmIChsb2dTaGFwZS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgbG9nU2hhcGUgPSBbMiwgbG9nU2hhcGVbMF1dO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIGxvZ2ljYWwgc2hhcGUgaXMgMiwgd2UgZG9uJ3Qgc3F1ZWV6ZSwgc2luY2Ugd2Ugd2FudCB0byBtYXRjaCBwaHlzaWNhbC5cbiAgICBpZiAobG9nU2hhcGUubGVuZ3RoICE9PSAyKSB7XG4gICAgICBjb25zdCBzcXVlZXplUmVzdWx0ID0gc3F1ZWV6ZVNoYXBlKGxvZ1NoYXBlKTtcbiAgICAgIGxvZ1NoYXBlID0gc3F1ZWV6ZVJlc3VsdC5uZXdTaGFwZTtcbiAgICB9XG5cbiAgICBjb25zdCBzaXplID0gc2l6ZUZyb21TaGFwZShsb2dTaGFwZSk7XG4gICAgaWYgKGxvZ1NoYXBlLmxlbmd0aCA8PSAxICYmIHNpemUgPD0gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgIHJldHVybiBbMSwgc2l6ZV07XG4gICAgfSBlbHNlIGlmIChsb2dTaGFwZS5sZW5ndGggPT09IDIgJiYgbG9nU2hhcGVbMF0gPD0gbWF4VGV4dHVyZVNpemUgJiYgbG9nU2hhcGVbMV0gPD0gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgIHJldHVybiBsb2dTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdO1xuICAgIH0gZWxzZSBpZiAobG9nU2hhcGUubGVuZ3RoID09PSAzICYmIGxvZ1NoYXBlWzBdICogbG9nU2hhcGVbMV0gPD0gbWF4VGV4dHVyZVNpemUgJiYgbG9nU2hhcGVbMl0gPD0gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgIHJldHVybiBbbG9nU2hhcGVbMF0gKiBsb2dTaGFwZVsxXSwgbG9nU2hhcGVbMl1dO1xuICAgIH0gZWxzZSBpZiAobG9nU2hhcGUubGVuZ3RoID09PSAzICYmIGxvZ1NoYXBlWzBdIDw9IG1heFRleHR1cmVTaXplICYmIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0gPD0gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgIHJldHVybiBbbG9nU2hhcGVbMF0sIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl1dO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGxvZ1NoYXBlLmxlbmd0aCA9PT0gNCAmJiBsb2dTaGFwZVswXSAqIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0gPD0gbWF4VGV4dHVyZVNpemUgJiZcbiAgICAgICAgbG9nU2hhcGVbM10gPD0gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgIHJldHVybiBbbG9nU2hhcGVbMF0gKiBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdLCBsb2dTaGFwZVszXV07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgICAgbG9nU2hhcGUubGVuZ3RoID09PSA0ICYmIGxvZ1NoYXBlWzBdIDw9IG1heFRleHR1cmVTaXplICYmXG4gICAgICAgIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0gKiBsb2dTaGFwZVszXSA8PSBtYXhUZXh0dXJlU2l6ZSkge1xuICAgICAgcmV0dXJuIFtsb2dTaGFwZVswXSwgbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXSAqIGxvZ1NoYXBlWzNdXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICAgIC8vIEZvciBwYWNrZWQgdGV4dHVyZXMgc2l6ZSBlcXVhbHMgdGhlIG51bWJlciBvZiBjaGFubmVscyByZXF1aXJlZCB0b1xuICAgICAgICAvLyBhY2NvbW1vZGF0ZSB0aGUgdGV4dHVyZSBkYXRhLiBIb3dldmVyIGluIG9yZGVyIHRvIHNxdWFyaWZ5IHN1Y2ggdGhhdFxuICAgICAgICAvLyBpbm5lciBkaW1lbnNpb25zIHN0YXkgZXZlbiwgd2UgcmV3cml0ZSBzaXplIHRvIGVxdWFsIHRoZSBudW1iZXIgb2ZcbiAgICAgICAgLy8gdGV4ZWxzLiBUaGVuIGluIHRoZSByZXR1cm4gc3RhdGVtZW50IHdlIHJlaHlkcmF0ZSB0aGUgc3F1YXJpZmllZFxuICAgICAgICAvLyBkaW1lbnNpb25zIHRvIGNoYW5uZWwgdW5pdHMuXG4gICAgICAgIHJldHVybiBzaXplVG9TcXVhcmlzaFNoYXBlKHNpemUgLyA0KS5tYXAoZCA9PiBkICogMikgYXMgW251bWJlciwgbnVtYmVyXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzaXplVG9TcXVhcmlzaFNoYXBlKHNpemUpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc3F1ZWV6ZVNoYXBlKHNoYXBlOiBudW1iZXJbXSwgYXhpcz86IG51bWJlcltdKToge25ld1NoYXBlOiBudW1iZXJbXTsga2VwdERpbXM6IG51bWJlcltdfSB7XG4gIGNvbnN0IG5ld1NoYXBlOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBrZXB0RGltczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaXNFbXB0eUFycmF5ID0gYXhpcyAhPSBudWxsICYmIEFycmF5LmlzQXJyYXkoYXhpcykgJiYgYXhpcy5sZW5ndGggPT09IDA7XG4gIGNvbnN0IGF4ZXMgPSAoYXhpcyA9PSBudWxsIHx8IGlzRW1wdHlBcnJheSkgPyBudWxsIDogcGFyc2VBeGlzUGFyYW0oYXhpcywgc2hhcGUpLnNvcnQoKTtcbiAgbGV0IGogPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNoYXBlLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGF4ZXMgIT0gbnVsbCkge1xuICAgICAgaWYgKGF4ZXNbal0gPT09IGkgJiYgc2hhcGVbaV0gIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCBzcXVlZXplIGF4aXMgJHtpfSBzaW5jZSBpdHMgZGltICcke3NoYXBlW2ldfScgaXMgbm90IDFgKTtcbiAgICAgIH1cbiAgICAgIGlmICgoYXhlc1tqXSA9PSBudWxsIHx8IGF4ZXNbal0gPiBpKSAmJiBzaGFwZVtpXSA9PT0gMSkge1xuICAgICAgICBuZXdTaGFwZS5wdXNoKHNoYXBlW2ldKTtcbiAgICAgICAga2VwdERpbXMucHVzaChpKTtcbiAgICAgIH1cbiAgICAgIGlmIChheGVzW2pdIDw9IGkpIHtcbiAgICAgICAgaisrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2hhcGVbaV0gIT09IDEpIHtcbiAgICAgIG5ld1NoYXBlLnB1c2goc2hhcGVbaV0pO1xuICAgICAga2VwdERpbXMucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHtuZXdTaGFwZSwga2VwdERpbXN9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VBeGlzUGFyYW0oYXhpczogbnVtYmVyfG51bWJlcltdLCBzaGFwZTogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgLy8gTm9ybWFsaXplIGlucHV0XG4gIGF4aXMgPSBheGlzID09IG51bGwgPyBzaGFwZS5tYXAoKF9zLCBpKSA9PiBpKSA6IChbXSBhcyBudW1iZXJbXSkuY29uY2F0KGF4aXMpO1xuXG4gIC8vIENoZWNrIGZvciB2YWxpZCByYW5nZVxuICBhc3NlcnQoXG4gICAgICBheGlzLmV2ZXJ5KGF4ID0+IGF4ID49IC1yYW5rICYmIGF4IDwgcmFuayksXG4gICAgICAoKSA9PiBgQWxsIHZhbHVlcyBpbiBheGlzIHBhcmFtIG11c3QgYmUgaW4gcmFuZ2UgWy0ke3Jhbmt9LCAke3Jhbmt9KSBidXQgYCArXG4gICAgICAgICAgYGdvdCBheGlzICR7YXhpc31gKTtcblxuICAvLyBDaGVjayBmb3Igb25seSBpbnRlZ2Vyc1xuICBhc3NlcnQoXG4gICAgICBheGlzLmV2ZXJ5KGlzSW50KSxcbiAgICAgICgpID0+ICdBbGwgdmFsdWVzIGluIGF4aXMgcGFyYW0gbXVzdCBiZSBpbnRlZ2VycyBidXQgJyArXG4gICAgICAgICAgYGdvdCBheGlzICR7YXhpc31gKTtcblxuICAvLyBIYW5kbGUgbmVnYXRpdmUgYXhpcy5cbiAgcmV0dXJuIGF4aXMubWFwKGEgPT4gYSA8IDAgPyByYW5rICsgYSA6IGEpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGlzSW50KGE6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gYSAlIDEgPT09IDA7XG59XG5leHBvcnQgZnVuY3Rpb24gc2l6ZUZyb21TaGFwZShzaGFwZTogbnVtYmVyW10pOiBudW1iZXIge1xuICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gU2NhbGFyLlxuICAgIHJldHVybiAxO1xuICB9XG4gIGxldCBzaXplID0gc2hhcGVbMF07XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgc2hhcGUubGVuZ3RoOyBpKyspIHtcbiAgICBzaXplICo9IHNoYXBlW2ldO1xuICB9XG4gIHJldHVybiBzaXplO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvd3NDb2xzKHNoYXBlOiBudW1iZXJbXSk6IFtudW1iZXIsIG51bWJlcl0ge1xuICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Nhbm5vdCBnZXQgcm93cyBhbmQgY29sdW1ucyBvZiBhbiBlbXB0eSBzaGFwZSBhcnJheS4nKTtcbiAgfVxuXG4gIHJldHVybiBbc2hhcGUubGVuZ3RoID4gMSA/IHNoYXBlW3NoYXBlLmxlbmd0aCAtIDJdIDogMSwgc2hhcGVbc2hhcGUubGVuZ3RoIC0gMV1dO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNpemVUb1NxdWFyaXNoU2hhcGUoc2l6ZTogbnVtYmVyKTogW251bWJlciwgbnVtYmVyXSB7XG4gIGNvbnN0IHdpZHRoID0gTWF0aC5jZWlsKE1hdGguc3FydChzaXplKSk7XG4gIHJldHVybiBbd2lkdGgsIE1hdGguY2VpbChzaXplIC8gd2lkdGgpXTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRCYXRjaERpbShzaGFwZTogbnVtYmVyW10sIGRpbXNUb1NraXAgPSAyKTogbnVtYmVyIHtcbiAgcmV0dXJuIHNpemVGcm9tU2hhcGUoc2hhcGUuc2xpY2UoMCwgc2hhcGUubGVuZ3RoIC0gZGltc1RvU2tpcCkpO1xufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0FycmF5VXRpbCwgQnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsfSBmcm9tICcuLi8uLi91dGlsJztcblxuaW1wb3J0IHtHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmV9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQge2dldEdsc2x9IGZyb20gJy4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtzcXVlZXplU2hhcGV9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHtUZXh0dXJlTGF5b3V0fSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7Z2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lLCBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWVBdE91dENvb3JkcywgZ2V0Q29vcmRzRGF0YVR5cGUsIGdldEdsQ2hhbm5lbHMsIGdldFNxdWVlemVkUGFyYW1zLCBzcXVlZXplSW5wdXRTaGFwZX0gZnJvbSAnLi91dGlscyc7XG5cbi8qKlxuICogR0xTTCBMaWJyYXJ5IHJlc3BvbnNpYmxlIGZvciBkYXRhIHR5cGVzIGFuZCByb3V0aW5lcyBmb3IgbWFuaXB1bGF0aW5nXG4gKiBjb29yZGluYXRlcyBhbmQgbWFwcGluZyB0by9mcm9tIHRlbnNvciBpbmRpY2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBDb29yZHNHbHNsTGliIGV4dGVuZHMgR2xzbExpYiB7XG4gIHJldHVyblR5cGU6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBHbHNsQ29udGV4dCkge1xuICAgIHN1cGVyKGNvbnRleHQpO1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMub2Zmc2V0VG9Db29yZHMoKSxcbiAgICAgIC4uLnRoaXMuY29vcmRzVG9PZmZzZXQoKSxcbiAgICAgIC4uLnRoaXMudG9WZWMoKSxcbiAgICAgIC4uLnRoaXMudmFsdWVGcm9tKCksXG4gICAgICAvLyBUT0RPIHJldHVybiB0aGVzZSBvbmx5IHdoZW4gcGFja2luZyBpcyBlbmFibGVkLlxuICAgICAgLi4udGhpcy5nZXRDb21tb25VdGlsRnVuY3MoKSxcbiAgICAgIC4uLnRoaXMuZ2V0SW5wdXRzU2FtcGxpbmdTbmlwcGV0cygpLFxuICAgICAgLi4udGhpcy5nZXRPdXRwdXRTYW1wbGluZ1NuaXBwZXQoKVxuICAgIH07XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIGZ1bmN0aW9uIHRoYXQgY2FuIG1hcCBmcm9tXG4gICAqIDJEIG5vcm1hbHppZWQgY29vcmRpbmF0ZXMgKHMsdCkgdG8gYSBmbGF0IG9mZnNldFxuICAgKi9cbiAgcHJvdGVjdGVkIG9mZnNldFRvQ29vcmRzKCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCBmdW5jTmFtZSA9ICdvZmZzZXRUb0Nvb3Jkcyc7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9mZnNldFRvQ29vcmRzOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgdmVjMiAke2Z1bmNOYW1lfShpbnQgb2Zmc2V0LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHtcbiAgICAgICAgaW50IHQgPSBvZmZzZXQgLyB3aWR0aDtcbiAgICAgICAgaW50IHMgPSBvZmZzZXQgLSB0KndpZHRoO1xuICAgICAgICB2ZWMyIGNvb3JkcyA9ICh2ZWMyKHMsdCkgKyB2ZWMyKDAuNSwwLjUpKSAvIHZlYzIod2lkdGgsIGhlaWdodCk7XG4gICAgICAgIHJldHVybiBjb29yZHM7XG4gICAgICB9XG4gICAgICBgKVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUHJvZHVjZXMgYSBmdW5jdGlvbiB0aGF0IGNhbiBtYXAgZnJvbVxuICAgKiAyRCBub3JtYWx6aWVkIGNvb3JkaW5hdGVzIChzLHQpIHRvIGEgZmxhdCBvZmZzZXRcbiAgICovXG4gIHByb3RlY3RlZCBjb29yZHNUb09mZnNldCgpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3QgZnVuY05hbWUgPSAnY29vcmRzVG9PZmZzZXQnO1xuICAgIHJldHVybiB7XG4gICAgICBjb29yZHNUb09mZnNldDogbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIGludCAke2Z1bmNOYW1lfSh2ZWMyIGNvb3JkcywgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7XG4gICAgICAgIGZsb2F0IHMgPSBjb29yZHMucyAqIGZsb2F0KHdpZHRoKTtcbiAgICAgICAgZmxvYXQgdCA9IGNvb3Jkcy50ICogZmxvYXQoaGVpZ2h0KTtcbiAgICAgICAgaW50IG9mZnNldCA9IGludCh0KSAqIHdpZHRoICsgaW50KHMpO1xuICAgICAgICByZXR1cm4gb2Zmc2V0O1xuICAgICAgfVxuICAgICAgYClcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBjb2RlIGZvciBvdXRwdXQgc2FtcGxlci5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldE91dHB1dFNhbXBsaW5nU25pcHBldCgpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgaWYgKG91dHB1dExheW91dC5pc1BhY2tlZCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBjb2RlIGZvciBwYWNrZWQgb3V0cHV0IHNhbXBsZXIuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCBvdXRTaGFwZSA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IG91dFRleFNoYXBlID0gW291dHB1dExheW91dC53aWR0aCwgb3V0cHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgcmVzdWx0OiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSA9IHt9O1xuICAgIGNvbnN0IGZ1bmNOYW1lID0gJ2dldE91dHB1dENvb3Jkcyc7XG4gICAgc3dpdGNoIChvdXRTaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0U2NhbGFyQ29vcmRzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWQxRENvb3JkcyhvdXRTaGFwZSBhcyBbbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWQyRENvb3JkcyhvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPVxuICAgICAgICAgICAgdGhpcy5nZXRPdXRwdXRQYWNrZWQzRENvb3JkcyhvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFBhY2tlZE5EQ29vcmRzKG91dFNoYXBlLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICB9XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAvLyBUT0RPIHdlIG5lZWQgdGhpcyB0byBwcm9wZXJseSByZXR1cm4gYSBwYWNrZWQgdmVjNCBmcm9tIGtlcm5lbHMuXG4gICAgLy8gUmVwbGFjZSBhbGwgJ3tnbHNsLm91dHB1dH0gPSByZXN1bHQnIHdpdGggJ3NldE91dHB1dChyZXN1bHQpJyBpbiBhbGwga2VybmVscy5cbiAgICBjb25zdCBmbG9hdFRleHR1cmVTZXRSR0JBU291cmNlID0gYFxuICAgICAgdm9pZCBzZXRPdXRwdXQodmVjNCB2YWwpIHtcbiAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2YWw7XG4gICAgICB9XG4gICAgYDtcbiAgICBjb25zdCBmbG9hdFRleHR1cmVTZXRSR0JBRnVuY05hbWUgPSAnZmxvYXRUZXh0dXJlU2V0UkdCQSc7XG4gICAgcmVzdWx0W2Zsb2F0VGV4dHVyZVNldFJHQkFGdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoZmxvYXRUZXh0dXJlU2V0UkdCQVNvdXJjZSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgY29kZSBmb3IgdW5wYWNrZWQgb3V0cHV0IHNhbXBsZXIuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRPdXRwdXRTYW1wbGluZ1NuaXBwZXQob3V0cHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgb3V0VGV4U2hhcGUgPSBbb3V0cHV0TGF5b3V0LndpZHRoLCBvdXRwdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCByZXN1bHQ6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9ID0ge307XG4gICAgY29uc3QgZnVuY05hbWUgPSAnZ2V0T3V0cHV0Q29vcmRzJztcbiAgICBzd2l0Y2ggKG91dFNoYXBlLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRTY2FsYXJDb29yZHMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkMURDb29yZHMob3V0U2hhcGUgYXMgW251bWJlcl0sIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9XG4gICAgICAgICAgICB0aGlzLmdldE91dHB1dFVucGFja2VkMkRDb29yZHMob3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID1cbiAgICAgICAgICAgIHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQzRENvb3JkcyhvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNDpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0VW5wYWNrZWQ0RENvb3JkcyhcbiAgICAgICAgICAgIG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDU6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkNURDb29yZHMoXG4gICAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDY6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkNkRDb29yZHMoXG4gICAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgb3V0cHV0IGRpbWVuc2lvbmFsaXR5OiAke291dFNoYXBlLmxlbmd0aH1gKTtcbiAgICB9XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAvLyBUT0RPIHdlIG5lZWQgdGhpcyB0byBwcm9wZXJseSByZXR1cm4gYSBwYWNrZWQgdmVjNCBmcm9tIGtlcm5lbHMuXG4gICAgLy8gUmVwbGFjZSBhbGwgJ3tnbHNsLm91dHB1dH0gPSByZXN1bHQnIHdpdGggJ3NldE91dHB1dChyZXN1bHQpJyBpbiBhbGwga2VybmVscy5cbiAgICBjb25zdCBmbG9hdFRleHR1cmVTZXRSU291cmNlID0gYFxuICAgICAgICB2b2lkIHNldE91dHB1dChmbG9hdCB2YWwpIHtcbiAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQodmFsLCAwLCAwLCAwKTtcbiAgICAgICAgfVxuICAgIGA7XG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UkZ1bmNOYW1lID0gJ2Zsb2F0VGV4dHVyZVNldFInO1xuICAgIHJlc3VsdFtmbG9hdFRleHR1cmVTZXRSRnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGZsb2F0VGV4dHVyZVNldFJTb3VyY2UpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogU2NhbGFyIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRTY2FsYXJDb29yZHMoKTogR2xzbExpYlJvdXRpbmUge1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgYCk7XG4gIH1cblxuICAvKipcbiAgICogMUQgcGFja2VkIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRQYWNrZWQxRENvb3Jkcyhfc2hhcGU6IFtudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IHRleFNoYXBlO1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBpZiAocGFja2VkVGV4U2hhcGVbMF0gPT09IDEpIHtcbiAgICAgIHNvdXJjZSA9IGBcbiAgICAgICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIDIgKiBpbnQoVGV4Q29vcmRzLnkgKiAke3BhY2tlZFRleFNoYXBlWzFdfS4wKTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gICAgfVxuXG4gICAgaWYgKHBhY2tlZFRleFNoYXBlWzFdID09PSAxKSB7XG4gICAgICBzb3VyY2UgPSBgXG4gICAgICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICAgIHJldHVybiAyICogaW50KFRleENvb3Jkcy54ICogJHtwYWNrZWRUZXhTaGFwZVswXX0uMCk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICAgIH1cblxuICAgIHNvdXJjZSA9IGBcbiAgICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIHJldHVybiAyICogKHJlc1RleFJDLnkgKiAke3BhY2tlZFRleFNoYXBlWzBdfSArIHJlc1RleFJDLngpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAyRCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZDJEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgaWYgKEFycmF5VXRpbC5hcnJheXNFcXVhbChzaGFwZSwgdGV4U2hhcGUpKSB7XG4gICAgICBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICByZXR1cm4gMiAqIGl2ZWMyKFRleENvb3Jkcy54eSAqIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gICAgfVxuXG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSB0ZXhTaGFwZTtcbiAgICAvLyB0ZXhlbHMgbmVlZGVkIHRvIGFjY29tbW9kYXRlIGEgbG9naWNhbCByb3dcbiAgICBjb25zdCB0ZXhlbHNJbkxvZ2ljYWxSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMV0gLyAyKTtcblxuICAgIC8qKlxuICAgICAqIGdldE91dHB1dENvb3Jkc1xuICAgICAqXG4gICAgICogcmVzVGV4UkM6IFRoZSByb3dzIGFuZCBjb2x1bW5zIG9mIHRoZSB0ZXhlbHMuIElmIHlvdSBtb3ZlIG92ZXIgb25lXG4gICAgICogdGV4ZWwgdG8gdGhlIHJpZ2h0IGluIHRoZSBwYWNrZWQgdGV4dHVyZSwgeW91IGFyZSBtb3Zpbmcgb3ZlciBvbmUgY29sdW1uXG4gICAgICogKG5vdCB0d28pLlxuICAgICAqXG4gICAgICogaW5kZXg6IFRoZSB0ZXhlbCBpbmRleFxuICAgICAqL1xuICAgIHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0pKTtcblxuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3BhY2tlZFRleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG5cbiAgICAgICAgICAvLyByZXZlcnNlIHIgYW5kIGMgb3JkZXIgZm9yIHBhY2tlZCB0ZXh0dXJlXG4gICAgICAgICAgaW50IHIgPSBpbW9kKGluZGV4LCAke3RleGVsc0luTG9naWNhbFJvd30pICogMjtcbiAgICAgICAgICBpbnQgYyA9IDIgKiAoaW5kZXggLyAke3RleGVsc0luTG9naWNhbFJvd30pO1xuXG4gICAgICAgICAgcmV0dXJuIGl2ZWMyKHIsIGMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAzRCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZDNEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG4gICAgY29uc3QgdGV4ZWxzSW5Mb2dpY2FsUm93ID0gTWF0aC5jZWlsKHNoYXBlWzJdIC8gMik7XG4gICAgY29uc3QgdGV4ZWxzSW5CYXRjaCA9IHRleGVsc0luTG9naWNhbFJvdyAqIE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzMgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHtwYWNrZWRUZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuXG4gICAgICAgICAgaW50IGIgPSBpbmRleCAvICR7dGV4ZWxzSW5CYXRjaH07XG4gICAgICAgICAgaW5kZXggLT0gYiAqICR7dGV4ZWxzSW5CYXRjaH07XG5cbiAgICAgICAgICAvLyByZXZlcnNlIHIgYW5kIGMgb3JkZXIgZm9yIHBhY2tlZCB0ZXh0dXJlXG4gICAgICAgICAgaW50IHIgPSBpbW9kKGluZGV4LCAke3RleGVsc0luTG9naWNhbFJvd30pICogMjtcbiAgICAgICAgICBpbnQgYyA9IDIgKiAoaW5kZXggLyAke3RleGVsc0luTG9naWNhbFJvd30pO1xuXG4gICAgICAgICAgcmV0dXJuIGl2ZWMzKGIsIHIsIGMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBORCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZE5EQ29vcmRzKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSBbdGV4U2hhcGVbMF0sIHRleFNoYXBlWzFdXTtcblxuICAgIGNvbnN0IHRleGVsc0luTG9naWNhbFJvdyA9IE1hdGguY2VpbChzaGFwZVtzaGFwZS5sZW5ndGggLSAxXSAvIDIpO1xuICAgIGNvbnN0IHRleGVsc0luQmF0Y2ggPSB0ZXhlbHNJbkxvZ2ljYWxSb3cgKiBNYXRoLmNlaWwoc2hhcGVbc2hhcGUubGVuZ3RoIC0gMl0gLyAyKTtcbiAgICBsZXQgdGV4ZWxzSW5CYXRjaE4gPSB0ZXhlbHNJbkJhdGNoO1xuICAgIGxldCBiYXRjaGVzID0gJyc7XG4gICAgbGV0IGNvb3JkcyA9ICdiLCByLCBjJztcblxuICAgIGZvciAobGV0IGIgPSAyOyBiIDwgc2hhcGUubGVuZ3RoIC0gMTsgYisrKSB7XG4gICAgICB0ZXhlbHNJbkJhdGNoTiAqPSBzaGFwZVtzaGFwZS5sZW5ndGggLSBiIC0gMV07XG4gICAgICBiYXRjaGVzID0gYFxuICAgICAgaW50IGIke2J9ID0gaW5kZXggLyAke3RleGVsc0luQmF0Y2hOfTtcbiAgICAgIGluZGV4IC09IGIke2J9ICogJHt0ZXhlbHNJbkJhdGNoTn07XG4gICAgYCArIGJhdGNoZXM7XG4gICAgICBjb29yZHMgPSBgYiR7Yn0sIGAgKyBjb29yZHM7XG4gICAgfVxuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgIGl2ZWMke3NoYXBlLmxlbmd0aH0gZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSkpO1xuICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHtwYWNrZWRUZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuXG4gICAgICAgICR7YmF0Y2hlc31cblxuICAgICAgICBpbnQgYiA9IGluZGV4IC8gJHt0ZXhlbHNJbkJhdGNofTtcbiAgICAgICAgaW5kZXggLT0gYiAqICR7dGV4ZWxzSW5CYXRjaH07XG5cbiAgICAgICAgLy8gcmV2ZXJzZSByIGFuZCBjIG9yZGVyIGZvciBwYWNrZWQgdGV4dHVyZVxuICAgICAgICBpbnQgciA9IGltb2QoaW5kZXgsICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSkgKiAyO1xuICAgICAgICBpbnQgYyA9IDIgKiAoaW5kZXggLyAke3RleGVsc0luTG9naWNhbFJvd30pO1xuXG4gICAgICAgIHJldHVybiBpdmVjJHtzaGFwZS5sZW5ndGh9KCR7Y29vcmRzfSk7XG4gICAgICB9XG4gICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMUQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkMURDb29yZHMoX3NoYXBlOiBbbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICByZXR1cm4gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMkQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkMkRDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgIGludCByID0gaW5kZXggLyAke3NoYXBlWzFdfTtcbiAgICAgICAgICBpbnQgYyA9IGluZGV4IC0gciAqICR7c2hhcGVbMV19O1xuICAgICAgICAgIHJldHVybiBpdmVjMihyLCBjKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgM0Qgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkM0RDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICBsZXQgc3RyaWRlcyA9IG51bGw7XG4gICAgaWYgKHJhbmsgPCAyKSB7XG4gICAgICBzdHJpZGVzID0gW107XG4gICAgfVxuXG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rIC0gMSk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBzaGFwZVtyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogc2hhcGVbaSArIDFdO1xuICAgIH1cbiAgICBjb25zdCBjb29yZHNUb0NvbXB1dGUgPSBbJ3InLCAnYycsICdkJ107XG4gICAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9XG4gICAgICAgIHN0cmlkZXNcbiAgICAgICAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaV19ID0gaW5kZXggLyAke3N0cmlkZX1gO1xuICAgICAgICAgICAgICBjb25zdCBsaW5lMiA9IGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMSA/XG4gICAgICAgICAgICAgICAgICBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWAgOlxuICAgICAgICAgICAgICAgICAgYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICAgICBpdmVjMyBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiBpdmVjMyhyLCBjLCBkKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNEQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkNERDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6XG4gICAgICBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICBsZXQgc3RyaWRlcyA9IG51bGw7XG4gICAgaWYgKHJhbmsgPCAyKSB7XG4gICAgICBzdHJpZGVzID0gW107XG4gICAgfVxuXG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rIC0gMSk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBzaGFwZVtyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogc2hhcGVbaSArIDFdO1xuICAgIH1cbiAgICBjb25zdCBjb29yZHNUb0NvbXB1dGUgPSBbJ3InLCAnYycsICdkJywgJ2QyJ107XG4gICAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9XG4gICAgICAgIHN0cmlkZXNcbiAgICAgICAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaV19ID0gaW5kZXggLyAke3N0cmlkZX1gO1xuICAgICAgICAgICAgICBjb25zdCBsaW5lMiA9IGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMSA/XG4gICAgICAgICAgICAgICAgICBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWAgOlxuICAgICAgICAgICAgICAgICAgYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICAgaXZlYzQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgICByZXR1cm4gaXZlYzQociwgYywgZCwgZDIpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA1RCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQ1RENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOlxuICAgICAgR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgbGV0IHN0cmlkZXMgPSBudWxsO1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgc3RyaWRlcyA9IFtdO1xuICAgIH1cblxuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayAtIDEpO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gc2hhcGVbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIHNoYXBlW2kgKyAxXTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzVG9Db21wdXRlID0gWydyJywgJ2MnLCAnZCcsICdkMicsICdkMyddO1xuICAgIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPVxuICAgICAgICBzdHJpZGVzXG4gICAgICAgICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2ldfSA9IGluZGV4IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgICAgICAgY29uc3QgbGluZTIgPSBpID09PSBzdHJpZGVzLmxlbmd0aCAtIDEgP1xuICAgICAgICAgICAgICAgICAgYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpICsgMV19ID0gaW5kZXggLSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gIDpcbiAgICAgICAgICAgICAgICAgIGBpbmRleCAtPSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gO1xuICAgICAgICAgICAgICByZXR1cm4gYCR7bGluZTF9OyAke2xpbmUyfTtgO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5qb2luKCcnKTtcblxuICAgIHNvdXJjZSA9IGBcbiAgICAgIGl2ZWM1IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgICAke2Nvb3Jkc0Zyb21JbmRleFNuaXBwZXR9XG4gICAgICAgICAgcmV0dXJuIGl2ZWM1KHIsIGMsIGQsIGQyLCBkMyk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDZEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDZEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbXG4gICAgbnVtYmVyLCBudW1iZXJcbiAgXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAgIGxldCBzdHJpZGVzID0gbnVsbDtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHN0cmlkZXMgPSBbXTtcbiAgICB9XG5cbiAgICBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmsgLSAxKTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IHNoYXBlW3JhbmsgLSAxXTtcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDM7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBzdHJpZGVzW2ldID0gc3RyaWRlc1tpICsgMV0gKiBzaGFwZVtpICsgMV07XG4gICAgfVxuICAgIGNvbnN0IGNvb3Jkc1RvQ29tcHV0ZSA9IFsncicsICdjJywgJ2QnLCAnZDInLCAnZDMnLCAnZDQnXTtcbiAgICBjb25zdCBjb29yZHNGcm9tSW5kZXhTbmlwcGV0ID1cbiAgICAgICAgc3RyaWRlc1xuICAgICAgICAgICAgLm1hcCgoc3RyaWRlLCBpKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gPSBpbmRleCAvICR7c3RyaWRlfWA7XG4gICAgICAgICAgICAgIGNvbnN0IGxpbmUyID0gaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxID9cbiAgICAgICAgICAgICAgICAgIGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaSArIDFdfSA9IGluZGV4IC0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YCA6XG4gICAgICAgICAgICAgICAgICBgaW5kZXggLT0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuam9pbignJyk7XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgIGl2ZWM2IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgIHJldHVybiBpdmVjNihyLCBjLCBkLCBkMiwgZDMsIGQ0KTtcbiAgICAgICB9XG4gICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBjb2RlIGZvciBjb21tb24gVVYgY29vcmRzIGNvbXB1dGF0aW9uIHV0aWxpdHkgZnVuY3Rpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldENvbW1vblV0aWxGdW5jcygpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSA9IHt9O1xuICAgIGxldCBmdW5jTmFtZSA9ICd1dkZyb21GbGF0JztcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICB2ZWMyIHV2RnJvbUZsYXQoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLCBpbnQgaW5kZXgpIHtcbiAgICAgIGludCB0ZXhDID0gaW5kZXggLyB0ZXhOdW1SO1xuICAgICAgaW50IHRleFIgPSBpbmRleCAtIHRleEMgKiB0ZXhOdW1SO1xuICAgICAgLy8gVE9ETzogc3dhcCB0ZXhSLCB0ZXhDIG9yZGVyIGluIGZvbGxvd2luZyBmdW5jdGlvbiBzbyByb3cgaXMgY29ycmVzcG9uZGluZyB0byB1IGFuZCBjb2x1bW4gaXMgY29ycmVzcG9uZGluZyB0b1xuICAgICAgLy8gICAgICAgdi5cbiAgICAgIHJldHVybiAodmVjMih0ZXhSLCB0ZXhDKSArIGhhbGZDUikgLyB2ZWMyKHRleE51bVIsIHRleE51bUMpO1xuICAgIH1cbiAgICBgKTtcbiAgICBmdW5jTmFtZSA9ICdwYWNrZWRVVmZyb20xRCc7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICB2ZWMyIHBhY2tlZFVWZnJvbTFEKGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQywgaW50IGluZGV4KSB7XG4gICAgICAgIGludCB0ZXhlbEluZGV4ID0gaW5kZXggLyAyO1xuICAgICAgICBpbnQgdGV4UiA9IHRleGVsSW5kZXggLyB0ZXhOdW1DO1xuICAgICAgICBpbnQgdGV4QyA9IHRleGVsSW5kZXggLSB0ZXhSICogdGV4TnVtQztcbiAgICAgICAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7XG4gICAgICB9XG4gICAgICBgKTtcbiAgICBmdW5jTmFtZSA9ICdwYWNrZWRVVmZyb20yRCc7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICB2ZWMyIHBhY2tlZFVWZnJvbTJEKGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQywgaW50IHRleGVsc0luTG9naWNhbFJvdywgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICBpbnQgdGV4ZWxJbmRleCA9IChyb3cgLyAyKSAqIHRleGVsc0luTG9naWNhbFJvdyArIChjb2wgLyAyKTtcbiAgICAgICAgaW50IHRleFIgPSB0ZXhlbEluZGV4IC8gdGV4TnVtQztcbiAgICAgICAgaW50IHRleEMgPSB0ZXhlbEluZGV4IC0gdGV4UiAqIHRleE51bUM7XG4gICAgICAgIHJldHVybiAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKHRleE51bUMsIHRleE51bVIpO1xuICAgICAgfVxuICAgICAgYCk7XG4gICAgZnVuY05hbWUgPSAncGFja2VkVVZmcm9tM0QnO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgdmVjMiBwYWNrZWRVVmZyb20zRChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsXG4gICAgICAgICAgaW50IHRleGVsc0luQmF0Y2gsIGludCB0ZXhlbHNJbkxvZ2ljYWxSb3csIGludCBiLFxuICAgICAgICAgIGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgaW50IGluZGV4ID0gYiAqIHRleGVsc0luQmF0Y2ggKyAocm93IC8gMikgKiB0ZXhlbHNJbkxvZ2ljYWxSb3cgKyAoY29sIC8gMik7XG4gICAgICAgIGludCB0ZXhSID0gaW5kZXggLyB0ZXhOdW1DO1xuICAgICAgICBpbnQgdGV4QyA9IGluZGV4IC0gdGV4UiAqIHRleE51bUM7XG4gICAgICAgIHJldHVybiAodmVjMih0ZXhDLCB0ZXhSKSArIGhhbGZDUikgLyB2ZWMyKHRleE51bUMsIHRleE51bVIpO1xuICAgICAgfVxuICAgICAgYCk7XG4gICAgZnVuY05hbWUgPSAnc2FtcGxlVGV4dHVyZSc7XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgICAgZmxvYXQgc2FtcGxlVGV4dHVyZShzYW1wbGVyMkQgdGV4dHVyZVNhbXBsZXIsIHZlYzIgdXYpIHtcbiAgICAgICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSh0ZXh0dXJlU2FtcGxlciwgdXYpLnI7XG4gICAgICAgIH1gKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3IgaW5wdXRzXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0SW5wdXRzU2FtcGxpbmdTbmlwcGV0cygpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSA9IHt9O1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKHNhbXBsZXJOYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBpbnB1dExheW91dCA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldO1xuICAgICAgY29uc3QgZnVuY05hbWUgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUoc2FtcGxlck5hbWUpO1xuICAgICAgaWYgKGlucHV0TGF5b3V0LmlzUGFja2VkKSB7XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldFBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIHNhbXBsZXJOYW1lLCBpbnB1dExheW91dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIHNhbXBsZXJOYW1lLCBpbnB1dExheW91dCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG91dENvb3JkRnVuY05hbWUgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWVBdE91dENvb3JkcyhzYW1wbGVyTmFtZSk7XG4gICAgICBpZiAoaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGggPD0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoKSB7XG4gICAgICAgIGlmIChpbnB1dExheW91dC5pc1BhY2tlZCkge1xuICAgICAgICAgIHJlc3VsdFtvdXRDb29yZEZ1bmNOYW1lXSA9XG4gICAgICAgICAgICAgIHRoaXMuZ2V0UGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKG91dENvb3JkRnVuY05hbWUsIGlucHV0TGF5b3V0LCBvdXRwdXRMYXlvdXQsIHNhbXBsZXJOYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHRbb3V0Q29vcmRGdW5jTmFtZV0gPVxuICAgICAgICAgICAgICB0aGlzLmdldFVucGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKG91dENvb3JkRnVuY05hbWUsIGlucHV0TGF5b3V0LCBvdXRwdXRMYXlvdXQsIHNhbXBsZXJOYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIG91dHB1dCBjb29yZGluYXRlcyBvZiBzYW1wbGVyc1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJBdE91dHB1dENvb3JkcyhcbiAgICAgIGZ1bmNOYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0LCBvdXRwdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQsIG5hbWU6IHN0cmluZyk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBpblNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRTaGFwZSA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleE5hbWUgPSBuYW1lO1xuICAgIGNvbnN0IHRleEZ1bmNTbmlwcGV0ID0gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lKHRleE5hbWUpO1xuXG4gICAgY29uc3QgaW5SYW5rID0gaW5TaGFwZS5sZW5ndGg7XG4gICAgY29uc3Qgb3V0UmFuayA9IG91dFNoYXBlLmxlbmd0aDtcblxuICAgIGNvbnN0IGJyb2FkY2FzdERpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5TaGFwZSwgb3V0U2hhcGUpO1xuXG4gICAgY29uc3QgdHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dFJhbmspO1xuICAgIGNvbnN0IHJhbmtEaWZmID0gb3V0UmFuayAtIGluUmFuaztcbiAgICBsZXQgY29vcmRzU25pcHBldDogc3RyaW5nO1xuICAgIGNvbnN0IGZpZWxkcyA9IGdldEdsQ2hhbm5lbHMoKTtcblxuICAgIGlmIChpblJhbmsgPT09IDApIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnJztcbiAgICB9IGVsc2UgaWYgKG91dFJhbmsgPCAyICYmIGJyb2FkY2FzdERpbXMubGVuZ3RoID49IDEpIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnY29vcmRzID0gMDsnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb29yZHNTbmlwcGV0ID0gYnJvYWRjYXN0RGltcy5tYXAoZCA9PiBgY29vcmRzLiR7ZmllbGRzW2QgKyByYW5rRGlmZl19ID0gMDtgKS5qb2luKCdcXG4nKTtcbiAgICB9XG4gICAgbGV0IHVucGFja2VkQ29vcmRzU25pcHBldCA9ICcnO1xuICAgIGlmIChvdXRSYW5rIDwgMiAmJiBpblJhbmsgPiAwKSB7XG4gICAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnY29vcmRzJztcbiAgICB9IGVsc2Uge1xuICAgICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gaW5TaGFwZS5tYXAoKF9zLCBpKSA9PiBgY29vcmRzLiR7ZmllbGRzW2kgKyByYW5rRGlmZl19YCkuam9pbignLCAnKTtcbiAgICB9XG5cbiAgICBsZXQgb3V0cHV0ID0gJ3JldHVybiBvdXRwdXRWYWx1ZTsnO1xuICAgIGNvbnN0IGluU2l6ZSA9IFNoYXBlVXRpbC5zaXplKGluU2hhcGUpO1xuICAgIGNvbnN0IGlzSW5wdXRTY2FsYXIgPSBpblNpemUgPT09IDE7XG4gICAgY29uc3Qgb3V0U2l6ZSA9IFNoYXBlVXRpbC5zaXplKG91dFNoYXBlKTtcbiAgICBjb25zdCBpc091dHB1dFNjYWxhciA9IG91dFNpemUgPT09IDE7XG5cbiAgICBpZiAoaW5SYW5rID09PSAxICYmICFpc0lucHV0U2NhbGFyICYmICFpc091dHB1dFNjYWxhcikge1xuICAgICAgb3V0cHV0ID0gYFxuICAgICAgICByZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54eSwgb3V0cHV0VmFsdWUueHkpO1xuICAgICAgYDtcbiAgICB9IGVsc2UgaWYgKGlzSW5wdXRTY2FsYXIgJiYgIWlzT3V0cHV0U2NhbGFyKSB7XG4gICAgICBpZiAob3V0UmFuayA9PT0gMSkge1xuICAgICAgICBvdXRwdXQgPSBgXG4gICAgICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueCwgMC4sIDAuKTtcbiAgICAgICAgYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG91dHB1dCA9IGBcbiAgICAgICAgICByZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54KTtcbiAgICAgICAgYDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGJyb2FkY2FzdERpbXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCByb3dzID0gaW5SYW5rIC0gMjtcbiAgICAgIGNvbnN0IGNvbHMgPSBpblJhbmsgLSAxO1xuXG4gICAgICBpZiAoYnJvYWRjYXN0RGltcy5pbmRleE9mKHJvd3MpID4gLTEgJiYgYnJvYWRjYXN0RGltcy5pbmRleE9mKGNvbHMpID4gLTEpIHtcbiAgICAgICAgb3V0cHV0ID0gJ3JldHVybiB2ZWM0KG91dHB1dFZhbHVlLngpOyc7XG4gICAgICB9IGVsc2UgaWYgKGJyb2FkY2FzdERpbXMuaW5kZXhPZihyb3dzKSA+IC0xKSB7XG4gICAgICAgIG91dHB1dCA9ICdyZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54LCBvdXRwdXRWYWx1ZS55LCAnICtcbiAgICAgICAgICAgICdvdXRwdXRWYWx1ZS54LCBvdXRwdXRWYWx1ZS55KTsnO1xuICAgICAgfSBlbHNlIGlmIChicm9hZGNhc3REaW1zLmluZGV4T2YoY29scykgPiAtMSkge1xuICAgICAgICBvdXRwdXQgPSAncmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueHgsIG91dHB1dFZhbHVlLnp6KTsnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN3YXBMYXN0RGltc1NuaXBwZXQgPSBgXG4gICAgICAgIGludCBsYXN0RGltID0gY29vcmRzLiR7ZmllbGRzW291dFJhbmsgLSAxXX07XG4gICAgICAgIGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMV19ID0gY29vcmRzLiR7ZmllbGRzW291dFJhbmsgLSAyXX07XG4gICAgICAgIGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMl19ID0gbGFzdERpbTtcbiAgICAgIGA7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgdmVjNCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgJHt0eXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICAgICAgJHtzd2FwTGFzdERpbXNTbmlwcGV0fVxuICAgICAgICAke2Nvb3Jkc1NuaXBwZXR9XG4gICAgICAgIHZlYzQgb3V0cHV0VmFsdWUgPSAke3RleEZ1bmNTbmlwcGV0fSgke3VucGFja2VkQ29vcmRzU25pcHBldH0pO1xuICAgICAgICAke291dHB1dH1cbiAgICAgIH1cbiAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLmdldE91dHB1dENvb3JkcyddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIHVucGFja2VkIG91dHB1dCBjb29yZGluYXRlcyBvZiBzYW1wbGVyc1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKFxuICAgICAgZnVuY05hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQsIG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCwgbmFtZTogc3RyaW5nKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IG91dFRleFNoYXBlID0gW291dHB1dExheW91dC53aWR0aCwgb3V0cHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgaW5UZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBpblJhbmsgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBvdXRSYW5rID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IGluU2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4RnVuY1NuaXBwZXQgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUobmFtZSk7XG5cbiAgICBpZiAoaW5SYW5rID09PSBvdXRSYW5rICYmIEFycmF5VXRpbC5hcnJheXNFcXVhbChpblRleFNoYXBlLCBvdXRUZXhTaGFwZSkpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIFRleENvb3Jkcyk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0UmFuayk7XG4gICAgY29uc3QgYnJvYWRjYXN0RGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpblNoYXBlLCBvdXRTaGFwZSk7XG4gICAgY29uc3QgcmFua0RpZmYgPSBvdXRSYW5rIC0gaW5SYW5rO1xuICAgIGxldCBjb29yZHNTbmlwcGV0OiBzdHJpbmc7XG4gICAgY29uc3QgZmllbGRzID0gZ2V0R2xDaGFubmVscygpO1xuXG4gICAgaWYgKGluUmFuayA9PT0gMCkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICcnO1xuICAgIH0gZWxzZSBpZiAob3V0UmFuayA8IDIgJiYgYnJvYWRjYXN0RGltcy5sZW5ndGggPj0gMSkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICdjb29yZHMgPSAwOyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSBicm9hZGNhc3REaW1zLm1hcChkID0+IGBjb29yZHMuJHtmaWVsZHNbZCArIHJhbmtEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICAgIH1cbiAgICBsZXQgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJyc7XG4gICAgaWYgKG91dFJhbmsgPCAyICYmIGluUmFuayA+IDApIHtcbiAgICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9ICdjb29yZHMnO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlLm1hcCgoX3MsIGkpID0+IGBjb29yZHMuJHtmaWVsZHNbaSArIHJhbmtEaWZmXX1gKS5qb2luKCcsICcpO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgICR7dHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICAgJHtjb29yZHNTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiAke3RleEZ1bmNTbmlwcGV0fSgke3VucGFja2VkQ29vcmRzU25pcHBldH0pO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLmdldE91dHB1dENvb3JkcyddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIHBhY2tlZCBvcGVyYXRpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBzd2l0Y2ggKGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXJTY2FsYXIoZnVuY05hbWUsIG5hbWUpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRTYW1wbGVyMUQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXIzRChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlck5EKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3IgdW5wYWNrZWQgb3BlcmF0aW9ucy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgc3dpdGNoIChzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjFEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjREKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDU6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjVEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDY6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjZEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBUT0RPIHN1cHBvcnQgbW9yZSBkaW1lbnNpb25hbGl0aWVzXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZGltZW5zaW9uICR7c2hhcGUubGVuZ3RofS1EYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhY2tlZCBzY2FsYXIgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICB2ZWM0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIGhhbGZDUik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgMUQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyMUQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCB0ZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVsxXSwgdGV4U2hhcGVbMF1dO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMUQoXG4gICAgICAke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0sIGluZGV4KTtcbiAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgfWA7XG4gICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5wYWNrZWRVVmZyb20xRCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgMkQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyMkQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICBjb25zdCB0ZXhOdW1SID0gdGV4U2hhcGVbMF07XG4gICAgY29uc3QgdGV4TnVtQyA9IHRleFNoYXBlWzFdO1xuXG4gICAgaWYgKHRleFNoYXBlICE9IG51bGwgJiYgQXJyYXlVdGlsLmFycmF5c0VxdWFsKHNoYXBlLCB0ZXhTaGFwZSkpIHtcbiAgICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIHZlYzIgdXYgPSAodmVjMihjb2wsIHJvdykgKyBoYWxmQ1IpIC8gdmVjMigke3RleE51bUN9LjAsICR7dGV4TnVtUn0uMCk7XG4gICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgICB9YDtcblxuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShwYWNrZWRTYW1wbGVyKTtcbiAgICB9XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSB0ZXhTaGFwZTtcbiAgICBjb25zdCB2YWx1ZXNQZXJSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMV0gLyAyKTtcbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgdmVjMiB1diA9IHBhY2tlZFVWZnJvbTJEKCR7cGFja2VkVGV4U2hhcGVbMV19LCAke3BhY2tlZFRleFNoYXBlWzBdfSwgJHt2YWx1ZXNQZXJSb3d9LCByb3csIGNvbCk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO1xuICAgIH1gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMucGFja2VkVVZmcm9tMkQnXSk7XG4gIH1cblxuICAvKipcbiAgICogUGFja2VkIDNEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICAgIGlmIChzaGFwZVswXSA9PT0gMSkge1xuICAgICAgY29uc3Qgc3F1ZWV6ZWRTaGFwZSA9IHNoYXBlLnNsaWNlKDEpO1xuICAgICAgY29uc3Qga2VwdERpbXMgPSBbMSwgMl07XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIHNxdWVlemVkU2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydiJywgJ3JvdycsICdjb2wnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG4gICAgICBjb25zdCBzYW1wbGVyUm91dGluZSA9IHRoaXMuZ2V0UGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpO1xuICAgICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGAke3NhbXBsZXJSb3V0aW5lLnJvdXRpbmVCb2R5fVxuICAgICAgdmVjNCAke2Z1bmNOYW1lfShpbnQgYiwgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgfSBgO1xuICAgICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBzYW1wbGVyUm91dGluZS5kZXBlbmRlbmNpZXMpO1xuICAgIH1cbiAgICBjb25zdCB0ZXhOdW1SID0gcGFja2VkVGV4U2hhcGVbMF07XG4gICAgY29uc3QgdGV4TnVtQyA9IHBhY2tlZFRleFNoYXBlWzFdO1xuXG4gICAgY29uc3QgdmFsdWVzUGVyUm93ID0gTWF0aC5jZWlsKHNoYXBlWzJdIC8gMik7XG4gICAgY29uc3QgdGV4ZWxzSW5CYXRjaCA9IHZhbHVlc1BlclJvdyAqIE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuXG4gICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGB2ZWM0ICR7ZnVuY05hbWV9KGludCBiLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tM0QoXG4gICAgICAgICR7dGV4TnVtQ30sICR7dGV4TnVtUn0sICR7dGV4ZWxzSW5CYXRjaH0sICR7dmFsdWVzUGVyUm93fSwgYiwgcm93LCBjb2wpO1xuICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIHV2KTt9YDtcbiAgICBjb25zdCBzb3VyY2UgPSBwYWNrZWRTYW1wbGVyO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnBhY2tlZFVWZnJvbTNEJ10pO1xuICB9XG4gIC8qXG4gICAqIFBhY2tlZCBORCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJORChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV1dO1xuICAgIGNvbnN0IHRleE51bVIgPSBwYWNrZWRUZXhTaGFwZVsxXTtcbiAgICBjb25zdCB0ZXhOdW1DID0gcGFja2VkVGV4U2hhcGVbMF07XG4gICAgY29uc3QgdmFsdWVzUGVyUm93ID0gTWF0aC5jZWlsKHNoYXBlW3JhbmsgLSAxXSAvIDIpO1xuICAgIGxldCB0ZXhlbHNJbkJhdGNoID0gdmFsdWVzUGVyUm93ICogTWF0aC5jZWlsKHNoYXBlW3JhbmsgLSAyXSAvIDIpO1xuICAgIGxldCBwYXJhbXMgPSAnaW50IGIsIGludCByb3csIGludCBjb2wnO1xuICAgIGxldCBpbmRleCA9IGBiICogJHt0ZXhlbHNJbkJhdGNofSArIChyb3cgLyAyKSAqICR7dmFsdWVzUGVyUm93fSArIChjb2wgLyAyKWA7XG4gICAgZm9yIChsZXQgYiA9IDI7IGIgPCByYW5rIC0gMTsgYisrKSB7XG4gICAgICBwYXJhbXMgPSBgaW50IGIke2J9LCBgICsgcGFyYW1zO1xuICAgICAgdGV4ZWxzSW5CYXRjaCAqPSBzaGFwZVtyYW5rIC0gYiAtIDFdO1xuICAgICAgaW5kZXggPSBgYiR7Yn0gKiAke3RleGVsc0luQmF0Y2h9ICsgYCArIGluZGV4O1xuICAgIH1cbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oJHtwYXJhbXN9KSB7XG4gICAgICBpbnQgaW5kZXggPSAke2luZGV4fTtcbiAgICAgIGludCB0ZXhSID0gaW5kZXggLyAke3RleE51bUN9O1xuICAgICAgaW50IHRleEMgPSBpbmRleCAtIHRleFIgKiAke3RleE51bUN9O1xuICAgICAgdmVjMiB1diA9ICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIoJHt0ZXhOdW1DfSwgJHt0ZXhOdW1SfSk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO1xuICAgIH1gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIHNjYWxhciBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlclNjYWxhcihmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IFt0ZXhOdW1SLCB0ZXhOdW1DXSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBpZiAodGV4TnVtUiA9PT0gMSAmJiB0ZXhOdW1DID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBoYWxmQ1IpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICBpbnQgb2Zmc2V0XyR7bmFtZX0gPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7dGV4TnVtUn0sICR7dGV4TnVtQ30pO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIG9mZnNldF8ke25hbWV9KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAxRCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjFEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgdE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcblxuICAgIGlmICh0TnVtQyA9PT0gMSAmJiB0TnVtUiA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBoYWxmQ1IpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBpZiAodE51bUMgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKChmbG9hdChpbmRleCkgKyAwLjUpIC8gJHt0TnVtUn0uMCwgMC41KTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cbiAgICBpZiAodE51bVIgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKDAuNSwgKGZsb2F0KGluZGV4KSArIDAuNSkgLyAke3ROdW1DfS4wKTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCBpbmRleCkge1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dE51bVJ9LCAke3ROdW1DfSwgaW5kZXgpO1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy51dkZyb21GbGF0JywgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMkQgc25pcHBldC5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuXG4gICAgLy8gVE9ETzogbW9kaWZ5IHJvdy9jb2wgb3JkZXIgZm9yIG90aGVyIGRpbWVuc2lvbnMuXG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQuaGVpZ2h0LCBpbnB1dExheW91dC53aWR0aF07XG5cbiAgICBpZiAodGV4U2hhcGUgIT0gbnVsbCAmJiBBcnJheVV0aWwuYXJyYXlzRXF1YWwoc2hhcGUsIHRleFNoYXBlKSkge1xuICAgICAgY29uc3QgdGV4TnVtUiA9IHRleFNoYXBlWzFdO1xuICAgICAgY29uc3QgdGV4TnVtQyA9IHRleFNoYXBlWzBdO1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSAodmVjMihyb3csIGNvbCkgKyBoYWxmQ1IpIC8gdmVjMigke3RleE51bVJ9LjAsICR7dGV4TnVtQ30uMCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCB7bmV3U2hhcGUsIGtlcHREaW1zfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgY29uc3Qgc3F1ZWV6ZWRTaGFwZSA9IG5ld1NoYXBlO1xuICAgIGlmIChzcXVlZXplZFNoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBzcXVlZXplZFNoYXBlKTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IFsnY29sJywgJ3JvdyddO1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgICR7dGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KS5yb3V0aW5lQm9keX1cbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IHRleFNoYXBlWzFdO1xuICAgIGNvbnN0IHRleE51bUMgPSB0ZXhTaGFwZVswXTtcbiAgICBpZiAodGV4TnVtQyA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIGludCBvZmZzZXRfJHtuYW1lfSA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSk7XG4gICAgICAgICAgICBmbG9hdCBpbmRleCA9IGRvdCh2ZWMzKHJvdywgY29sLCBvZmZzZXRfJHtuYW1lfSksIHZlYzMoJHtzaGFwZVsxXX0sIDEsIDEpKTtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKDAuNSwgKGluZGV4ICsgMC41KSAvICR7dGV4TnVtUn0uMCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICB9XG5cbiAgICBpZiAodGV4TnVtUiA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIGludCBvZmZzZXRfJHtuYW1lfSA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSk7XG4gICAgICAgICAgICBmbG9hdCBpbmRleCA9IGRvdCh2ZWMzKHJvdywgY29sLCBvZmZzZXRfJHtuYW1lfSksIHZlYzMoJHtzaGFwZVsxXX0sIDEsIDEpKTtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKChpbmRleCArIDAuNSkgLyAke3RleE51bUN9LjAsIDAuNSk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICBpbnQgaW5kZXggPSBjb2wgKiAke3NoYXBlWzFdfSArIHJvdztcbiAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgIHNvdXJjZSwgWydjb29yZGluYXRlcy51dkZyb21GbGF0JywgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgM0Qgc25pcHBldC5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHNoYXBlWzJdO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXTtcblxuICAgIGNvbnN0IHtuZXdTaGFwZSwga2VwdERpbXN9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICBjb25zdCBzcXVlZXplZFNoYXBlID0gbmV3U2hhcGU7XG4gICAgaWYgKHNxdWVlemVkU2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIHNxdWVlemVkU2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydiYXRjaCcsICdjb2wnLCAncm93J107XG4gICAgICAvLyBEZWVwIGNvcHkgb2YgaW5wdXQgdGV4dHVyZSBsYXlvdXQuXG4gICAgICBjb25zdCBuZXdJbnB1dExheW91dDogVGV4dHVyZUxheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRMYXlvdXQpKTtcbiAgICAgIG5ld0lucHV0TGF5b3V0LnVucGFja2VkU2hhcGUgPSBuZXdJbnB1dFNoYXBlO1xuICAgICAgY29uc3Qgcm91dGluZSA9IHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCk7XG4gICAgICAvLyBUT0RPOiByZXZpc2l0IHRoZSBsb2dpYyBoZXJlIHRvIG1ha2UgaXQgc2ltcGxlclxuICAgICAgY29uc3QgcmV2RGltcyA9IGtlcHREaW1zLnJldmVyc2UoKTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAke3JvdXRpbmUucm91dGluZUJvZHl9XG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGJhdGNoLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIHJldkRpbXMpfSk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIHJvdXRpbmUuZGVwZW5kZW5jaWVzKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGRlcHRoLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICAvLyBFeHBsaWNpdGx5IHVzZSBpbnRlZ2VyIG9wZXJhdGlvbnMgYXMgZG90KCkgb25seSB3b3JrcyBvbiBmbG9hdHMuXG4gICAgICAgICAgICBpbnQgaW5kZXggPSBkZXB0aCAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgcm93O1xuICAgICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA0RCBzbmlwcGV0LlxuICAgKi9cblxuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNEQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlMiA9IHNoYXBlWzNdO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXSAqIHN0cmlkZTI7XG4gICAgY29uc3Qgc3RyaWRlMCA9IHNoYXBlWzFdICogc3RyaWRlMTtcblxuICAgIC8vXG4gICAgLy8gVE9ETzogcmUtZW5hYmxlIHRoaXMgc2hvcnRjdXQgb25jZSB0aGUgaW5kZXggY2FsY3VsYXRpb24gYnVnIGlzIGZpeGVkLlxuICAgIC8vXG4gICAgLy8gY29uc3Qge25ld1NoYXBlLCBrZXB0RGltc30gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIC8vIGlmIChuZXdTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAvLyAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgbmV3U2hhcGUpO1xuICAgIC8vICAgY29uc3QgcGFyYW1zID0gWydyb3cnLCAnY29sJywgJ2RlcHRoJywgJ2RlcHRoMiddO1xuICAgIC8vICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgIC8vICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgLy8gICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcbiAgICAvLyAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAvLyAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgLy8gICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7XG4gICAgLy8gICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgIC8vICAgICAgIH1cbiAgICAvLyAgICAgYDtcbiAgICAvLyAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgLy8gICAgICAgc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICAvLyB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikge1xuICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICtcbiAgICAgICAgICAgICAgZGVwdGgyICogJHtzdHJpZGUyfSArIGRlcHRoO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDVEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNUQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlMyA9IHNoYXBlWzRdO1xuICAgIGNvbnN0IHN0cmlkZTIgPSBzaGFwZVszXSAqIHN0cmlkZTM7XG4gICAgY29uc3Qgc3RyaWRlMSA9IHNoYXBlWzJdICogc3RyaWRlMjtcbiAgICBjb25zdCBzdHJpZGUwID0gc2hhcGVbMV0gKiBzdHJpZGUxO1xuXG4gICAgY29uc3Qge25ld1NoYXBlLCBrZXB0RGltc30gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIGlmIChuZXdTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgbmV3U2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydyb3cnLCAnY29sJywgJ2RlcHRoJywgJ2RlcHRoMicsICdkZXB0aDMnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMiwgaW50IGRlcHRoMykge1xuICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgZGVwdGggKiAke3N0cmlkZTJ9ICtcbiAgICAgICAgICBkZXB0aDMgKiAke3N0cmlkZTN9ICsgZGVwdGgyO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy51dkZyb21GbGF0J10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDZEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNkQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlNCA9IHNoYXBlWzVdO1xuICAgIGNvbnN0IHN0cmlkZTMgPSBzaGFwZVs0XSAqIHN0cmlkZTQ7XG4gICAgY29uc3Qgc3RyaWRlMiA9IHNoYXBlWzNdICogc3RyaWRlMztcbiAgICBjb25zdCBzdHJpZGUxID0gc2hhcGVbMl0gKiBzdHJpZGUyO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHN0cmlkZTE7XG5cbiAgICBjb25zdCB7bmV3U2hhcGUsIGtlcHREaW1zfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgaWYgKG5ld1NoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBuZXdTaGFwZSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbJ3JvdycsICdjb2wnLCAnZGVwdGgnLCAnZGVwdGgyJywgJ2RlcHRoMycsICdkZXB0aDQnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAgICR7dGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KS5yb3V0aW5lQm9keX1cbiAgICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCxcbiAgICAgICAgICAgICAgaW50IGRlcHRoMiwgaW50IGRlcHRoMywgaW50IGRlcHRoNCkge1xuICAgICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IGlucHV0TGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IHRleE51bUMgPSBpbnB1dExheW91dC5oZWlnaHQ7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCxcbiAgICAgICAgICAgIGludCBkZXB0aDIsIGludCBkZXB0aDMsIGludCBkZXB0aDQpIHtcbiAgICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgZGVwdGggKiAke3N0cmlkZTJ9ICtcbiAgICAgICAgICAgIGRlcHRoMiAqICR7c3RyaWRlM30gKyBkZXB0aDMgKiAke3N0cmlkZTR9ICsgZGVwdGg0O1xuICAgICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgICAgICBzb3VyY2UsIFsnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0J10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgaXMgdGhlIG1haW4gZnVuY3Rpb24gdG8gbWFwIGZyb20gdGhlIGdpdmVuIHRleHR1cmUgY29vcmRpYW50ZXMgKHMsdClcbiAgICogdG8gbG9naWNhbCBpbmRpY2VzIGZvciB0aGUgb3V0cHV0XG4gICAqIFRoZXJlIHdpbGwgb25seSBiZSBvbmUgc2luZ2xlIHZhcmlhdGlvbiBvZiB0aGlzXG4gICAqIEFsc28gc2VlIGNvb3Jkc1RvT2Zmc2V0IGFuZCBvZmZzZXRUb0luZGljZXMgZm9yIGlucHV0LXNwZWNpZmljIHZlcnNpb25zXG4gICAqL1xuICBwcm90ZWN0ZWQgdG9WZWMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IG91dHB1dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXQuc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHN0cmlkZXMgPSBvdXRwdXQuc3RyaWRlcztcbiAgICBjb25zdCB4U2NhbGUgPSBvdXRwdXQud2lkdGg7XG4gICAgY29uc3QgeVNjYWxlID0gb3V0cHV0LmhlaWdodDtcblxuICAgIGNvbnN0IHN0cmlkZXNCbG9jayA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgICBjWyR7aX1dID0gb2Zmc2V0IC8gJHtzdHJpZGVzW2ldfTtgKTtcbiAgICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgICAgb2Zmc2V0IC09IGNbJHtpfV0gKiAke3N0cmlkZXNbaV19O2ApO1xuICAgIH1cbiAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICAgIGNbJHtyYW5rIC0gMX1dID0gb2Zmc2V0O2ApO1xuICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICB2b2lkIHRvVmVjKHZlYzIgdGV4Q29vcmRzLCBvdXQgaW50IGNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IG9mZnNldCA9IGNvb3Jkc1RvT2Zmc2V0KHRleENvb3JkcywgJHt4U2NhbGV9LCAke3lTY2FsZX0pO1xuICAgICAgICAke3N0cmlkZXNCbG9jay5qb2luKCcnKX1cbiAgICAgIH1cbiAgICAgIHZvaWQgdG9WZWMoaW50IG9mZnNldCwgb3V0IGludCBjWyR7cmFua31dKSB7XG4gICAgICAgICR7c3RyaWRlc0Jsb2NrLmpvaW4oJycpfVxuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIHt0b1ZlYzogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHksIFsnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnXSl9O1xuICB9XG4gIC8qKlxuICAgKiBUaGVzZSBhcmUgdmFsdWUgZ2V0dGVyIGZ1bmN0aW9ucyBnZW5lcmF0ZWQgZm9yIGVhY2ggaW5wdXRcbiAgICogRWFjaCBmdW5jdGlvbiBpcyBoYXJkd2lyZWQgdG8gdGhlIG5hbWUgYW5kIGRpbWVuc2lvbnMgb2YgdGhlIGlucHV0XG4gICAqIEFuICdfVCcgdmFyaWF0aW9uIGlzIGFsc28gcHJvZHVjZWQgd2hpY2ggYWNjZXNzZXMgdmFsdWVzIGFzIGlmIHRoZVxuICAgKiBpbnB1dCB3YXMgdHJhbnNwb3NlZFxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbHVlRnJvbSgpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IGxheW91dCA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldO1xuICAgICAgY29uc3Qgc2hhcGUgPSBsYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGggPiAwID8gbGF5b3V0LnVucGFja2VkU2hhcGUgOiBsYXlvdXQuc2hhcGU7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgbGV0IGZ1bmNOYW1lID0gYF8ke25hbWV9YDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgICAgdGhpcy5nZXRWYWx1ZUZyb21TaW5nbGUobmFtZSwgcmFuaywgbGF5b3V0LndpZHRoLCBsYXlvdXQuaGVpZ2h0LCBmYWxzZSksXG4gICAgICAgICAgW2BzaGFwZVV0aWxzLmluZGljZXNUb09mZnNldCR7ZnVuY05hbWV9YCwgJ2Nvb3JkaW5hdGVzLm9mZnNldFRvQ29vcmRzJywgJ2ZyYWdjb2xvci5nZXRDb2xvckFzRmxvYXQnXSk7XG4gICAgICBmdW5jTmFtZSA9IGZ1bmNOYW1lICsgJ19UJztcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgICAgdGhpcy5nZXRWYWx1ZUZyb21TaW5nbGUobmFtZSwgcmFuaywgbGF5b3V0LndpZHRoLCBsYXlvdXQuaGVpZ2h0LCB0cnVlKSxcbiAgICAgICAgICBbYHNoYXBlVXRpbHMuaW5kaWNlc1RvT2Zmc2V0JHtmdW5jTmFtZX1gLCAnY29vcmRpbmF0ZXMub2Zmc2V0VG9Db29yZHMnLCAnZnJhZ2NvbG9yLmdldENvbG9yQXNGbG9hdCddKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIC8qKlxuICAgKiBQcm9kdWNlcyBvbmUgdmFsdWUgZ2V0dGVyIGZ1bmN0aW9uIGZvciB0aGUgbmFtZSBhbmQgcmFuayBnaXZlblxuICAgKiBJZiBhIHRyYW5zcG9zZSBpcyBzZXQgcHJvcGVyIG9mZnNldFRvQ29vcmRzIG1hcHBpbmcgd2lsbCBiZSB1c2VkXG4gICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSByYW5rIHJhbmsgb2YgdGhlIGlucHV0XG4gICAqIEBwYXJhbSB0cmFuc3Bvc2Ugd2hldGhlciBvciBub3Qgc2hvdWxkIGdlbmVyYXRlIGEgdHJhbnNwb3NlIHZhcmlhdGlvblxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFZhbHVlRnJvbVNpbmdsZSh2YXJOYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlciwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIHRyYW5zcG9zZTogYm9vbGVhbik6XG4gICAgICBzdHJpbmcge1xuICAgIGxldCBuYW1lID0gYF8ke3Zhck5hbWV9YDtcbiAgICBpZiAodHJhbnNwb3NlKSB7XG4gICAgICBuYW1lID0gbmFtZSArICdfVCc7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgcmV0dXJuIGBcbiAgICAgICAgZmxvYXQgJHtuYW1lfShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBvZmZzZXQgPSBpbmRpY2VzVG9PZmZzZXQke25hbWV9KG0pO1xuICAgICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfSgke3Zhck5hbWV9LCBjb29yZHMpKTtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIHBhY2tlZCB2YWx1ZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIHRoZSBuYW1lIGFuZCByYW5rIGdpdmVuXG4gICAqIElmIGEgdHJhbnNwb3NlIGlzIHNldCBwcm9wZXIgb2Zmc2V0VG9Db29yZHMgbWFwcGluZyB3aWxsIGJlIHVzZWRcbiAgICogQHBhcmFtIG5hbWUgbmFtZSBvZiB0aGUgZnVuY3Rpb25cbiAgICogQHBhcmFtIHJhbmsgcmFuayBvZiB0aGUgaW5wdXRcbiAgICogQHBhcmFtIHRyYW5zcG9zZSB3aGV0aGVyIG9yIG5vdCBzaG91bGQgZ2VuZXJhdGUgYSB0cmFuc3Bvc2UgdmFyaWF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkVmFsdWVGcm9tKHZhck5hbWU6IHN0cmluZywgcmFuazogbnVtYmVyLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgdHJhbnNwb3NlOiBib29sZWFuKTpcbiAgICAgIHN0cmluZyB7XG4gICAgbGV0IG5hbWUgPSBgXyR7dmFyTmFtZX1fUGFja2A7XG4gICAgaWYgKHRyYW5zcG9zZSkge1xuICAgICAgbmFtZSA9IG5hbWUgKyAnX1QnO1xuICAgIH1cbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJldHVybiBgXG4gICAgICAgIHZlYzQgJHtuYW1lfShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBvZmZzZXQgPSBpbmRpY2VzVG9PZmZzZXRfJHt2YXJOYW1lfShtKTtcbiAgICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7dmFyTmFtZX0sIGNvb3Jkcyk7XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZX0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcblxuLyoqXG4gKiBUaGlzIEdMU0wgbGlicmFyeSBoYW5kbGVzIHJvdXRpbmVzIGNvbnZlcnRpbmdcbiAqIGZsb2F0MzIgdG8vZnJvbSBVbnNpZ25lZCBieXRlIG9yIGZsb2F0IDE2XG4gKi9cbmV4cG9ydCBjbGFzcyBFbmNvZGluZ0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIHJldHVybiB7Li4udGhpcy5lbmNvZGVGbG9hdDMyKCksIC4uLnRoaXMuZGVjb2RlRmxvYXQzMigpfTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7W25hbWU6IHN0cmluZ106IHN0cmluZ30ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBwcm90ZWN0ZWQgZW5jb2RlRmxvYXQzMigpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVuY29kZTogbmV3IEdsc2xMaWJSb3V0aW5lKGBoaWdocCB2ZWM0IGVuY29kZShoaWdocCBmbG9hdCBmKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KGYsIDAuMCwgMC4wLCAwLjApO1xuICAgICAgfVxuICAgICAgICBgKVxuICAgIH07XG4gIH1cbiAgcHJvdGVjdGVkIGRlY29kZUZsb2F0MzIoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIHJldHVybiB7XG4gICAgICBkZWNvZGU6IG5ldyBHbHNsTGliUm91dGluZShgaGlnaHAgZmxvYXQgZGVjb2RlKGhpZ2hwIHZlYzQgcmdiYSkge1xuICAgICAgICByZXR1cm4gcmdiYS5yO1xuICAgICAgfVxuICAgICAgICBgKVxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIHJldHVybnMgdGhlIHJvdXRpbmUgdG8gZW5jb2RlIGVuY29kZSBhIDMyYml0IGZsb2F0IHRvIGEgdmVjNCAob2YgdW5zaWduZWQgYnl0ZXMpXG4gICAqIEBjcmVkaXQ6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzcwNTk5NjIvaG93LWRvLWktY29udmVydC1hLXZlYzQtcmdiYS12YWx1ZS10by1hLWZsb2F0XG4gICAqL1xuICBwcm90ZWN0ZWQgZW5jb2RlVWludDgoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IGVuZGlhbm5lc3MgPSBFbmNvZGluZ0dsc2xMaWIuaXNMaXR0bGVFbmRpYW4oKSA/ICdyZ2JhLnJnYmE9cmdiYS5hYmdyOycgOiAnJztcbiAgICByZXR1cm4ge1xuICAgICAgZW5jb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgaGlnaHAgdmVjNCBlbmNvZGUoaGlnaHAgZmxvYXQgZikge1xuICAgICAgICBoaWdocCBmbG9hdCBGID0gYWJzKGYpO1xuICAgICAgICBoaWdocCBmbG9hdCBTaWduID0gc3RlcCgwLjAsLWYpO1xuICAgICAgICBoaWdocCBmbG9hdCBFeHBvbmVudCA9IGZsb29yKGxvZzIoRikpO1xuICAgICAgICBoaWdocCBmbG9hdCBNYW50aXNzYSA9IChleHAyKC0gRXhwb25lbnQpICogRik7XG4gICAgICAgIEV4cG9uZW50ID0gZmxvb3IobG9nMihGKSArIDEyNy4wKSArIGZsb29yKGxvZzIoTWFudGlzc2EpKTtcbiAgICAgICAgaGlnaHAgdmVjNCByZ2JhO1xuICAgICAgICByZ2JhWzBdID0gMTI4LjAgKiBTaWduICArIGZsb29yKEV4cG9uZW50KmV4cDIoLTEuMCkpO1xuICAgICAgICByZ2JhWzFdID0gMTI4LjAgKiBtb2QoRXhwb25lbnQsMi4wKSArIG1vZChmbG9vcihNYW50aXNzYSoxMjguMCksMTI4LjApO1xuICAgICAgICByZ2JhWzJdID0gZmxvb3IobW9kKGZsb29yKE1hbnRpc3NhKmV4cDIoMjMuMCAtOC4wKSksZXhwMig4LjApKSk7XG4gICAgICAgIHJnYmFbM10gPSBmbG9vcihleHAyKDIzLjApKm1vZChNYW50aXNzYSxleHAyKC0xNS4wKSkpO1xuICAgICAgICAke2VuZGlhbm5lc3N9XG4gICAgICAgIHJnYmEgPSByZ2JhIC8gMjU1LjA7IC8vIHZhbHVlcyBuZWVkIHRvIGJlIG5vcm1hbGl6ZWQgdG8gWzAsMV1cbiAgICAgICAgcmV0dXJuIHJnYmE7XG4gICAgfVxuICAgICAgICBgKVxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIHJldHVybnMgdGhlIHJvdXRpbmUgdG8gZW5jb2RlIGEgdmVjNCBvZiB1bnNpZ25lZCBieXRlcyB0byBmbG9hdDMyXG4gICAqIEBjcmVkaXQ6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzcwNTk5NjIvaG93LWRvLWktY29udmVydC1hLXZlYzQtcmdiYS12YWx1ZS10by1hLWZsb2F0XG4gICAqL1xuICBwcm90ZWN0ZWQgZGVjb2RlVWludDgoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IGVuZGlhbm5lc3MgPSBFbmNvZGluZ0dsc2xMaWIuaXNMaXR0bGVFbmRpYW4oKSA/ICdyZ2JhLnJnYmE9cmdiYS5hYmdyOycgOiAnJztcbiAgICByZXR1cm4ge1xuICAgICAgZGVjb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgICBoaWdocCBmbG9hdCBkZWNvZGUoaGlnaHAgdmVjNCByZ2JhKSB7XG4gICAgICAgICAgcmdiYSA9IHJnYmEgKiAyNTUuMDsgLy8gdmFsdWVzIG5lZWQgdG8gYmUgZGUtbm9ybWFsaXplZCBmcm9tIFswLDFdIHRvIFswLDI1NV1cbiAgICAgICAgICAke2VuZGlhbm5lc3N9XG4gICAgICAgICAgaGlnaHAgZmxvYXQgU2lnbiA9IDEuMCAtIHN0ZXAoMTI4LjAscmdiYVswXSkqMi4wO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IEV4cG9uZW50ID0gMi4wICogbW9kKHJnYmFbMF0sMTI4LjApICsgc3RlcCgxMjguMCxyZ2JhWzFdKSAtIDEyNy4wO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IE1hbnRpc3NhID0gbW9kKHJnYmFbMV0sMTI4LjApKjY1NTM2LjAgKyByZ2JhWzJdKjI1Ni4wICtyZ2JhWzNdICsgZmxvYXQoMHg4MDAwMDApO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IFJlc3VsdCA9ICBTaWduICogZXhwMihFeHBvbmVudCkgKiAoTWFudGlzc2EgKiBleHAyKC0yMy4wICkpO1xuICAgICAgICAgIHJldHVybiBSZXN1bHQ7XG4gICAgICB9XG4gICAgICAgIGApXG4gICAgfTtcbiAgfVxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBpZiB0aGUgbWFjaGluZSBpcyBsaXR0bGUgZW5kaWFuIG9yIG5vdFxuICAgKiBAY3JlZGl0OiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9Ub29UYWxsTmF0ZS80NzUwOTUzXG4gICAqL1xuICBzdGF0aWMgaXNMaXR0bGVFbmRpYW4oKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYiA9IG5ldyBBcnJheUJ1ZmZlcig0KTtcbiAgICBjb25zdCBhID0gbmV3IFVpbnQzMkFycmF5KGIpO1xuICAgIGNvbnN0IGMgPSBuZXcgVWludDhBcnJheShiKTtcbiAgICBhWzBdID0gMHhkZWFkYmVlZjtcbiAgICBpZiAoY1swXSA9PT0gMHhlZikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChjWzBdID09PSAweGRlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBlbmRpYW5uZXNzJyk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmV9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQge2dldEdsc2x9IGZyb20gJy4vZ2xzbC1zb3VyY2UnO1xuXG4vKipcbiAqIFRoaXMgR0xTTCBsaWJyYXJ5IGhhbmRsZXMgcm91dGluZXMgYXJvdW5kIHJlYWRpbmcgYSB0ZXhsZXQgYW5kIHdyaXRpbmcgdG8gaXRcbiAqIFJlYWRpbmcgYW5kIHdyaXRpbmcgY291bGQgYmUgbW9yZSB0aGFuIGp1c3QgZGVhbGluZyB3aXRoIG9uZSBjaGFubmVsXG4gKiBJdCBtYXkgcmVxdWlyZSBlbmNvZGluZy9kZWNvZGluZyB0by9mcm9tIDQgY2hhbm5lbHMgaW50byBvbmVcbiAqL1xuZXhwb3J0IGNsYXNzIEZyYWdDb2xvckdsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIHJldHVybiB7Li4udGhpcy5zZXRGcmFnQ29sb3IoKSwgLi4udGhpcy5nZXRDb2xvckFzRmxvYXQoKX07XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKToge1tuYW1lOiBzdHJpbmddOiBzdHJpbmd9IHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgcHJvdGVjdGVkIHNldEZyYWdDb2xvcigpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICByZXR1cm4ge1xuICAgICAgc2V0RnJhZ0NvbG9yOiBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgICAgYFxuICAgICAgICB2b2lkIHNldEZyYWdDb2xvcihmbG9hdCB2YWx1ZSkge1xuICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSBlbmNvZGUodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGAsXG4gICAgICAgICAgWydlbmNvZGluZy5lbmNvZGUnXSlcbiAgICB9O1xuICB9XG4gIHByb3RlY3RlZCBnZXRDb2xvckFzRmxvYXQoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIHJldHVybiB7XG4gICAgICBnZXRDb2xvckFzRmxvYXQ6IG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgICBgXG4gICAgICAgIGZsb2F0IGdldENvbG9yQXNGbG9hdCh2ZWM0IGNvbG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVjb2RlKGNvbG9yKTtcbiAgICAgICAgfVxuICAgICAgICBgLFxuICAgICAgICAgIFsnZW5jb2RpbmcuZGVjb2RlJ10pXG4gICAgfTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZX0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcblxuLyoqXG4gKiBHTFNMIExpYnJhcnkgcmVzcG9uc2libGUgZm9yIGRhdGEgdHlwZXMgYW5kIHJvdXRpbmVzIGZvciBtYW5pcHVsYXRpbmdcbiAqIGNvb3JkaW5hdGVzIGFuZCBtYXBwaW5nIHRvL2Zyb20gdGVuc29yIGluZGljZXNcbiAqL1xuZXhwb3J0IGNsYXNzIFNoYXBlVXRpbHNHbHNsTGliIGV4dGVuZHMgR2xzbExpYiB7XG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IEdsc2xDb250ZXh0KSB7XG4gICAgc3VwZXIoY29udGV4dCk7XG4gIH1cbiAgZ2V0RnVuY3Rpb25zKCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5iY2FzdEluZGV4KCksXG4gICAgICAuLi50aGlzLmJjYXN0TWF0bXVsSW5kZXgoKSxcbiAgICAgIC4uLnRoaXMub2Zmc2V0VG9JbmRpY2VzKCksXG4gICAgICAuLi50aGlzLmluZGljZXNUb09mZnNldCgpLFxuICAgICAgLi4udGhpcy5pbmNyZW1lbnRJbmRpY2VzKClcbiAgICB9O1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBwcm90ZWN0ZWQgYmNhc3RJbmRleCgpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3Qgb3V0cHV0UmFuayA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCByZXN1bHQ6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS51bnBhY2tlZFNoYXBlO1xuICAgICAgaWYgKHNoYXBlLmxlbmd0aCA8PSBvdXRwdXRSYW5rKSB7XG4gICAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGRpbU9mZnNldCA9IG91dHB1dFJhbmsgLSByYW5rO1xuICAgICAgICBjb25zdCBmdW5jTmFtZSA9IGBiY2FzdEluZGljZXNfJHtuYW1lfWA7XG4gICAgICAgIGxldCBibG9jayA9ICcnO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgICAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgICByZWFsSW5kaWNlc1ske2l9XSA9IGludCggbW9kKGZsb2F0KGJjYXN0ZWRJbmRpY2VzWyR7ZGltT2Zmc2V0ICsgaX1dKSwgJHtzaGFwZVtpXX0uMCkgKTtcbiAgICAgICAgICBgO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICAgIHZvaWQgJHtmdW5jTmFtZX0gKGludCBiY2FzdGVkSW5kaWNlc1ske291dHB1dFJhbmt9XSwgb3V0IGludCByZWFsSW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgICR7YmxvY2t9XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShib2R5KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHByb3RlY3RlZCBiY2FzdE1hdG11bEluZGV4KCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCBvdXRwdXRSYW5rID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHJlc3VsdDoge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgaWYgKCEoc2hhcGUubGVuZ3RoIDwgMiB8fCBzaGFwZS5sZW5ndGggPiBvdXRwdXRSYW5rKSkge1xuICAgICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgICBjb25zdCBkaW1PZmZzZXQgPSBvdXRwdXRSYW5rIC0gcmFuaztcbiAgICAgICAgY29uc3QgZnVuY05hbWUgPSBgYmNhc3RNYXRtdWxJbmRpY2VzXyR7bmFtZX1gO1xuICAgICAgICBsZXQgYmxvY2sgPSAnJztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMjsgKytpKSB7XG4gICAgICAgICAgYmxvY2sgKz0gYFxuICAgICAgICAgIHJlYWxJbmRpY2VzWyR7aX1dID0gaW50KCBtb2QoZmxvYXQoYmNhc3RlZEluZGljZXNbJHtkaW1PZmZzZXQgKyBpfV0pLCAke3NoYXBlW2ldfS4wKSApO1xuICAgICAgICAgIGA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYm9keSA9IGBcbiAgICAgICAgdm9pZCAke2Z1bmNOYW1lfShpbnQgYmNhc3RlZEluZGljZXNbJHtvdXRwdXRSYW5rfV0sIG91dCBpbnQgcmVhbEluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICAke2Jsb2NrfVxuICAgICAgICAgIHJlYWxJbmRpY2VzWyR7cmFuayAtIDF9XSA9IGJjYXN0ZWRJbmRpY2VzWyR7b3V0cHV0UmFuayAtIDF9XTtcbiAgICAgICAgICByZWFsSW5kaWNlc1ske3JhbmsgLSAyfV0gPSBiY2FzdGVkSW5kaWNlc1ske291dHB1dFJhbmsgLSAyfV07XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShib2R5KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHByb3RlY3RlZCBpbmRpY2VzVG9PZmZzZXQoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IHJlc3VsdDoge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgY29uc3Qgc3RyaWRlcyA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnN0cmlkZXM7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgbGV0IGZ1bmNOYW1lID0gYGluZGljZXNUb09mZnNldF8ke25hbWV9YDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoU2hhcGVVdGlsc0dsc2xMaWIuaW5kZXhUb09mZnNldFNpbmdsZShmdW5jTmFtZSwgcmFuaywgc3RyaWRlcykpO1xuICAgICAgZnVuY05hbWUgPSBgaW5kaWNlc1RvT2Zmc2V0XyR7bmFtZX1fVGA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID1cbiAgICAgICAgICBuZXcgR2xzbExpYlJvdXRpbmUoU2hhcGVVdGlsc0dsc2xMaWIuaW5kZXhUb09mZnNldFNpbmdsZShmdW5jTmFtZSwgcmFuaywgc3RyaWRlcy5zbGljZSgpLnJldmVyc2UoKSkpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgc3RhdGljIGluZGV4VG9PZmZzZXRTaW5nbGUobmFtZTogc3RyaW5nLCByYW5rOiBudW1iZXIsIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdKTogc3RyaW5nIHtcbiAgICBsZXQgYmxvY2sgPSAnJztcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBibG9jayArPSBgXG4gICAgICAgIG9mZnNldCArPSBpbmRpY2VzWyR7aX1dICogJHtzdHJpZGVzW2ldfTtcbiAgICAgICAgYDtcbiAgICB9XG4gICAgcmV0dXJuIGBcbiAgICAgIGludCAke25hbWV9KGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGludCBvZmZzZXQgPSAwO1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgICByZXR1cm4gb2Zmc2V0O1xuICAgICAgfVxuICAgICAgYDtcbiAgfVxuICBwcm90ZWN0ZWQgb2Zmc2V0VG9JbmRpY2VzKCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCByZXN1bHQ6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9ID0ge307XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgY29uc3Qgc2hhcGUgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zaGFwZTtcbiAgICAgIGNvbnN0IHN0cmlkZXMgPSB0aGlzLmNvbnRleHQuaW5wdXRUZXh0dXJlTGF5b3V0c1tpXS5zdHJpZGVzO1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGxldCBmdW5jTmFtZSA9IGBvZmZzZXRUb0luZGljZXNfJHtuYW1lfWA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKFNoYXBlVXRpbHNHbHNsTGliLm9mZnNldFRvSW5kaWNlc1NpbmdsZShmdW5jTmFtZSwgcmFuaywgc3RyaWRlcykpO1xuICAgICAgZnVuY05hbWUgPSBgb2Zmc2V0VG9JbmRpY2VzXyR7bmFtZX1fVGA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID1cbiAgICAgICAgICBuZXcgR2xzbExpYlJvdXRpbmUoU2hhcGVVdGlsc0dsc2xMaWIub2Zmc2V0VG9JbmRpY2VzU2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzLnNsaWNlKCkucmV2ZXJzZSgpKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBzdGF0aWMgb2Zmc2V0VG9JbmRpY2VzU2luZ2xlKG5hbWU6IHN0cmluZywgcmFuazogbnVtYmVyLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RyaWRlc0Jsb2NrID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rIC0gMTsgKytpKSB7XG4gICAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICBpbmRpY2VzWyR7aX1dID0gb2Zmc2V0IC8gJHtzdHJpZGVzW2ldfTtgKTtcbiAgICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgICAgb2Zmc2V0IC09IGluZGljZXNbJHtpfV0gKiAke3N0cmlkZXNbaV19O2ApO1xuICAgIH1cbiAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICBpbmRpY2VzWyR7cmFuayAtIDF9XSA9IG9mZnNldDtgKTtcbiAgICByZXR1cm4gYFxuICAgICAgdm9pZCAke25hbWV9KGludCBvZmZzZXQsIG91dCBpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAke3N0cmlkZXNCbG9jay5qb2luKCcnKX1cbiAgICAgIH1cbiAgICAgIGA7XG4gIH1cbiAgcHJvdGVjdGVkIGluY3JlbWVudEluZGljZXMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IHJlc3VsdDoge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IGZ1bmNOYW1lID0gYGluY3JlbWVudEluZGljZXNfJHtuYW1lfWA7XG4gICAgICBsZXQgc2hhcGVJbml0ID0gJyc7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgICAgICBzaGFwZUluaXQgKz0gYFxuICAgICAgICBzaGFwZVske2l9XSA9ICR7c2hhcGVbaV19O2A7XG4gICAgICB9XG4gICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7ZnVuY05hbWV9KGludCBheGlzLCBvdXQgaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgc2hhcGVbJHtyYW5rfV07XG4gICAgICAgICAgJHtzaGFwZUluaXR9O1xuICAgICAgICAgIGZvcihpbnQgaSA9ICR7cmFua30gLTEgOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgaWYoaSA+IGF4aXMpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaW5kaWNlc1tpXSArPSAxO1xuICAgICAgICAgICAgaWYoaW5kaWNlc1tpXSA8IHNoYXBlW2ldKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kaWNlc1tpXSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmV9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5cbi8qKlxuICogR0xTTCBMaWJyYXJ5IHJlc3BvbnNpYmxlIGZvciB2ZWMgcm91dGluZXNcbiAqIFZlYyBpcyBhbiB2YXJpYmxlIGxlbmd0aCBpbnQgYXJyYXkuIFRoZSBsZW5ndGggaXMgZml4ZWQgYXQgdGhlIHRpbWUgb2ZcbiAqIGdlbmVyYXRpbmcgdGhlIGxpYnJhcnkgZnVuY3Rpb25zIGZyb20gdGhlIGRpbWVuc2lvbnMgb2YgdGhlIG91dHB1dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7W25hbWU6IHN0cmluZ106IHN0cmluZ30ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIHJldHVybiB7Li4udGhpcy5iaW5hcnlWZWNGdW5jdGlvbnMoKSwgLi4udGhpcy5jb3B5VmVjKCksIC4uLnRoaXMuc2V0VmVjSXRlbSgpLCAuLi50aGlzLmdldFZlY0l0ZW0oKX07XG4gIH1cbiAgcHJvdGVjdGVkIGJpbmFyeVZlY0Z1bmN0aW9ucygpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dExheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgbmFtZU9wOiB7W25hbWU6IHN0cmluZ106IHN0cmluZ30gPSB7YWRkOiAnKz0nLCBzdWI6ICctPScsIG11bDogJyo9JywgZGl2OiAnLz0nfTtcbiAgICBjb25zdCByZXN1bHQ6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9ID0ge307XG4gICAgZm9yIChjb25zdCBuYW1lIGluIG5hbWVPcCkge1xuICAgICAgY29uc3QgZm5hbWUgPSBgJHtuYW1lfVZlY2A7XG4gICAgICBsZXQgYXNzaWdubWVudEJsb2NrID0gJyc7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgICAgICBhc3NpZ25tZW50QmxvY2sgKz0gYFxuICAgICAgICAgIGRlc3RbJHtpfV0gJHtuYW1lT3BbbmFtZV19IHNyY1ske2l9XTtcbiAgICAgICAgICBgO1xuICAgICAgfVxuICAgICAgY29uc3QgYm9keSA9IGBcbiAgICAgICAgdm9pZCAke2ZuYW1lfShpbnQgc3JjWyR7cmFua31dLCBvdXQgaW50IGRlc3RbJHtyYW5rfV0pIHtcbiAgICAgICAgICAke2Fzc2lnbm1lbnRCbG9ja31cbiAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmVzdWx0W2ZuYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShib2R5KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHByb3RlY3RlZCBjb3B5VmVjKCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0TGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBsZXQgYXNzaWdubWVudEJsb2NrID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAgIGFzc2lnbm1lbnRCbG9jayArPSBgXG4gICAgICAgIGRlc3RbJHtpfV0gPSBzcmNbJHtpfV07XG4gICAgICAgIGA7XG4gICAgfVxuICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICB2b2lkIGNvcHlWZWMoaW50IHNyY1ske3Jhbmt9XSwgb3V0IGludCBkZXN0WyR7cmFua31dKSB7XG4gICAgICAgICR7YXNzaWdubWVudEJsb2NrfVxuICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4ge2NvcHlWZWM6IG5ldyBHbHNsTGliUm91dGluZShib2R5KX07XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0VmVjSXRlbSgpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dExheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgbGV0IGJsb2NrID0gYFxuICAgICAgICBpZihpbmRleCA8IDApXG4gICAgICAgICAgICBpbmRleCA9JHtyYW5rfSArIGluZGV4O1xuICAgICAgICBpZiAoaW5kZXggPT0gMClcbiAgICAgICAgICAgIG1bMF0gPSB2YWx1ZTtcbiAgICAgICAgYDtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJhbmsgLSAxOyArK2kpIHtcbiAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgZWxzZSBpZiAoaW5kZXggPT0gJHtpfSlcbiAgICAgICAgICAgIG1bJHtpfV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIGA7XG4gICAgfVxuICAgIGJsb2NrICs9IGBcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbVske3JhbmsgLSAxfV0gPSB2YWx1ZTtcbiAgICAgICAgYDtcbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgdm9pZCBzZXRWZWNJdGVtKG91dCBpbnQgbVske3Jhbmt9XSwgaW50IGluZGV4LCBpbnQgdmFsdWUpIHtcbiAgICAgICAgJHtibG9ja31cbiAgICAgIH1cbiAgICAgICAgYDtcbiAgICByZXR1cm4ge3NldFZlY0l0ZW06IG5ldyBHbHNsTGliUm91dGluZShib2R5KX07XG4gIH1cbiAgcHJvdGVjdGVkIGdldFZlY0l0ZW0oKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGxldCBibG9jayA9IGBcbiAgICAgICAgaWYoaW5kZXggPCAwKVxuICAgICAgICAgICAgaW5kZXggPSAke3Jhbmt9ICsgaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIG1bMF07XG4gICAgICBgO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PSAke2l9KVxuICAgICAgICAgICAgcmV0dXJuIG1bJHtpfV07XG4gICAgICBgO1xuICAgIH1cbiAgICBibG9jayArPSBgXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiBtWyR7cmFuayAtIDF9XTtcbiAgICAgICAgYDtcbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgaW50IGdldFZlY0l0ZW0oaW50IG1bJHtyYW5rfV0sIGludCBpbmRleCkge1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIHtnZXRWZWNJdGVtOiBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSl9O1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7Q29vcmRzR2xzbExpYn0gZnJvbSAnLi9nbHNsLWNvb3JkaW5hdGUtbGliJztcbmltcG9ydCB7R2xzbENvbnRleHQsIEdsc2xMaWJ9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQge0VuY29kaW5nR2xzbExpYn0gZnJvbSAnLi9nbHNsLWVuY29kaW5nLWxpYic7XG5pbXBvcnQge0ZyYWdDb2xvckdsc2xMaWJ9IGZyb20gJy4vZ2xzbC1mcmFnY29sb3ItbGliJztcbmltcG9ydCB7U2hhcGVVdGlsc0dsc2xMaWJ9IGZyb20gJy4vZ2xzbC1zaGFwZS11dGlscy1saWInO1xuaW1wb3J0IHtWZWNHbHNsTGlifSBmcm9tICcuL2dsc2wtdmVjLWxpYic7XG5cbmV4cG9ydCBjb25zdCBnbHNsUmVnaXN0cnk6IHtbbmFtZTogc3RyaW5nXTogbmV3IChjb250ZXh0OiBHbHNsQ29udGV4dCkgPT4gR2xzbExpYn0gPSB7XG4gICdlbmNvZGluZyc6IEVuY29kaW5nR2xzbExpYixcbiAgJ2ZyYWdjb2xvcic6IEZyYWdDb2xvckdsc2xMaWIsXG4gICd2ZWMnOiBWZWNHbHNsTGliLFxuICAnc2hhcGVVdGlscyc6IFNoYXBlVXRpbHNHbHNsTGliLFxuICAnY29vcmRpbmF0ZXMnOiBDb29yZHNHbHNsTGliLFxuICAvLyAgJ2FycmF5cyc6IEFycmF5R2xzbFNMaWJcbn07XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7R2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lTm9kZSwgVG9wb2xvZ2ljYWxTb3J0R2xzbFJvdXRpbmVzfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHtyZXBsYWNlSW5saW5lc30gZnJvbSAnLi9nbHNsLWZ1bmN0aW9uLWlubGluZXInO1xuaW1wb3J0IHtnbHNsUmVnaXN0cnl9IGZyb20gJy4vZ2xzbC1yZWdpc3RlcmVkLWxpYnMnO1xuaW1wb3J0IHtnZXREZWZhdWx0RnJhZ1NoYWRlck1haW4sIGdldEZyYWdTaGFkZXJQcmVhbWJsZX0gZnJvbSAnLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBUZXh0dXJlTGF5b3V0LCBWYXJpYWJsZUluZm99IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtXZWJHTENvbnRleHR9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbi8qKlxuICogUHJlcHJvY2Vzc29yIGZvciB0aGUgYWRkaXRpb25zIHRvIHRoZSBHTFNMIGxhbmd1YWdlXG4gKiBJdCBkZWFscyB3aXRoOlxuICogIEBpbmNsdWRlIGRpcmVjdGl2ZXNcbiAqICBAaW5saW5lXG4gKiAgTG9vcCB1bnJvbGxpbmcgKG5vdCBpbXBsZW1lbnRlZClcbiAqICBNYWNybyByZXNvbHV0aW9uIChub3QgaW1wbGVtZW50ZWQpXG4gKi9cbmV4cG9ydCBjbGFzcyBHbHNsUHJlcHJvY2Vzc29yIHtcbiAgcmVhZG9ubHkgY29udGV4dDogR2xzbENvbnRleHQ7XG4gIHJlYWRvbmx5IGxpYnM6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYn0gPSB7fTtcbiAgcmVhZG9ubHkgZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGg6IHtbcm91dGluZU5hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lTm9kZX0gPSB7fTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICAgIGdsQ29udGV4dDogV2ViR0xDb250ZXh0LCBwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm8sIGlucHV0VGV4dHVyZUxheW91dHM6IFRleHR1cmVMYXlvdXRbXSxcbiAgICAgIG91dHB1dFRleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQpIHtcbiAgICB0aGlzLmNvbnRleHQgPSBuZXcgR2xzbENvbnRleHQoZ2xDb250ZXh0LCBwcm9ncmFtSW5mbywgaW5wdXRUZXh0dXJlTGF5b3V0cywgb3V0cHV0VGV4dHVyZUxheW91dCk7XG5cbiAgICAvLyBjb25zdHJ1Y3QgR2xzbExpYnNcbiAgICBPYmplY3Qua2V5cyhnbHNsUmVnaXN0cnkpLmZvckVhY2goKG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgbGliID0gbmV3IGdsc2xSZWdpc3RyeVtuYW1lXSh0aGlzLmNvbnRleHQpO1xuICAgICAgdGhpcy5saWJzW25hbWVdID0gbGliO1xuICAgIH0pO1xuXG4gICAgLy8gY29uc3RydWN0IEdsc2xSb3V0aW5lRGVwZW5kZW5jeUdyYXBoXG4gICAgY29uc3QgbWFwID0gdGhpcy5nbHNsTGliUm91dGluZURlcGVuZGVuY3lHcmFwaDtcbiAgICBmb3IgKGNvbnN0IGxpYk5hbWUgaW4gdGhpcy5saWJzKSB7XG4gICAgICBjb25zdCBsaWIgPSB0aGlzLmxpYnNbbGliTmFtZV07XG4gICAgICBjb25zdCByb3V0aW5lc0luTGliID0gbGliLmdldEZ1bmN0aW9ucygpO1xuICAgICAgZm9yIChjb25zdCByb3V0aW5lIGluIHJvdXRpbmVzSW5MaWIpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gbGliTmFtZSArICcuJyArIHJvdXRpbmU7XG4gICAgICAgIGxldCBjdXJyZW50Tm9kZTogR2xzbExpYlJvdXRpbmVOb2RlO1xuICAgICAgICBpZiAobWFwW2tleV0pIHtcbiAgICAgICAgICBjdXJyZW50Tm9kZSA9IG1hcFtrZXldO1xuICAgICAgICAgIGN1cnJlbnROb2RlLnJvdXRpbmVCb2R5ID0gcm91dGluZXNJbkxpYltyb3V0aW5lXS5yb3V0aW5lQm9keTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJyZW50Tm9kZSA9IG5ldyBHbHNsTGliUm91dGluZU5vZGUoa2V5LCByb3V0aW5lc0luTGliW3JvdXRpbmVdLnJvdXRpbmVCb2R5KTtcbiAgICAgICAgICBtYXBba2V5XSA9IGN1cnJlbnROb2RlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IHJvdXRpbmVzSW5MaWJbcm91dGluZV0uZGVwZW5kZW5jaWVzO1xuICAgICAgICBpZiAoZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXBlbmRlbmNpZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmICghbWFwW2RlcGVuZGVuY2llc1tpXV0pIHtcbiAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IG5ldyBHbHNsTGliUm91dGluZU5vZGUoZGVwZW5kZW5jaWVzW2ldKTtcbiAgICAgICAgICAgICAgbWFwW2RlcGVuZGVuY2llc1tpXV0gPSBub2RlO1xuICAgICAgICAgICAgICBjdXJyZW50Tm9kZS5hZGREZXBlbmRlbmN5KG5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY3VycmVudE5vZGUuYWRkRGVwZW5kZW5jeShtYXBbZGVwZW5kZW5jaWVzW2ldXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJlcHJvY2VzcygpOiBzdHJpbmcge1xuICAgIGNvbnN0IHByb2dyYW1JbmZvID0gdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvO1xuICAgIGxldCBzb3VyY2UgPSBwcm9ncmFtSW5mby5zaGFkZXJTb3VyY2U7XG5cbiAgICAvLyBhcHBlbmQgbWFpbigpIGZ1bmN0aW9uXG4gICAgaWYgKCF0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaGFzTWFpbikge1xuICAgICAgc291cmNlID0gYCR7c291cmNlfVxuICAgICAgJHtnZXREZWZhdWx0RnJhZ1NoYWRlck1haW4odGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uLCB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dC5zaGFwZS5sZW5ndGgpfWA7XG4gICAgfVxuICAgIC8vIHJlcGxhY2UgaW5saW5lc1xuICAgIHNvdXJjZSA9IHJlcGxhY2VJbmxpbmVzKHNvdXJjZSk7XG5cbiAgICAvLyBjb25jYXQgZmluYWwgc291cmNlIHN0cmluZ1xuICAgIHJldHVybiBgJHtnZXRGcmFnU2hhZGVyUHJlYW1ibGUodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKX1cbiAgICAke3RoaXMuZ2V0VW5pZm9ybXMocHJvZ3JhbUluZm8uaW5wdXROYW1lcywgcHJvZ3JhbUluZm8udmFyaWFibGVzKX1cbiAgICAke3RoaXMuZ2V0SW1wb3J0cyhzb3VyY2UpfVxuICAgICR7c291cmNlfWA7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0SW1wb3J0cyhzY3JpcHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3Qgcm91dGluZXNJbmNsdWRlZCA9IHRoaXMuc2VsZWN0R2xzbExpYlJvdXRpbmVzVG9CZUluY2x1ZGVkKHNjcmlwdCk7XG5cbiAgICBpZiAocm91dGluZXNJbmNsdWRlZC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBsZXQgcm91dGluZXMgPSAnJztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvdXRpbmVzSW5jbHVkZWQubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmIChyb3V0aW5lc0luY2x1ZGVkW2ldLnJvdXRpbmVCb2R5KSB7XG4gICAgICAgIHJvdXRpbmVzICs9IHJvdXRpbmVzSW5jbHVkZWRbaV0ucm91dGluZUJvZHkgKyAnXFxuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyBib2R5IGZvciB0aGUgR2xzbCBMaWJyYXJ5IHJvdXRpbmU6ICR7cm91dGluZXNJbmNsdWRlZFtpXS5uYW1lfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByb3V0aW5lcztcbiAgfVxuICBwcml2YXRlIHNlbGVjdEdsc2xMaWJSb3V0aW5lc1RvQmVJbmNsdWRlZChzY3JpcHQ6IHN0cmluZyk6IEdsc2xMaWJSb3V0aW5lTm9kZVtdIHtcbiAgICBjb25zdCBub2RlczogR2xzbExpYlJvdXRpbmVOb2RlW10gPSBbXTtcblxuICAgIE9iamVjdC5rZXlzKHRoaXMuZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGgpLmZvckVhY2goY2xhc3NBbmRSb3V0aW5lID0+IHtcbiAgICAgIGNvbnN0IHJvdXRpbmUgPSBjbGFzc0FuZFJvdXRpbmUuc3BsaXQoJy4nKVsxXTtcbiAgICAgIGlmIChzY3JpcHQuaW5kZXhPZihyb3V0aW5lKSAhPT0gLTEpIHtcbiAgICAgICAgbm9kZXMucHVzaCh0aGlzLmdsc2xMaWJSb3V0aW5lRGVwZW5kZW5jeUdyYXBoW2NsYXNzQW5kUm91dGluZV0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIFRvcG9sb2dpY2FsU29ydEdsc2xSb3V0aW5lcy5yZXR1cm5PcmRlcmVkTm9kZXMobm9kZXMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldFVuaWZvcm1zKHNhbXBsZXJzPzogc3RyaW5nW10sIHZhcmlhYmxlcz86IFZhcmlhYmxlSW5mb1tdKTogc3RyaW5nIHtcbiAgICBjb25zdCB1bmlmb3JtTGluZXM6IHN0cmluZ1tdID0gW107XG4gICAgaWYgKHNhbXBsZXJzKSB7XG4gICAgICBmb3IgKGNvbnN0IHNhbXBsZXIgb2Ygc2FtcGxlcnMpIHtcbiAgICAgICAgdW5pZm9ybUxpbmVzLnB1c2goYHVuaWZvcm0gc2FtcGxlcjJEICR7c2FtcGxlcn07YCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh2YXJpYWJsZXMpIHtcbiAgICAgIGZvciAoY29uc3QgdmFyaWFibGUgb2YgdmFyaWFibGVzKSB7XG4gICAgICAgIHVuaWZvcm1MaW5lcy5wdXNoKFxuICAgICAgICAgICAgYHVuaWZvcm0gJHt2YXJpYWJsZS50eXBlfSAke3ZhcmlhYmxlLm5hbWV9JHt2YXJpYWJsZS5hcnJheUxlbmd0aCA/IGBbJHt2YXJpYWJsZS5hcnJheUxlbmd0aH1dYCA6ICcnfTtgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuaWZvcm1MaW5lcy5qb2luKCdcXG4nKTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge2Vudn0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHtMb2dnZXIsIFByb2ZpbGVyfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcblxuaW1wb3J0IHtHbHNsUHJlcHJvY2Vzc29yfSBmcm9tICcuL2dsc2wtcHJlcHJvY2Vzc29yJztcbmltcG9ydCB7Z2V0VmVydGV4U2hhZGVyU291cmNlfSBmcm9tICcuL2dsc2wtc291cmNlJztcbmltcG9ydCB7VGV4dHVyZUxheW91dFN0cmF0ZWd5fSBmcm9tICcuL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5JztcbmltcG9ydCB7QXJ0aWZhY3QsIFByb2dyYW1JbmZvLCBQcm9ncmFtVmFyaWFibGUsIFRleHR1cmVEYXRhLCBUZXh0dXJlTGF5b3V0LCBWYXJpYWJsZUluZm99IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtXZWJHTENvbnRleHR9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbi8qKlxuICogUHJvZ3JhbU1hbmFnZXIgaXMgdGhlIG1haW4gY2xhc3MgYmVoaW5kIHJ1bm5pbmcgY29tcHV0YXRpb25zXG4gKiBJdCBidWlsZHMgUHJvZ3JhbUluZm8ncyBpbnRvIEFydGlmYWN0c1xuICogSXQgY29tcGlsZXMgZ2l2ZW4gUHJvZ3JhbUluZm8ncyBpbnRvIFdlYkdMIFByb3JhbXMgKGNhY2hlZCBhcyBBcnRpZmFjdHMpXG4gKiBVc2VzIHRoZSBhcnRpZmFjdCB0byBydW4gdGhlIGNvbXB1dGF0aW9uIGJ5IGNhbGxpbmcgRHJhdyBvblxuICogdGhlIFdlYkdMIGRyYXdpbmcgYnVmZmVyXG4gKiBQcm9ncmFtTWFuYWdlciBhdXRvbWF0aWNhbGx5IG1hcHMgKGJpbmRzKSBpbnB1dCB2YXJpYWJsZXMgdG8gdGhlaXJcbiAqIGNvcnJlc3BvbmRpbmcgTG9jYXRpb24ncyBpbiB0aGUgYmluYXJ5IHByb2dyYW1cbiAqL1xuZXhwb3J0IGNsYXNzIFByb2dyYW1NYW5hZ2VyIHtcbiAgcmVwbzogTWFwPHVua25vd24sIEFydGlmYWN0PjsgIC8vIHRoaXMgc2hvdWxkIGJlIHBlci1zZXNzaW9uIG9iamVjdFxuICB2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyO1xuICBhdHRyaWJ1dGVzQm91bmQ6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPiwgcHVibGljIGdsQ29udGV4dDogV2ViR0xDb250ZXh0LFxuICAgICAgcHVibGljIHRleHR1cmVMYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5KSB7XG4gICAgdGhpcy5yZXBvID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuYXR0cmlidXRlc0JvdW5kID0gZmFsc2U7XG4gIH1cbiAgZ2V0QXJ0aWZhY3Qoa2V5OiB1bmtub3duKTogQXJ0aWZhY3R8dW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5yZXBvLmdldChrZXkpO1xuICB9XG4gIHNldEFydGlmYWN0KGtleTogdW5rbm93biwgYXJ0aWZhY3Q6IEFydGlmYWN0KTogdm9pZCB7XG4gICAgdGhpcy5yZXBvLnNldChrZXksIGFydGlmYWN0KTtcbiAgfVxuICBydW4oYnVpbGRBcnRpZmFjdDogQXJ0aWZhY3QsIGlucHV0czogVGV4dHVyZURhdGFbXSwgb3V0cHV0OiBUZXh0dXJlRGF0YSk6IHZvaWQge1xuICAgIHRoaXMucHJvZmlsZXIuZXZlbnQoJ29wJywgYFByb2dyYW1NYW5hZ2VyLnJ1biAke2J1aWxkQXJ0aWZhY3QucHJvZ3JhbUluZm8ubmFtZSA/PyAndW5rbm93biBrZXJuZWwnfWAsICgpID0+IHtcbiAgICAgIGNvbnN0IGdsID0gdGhpcy5nbENvbnRleHQuZ2w7XG4gICAgICBjb25zdCBwcm9ncmFtID0gYnVpbGRBcnRpZmFjdC5wcm9ncmFtO1xuICAgICAgZ2wudXNlUHJvZ3JhbShwcm9ncmFtKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuYmluZE91dHB1dChvdXRwdXQpO1xuICAgICAgICBpZiAoIXRoaXMuYXR0cmlidXRlc0JvdW5kKSB7XG4gICAgICAgICAgdGhpcy5iaW5kQXR0cmlidXRlcyhidWlsZEFydGlmYWN0LmF0dHJpYkxvY2F0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5iaW5kVW5pZm9ybXMoYnVpbGRBcnRpZmFjdC51bmlmb3JtTG9jYXRpb25zLCBidWlsZEFydGlmYWN0LnByb2dyYW1JbmZvLnZhcmlhYmxlcyA/PyBbXSwgaW5wdXRzKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBMb2dnZXIuZXJyb3IoJ1Byb2dyYW1NYW5hZ2VyJywgYnVpbGRBcnRpZmFjdC5wcm9ncmFtSW5mby5zaGFkZXJTb3VyY2UpO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgICB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ0dsQ29udGV4dC5kcmF3KCknLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuZ2xDb250ZXh0LmRyYXcoKTtcbiAgICAgIH0pO1xuICAgIH0sIHRoaXMuZ2xDb250ZXh0KTtcbiAgfVxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnZlcnRleFNoYWRlcikge1xuICAgICAgdGhpcy5nbENvbnRleHQuZGVsZXRlU2hhZGVyKHRoaXMudmVydGV4U2hhZGVyKTtcbiAgICB9XG4gICAgdGhpcy5yZXBvLmZvckVhY2goYSA9PiB0aGlzLmdsQ29udGV4dC5kZWxldGVQcm9ncmFtKGEucHJvZ3JhbSkpO1xuICB9XG4gIGJ1aWxkKHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbywgaW5wdXRUZXh0dXJlTGF5b3V0czogVGV4dHVyZUxheW91dFtdLCBvdXRwdXRUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogQXJ0aWZhY3Qge1xuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ1Byb2dyYW1NYW5hZ2VyLmJ1aWxkJywgKCkgPT4ge1xuICAgICAgY29uc3QgcHJlcHJvY2Vzc29yID0gbmV3IEdsc2xQcmVwcm9jZXNzb3IodGhpcy5nbENvbnRleHQsIHByb2dyYW1JbmZvLCBpbnB1dFRleHR1cmVMYXlvdXRzLCBvdXRwdXRUZXh0dXJlTGF5b3V0KTtcbiAgICAgIGNvbnN0IGZyYWdTY3JpcHQgPSBwcmVwcm9jZXNzb3IucHJlcHJvY2VzcygpO1xuICAgICAgY29uc3QgcHJvZ3JhbSA9IHRoaXMuY29tcGlsZShmcmFnU2NyaXB0KTtcbiAgICAgIGNvbnN0IGFydGlmYWN0ID0ge1xuICAgICAgICBwcm9ncmFtSW5mbyxcbiAgICAgICAgcHJvZ3JhbSxcbiAgICAgICAgdW5pZm9ybUxvY2F0aW9uczogdGhpcy5nZXRVbmlmb3JtTG9jYXRpb25zKFxuICAgICAgICAgICAgcHJvZ3JhbSwgcHJlcHJvY2Vzc29yLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcywgcHJlcHJvY2Vzc29yLmNvbnRleHQucHJvZ3JhbUluZm8udmFyaWFibGVzKSxcbiAgICAgICAgYXR0cmliTG9jYXRpb25zOiB0aGlzLmdldEF0dHJpYkxvY2F0aW9ucyhwcm9ncmFtKVxuICAgICAgfTtcbiAgICAgIHJldHVybiBhcnRpZmFjdDtcbiAgICB9KTtcbiAgfVxuICBwcm90ZWN0ZWQgY29tcGlsZShmcmFnU2hhZGVyU2NyaXB0OiBzdHJpbmcpOiBXZWJHTFByb2dyYW0ge1xuICAgIGlmICghdGhpcy52ZXJ0ZXhTaGFkZXIpIHtcbiAgICAgIExvZ2dlci52ZXJib3NlKCdQcm9yZ3JhbU1hbmFnZXInLCAnQ29tcGlsaW5nIGFuZCBjYWNoaW5nIFZlcnRleCBzaGFkZXIgZm9yIHRoZSBmaXJzdCB0aW1lJyk7XG4gICAgICBjb25zdCB2ZXJ0ZXhTaGFkZXJTY3JpcHQgPSBnZXRWZXJ0ZXhTaGFkZXJTb3VyY2UodGhpcy5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICB0aGlzLnZlcnRleFNoYWRlciA9IHRoaXMuZ2xDb250ZXh0LmNvbXBpbGVTaGFkZXIodmVydGV4U2hhZGVyU2NyaXB0LCB0aGlzLmdsQ29udGV4dC5nbC5WRVJURVhfU0hBREVSKTtcbiAgICB9XG4gICAgaWYgKGVudi5kZWJ1Zykge1xuICAgICAgTG9nZ2VyLnZlcmJvc2UoJ1Byb3JncmFtTWFuYWdlcicsIGBGcmFnU2hhZGVyOlxuJHtmcmFnU2hhZGVyU2NyaXB0fVxuYCk7XG4gICAgfVxuICAgIGNvbnN0IGZyYWdTaGFkZXIgPSB0aGlzLmdsQ29udGV4dC5jb21waWxlU2hhZGVyKGZyYWdTaGFkZXJTY3JpcHQsIHRoaXMuZ2xDb250ZXh0LmdsLkZSQUdNRU5UX1NIQURFUik7XG4gICAgY29uc3QgcHJvZ3JhbSA9IHRoaXMuZ2xDb250ZXh0LmNyZWF0ZVByb2dyYW0odGhpcy52ZXJ0ZXhTaGFkZXIsIGZyYWdTaGFkZXIpO1xuICAgIHRoaXMuZ2xDb250ZXh0LmRlbGV0ZVNoYWRlcihmcmFnU2hhZGVyKTtcbiAgICByZXR1cm4gcHJvZ3JhbTtcbiAgfVxuICBiaW5kT3V0cHV0KHRkOiBUZXh0dXJlRGF0YSk6IHZvaWQge1xuICAgIGNvbnN0IHdpZHRoID0gdGQud2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGQuaGVpZ2h0O1xuICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAnUHJvcmdyYW1NYW5hZ2VyJyxcbiAgICAgICAgYEJpbmRpbmcgb3V0cHV0IHRleHR1cmUgdG8gRnJhbWVidWZmZXI6IHcvaD0ke3dpZHRofS8ke2hlaWdodH0sIHNoYXBlPSR7dGQuc2hhcGV9LCB0eXBlPSR7dGQudGVuc29yLnR5cGV9YCk7XG4gICAgdGhpcy5nbENvbnRleHQuYXR0YWNoRnJhbWVidWZmZXIodGQudGV4dHVyZSwgd2lkdGgsIGhlaWdodCk7XG4gIH1cbiAgYmluZEF0dHJpYnV0ZXMoYXR0cmliTG9jYXRpb25zOiBBcnRpZmFjdC5BdHRyaWJMb2NhdGlvbnMpOiB2b2lkIHtcbiAgICBjb25zdCBwb3NpdGlvbkhhbmRsZSA9IGF0dHJpYkxvY2F0aW9ucy5wb3NpdGlvbjtcbiAgICBjb25zdCB0ZXh0dXJlQ29vcmRIYW5kbGUgPSBhdHRyaWJMb2NhdGlvbnMudGV4dHVyZUNvb3JkO1xuICAgIHRoaXMuZ2xDb250ZXh0LnNldFZlcnRleEF0dHJpYnV0ZXMocG9zaXRpb25IYW5kbGUsIHRleHR1cmVDb29yZEhhbmRsZSk7XG4gICAgdGhpcy5hdHRyaWJ1dGVzQm91bmQgPSB0cnVlO1xuICB9XG4gIGJpbmRVbmlmb3Jtcyh1bmlmb3JtTG9jYXRpb25zOiBBcnRpZmFjdC5Vbmlmb3JtTG9jYXRpb25zLCB2YXJpYWJsZXM6IFByb2dyYW1WYXJpYWJsZVtdLCB0ZXh0dXJlczogVGV4dHVyZURhdGFbXSk6XG4gICAgICB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2xDb250ZXh0LmdsO1xuICAgIGxldCB0ZXh0dXJlUG9zaXRpb24gPSAwO1xuICAgIGZvciAoY29uc3Qge25hbWUsIHR5cGUsIGxvY2F0aW9uLCBhcnJheUxlbmd0aH0gb2YgdW5pZm9ybUxvY2F0aW9ucykge1xuICAgICAgY29uc3QgdmFsdWUgPSB2YXJpYWJsZXMuZmluZCh2ID0+IHYubmFtZSA9PT0gbmFtZSk/LmRhdGE7XG4gICAgICBpZiAodHlwZSAhPT0gJ3NhbXBsZXIyRCcgJiYgIXZhbHVlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdmFyaWFibGUgJyR7bmFtZX0nIGRvZXMgbm90IGhhdmUgZGF0YSBkZWZpbmVkIGluIHByb2dyYW0gaW5mb2ApO1xuICAgICAgfVxuICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgIGNhc2UgJ3NhbXBsZXIyRCc6XG4gICAgICAgICAgdGhpcy5iaW5kVGV4dHVyZSh0ZXh0dXJlc1t0ZXh0dXJlUG9zaXRpb25dLCBsb2NhdGlvbiwgdGV4dHVyZVBvc2l0aW9uKTtcbiAgICAgICAgICB0ZXh0dXJlUG9zaXRpb24rKztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZmxvYXQnOlxuICAgICAgICAgIGlmIChhcnJheUxlbmd0aCkge1xuICAgICAgICAgICAgZ2wudW5pZm9ybTFmdihsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyW10pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWYobG9jYXRpb24sIHZhbHVlIGFzIG51bWJlcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdpbnQnOlxuICAgICAgICAgIGlmIChhcnJheUxlbmd0aCkge1xuICAgICAgICAgICAgZ2wudW5pZm9ybTFpdihsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyW10pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWkobG9jYXRpb24sIHZhbHVlIGFzIG51bWJlcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5pZm9ybSBub3QgaW1wbGVtZW50ZWQ6ICR7dHlwZX1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgYmluZFRleHR1cmUodGQ6IFRleHR1cmVEYXRhLCB1bmlmb3JtSGFuZGxlOiBXZWJHTFVuaWZvcm1Mb2NhdGlvbiwgcG9zaXRpb246IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZ2xDb250ZXh0LmJpbmRUZXh0dXJlVG9Vbmlmb3JtKHRkLnRleHR1cmUsIHBvc2l0aW9uLCB1bmlmb3JtSGFuZGxlKTtcbiAgfVxuICBnZXRBdHRyaWJMb2NhdGlvbnMocHJvZ3JhbTogV2ViR0xQcm9ncmFtKTogQXJ0aWZhY3QuQXR0cmliTG9jYXRpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgcG9zaXRpb246IHRoaXMuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgJ3Bvc2l0aW9uJyksXG4gICAgICB0ZXh0dXJlQ29vcmQ6IHRoaXMuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgJ3RleHR1cmVDb29yZCcpXG4gICAgfTtcbiAgfVxuICBnZXRVbmlmb3JtTG9jYXRpb25zKHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgc2FtcGxlcnM/OiBzdHJpbmdbXSwgdmFyaWFibGVzPzogVmFyaWFibGVJbmZvW10pOlxuICAgICAgQXJ0aWZhY3QuVW5pZm9ybUxvY2F0aW9ucyB7XG4gICAgY29uc3QgdW5pZm9ybUxvY2F0aW9uczogQXJ0aWZhY3QuVW5pZm9ybUxvY2F0aW9ucyA9IFtdO1xuICAgIGlmIChzYW1wbGVycykge1xuICAgICAgZm9yIChjb25zdCBzYW1wbGVyIG9mIHNhbXBsZXJzKSB7XG4gICAgICAgIHVuaWZvcm1Mb2NhdGlvbnMucHVzaCh7bmFtZTogc2FtcGxlciwgdHlwZTogJ3NhbXBsZXIyRCcsIGxvY2F0aW9uOiB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBzYW1wbGVyKX0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodmFyaWFibGVzKSB7XG4gICAgICBmb3IgKGNvbnN0IHZhcmlhYmxlIG9mIHZhcmlhYmxlcykge1xuICAgICAgICB1bmlmb3JtTG9jYXRpb25zLnB1c2goey4uLnZhcmlhYmxlLCBsb2NhdGlvbjogdGhpcy5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgdmFyaWFibGUubmFtZSl9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuaWZvcm1Mb2NhdGlvbnM7XG4gIH1cbiAgZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgbmFtZTogc3RyaW5nKTogV2ViR0xVbmlmb3JtTG9jYXRpb24ge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbENvbnRleHQuZ2w7XG4gICAgY29uc3QgcmVmZXJlbmNlID0gZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIG5hbWUpO1xuICAgIGlmIChyZWZlcmVuY2UgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5pZm9ybSAke25hbWV9IG5vdCBmb3VuZC5gKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlZmVyZW5jZTtcbiAgfVxuICBnZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtOiBXZWJHTFByb2dyYW0sIG5hbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICBjb25zdCBhdHRyaWJ1dGVMb2NhdGlvbjogbnVtYmVyID0gZ2wuZ2V0QXR0cmliTG9jYXRpb24ocHJvZ3JhbSwgbmFtZSk7XG4gICAgcmV0dXJuIGF0dHJpYnV0ZUxvY2F0aW9uO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7TG9nZ2VyLCBQcm9maWxlcn0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vdGVuc29yJztcblxuaW1wb3J0IHtFbmNvZGVyLCBFbmNvZGVyVXNhZ2V9IGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHtUZXh0dXJlTGF5b3V0U3RyYXRlZ3l9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHtUZXh0dXJlRGF0YSwgVGV4dHVyZUxheW91dH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQge1dlYkdMQ29udGV4dH0gZnJvbSAnLi93ZWJnbC1jb250ZXh0JztcblxuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlTWFuYWdlckNvbmZpZyB7XG4gIHJldXNlVGV4dHVyZXM/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFRleHR1cmVNYW5hZ2VyIGlzIHRoZSBtYWlubHkgcmVzcG9uc2libGUgZm9yIGNhY2hpbmcgVGV4dHVyZXNcbiAqIFRleHR1cmVzIGFyZSBjYWNoZWQgaW4gMiBsZXZlbHM6XG4gKiAgIDEuIHRoZSB0ZXh1cmVzIHdoaWNoIGFyZSBhc3NvY2lhdGVkIHdpdGggYSBkYXRhSWQgKGZyb20gVGVuc29yKVxuICogICAgQ2FjaGluZyB0aGVzZSBpcyBjcnVjaWFsIHRvIHBlcmZvcm1hbmNlLiBUaGVzZSBhcmUgSW4tdXNlIFRleHR1cmVzXG4gKiAgIDIuIHRleHR1cmVzIHdoaWNoIGFyZSBub3QgaW4gdXNlIGJ5IGFueSBjdXJyZW50IFByb2dyYW1JbmZvL1RlbnNvclxuICogICAgIFRoZXNlIGFyZSBjYWxsZWQgRnJlZSBUZXh0dXJlc1xuICogVGV4dHVyZU1hbmFnZXIgaXMgYWxzbyB1c2VkIHRvIGhlbHAgY3JlYXRpbmcgdGV4dHVyZXMuIEZvciB0aGlzIGl0XG4gKiB1c2VzIFdlYkdMQ29udGV4dCBhbmQgVGV4dHVyZUxheW91dFN0cmF0ZWd5XG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0dXJlTWFuYWdlciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5Vc2VUZXh0dXJlczogTWFwPHN0cmluZywgV2ViR0xUZXh0dXJlW10+O1xuICBwcml2YXRlIHJlYWRvbmx5IGlkbGVUZXh0dXJlczogTWFwPHN0cmluZywgV2ViR0xUZXh0dXJlW10+O1xuICBwcml2YXRlIHJlYWRvbmx5IHRleHR1cmVMb29rdXA6IE1hcDxXZWJHTFRleHR1cmUsIHN0cmluZz47XG4gIHByaXZhdGUgcmVhZG9ubHkgcGVuZGluZ1JlYWQ6IE1hcDxUZW5zb3IuSWQsIEFycmF5PChhcnI6IFRlbnNvci5OdW1iZXJUeXBlKSA9PiB2b2lkPj4gPSBuZXcgTWFwKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsIHB1YmxpYyBsYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5LCBwdWJsaWMgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPixcbiAgICAgIHByaXZhdGUgY29uZmlnOiBUZXh0dXJlTWFuYWdlckNvbmZpZykge1xuICAgIGlmIChjb25maWcucmV1c2VUZXh0dXJlcykge1xuICAgICAgdGhpcy5pblVzZVRleHR1cmVzID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5pZGxlVGV4dHVyZXMgPSBuZXcgTWFwKCk7XG4gICAgICB0aGlzLnRleHR1cmVMb29rdXAgPSBuZXcgTWFwKCk7XG4gICAgfVxuICB9XG4gIGNyZWF0ZVRleHR1cmVGcm9tTGF5b3V0KFxuICAgICAgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LCBkYXRhPzogVGVuc29yLk51bWJlclR5cGUsIHVzYWdlPzogRW5jb2RlclVzYWdlKSB7XG4gICAgY29uc3QgdGV4dHVyZURhdGFUeXBlID0gdGhpcy50b0VuY29kZXJUeXBlKGRhdGFUeXBlKTtcblxuICAgIGNvbnN0IGVuY29kZXIgPSB0aGlzLmdsQ29udGV4dC5nZXRFbmNvZGVyKHRleHR1cmVEYXRhVHlwZSwgbGF5b3V0LmNoYW5uZWxzIHx8IDEsIHVzYWdlKTtcbiAgICBpZiAobGF5b3V0LmlzUGFja2VkICYmIHVzYWdlID09PSBFbmNvZGVyVXNhZ2UuVXBsb2FkT25seSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG4gICAgY29uc3Qgd2lkdGggPSBsYXlvdXQud2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gbGF5b3V0LmhlaWdodDtcblxuICAgIGxldCBrZXk6IHN0cmluZ3x1bmRlZmluZWQ7XG4gICAgbGV0IGluVXNlVGV4dHVyZXM6IFdlYkdMVGV4dHVyZVtdfHVuZGVmaW5lZDtcbiAgICBpZiAodGhpcy5jb25maWcucmV1c2VUZXh0dXJlcykge1xuICAgICAga2V5ID0gYCR7d2lkdGh9eCR7aGVpZ2h0fV8ke2VuY29kZXIuZm9ybWF0fV8ke2VuY29kZXIuaW50ZXJuYWxGb3JtYXR9XyR7ZW5jb2Rlci50ZXh0dXJlVHlwZX1gO1xuICAgICAgaW5Vc2VUZXh0dXJlcyA9IHRoaXMuaW5Vc2VUZXh0dXJlcy5nZXQoa2V5KTtcbiAgICAgIGlmICghaW5Vc2VUZXh0dXJlcykge1xuICAgICAgICBpblVzZVRleHR1cmVzID0gW107XG4gICAgICAgIHRoaXMuaW5Vc2VUZXh0dXJlcy5zZXQoa2V5LCBpblVzZVRleHR1cmVzKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaWRsZVRleHR1cmVzID0gdGhpcy5pZGxlVGV4dHVyZXMuZ2V0KGtleSk7XG4gICAgICBpZiAoaWRsZVRleHR1cmVzICYmIGlkbGVUZXh0dXJlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHRleHR1cmUgPSBpZGxlVGV4dHVyZXMucG9wKCkhO1xuICAgICAgICBpblVzZVRleHR1cmVzLnB1c2godGV4dHVyZSk7XG4gICAgICAgIGlmICh1c2FnZSA9PT0gRW5jb2RlclVzYWdlLlVwbG9hZE9ubHkpIHtcbiAgICAgICAgICB0aGlzLmdsQ29udGV4dC51cGRhdGVUZXh0dXJlKHRleHR1cmUsIHdpZHRoLCBoZWlnaHQsIGVuY29kZXIsIHRoaXMudG9UZXh0dXJlRGF0YShkYXRhVHlwZSwgZGF0YSkhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGV4dHVyZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBMb2dnZXIudmVyYm9zZSgnVGV4dHVyZU1hbmFnZXInLCBgQ3JlYXRpbmcgbmV3IHRleHR1cmUgb2Ygc2l6ZSAke2xheW91dC53aWR0aH14JHtsYXlvdXQuaGVpZ2h0fWApO1xuICAgIGNvbnN0IHRleHR1cmUgPSB0aGlzLmdsQ29udGV4dC5hbGxvY2F0ZVRleHR1cmUod2lkdGgsIGhlaWdodCwgZW5jb2RlciwgdGhpcy50b1RleHR1cmVEYXRhKGRhdGFUeXBlLCBkYXRhKSk7XG5cbiAgICBpZiAodGhpcy5jb25maWcucmV1c2VUZXh0dXJlcykge1xuICAgICAgaW5Vc2VUZXh0dXJlcyEucHVzaCh0ZXh0dXJlKTtcbiAgICAgIHRoaXMudGV4dHVyZUxvb2t1cC5zZXQodGV4dHVyZSwga2V5ISk7XG4gICAgfVxuICAgIHJldHVybiB0ZXh0dXJlO1xuICB9XG4gIHJlYWRUZXh0dXJlKHRkOiBUZXh0dXJlRGF0YSwgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgY2hhbm5lbHM/OiBudW1iZXIpOiBUZW5zb3IuTnVtYmVyVHlwZSB7XG4gICAgaWYgKCFjaGFubmVscykge1xuICAgICAgY2hhbm5lbHMgPSAxO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnYmFja2VuZCcsICdUZXh0dXJlTWFuYWdlci5yZWFkVGV4dHVyZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGRhdGFTaXplID0gdGQuc2hhcGUucmVkdWNlKChhLCBiKSA9PiBhICogYikgKiBjaGFubmVscyE7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5nbENvbnRleHQucmVhZFRleHR1cmUoXG4gICAgICAgICAgdGQudGV4dHVyZSwgdGQud2lkdGgsIHRkLmhlaWdodCwgZGF0YVNpemUsIHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSksIGNoYW5uZWxzISk7XG4gICAgICByZXR1cm4gdGhpcy50b1RlbnNvckRhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgIH0pO1xuICB9XG4gIGFzeW5jIHJlYWRUZXh0dXJlQXN5bmModGQ6IFRleHR1cmVEYXRhLCBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBjaGFubmVscz86IG51bWJlcik6IFByb21pc2U8VGVuc29yLk51bWJlclR5cGU+IHtcbiAgICBjb25zdCBkYXRhSWQgPSB0ZC50ZW5zb3IuZGF0YUlkO1xuICAgIGlmICghY2hhbm5lbHMpIHtcbiAgICAgIGNoYW5uZWxzID0gMTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGVuZGluZ1JlYWQuaGFzKGRhdGFJZCkpIHtcbiAgICAgIGNvbnN0IHN1YnNjcmliZXJzID0gdGhpcy5wZW5kaW5nUmVhZC5nZXQoZGF0YUlkKTtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxUZW5zb3IuTnVtYmVyVHlwZT4ocmVzb2x2ZSA9PiBzdWJzY3JpYmVycz8ucHVzaChyZXNvbHZlKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ1RleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlQXN5bmMnLCBhc3luYyAoKSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdSZWFkLnNldChkYXRhSWQsIFtdKTtcbiAgICAgIGNvbnN0IGRhdGFTaXplID0gdGQuc2hhcGUucmVkdWNlKChhLCBiKSA9PiBhICogYikgKiBjaGFubmVscyE7XG4gICAgICAvLyBhZGQgYSBmZW5jZSB3YWl0aW5nIGZvciB0aGUgZGF0YSB0byBiZSByZWFkeVxuICAgICAgYXdhaXQgdGhpcy5nbENvbnRleHQuY3JlYXRlQW5kV2FpdEZvckZlbmNlKCk7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5nbENvbnRleHQucmVhZFRleHR1cmUoXG4gICAgICAgICAgdGQudGV4dHVyZSwgdGQud2lkdGgsIHRkLmhlaWdodCwgZGF0YVNpemUsIHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSksIGNoYW5uZWxzISk7XG4gICAgICBjb25zdCB0ZW5zb3JEYXRhID0gdGhpcy50b1RlbnNvckRhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgICAgY29uc3Qgc3Vic2NyaWJlcnMgPSB0aGlzLnBlbmRpbmdSZWFkLmdldChkYXRhSWQpO1xuICAgICAgdGhpcy5wZW5kaW5nUmVhZC5kZWxldGUoZGF0YUlkKTtcbiAgICAgIHN1YnNjcmliZXJzPy5mb3JFYWNoKHJlc29sdmUgPT4gcmVzb2x2ZSh0ZW5zb3JEYXRhKSk7XG4gICAgICByZXR1cm4gdGVuc29yRGF0YTtcbiAgICB9KTtcbiAgfVxuICByZWFkVWludDhUZXh0dXJlQXNGbG9hdCh0ZDogVGV4dHVyZURhdGEpOiBGbG9hdDMyQXJyYXkge1xuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ1RleHR1cmVNYW5hZ2VyLnJlYWRVaW50OFRleHR1cmVBc0Zsb2F0JywgKCkgPT4ge1xuICAgICAgY29uc3QgZGF0YVNpemUgPSB0ZC5zaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdsQ29udGV4dC5yZWFkVGV4dHVyZSh0ZC50ZXh0dXJlLCB0ZC53aWR0aCwgdGQuaGVpZ2h0LCBkYXRhU2l6ZSAqIDQsICdieXRlJywgNCk7XG4gICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShkYXRhLmJ1ZmZlciwgZGF0YS5ieXRlT2Zmc2V0LCBkYXRhU2l6ZSk7XG4gICAgfSk7XG4gIH1cbiAgcmVsZWFzZVRleHR1cmUodGV4dHVyZURhdGE6IFRleHR1cmVEYXRhLCBkZWxldGVUZXh0dXJlPzogYm9vbGVhbik6IHZvaWQge1xuICAgIGxldCBrZXk6IHN0cmluZ3x1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIGtleSA9IHRoaXMudGV4dHVyZUxvb2t1cC5nZXQodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICBpZiAoa2V5KSB7XG4gICAgICAgIGlmIChkZWxldGVUZXh0dXJlKSB7XG4gICAgICAgICAgdGhpcy50ZXh0dXJlTG9va3VwLmRlbGV0ZShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGluVXNlVGV4dHVyZXMgPSB0aGlzLmluVXNlVGV4dHVyZXMuZ2V0KGtleSk7XG4gICAgICAgIGlmIChpblVzZVRleHR1cmVzKSB7XG4gICAgICAgICAgY29uc3QgaW5kZXggPSBpblVzZVRleHR1cmVzLmluZGV4T2YodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgaW5Vc2VUZXh0dXJlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgbGV0IGlkbGVUZXh0dXJlcyA9IHRoaXMuaWRsZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgICAgICAgaWYgKCFpZGxlVGV4dHVyZXMpIHtcbiAgICAgICAgICAgICAgaWRsZVRleHR1cmVzID0gW107XG4gICAgICAgICAgICAgIHRoaXMuaWRsZVRleHR1cmVzLnNldChrZXksIGlkbGVUZXh0dXJlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZGxlVGV4dHVyZXMucHVzaCh0ZXh0dXJlRGF0YS50ZXh0dXJlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWtleSB8fCBkZWxldGVUZXh0dXJlKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZSgnVGV4dHVyZU1hbmFnZXInLCBgRGVsZXRpbmcgdGV4dHVyZSBvZiBzaXplICR7dGV4dHVyZURhdGEud2lkdGh9eCR7dGV4dHVyZURhdGEuaGVpZ2h0fWApO1xuICAgICAgdGhpcy5nbENvbnRleHQuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlRGF0YS50ZXh0dXJlKTtcbiAgICB9XG4gIH1cbiAgdG9UZW5zb3JEYXRhKGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGRhdGE6IEVuY29kZXIuRGF0YUFycmF5VHlwZSk6IFRlbnNvci5OdW1iZXJUeXBlIHtcbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50MTZBcnJheSA/IGRhdGEgOiBJbnQxNkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50MzJBcnJheSA/IGRhdGEgOiBJbnQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBJbnQ4QXJyYXkgPyBkYXRhIDogSW50OEFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIFVpbnQxNkFycmF5ID8gZGF0YSA6IFVpbnQxNkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIFVpbnQzMkFycmF5ID8gZGF0YSA6IFVpbnQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5ID8gZGF0YSA6IFVpbnQ4QXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IGRhdGEgOiBGbG9hdDMyQXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGRhdGEgOiBGbG9hdDY0QXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yRGF0YSB0eXBlICR7ZGF0YVR5cGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICB9XG4gIH1cbiAgdG9UZXh0dXJlRGF0YShfZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgZGF0YTogVGVuc29yLk51bWJlclR5cGV8dW5kZWZpbmVkKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlfHVuZGVmaW5lZCB7XG4gICAgaWYgKCFkYXRhKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gKGRhdGEgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkpID8gZGF0YSA6IG5ldyBGbG9hdDMyQXJyYXkoZGF0YSk7XG4gICAgLypcbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBVaW50MzJBcnJheSkgPyBkYXRhIGFzIFVpbnQzMkFycmF5IDogbmV3IFVpbnQzMkFycmF5KGRhdGEpO1xuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBVaW50OEFycmF5KSA/IGRhdGEgYXMgVWludDhBcnJheSA6IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICAgICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIChkYXRhLmNvbnN0cnVjdG9yID09PSBGbG9hdDMyQXJyYXkpID8gZGF0YSBhcyBGbG9hdDMyQXJyYXkgOiBuZXcgRmxvYXQzMkFycmF5KGRhdGEpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JEYXRhIHR5cGUgJHtkYXRhVHlwZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICAgIH1cbiAgICAqL1xuICB9XG4gIHRvRW5jb2RlclR5cGUoX2RhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUpOiBFbmNvZGVyLkRhdGFUeXBlIHtcbiAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICAvLyBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgLy8gICBjYXNlICdpbnQxNic6XG4gICAgLy8gICBjYXNlICdpbnQzMic6XG4gICAgLy8gICBjYXNlICd1aW50MTYnOlxuICAgIC8vICAgY2FzZSAndWludDMyJzpcbiAgICAvLyAgICAgcmV0dXJuICdpbnQnO1xuICAgIC8vICAgY2FzZSAndWludDgnOlxuICAgIC8vICAgY2FzZSAnYm9vbCc6XG4gICAgLy8gICAgIHJldHVybiAnYnl0ZSc7XG4gICAgLy8gICBjYXNlICdmbG9hdDMyJzpcbiAgICAvLyAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgIC8vICAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICAvLyAgIGRlZmF1bHQ6XG4gICAgLy8gICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yRGF0YSB0eXBlICR7ZGF0YVR5cGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICAvLyB9XG4gIH1cbiAgY2xlYXJBY3RpdmVUZXh0dXJlcygpOiB2b2lkIHtcbiAgICB0aGlzLmdsQ29udGV4dC5jbGVhckFjdGl2ZVRleHR1cmVzKCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtTZXNzaW9uSGFuZGxlcn0gZnJvbSAnLi4vLi4vYmFja2VuZCc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi9ncmFwaCc7XG5pbXBvcnQge0xvZ2dlcn0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQge09wZXJhdG9yfSBmcm9tICcuLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtPcFNldCwgcmVzb2x2ZU9wZXJhdG9yfSBmcm9tICcuLi8uLi9vcHNldCc7XG5pbXBvcnQge1Nlc3Npb259IGZyb20gJy4uLy4uL3Nlc3Npb24nO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1dlYkdMQmFja2VuZH0gZnJvbSAnLi4vYmFja2VuZC13ZWJnbCc7XG5cbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7V0VCR0xfT1BfUkVTT0xWRV9SVUxFU30gZnJvbSAnLi9vcC1yZXNvbHZlLXJ1bGVzJztcbmltcG9ydCB7UHJvZ3JhbU1hbmFnZXJ9IGZyb20gJy4vcHJvZ3JhbS1tYW5hZ2VyJztcbmltcG9ydCB7UHJlZmVyTG9naWNhbFN0cmF0ZWd5LCBUZXh0dXJlTGF5b3V0U3RyYXRlZ3l9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHtUZXh0dXJlTWFuYWdlcn0gZnJvbSAnLi90ZXh0dXJlLW1hbmFnZXInO1xuaW1wb3J0IHtUZXh0dXJlRGF0YX0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBXZWJHTFNlc3Npb25IYW5kbGVyIGltcGxlbWVudHMgU2Vzc2lvbkhhbmRsZXIge1xuICBwcm9ncmFtTWFuYWdlcjogUHJvZ3JhbU1hbmFnZXI7XG4gIHRleHR1cmVNYW5hZ2VyOiBUZXh0dXJlTWFuYWdlcjtcbiAgbGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneTtcbiAgcGFja2VkVGV4dHVyZURhdGFDYWNoZTogTWFwPFRlbnNvci5JZCwgVGV4dHVyZURhdGE+O1xuICB1bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGU6IE1hcDxUZW5zb3IuSWQsIFRleHR1cmVEYXRhPjtcbiAgcGFjazJ1bnBhY2tNYXA6IE1hcDxUZW5zb3IuSWQsIFRlbnNvci5JZD47XG4gIHVucGFjazJwYWNrTWFwOiBNYXA8VGVuc29yLklkLCBUZW5zb3IuSWQ+O1xuICBpbml0aWFsaXplcnM6IFNldDxUZW5zb3IuSWQ+O1xuICBwYWNrPzogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgYmFja2VuZDogV2ViR0xCYWNrZW5kLCBwdWJsaWMgcmVhZG9ubHkgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0KSB7XG4gICAgdGhpcy5sYXlvdXRTdHJhdGVneSA9IG5ldyBQcmVmZXJMb2dpY2FsU3RyYXRlZ3koYmFja2VuZC5nbENvbnRleHQubWF4VGV4dHVyZVNpemUpO1xuICAgIHRoaXMucHJvZ3JhbU1hbmFnZXIgPSBuZXcgUHJvZ3JhbU1hbmFnZXIodGhpcy5jb250ZXh0LnByb2ZpbGVyLCBiYWNrZW5kLmdsQ29udGV4dCwgdGhpcy5sYXlvdXRTdHJhdGVneSk7XG4gICAgdGhpcy50ZXh0dXJlTWFuYWdlciA9IG5ldyBUZXh0dXJlTWFuYWdlcihcbiAgICAgICAgYmFja2VuZC5nbENvbnRleHQsIHRoaXMubGF5b3V0U3RyYXRlZ3ksIHRoaXMuY29udGV4dC5wcm9maWxlcixcbiAgICAgICAge3JldXNlVGV4dHVyZXM6IGJhY2tlbmQudGV4dHVyZUNhY2hlTW9kZSA9PT0gJ2Z1bGwnfSk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMucGFjayA9IGJhY2tlbmQucGFjaztcbiAgICB0aGlzLnBhY2sydW5wYWNrTWFwID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrMnBhY2tNYXAgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBjcmVhdGVJbmZlcmVuY2VIYW5kbGVyKCkge1xuICAgIHJldHVybiBuZXcgV2ViR0xJbmZlcmVuY2VIYW5kbGVyKHRoaXMpO1xuICB9XG4gIG9uR3JhcGhJbml0aWFsaXplZChncmFwaDogR3JhcGgpOiB2b2lkIHtcbiAgICBjb25zdCBpbml0aWFsaXplcnMgPSBncmFwaC5nZXRWYWx1ZXMoKS5maWx0ZXIodiA9PiB2LmZyb20gPT09IC0xICYmIHYudGVuc29yKS5tYXAodiA9PiB2LnRlbnNvciEuZGF0YUlkKTtcbiAgICB0aGlzLmluaXRpYWxpemVycyA9IG5ldyBTZXQoaW5pdGlhbGl6ZXJzKTtcbiAgfVxuICBpc0luaXRpYWxpemVyKHRlbnNvcklkOiBUZW5zb3IuSWQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pbml0aWFsaXplcnMgPyB0aGlzLmluaXRpYWxpemVycy5oYXModGVuc29ySWQpIDogZmFsc2U7XG4gIH1cbiAgYWRkSW5pdGlhbGl6ZXIodGVuc29ySWQ6IFRlbnNvci5JZCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdGlhbGl6ZXJzLmFkZCh0ZW5zb3JJZCk7XG4gIH1cbiAgZ2V0VGV4dHVyZURhdGEodGVuc29ySWQ6IFRlbnNvci5JZCwgaXNQYWNrZWQ6IGJvb2xlYW4pOiBUZXh0dXJlRGF0YXx1bmRlZmluZWQge1xuICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgcmV0dXJuIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5nZXQodGVuc29ySWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKTtcbiAgICB9XG4gIH1cbiAgc2V0VGV4dHVyZURhdGEodGVuc29ySWQ6IFRlbnNvci5JZCwgdGV4dHVyZURhdGE6IFRleHR1cmVEYXRhLCBpc1BhY2tlZCA9IGZhbHNlKTogdm9pZCB7XG4gICAgTG9nZ2VyLnZlcmJvc2UoJ1dlYkdMU2Vzc2lvbkhhbmRsZXInLCAnU3RvcmluZyBUZXh0dXJlIGRhdGEgaW4gY2FjaGUnKTtcbiAgICBpZiAoaXNQYWNrZWQpIHtcbiAgICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5zZXQodGVuc29ySWQsIHRleHR1cmVEYXRhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuc2V0KHRlbnNvcklkLCB0ZXh0dXJlRGF0YSk7XG4gICAgfVxuICB9XG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5wcm9ncmFtTWFuYWdlci5kaXNwb3NlKCk7XG4gICAgdGhpcy50ZXh0dXJlTWFuYWdlci5jbGVhckFjdGl2ZVRleHR1cmVzKCk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2godGQgPT4gdGhpcy50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCwgdHJ1ZSkpO1xuICAgIHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5mb3JFYWNoKHRkID0+IHRoaXMudGV4dHVyZU1hbmFnZXIucmVsZWFzZVRleHR1cmUodGQsIHRydWUpKTtcbiAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZSA9IG5ldyBNYXAoKTtcbiAgfVxuICByZXNvbHZlKG5vZGU6IEdyYXBoLk5vZGUsIG9wc2V0czogcmVhZG9ubHkgT3BTZXRbXSwgZ3JhcGg6IEdyYXBoKTogT3BlcmF0b3Ige1xuICAgIGNvbnN0IG9wID0gcmVzb2x2ZU9wZXJhdG9yKG5vZGUsIG9wc2V0cywgV0VCR0xfT1BfUkVTT0xWRV9SVUxFUyk7XG4gICAgcmV0dXJuIHtpbXBsOiBvcC5vcEltcGwsIGNvbnRleHQ6IG9wLm9wSW5pdCA/IG9wLm9wSW5pdChub2RlLCBncmFwaCkgOiBub2RlfTtcbiAgfVxufVxuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge2Vudn0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0ICogYXMgRGF0YUVuY29kZXJzIGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHtEYXRhRW5jb2RlciwgRW5jb2RlciwgRW5jb2RlclVzYWdlfSBmcm9tICcuL3RleHR1cmUtZGF0YS1lbmNvZGVyJztcbmltcG9ydCB7cmVwZWF0ZWRUcnl9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZlbmNlQ29udGV4dCB7XG4gIHF1ZXJ5OiBXZWJHTFN5bmN8bnVsbDtcbiAgaXNGZW5jZVBhc3NlZCgpOiBib29sZWFuO1xufVxuXG50eXBlIFBvbGxJdGVtID0ge1xuICBpc0RvbmVGbjogKCkgPT4gYm9vbGVhbjsgcmVzb2x2ZUZuOiAoKSA9PiB2b2lkO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclNlYXJjaExhc3RUcnVlKGFycjogQXJyYXk8KCkgPT4gYm9vbGVhbj4pOiBudW1iZXIge1xuICBsZXQgaSA9IDA7XG4gIGZvciAoOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgaXNEb25lID0gYXJyW2ldKCk7XG4gICAgaWYgKCFpc0RvbmUpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gaSAtIDE7XG59XG5cbi8qKlxuICogQWJzdHJhY3Rpb24gYW5kIHdyYXBwZXIgYXJvdW5kIFdlYkdMUmVuZGVyaW5nQ29udGV4dCBhbmQgaXRzIG9wZXJhdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIFdlYkdMQ29udGV4dCB7XG4gIGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XG4gIHZlcnNpb246IDF8MjtcblxuICBwcml2YXRlIHZlcnRleGJ1ZmZlcjogV2ViR0xCdWZmZXI7XG4gIHByaXZhdGUgZnJhbWVidWZmZXI6IFdlYkdMRnJhbWVidWZmZXI7XG5cbiAgLy8gV2ViR0wgZmxhZ3MgYW5kIHZpdGFsIHBhcmFtZXRlcnNcbiAgcHJpdmF0ZSBpc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyOiBib29sZWFuO1xuICBpc0Zsb2F0MzJEb3dubG9hZFN1cHBvcnRlZDogYm9vbGVhbjtcbiAgaXNSZW5kZXJGbG9hdDMyU3VwcG9ydGVkOiBib29sZWFuO1xuICBpc0JsZW5kU3VwcG9ydGVkOiBib29sZWFuO1xuICBtYXhUZXh0dXJlU2l6ZTogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heENvbWJpbmVkVGV4dHVyZUltYWdlVW5pdHM6IG51bWJlcjtcbiAgcHJpdmF0ZSBtYXhUZXh0dXJlSW1hZ2VVbml0czogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heEN1YmVNYXBUZXh0dXJlU2l6ZTogbnVtYmVyO1xuICAvLyBwcml2YXRlIHNoYWRpbmdMYW5ndWFnZVZlcnNpb246IHN0cmluZztcbiAgLy8gcHJpdmF0ZSB3ZWJnbFZlbmRvcjogc3RyaW5nO1xuICAvLyBwcml2YXRlIHdlYmdsVmVyc2lvbjogc3RyaW5nO1xuXG4gIC8vIFdlYkdMMiBmbGFncyBhbmQgdml0YWwgcGFyYW1ldGVyc1xuICAvLyBwcml2YXRlIG1heDNEVGV4dHVyZVNpemU6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhBcnJheVRleHR1cmVMYXllcnM6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhDb2xvckF0dGFjaG1lbnRzOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4RHJhd0J1ZmZlcnM6IG51bWJlcjtcblxuICAvLyBXZWJHTCBleHRlbnNpb25zXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjYW1lbGNhc2VcbiAgdGV4dHVyZUZsb2F0RXh0ZW5zaW9uOiBPRVNfdGV4dHVyZV9mbG9hdHxudWxsO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlXG4gIHRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb246IE9FU190ZXh0dXJlX2hhbGZfZmxvYXR8bnVsbDtcblxuICAvLyBXZWJHTDIgZXh0ZW5zaW9uc1xuICBjb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uOiB1bmtub3dufG51bGw7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uOiB7VElNRV9FTEFQU0VEX0VYVDogR0xlbnVtOyBHUFVfRElTSk9JTlRfRVhUOiBHTGVudW19fG51bGw7XG5cbiAgcHJpdmF0ZSBkaXNwb3NlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBmcmFtZUJ1ZmZlckJvdW5kID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdmVyc2lvbjogMXwyKSB7XG4gICAgdGhpcy5nbCA9IGdsO1xuICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247XG5cbiAgICB0aGlzLmdldEV4dGVuc2lvbnMoKTtcbiAgICB0aGlzLnZlcnRleGJ1ZmZlciA9IHRoaXMuY3JlYXRlVmVydGV4YnVmZmVyKCk7XG4gICAgdGhpcy5mcmFtZWJ1ZmZlciA9IHRoaXMuY3JlYXRlRnJhbWVidWZmZXIoKTtcbiAgICB0aGlzLnF1ZXJ5Vml0YWxQYXJhbWV0ZXJzKCk7XG4gIH1cblxuICBhbGxvY2F0ZVRleHR1cmUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIGVuY29kZXI6IERhdGFFbmNvZGVyLCBkYXRhPzogRW5jb2Rlci5EYXRhQXJyYXlUeXBlKTogV2ViR0xUZXh0dXJlIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgLy8gY3JlYXRlIHRoZSB0ZXh0dXJlXG4gICAgY29uc3QgdGV4dHVyZSA9IGdsLmNyZWF0ZVRleHR1cmUoKTtcbiAgICAvLyBiaW5kIHRoZSB0ZXh0dXJlIHNvIHRoZSBmb2xsb3dpbmcgbWV0aG9kcyBlZmZlY3QgdGhpcyB0ZXh0dXJlLlxuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NSU5fRklMVEVSLCBnbC5ORUFSRVNUKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUFHX0ZJTFRFUiwgZ2wuTkVBUkVTVCk7XG4gICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX1dSQVBfUywgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX1dSQVBfVCwgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgY29uc3QgYnVmZmVyID0gZGF0YSA/IGVuY29kZXIuZW5jb2RlKGRhdGEsIHdpZHRoICogaGVpZ2h0KSA6IG51bGw7XG4gICAgZ2wudGV4SW1hZ2UyRChcbiAgICAgICAgZ2wuVEVYVFVSRV8yRCxcbiAgICAgICAgMCwgIC8vIExldmVsIG9mIGRldGFpbC5cbiAgICAgICAgZW5jb2Rlci5pbnRlcm5hbEZvcm1hdCwgd2lkdGgsIGhlaWdodCxcbiAgICAgICAgMCwgIC8vIEFsd2F5cyAwIGluIE9wZW5HTCBFUy5cbiAgICAgICAgZW5jb2Rlci5mb3JtYXQsIGVuY29kZXIudGV4dHVyZVR5cGUsIGJ1ZmZlcik7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgcmV0dXJuIHRleHR1cmUgYXMgV2ViR0xUZXh0dXJlO1xuICB9XG4gIHVwZGF0ZVRleHR1cmUoXG4gICAgICB0ZXh0dXJlOiBXZWJHTFRleHR1cmUsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBlbmNvZGVyOiBEYXRhRW5jb2RlciwgZGF0YTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGVuY29kZXIuZW5jb2RlKGRhdGEsIHdpZHRoICogaGVpZ2h0KTtcbiAgICBnbC50ZXhTdWJJbWFnZTJEKFxuICAgICAgICBnbC5URVhUVVJFXzJELFxuICAgICAgICAwLCAgLy8gbGV2ZWxcbiAgICAgICAgMCwgIC8vIHhvZmZzZXRcbiAgICAgICAgMCwgIC8vIHlvZmZzZXRcbiAgICAgICAgd2lkdGgsIGhlaWdodCwgZW5jb2Rlci5mb3JtYXQsIGVuY29kZXIudGV4dHVyZVR5cGUsIGJ1ZmZlcik7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gIH1cbiAgYXR0YWNoRnJhbWVidWZmZXIodGV4dHVyZTogV2ViR0xUZXh0dXJlLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAvLyBNYWtlIGl0IHRoZSB0YXJnZXQgZm9yIGZyYW1lYnVmZmVyIG9wZXJhdGlvbnMgLSBpbmNsdWRpbmcgcmVuZGVyaW5nLlxuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgdGhpcy5mcmFtZWJ1ZmZlcik7XG4gICAgZ2wuZnJhbWVidWZmZXJUZXh0dXJlMkQoXG4gICAgICAgIGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSxcbiAgICAgICAgMCk7ICAvLyAwLCB3ZSBhcmVuJ3QgdXNpbmcgTUlQTUFQc1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICAgIGdsLnZpZXdwb3J0KDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICAgIGdsLnNjaXNzb3IoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gIH1cbiAgcmVhZFRleHR1cmUoXG4gICAgICB0ZXh0dXJlOiBXZWJHTFRleHR1cmUsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBkYXRhU2l6ZTogbnVtYmVyLCBkYXRhVHlwZTogRW5jb2Rlci5EYXRhVHlwZSxcbiAgICAgIGNoYW5uZWxzOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBpZiAoIWNoYW5uZWxzKSB7XG4gICAgICBjaGFubmVscyA9IDE7XG4gICAgfVxuICAgIGlmICghdGhpcy5mcmFtZUJ1ZmZlckJvdW5kKSB7XG4gICAgICB0aGlzLmF0dGFjaEZyYW1lYnVmZmVyKHRleHR1cmUsIHdpZHRoLCBoZWlnaHQpO1xuICAgIH1cbiAgICBjb25zdCBlbmNvZGVyID0gdGhpcy5nZXRFbmNvZGVyKGRhdGFUeXBlLCBjaGFubmVscyk7XG4gICAgY29uc3QgYnVmZmVyID0gZW5jb2Rlci5hbGxvY2F0ZSh3aWR0aCAqIGhlaWdodCk7XG4gICAgLy8gYmluZCB0ZXh0dXJlIHRvIGZyYW1lYnVmZmVyXG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgZ2wuZnJhbWVidWZmZXJUZXh0dXJlMkQoXG4gICAgICAgIGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSxcbiAgICAgICAgMCk7ICAvLyAwLCB3ZSBhcmVuJ3QgdXNpbmcgTUlQTUFQc1xuICAgIC8vIFRPRE86IENoZWNrIGlmIGZyYW1lYnVmZmVyIGlzIHJlYWR5XG4gICAgZ2wucmVhZFBpeGVscygwLCAwLCB3aWR0aCwgaGVpZ2h0LCBnbC5SR0JBLCBlbmNvZGVyLnRleHR1cmVUeXBlLCBidWZmZXIpO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICAgIC8vIHVuYmluZCBGQlxuICAgIHJldHVybiBlbmNvZGVyLmRlY29kZShidWZmZXIsIGRhdGFTaXplKTtcbiAgfVxuXG4gIGlzRnJhbWVidWZmZXJSZWFkeSgpOiBib29sZWFuIHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgbG9naWMgdG8gY2hlY2sgaWYgdGhlIGZyYW1lYnVmZmVyIGlzIHJlYWR5XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZ2V0QWN0aXZlVGV4dHVyZSgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBuID0gZ2wuZ2V0UGFyYW1ldGVyKHRoaXMuZ2wuQUNUSVZFX1RFWFRVUkUpO1xuICAgIHJldHVybiBgVEVYVFVSRSR7KG4gLSBnbC5URVhUVVJFMCl9YDtcbiAgfVxuICBnZXRUZXh0dXJlQmluZGluZygpOiBXZWJHTFRleHR1cmUge1xuICAgIHJldHVybiB0aGlzLmdsLmdldFBhcmFtZXRlcih0aGlzLmdsLlRFWFRVUkVfQklORElOR18yRCk7XG4gIH1cbiAgZ2V0RnJhbWVidWZmZXJCaW5kaW5nKCk6IFdlYkdMRnJhbWVidWZmZXIge1xuICAgIHJldHVybiB0aGlzLmdsLmdldFBhcmFtZXRlcih0aGlzLmdsLkZSQU1FQlVGRkVSX0JJTkRJTkcpO1xuICB9XG4gIHNldFZlcnRleEF0dHJpYnV0ZXMocG9zaXRpb25IYW5kbGU6IG51bWJlciwgdGV4dHVyZUNvb3JkSGFuZGxlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcihwb3NpdGlvbkhhbmRsZSwgMywgZ2wuRkxPQVQsIGZhbHNlLCAyMCwgMCk7XG4gICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkocG9zaXRpb25IYW5kbGUpO1xuICAgIGlmICh0ZXh0dXJlQ29vcmRIYW5kbGUgIT09IC0xKSB7XG4gICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHRleHR1cmVDb29yZEhhbmRsZSwgMiwgZ2wuRkxPQVQsIGZhbHNlLCAyMCwgMTIpO1xuICAgICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkodGV4dHVyZUNvb3JkSGFuZGxlKTtcbiAgICB9XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gIH1cbiAgY3JlYXRlUHJvZ3JhbShcbiAgICAgIHZlcnRleFNoYWRlcjogV2ViR0xTaGFkZXIsXG4gICAgICBmcmFnU2hhZGVyOiBXZWJHTFNoYWRlcixcbiAgICAgICk6IFdlYkdMUHJvZ3JhbSB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGNvbnN0IHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCkhO1xuXG4gICAgLy8gdGhlIHByb2dyYW0gY29uc2lzdHMgb2Ygb3VyIHNoYWRlcnNcbiAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgdmVydGV4U2hhZGVyKTtcbiAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgZnJhZ1NoYWRlcik7XG4gICAgZ2wubGlua1Byb2dyYW0ocHJvZ3JhbSk7XG4gICAgcmV0dXJuIHByb2dyYW07XG4gIH1cbiAgY29tcGlsZVNoYWRlcihzaGFkZXJTb3VyY2U6IHN0cmluZywgc2hhZGVyVHlwZTogbnVtYmVyKTogV2ViR0xTaGFkZXIge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBzaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoc2hhZGVyVHlwZSk7XG4gICAgaWYgKCFzaGFkZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY3JlYXRlU2hhZGVyKCkgcmV0dXJuZWQgbnVsbCB3aXRoIHR5cGUgJHtzaGFkZXJUeXBlfWApO1xuICAgIH1cblxuICAgIGdsLnNoYWRlclNvdXJjZShzaGFkZXIsIHNoYWRlclNvdXJjZSk7XG4gICAgZ2wuY29tcGlsZVNoYWRlcihzaGFkZXIpO1xuICAgIGlmIChnbC5nZXRTaGFkZXJQYXJhbWV0ZXIoc2hhZGVyLCBnbC5DT01QSUxFX1NUQVRVUykgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBjb21waWxlIHNoYWRlcjogJHtnbC5nZXRTaGFkZXJJbmZvTG9nKHNoYWRlcil9XG5TaGFkZXIgc291cmNlOlxuJHtzaGFkZXJTb3VyY2V9YCk7XG4gICAgfVxuICAgIHJldHVybiBzaGFkZXI7XG4gIH1cbiAgZGVsZXRlU2hhZGVyKHNoYWRlcjogV2ViR0xTaGFkZXIpOiB2b2lkIHtcbiAgICB0aGlzLmdsLmRlbGV0ZVNoYWRlcihzaGFkZXIpO1xuICB9XG4gIGJpbmRUZXh0dXJlVG9Vbmlmb3JtKHRleHR1cmU6IFdlYkdMVGV4dHVyZSwgcG9zaXRpb246IG51bWJlciwgdW5pZm9ybUhhbmRsZTogV2ViR0xVbmlmb3JtTG9jYXRpb24pOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wuYWN0aXZlVGV4dHVyZShnbC5URVhUVVJFMCArIHBvc2l0aW9uKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICBnbC51bmlmb3JtMWkodW5pZm9ybUhhbmRsZSwgcG9zaXRpb24pO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGRyYXcoKTogdm9pZCB7XG4gICAgdGhpcy5nbC5kcmF3QXJyYXlzKHRoaXMuZ2wuVFJJQU5HTEVfU1RSSVAsIDAsIDQpO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGNoZWNrRXJyb3IoKTogdm9pZCB7XG4gICAgaWYgKGVudi5kZWJ1Zykge1xuICAgICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgICAgY29uc3QgZXJyb3IgPSBnbC5nZXRFcnJvcigpO1xuICAgICAgbGV0IGxhYmVsID0gJyc7XG4gICAgICBzd2l0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNhc2UgKGdsLk5PX0VSUk9SKTpcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIGNhc2UgKGdsLklOVkFMSURfRU5VTSk6XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9FTlVNJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAoZ2wuSU5WQUxJRF9WQUxVRSk6XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9WQUxVRSc7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgKGdsLklOVkFMSURfT1BFUkFUSU9OKTpcbiAgICAgICAgICBsYWJlbCA9ICdJTlZBTElEX09QRVJBVElPTic7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgKGdsLklOVkFMSURfRlJBTUVCVUZGRVJfT1BFUkFUSU9OKTpcbiAgICAgICAgICBsYWJlbCA9ICdJTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTic7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgKGdsLk9VVF9PRl9NRU1PUlkpOlxuICAgICAgICAgIGxhYmVsID0gJ09VVF9PRl9NRU1PUlknO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIChnbC5DT05URVhUX0xPU1RfV0VCR0wpOlxuICAgICAgICAgIGxhYmVsID0gJ0NPTlRFWFRfTE9TVF9XRUJHTCc7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgbGFiZWwgPSBgVW5rbm93biBXZWJHTCBFcnJvcjogJHtlcnJvci50b1N0cmluZygxNil9YDtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihsYWJlbCk7XG4gICAgfVxuICB9XG4gIGRlbGV0ZVRleHR1cmUodGV4dHVyZTogV2ViR0xUZXh0dXJlKTogdm9pZCB7XG4gICAgdGhpcy5nbC5kZWxldGVUZXh0dXJlKHRleHR1cmUpO1xuICB9XG4gIGRlbGV0ZVByb2dyYW0ocHJvZ3JhbTogV2ViR0xQcm9ncmFtKTogdm9pZCB7XG4gICAgdGhpcy5nbC5kZWxldGVQcm9ncmFtKHByb2dyYW0pO1xuICB9XG4gIGdldEVuY29kZXIoZGF0YVR5cGU6IEVuY29kZXIuRGF0YVR5cGUsIGNoYW5uZWxzOiBudW1iZXIsIHVzYWdlOiBFbmNvZGVyVXNhZ2UgPSBFbmNvZGVyVXNhZ2UuRGVmYXVsdCk6IERhdGFFbmNvZGVyIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICByZXR1cm4gbmV3IERhdGFFbmNvZGVycy5SZWRGbG9hdDMyRGF0YUVuY29kZXIodGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0LCBjaGFubmVscyk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChkYXRhVHlwZSkge1xuICAgICAgY2FzZSAnZmxvYXQnOlxuICAgICAgICBpZiAodXNhZ2UgPT09IEVuY29kZXJVc2FnZS5VcGxvYWRPbmx5IHx8IHRoaXMuaXNSZW5kZXJGbG9hdDMyU3VwcG9ydGVkKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBEYXRhRW5jb2RlcnMuUkdCQUZsb2F0RGF0YUVuY29kZXIodGhpcy5nbCwgY2hhbm5lbHMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBuZXcgRGF0YUVuY29kZXJzLlJHQkFGbG9hdERhdGFFbmNvZGVyKFxuICAgICAgICAgICAgICB0aGlzLmdsLCBjaGFubmVscywgdGhpcy50ZXh0dXJlSGFsZkZsb2F0RXh0ZW5zaW9uIS5IQUxGX0ZMT0FUX09FUyk7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgJ2ludCc6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJyk7XG4gICAgICBjYXNlICdieXRlJzpcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRhRW5jb2RlcnMuVWludDhEYXRhRW5jb2Rlcih0aGlzLmdsLCBjaGFubmVscyk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YVR5cGU6ICR7ZGF0YVR5cGV9YCk7XG4gICAgfVxuICB9XG4gIGNsZWFyQWN0aXZlVGV4dHVyZXMoKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGZvciAobGV0IHVuaXQgPSAwOyB1bml0IDwgdGhpcy5tYXhUZXh0dXJlSW1hZ2VVbml0czsgKyt1bml0KSB7XG4gICAgICBnbC5hY3RpdmVUZXh0dXJlKGdsLlRFWFRVUkUwICsgdW5pdCk7XG4gICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBudWxsKTtcbiAgICB9XG4gIH1cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNwb3NlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBudWxsKTtcbiAgICBnbC5kZWxldGVGcmFtZWJ1ZmZlcih0aGlzLmZyYW1lYnVmZmVyKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgbnVsbCk7XG4gICAgZ2wuZGVsZXRlQnVmZmVyKHRoaXMudmVydGV4YnVmZmVyKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkVMRU1FTlRfQVJSQVlfQlVGRkVSLCBudWxsKTtcbiAgICBnbC5maW5pc2goKTtcbiAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRGVmYXVsdEdlb21ldHJ5KCk6IEZsb2F0MzJBcnJheSB7XG4gICAgLy8gU2V0cyBvZiB4LHkseig9MCkscyx0IGNvb3JkaW5hdGVzLlxuICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KFtcbiAgICAgIC0xLjAsIDEuMCwgIDAuMCwgMC4wLCAxLjAsICAvLyB1cHBlciBsZWZ0XG4gICAgICAtMS4wLCAtMS4wLCAwLjAsIDAuMCwgMC4wLCAgLy8gbG93ZXIgbGVmdFxuICAgICAgMS4wLCAgMS4wLCAgMC4wLCAxLjAsIDEuMCwgIC8vIHVwcGVyIHJpZ2h0XG4gICAgICAxLjAsICAtMS4wLCAwLjAsIDEuMCwgMC4wICAgLy8gbG93ZXIgcmlnaHRcbiAgICBdKTtcbiAgfVxuICBwcml2YXRlIGNyZWF0ZVZlcnRleGJ1ZmZlcigpOiBXZWJHTEJ1ZmZlciB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGdsLmNyZWF0ZUJ1ZmZlcigpO1xuICAgIGlmICghYnVmZmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NyZWF0ZUJ1ZmZlcigpIHJldHVybmVkIG51bGwnKTtcbiAgICB9XG4gICAgY29uc3QgZ2VvbWV0cnkgPSB0aGlzLmNyZWF0ZURlZmF1bHRHZW9tZXRyeSgpO1xuICAgIGdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCBidWZmZXIpO1xuICAgIGdsLmJ1ZmZlckRhdGEoZ2wuQVJSQVlfQlVGRkVSLCBnZW9tZXRyeSwgZ2wuU1RBVElDX0RSQVcpO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICAgIHJldHVybiBidWZmZXI7XG4gIH1cbiAgcHJpdmF0ZSBjcmVhdGVGcmFtZWJ1ZmZlcigpOiBXZWJHTEZyYW1lYnVmZmVyIHtcbiAgICBjb25zdCBmYiA9IHRoaXMuZ2wuY3JlYXRlRnJhbWVidWZmZXIoKTtcbiAgICBpZiAoIWZiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NyZWF0ZUZyYW1lYnVmZmVyIHJldHVybmVkIG51bGwnKTtcbiAgICB9XG4gICAgcmV0dXJuIGZiO1xuICB9XG5cbiAgcHJpdmF0ZSBxdWVyeVZpdGFsUGFyYW1ldGVycygpOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG5cbiAgICB0aGlzLmlzRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXIgPSB0aGlzLmNoZWNrRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXIoKTtcbiAgICB0aGlzLmlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZCA9IHRoaXMuY2hlY2tSZW5kZXJGbG9hdDMyKCk7XG4gICAgdGhpcy5pc0Zsb2F0MzJEb3dubG9hZFN1cHBvcnRlZCA9IHRoaXMuY2hlY2tGbG9hdDMyRG93bmxvYWQoKTtcblxuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDEgJiYgIXRoaXMudGV4dHVyZUhhbGZGbG9hdEV4dGVuc2lvbiAmJiAhdGhpcy5pc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYm90aCBmbG9hdDMyIGFuZCBmbG9hdDE2IFRleHR1cmVUeXBlIGFyZSBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0JsZW5kU3VwcG9ydGVkID0gIXRoaXMuaXNSZW5kZXJGbG9hdDMyU3VwcG9ydGVkIHx8IHRoaXMuY2hlY2tGbG9hdDMyQmxlbmQoKTtcblxuICAgIC8vIHRoaXMubWF4Q29tYmluZWRUZXh0dXJlSW1hZ2VVbml0cyA9IGdsLmdldFBhcmFtZXRlcihnbC5NQVhfQ09NQklORURfVEVYVFVSRV9JTUFHRV9VTklUUyk7XG4gICAgdGhpcy5tYXhUZXh0dXJlU2l6ZSA9IGdsLmdldFBhcmFtZXRlcihnbC5NQVhfVEVYVFVSRV9TSVpFKTtcbiAgICB0aGlzLm1heFRleHR1cmVJbWFnZVVuaXRzID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLk1BWF9URVhUVVJFX0lNQUdFX1VOSVRTKTtcbiAgICAvLyB0aGlzLm1heEN1YmVNYXBUZXh0dXJlU2l6ZSA9IGdsLmdldFBhcmFtZXRlcihnbC5NQVhfQ1VCRV9NQVBfVEVYVFVSRV9TSVpFKTtcbiAgICAvLyB0aGlzLnNoYWRpbmdMYW5ndWFnZVZlcnNpb24gPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuU0hBRElOR19MQU5HVUFHRV9WRVJTSU9OKTtcbiAgICAvLyB0aGlzLndlYmdsVmVuZG9yID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLlZFTkRPUik7XG4gICAgLy8gdGhpcy53ZWJnbFZlcnNpb24gPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuVkVSU0lPTik7XG5cbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICAvLyB0aGlzLm1heDNEVGV4dHVyZVNpemUgPSBnbC5nZXRQYXJhbWV0ZXIoV2ViR0wyUmVuZGVyaW5nQ29udGV4dC5NQVhfM0RfVEVYVFVSRV9TSVpFKTtcbiAgICAgIC8vIHRoaXMubWF4QXJyYXlUZXh0dXJlTGF5ZXJzID0gZ2wuZ2V0UGFyYW1ldGVyKFdlYkdMMlJlbmRlcmluZ0NvbnRleHQuTUFYX0FSUkFZX1RFWFRVUkVfTEFZRVJTKTtcbiAgICAgIC8vIHRoaXMubWF4Q29sb3JBdHRhY2htZW50cyA9IGdsLmdldFBhcmFtZXRlcihXZWJHTDJSZW5kZXJpbmdDb250ZXh0Lk1BWF9DT0xPUl9BVFRBQ0hNRU5UUyk7XG4gICAgICAvLyB0aGlzLm1heERyYXdCdWZmZXJzID0gZ2wuZ2V0UGFyYW1ldGVyKFdlYkdMMlJlbmRlcmluZ0NvbnRleHQuTUFYX0RSQVdfQlVGRkVSUyk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgZ2V0RXh0ZW5zaW9ucygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICB0aGlzLmNvbG9yQnVmZmVyRmxvYXRFeHRlbnNpb24gPSB0aGlzLmdsLmdldEV4dGVuc2lvbignRVhUX2NvbG9yX2J1ZmZlcl9mbG9hdCcpO1xuICAgICAgdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb24gPSB0aGlzLmdsLmdldEV4dGVuc2lvbignRVhUX2Rpc2pvaW50X3RpbWVyX3F1ZXJ5X3dlYmdsMicpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRleHR1cmVGbG9hdEV4dGVuc2lvbiA9IHRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdPRVNfdGV4dHVyZV9mbG9hdCcpO1xuICAgICAgdGhpcy50ZXh0dXJlSGFsZkZsb2F0RXh0ZW5zaW9uID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ09FU190ZXh0dXJlX2hhbGZfZmxvYXQnKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXIoKTogYm9vbGVhbiB7XG4gICAgLy8gdGVzdCB3aGV0aGVyIEZsb2F0MzIgdGV4dHVyZSBpcyBzdXBwb3J0ZWQ6XG4gICAgLy8gU1RFUC4xIGNyZWF0ZSBhIGZsb2F0IHRleHR1cmVcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgY29uc3QgdGV4dHVyZSA9IGdsLmNyZWF0ZVRleHR1cmUoKTtcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG4gICAgY29uc3QgaW50ZXJuYWxGb3JtYXQgPSB0aGlzLnZlcnNpb24gPT09IDIgPyAoZ2wgYXMgdW5rbm93biBhcyB7UkdCQTMyRjogbnVtYmVyfSkuUkdCQTMyRiA6IGdsLlJHQkE7XG4gICAgZ2wudGV4SW1hZ2UyRChnbC5URVhUVVJFXzJELCAwLCBpbnRlcm5hbEZvcm1hdCwgMSwgMSwgMCwgZ2wuUkdCQSwgZ2wuRkxPQVQsIG51bGwpO1xuICAgIC8vIFNURVAuMiBiaW5kIGEgZnJhbWUgYnVmZmVyXG4gICAgY29uc3QgZnJhbWVCdWZmZXIgPSBnbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgZnJhbWVCdWZmZXIpO1xuICAgIC8vIFNURVAuMyBhdHRhY2ggdGV4dHVyZSB0byBmcmFtZWJ1ZmZlclxuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSwgMCk7XG4gICAgLy8gU1RFUC40IHRlc3Qgd2hldGhlciBmcmFtZWJ1ZmZlciBpcyBjb21wbGV0ZVxuICAgIGNvbnN0IGlzQ29tcGxldGUgPSBnbC5jaGVja0ZyYW1lYnVmZmVyU3RhdHVzKGdsLkZSQU1FQlVGRkVSKSA9PT0gZ2wuRlJBTUVCVUZGRVJfQ09NUExFVEU7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgbnVsbCk7XG4gICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBudWxsKTtcbiAgICBnbC5kZWxldGVUZXh0dXJlKHRleHR1cmUpO1xuICAgIGdsLmRlbGV0ZUZyYW1lYnVmZmVyKGZyYW1lQnVmZmVyKTtcbiAgICByZXR1cm4gaXNDb21wbGV0ZTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tSZW5kZXJGbG9hdDMyKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIGlmICghdGhpcy5jb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF0aGlzLnRleHR1cmVGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXI7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrRmxvYXQzMkRvd25sb2FkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHtcbiAgICAgIGlmICghdGhpcy5jb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF0aGlzLnRleHR1cmVGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdXRUJHTF9jb2xvcl9idWZmZXJfZmxvYXQnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzRmxvYXRUZXh0dXJlQXR0YWNoYWJsZVRvRnJhbWVCdWZmZXI7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgd2hldGhlciBHTF9CTEVORCBpcyBzdXBwb3J0ZWRcbiAgICovXG4gIHByaXZhdGUgY2hlY2tGbG9hdDMyQmxlbmQoKTogYm9vbGVhbiB7XG4gICAgLy8gaXQgbG9va3MgbGlrZSBjdXJyZW50bHkgKDIwMTktMDUtMDgpIHRoZXJlIGlzIG5vIGVhc3kgd2F5IHRvIGRldGVjdCB3aGV0aGVyIEJMRU5EIGlzIHN1cHBvcnRlZFxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvb25ueGpzL2lzc3Vlcy8xNDVcblxuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcblxuICAgIGxldCB0ZXh0dXJlOiBXZWJHTFRleHR1cmV8bnVsbHx1bmRlZmluZWQ7XG4gICAgbGV0IGZyYW1lQnVmZmVyOiBXZWJHTEZyYW1lYnVmZmVyfG51bGx8dW5kZWZpbmVkO1xuICAgIGxldCB2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyfG51bGx8dW5kZWZpbmVkO1xuICAgIGxldCBmcmFnbWVudFNoYWRlcjogV2ViR0xTaGFkZXJ8bnVsbHx1bmRlZmluZWQ7XG4gICAgbGV0IHByb2dyYW06IFdlYkdMUHJvZ3JhbXxudWxsfHVuZGVmaW5lZDtcblxuICAgIHRyeSB7XG4gICAgICB0ZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgICAgZnJhbWVCdWZmZXIgPSBnbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICAgIGNvbnN0IGludGVybmFsRm9ybWF0ID0gdGhpcy52ZXJzaW9uID09PSAyID8gKGdsIGFzIHVua25vd24gYXMge1JHQkEzMkY6IG51bWJlcn0pLlJHQkEzMkYgOiBnbC5SR0JBO1xuICAgICAgZ2wudGV4SW1hZ2UyRChnbC5URVhUVVJFXzJELCAwLCBpbnRlcm5hbEZvcm1hdCwgMSwgMSwgMCwgZ2wuUkdCQSwgZ2wuRkxPQVQsIG51bGwpO1xuXG4gICAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIGZyYW1lQnVmZmVyKTtcbiAgICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSwgMCk7XG5cbiAgICAgIGdsLmVuYWJsZShnbC5CTEVORCk7XG5cbiAgICAgIHZlcnRleFNoYWRlciA9IGdsLmNyZWF0ZVNoYWRlcihnbC5WRVJURVhfU0hBREVSKTtcbiAgICAgIGlmICghdmVydGV4U2hhZGVyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGdsLnNoYWRlclNvdXJjZSh2ZXJ0ZXhTaGFkZXIsICd2b2lkIG1haW4oKXt9Jyk7XG4gICAgICBnbC5jb21waWxlU2hhZGVyKHZlcnRleFNoYWRlcik7XG5cbiAgICAgIGZyYWdtZW50U2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKGdsLkZSQUdNRU5UX1NIQURFUik7XG4gICAgICBpZiAoIWZyYWdtZW50U2hhZGVyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGdsLnNoYWRlclNvdXJjZShmcmFnbWVudFNoYWRlciwgJ3ByZWNpc2lvbiBoaWdocCBmbG9hdDt2b2lkIG1haW4oKXtnbF9GcmFnQ29sb3I9dmVjNCgwLjUpO30nKTtcbiAgICAgIGdsLmNvbXBpbGVTaGFkZXIoZnJhZ21lbnRTaGFkZXIpO1xuXG4gICAgICBwcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpO1xuICAgICAgaWYgKCFwcm9ncmFtKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGdsLmF0dGFjaFNoYWRlcihwcm9ncmFtLCB2ZXJ0ZXhTaGFkZXIpO1xuICAgICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIGZyYWdtZW50U2hhZGVyKTtcbiAgICAgIGdsLmxpbmtQcm9ncmFtKHByb2dyYW0pO1xuICAgICAgZ2wudXNlUHJvZ3JhbShwcm9ncmFtKTtcblxuICAgICAgZ2wuZHJhd0FycmF5cyhnbC5QT0lOVFMsIDAsIDEpO1xuICAgICAgcmV0dXJuIGdsLmdldEVycm9yKCkgPT09IGdsLk5PX0VSUk9SO1xuXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGdsLmRpc2FibGUoZ2wuQkxFTkQpO1xuXG4gICAgICBpZiAocHJvZ3JhbSkge1xuICAgICAgICBnbC5kZWxldGVQcm9ncmFtKHByb2dyYW0pO1xuICAgICAgfVxuICAgICAgaWYgKHZlcnRleFNoYWRlcikge1xuICAgICAgICBnbC5kZWxldGVTaGFkZXIodmVydGV4U2hhZGVyKTtcbiAgICAgIH1cbiAgICAgIGlmIChmcmFnbWVudFNoYWRlcikge1xuICAgICAgICBnbC5kZWxldGVTaGFkZXIoZnJhZ21lbnRTaGFkZXIpO1xuICAgICAgfVxuICAgICAgaWYgKGZyYW1lQnVmZmVyKSB7XG4gICAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7XG4gICAgICAgIGdsLmRlbGV0ZUZyYW1lYnVmZmVyKGZyYW1lQnVmZmVyKTtcbiAgICAgIH1cbiAgICAgIGlmICh0ZXh0dXJlKSB7XG4gICAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpO1xuICAgICAgICBnbC5kZWxldGVUZXh0dXJlKHRleHR1cmUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGJlZ2luVGltZXIoKTogV2ViR0xRdWVyeSB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMiAmJiB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbikge1xuICAgICAgY29uc3QgZ2wyID0gdGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgICAgY29uc3QgZXh0ID0gdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb247XG5cbiAgICAgIGNvbnN0IHF1ZXJ5ID0gZ2wyLmNyZWF0ZVF1ZXJ5KCkgYXMgV2ViR0xRdWVyeTtcbiAgICAgIGdsMi5iZWdpblF1ZXJ5KGV4dC5USU1FX0VMQVBTRURfRVhULCBxdWVyeSk7XG4gICAgICByZXR1cm4gcXVlcnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRPRE86IGFkZCB3ZWJnbCAxIGhhbmRsaW5nLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJHTDEgcHJvZmlsaW5nIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfVxuXG4gIGVuZFRpbWVyKCkge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIgJiYgdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb24pIHtcbiAgICAgIGNvbnN0IGdsMiA9IHRoaXMuZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICAgIGNvbnN0IGV4dCA9IHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uO1xuICAgICAgZ2wyLmVuZFF1ZXJ5KGV4dC5USU1FX0VMQVBTRURfRVhUKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogYWRkIHdlYmdsIDEgaGFuZGxpbmcuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMMSBwcm9maWxpbmcgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH1cblxuICBpc1RpbWVyUmVzdWx0QXZhaWxhYmxlKHF1ZXJ5OiBXZWJHTFF1ZXJ5KTogYm9vbGVhbiB7XG4gICAgbGV0IGF2YWlsYWJsZSA9IGZhbHNlLCBkaXNqb2ludCA9IGZhbHNlO1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIgJiYgdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb24pIHtcbiAgICAgIGNvbnN0IGdsMiA9IHRoaXMuZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICAgIGNvbnN0IGV4dCA9IHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uO1xuXG4gICAgICBhdmFpbGFibGUgPSBnbDIuZ2V0UXVlcnlQYXJhbWV0ZXIocXVlcnksIGdsMi5RVUVSWV9SRVNVTFRfQVZBSUxBQkxFKTtcbiAgICAgIGRpc2pvaW50ID0gZ2wyLmdldFBhcmFtZXRlcihleHQuR1BVX0RJU0pPSU5UX0VYVCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRPRE86IGFkZCB3ZWJnbCAxIGhhbmRsaW5nLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJHTDEgcHJvZmlsaW5nIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF2YWlsYWJsZSAmJiAhZGlzam9pbnQ7XG4gIH1cblxuICBnZXRUaW1lclJlc3VsdChxdWVyeTogV2ViR0xRdWVyeSk6IG51bWJlciB7XG4gICAgbGV0IHRpbWVFbGFwc2VkID0gMDtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBjb25zdCBnbDIgPSB0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgICB0aW1lRWxhcHNlZCA9IGdsMi5nZXRRdWVyeVBhcmFtZXRlcihxdWVyeSwgZ2wyLlFVRVJZX1JFU1VMVCk7XG4gICAgICBnbDIuZGVsZXRlUXVlcnkocXVlcnkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUT0RPOiBhZGQgd2ViZ2wgMSBoYW5kbGluZy5cbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViR0wxIHByb2ZpbGluZyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgICAvLyByZXR1cm4gbWlsaXNlY29uZHNcbiAgICByZXR1cm4gdGltZUVsYXBzZWQgLyAxMDAwMDAwO1xuICB9XG5cbiAgYXN5bmMgd2FpdEZvclF1ZXJ5QW5kR2V0VGltZShxdWVyeTogV2ViR0xRdWVyeSk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgYXdhaXQgcmVwZWF0ZWRUcnkoKCkgPT4gdGhpcy5pc1RpbWVyUmVzdWx0QXZhaWxhYmxlKHF1ZXJ5KSk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VGltZXJSZXN1bHQocXVlcnkpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGNyZWF0ZUFuZFdhaXRGb3JGZW5jZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBmZW5jZUNvbnRleHQgPSB0aGlzLmNyZWF0ZUZlbmNlKHRoaXMuZ2wpO1xuICAgIHJldHVybiB0aGlzLnBvbGxGZW5jZShmZW5jZUNvbnRleHQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVGZW5jZShnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0KTogRmVuY2VDb250ZXh0IHtcbiAgICBsZXQgaXNGZW5jZVBhc3NlZDogKCkgPT4gYm9vbGVhbjtcbiAgICBjb25zdCBnbDIgPSBnbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgIGNvbnN0IHF1ZXJ5ID0gZ2wyLmZlbmNlU3luYyhnbDIuU1lOQ19HUFVfQ09NTUFORFNfQ09NUExFVEUsIDApO1xuICAgIGdsLmZsdXNoKCk7XG4gICAgaWYgKHF1ZXJ5ID09PSBudWxsKSB7XG4gICAgICBpc0ZlbmNlUGFzc2VkID0gKCkgPT4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaXNGZW5jZVBhc3NlZCA9ICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gZ2wyLmNsaWVudFdhaXRTeW5jKHF1ZXJ5LCAwLCAwKTtcbiAgICAgICAgcmV0dXJuIHN0YXR1cyA9PT0gZ2wyLkFMUkVBRFlfU0lHTkFMRUQgfHwgc3RhdHVzID09PSBnbDIuQ09ORElUSU9OX1NBVElTRklFRDtcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7cXVlcnksIGlzRmVuY2VQYXNzZWR9O1xuICB9XG5cbiAgYXN5bmMgcG9sbEZlbmNlKGZlbmNlQ29udGV4dDogRmVuY2VDb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4ge1xuICAgICAgdm9pZCB0aGlzLmFkZEl0ZW1Ub1BvbGwoKCkgPT4gZmVuY2VDb250ZXh0LmlzRmVuY2VQYXNzZWQoKSwgKCkgPT4gcmVzb2x2ZSgpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaXRlbXNUb1BvbGw6IFBvbGxJdGVtW10gPSBbXTtcblxuICBwb2xsSXRlbXMoKTogdm9pZCB7XG4gICAgLy8gRmluZCB0aGUgbGFzdCBxdWVyeSB0aGF0IGhhcyBmaW5pc2hlZC5cbiAgICBjb25zdCBpbmRleCA9IGxpbmVhclNlYXJjaExhc3RUcnVlKHRoaXMuaXRlbXNUb1BvbGwubWFwKHggPT4geC5pc0RvbmVGbikpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IGluZGV4OyArK2kpIHtcbiAgICAgIGNvbnN0IHtyZXNvbHZlRm59ID0gdGhpcy5pdGVtc1RvUG9sbFtpXTtcbiAgICAgIHJlc29sdmVGbigpO1xuICAgIH1cbiAgICB0aGlzLml0ZW1zVG9Qb2xsID0gdGhpcy5pdGVtc1RvUG9sbC5zbGljZShpbmRleCArIDEpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhZGRJdGVtVG9Qb2xsKGlzRG9uZUZuOiAoKSA9PiBib29sZWFuLCByZXNvbHZlRm46ICgpID0+IHZvaWQpIHtcbiAgICB0aGlzLml0ZW1zVG9Qb2xsLnB1c2goe2lzRG9uZUZuLCByZXNvbHZlRm59KTtcbiAgICBpZiAodGhpcy5pdGVtc1RvUG9sbC5sZW5ndGggPiAxKSB7XG4gICAgICAvLyBXZSBhbHJlYWR5IGhhdmUgYSBydW5uaW5nIGxvb3AgdGhhdCBwb2xscy5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gU3RhcnQgYSBuZXcgbG9vcCB0aGF0IHBvbGxzLlxuICAgIGF3YWl0IHJlcGVhdGVkVHJ5KCgpID0+IHtcbiAgICAgIHRoaXMucG9sbEl0ZW1zKCk7XG4gICAgICAvLyBFbmQgdGhlIGxvb3AgaWYgbm8gbW9yZSBpdGVtcyB0byBwb2xsLlxuICAgICAgcmV0dXJuIHRoaXMuaXRlbXNUb1BvbGwubGVuZ3RoID09PSAwO1xuICAgIH0pO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcblxuaW1wb3J0IHtXZWJHTENvbnRleHR9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbmNvbnN0IGNhY2hlOiB7W2NvbnRleHRJZDogc3RyaW5nXTogV2ViR0xDb250ZXh0fSA9IHt9O1xuXG4vKipcbiAqIFRoaXMgZmFjdG9yeSBmdW5jdGlvbiBjcmVhdGVzIHByb3BlciBXZWJHTFJlbmRlcmluZ0NvbnRleHQgYmFzZWQgb25cbiAqIHRoZSBjdXJyZW50IGJyb3dzZXJzIGNhcGFiaWxpdGllc1xuICogVGhlIG9yZGVyIGlzIGZyb20gaGlnaGVyL21vc3QgcmVjZW50IHZlcnNpb25zIHRvIG1vc3QgYmFzaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVdlYkdMQ29udGV4dChjb250ZXh0SWQ/OiAnd2ViZ2wnfCd3ZWJnbDInKTogV2ViR0xDb250ZXh0IHtcbiAgbGV0IGNvbnRleHQ6IFdlYkdMQ29udGV4dHx1bmRlZmluZWQ7XG4gIGlmICgoIWNvbnRleHRJZCB8fCBjb250ZXh0SWQgPT09ICd3ZWJnbDInKSAmJiAnd2ViZ2wyJyBpbiBjYWNoZSkge1xuICAgIGNvbnRleHQgPSBjYWNoZS53ZWJnbDI7XG4gIH0gZWxzZSBpZiAoKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wnKSAmJiAnd2ViZ2wnIGluIGNhY2hlKSB7XG4gICAgY29udGV4dCA9IGNhY2hlLndlYmdsO1xuICB9XG5cbiAgaWYgKCFjb250ZXh0KSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIHRyeSB0byBjcmVhdGUgd2ViZ2wgY29udGV4dCBmcm9tIGFuIG9mZnNjcmVlbiBjYW52YXNcbiAgICAgIGNvbnN0IG9mZnNjcmVlbkNhbnZhcyA9IGNyZWF0ZU9mZnNjcmVlbkNhbnZhcygpO1xuICAgICAgY29udGV4dCA9IGNyZWF0ZU5ld1dlYkdMQ29udGV4dChvZmZzY3JlZW5DYW52YXMsIGNvbnRleHRJZCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gaWYgZmFpbGVkLCBmYWxsYmFjayB0byB0cnkgdG8gdXNlIGEgbm9ybWFsIGNhbnZhcyBlbGVtZW50XG4gICAgICBjb25zdCBjYW52YXMgPSBjcmVhdGVDYW52YXMoKTtcbiAgICAgIGNvbnRleHQgPSBjcmVhdGVOZXdXZWJHTENvbnRleHQoY2FudmFzLCBjb250ZXh0SWQpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnRleHRJZCA9IGNvbnRleHRJZCB8fCBjb250ZXh0LnZlcnNpb24gPT09IDEgPyAnd2ViZ2wnIDogJ3dlYmdsMic7XG4gIGNvbnN0IGdsID0gY29udGV4dC5nbDtcblxuICBjYWNoZVtjb250ZXh0SWRdID0gY29udGV4dDtcblxuICBpZiAoZ2wuaXNDb250ZXh0TG9zdCgpKSB7XG4gICAgZGVsZXRlIGNhY2hlW2NvbnRleHRJZF07XG4gICAgcmV0dXJuIGNyZWF0ZVdlYkdMQ29udGV4dChjb250ZXh0SWQpO1xuICB9XG5cbiAgZ2wuZGlzYWJsZShnbC5ERVBUSF9URVNUKTtcbiAgZ2wuZGlzYWJsZShnbC5TVEVOQ0lMX1RFU1QpO1xuICBnbC5kaXNhYmxlKGdsLkJMRU5EKTtcbiAgZ2wuZGlzYWJsZShnbC5ESVRIRVIpO1xuICBnbC5kaXNhYmxlKGdsLlBPTFlHT05fT0ZGU0VUX0ZJTEwpO1xuICBnbC5kaXNhYmxlKGdsLlNBTVBMRV9DT1ZFUkFHRSk7XG4gIGdsLmVuYWJsZShnbC5TQ0lTU09SX1RFU1QpO1xuICBnbC5lbmFibGUoZ2wuQ1VMTF9GQUNFKTtcbiAgZ2wuY3VsbEZhY2UoZ2wuQkFDSyk7XG5cbiAgcmV0dXJuIGNvbnRleHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVOZXdXZWJHTENvbnRleHQoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCwgY29udGV4dElkPzogJ3dlYmdsJ3wnd2ViZ2wyJyk6IFdlYkdMQ29udGV4dCB7XG4gIGNvbnN0IGNvbnRleHRBdHRyaWJ1dGVzOiBXZWJHTENvbnRleHRBdHRyaWJ1dGVzID0ge1xuICAgIGFscGhhOiBmYWxzZSxcbiAgICBkZXB0aDogZmFsc2UsXG4gICAgYW50aWFsaWFzOiBmYWxzZSxcbiAgICBzdGVuY2lsOiBmYWxzZSxcbiAgICBwcmVzZXJ2ZURyYXdpbmdCdWZmZXI6IGZhbHNlLFxuICAgIHByZW11bHRpcGxpZWRBbHBoYTogZmFsc2UsXG4gICAgZmFpbElmTWFqb3JQZXJmb3JtYW5jZUNhdmVhdDogZmFsc2VcbiAgfTtcbiAgbGV0IGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHR8bnVsbDtcbiAgY29uc3QgY2EgPSBjb250ZXh0QXR0cmlidXRlcztcbiAgaWYgKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wyJykge1xuICAgIGdsID0gY2FudmFzLmdldENvbnRleHQoJ3dlYmdsMicsIGNhKTtcbiAgICBpZiAoZ2wpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgV2ViR0xDb250ZXh0KGdsLCAyKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBMb2dnZXIud2FybmluZygnR2xDb250ZXh0RmFjdG9yeScsIGBmYWlsZWQgdG8gY3JlYXRlIFdlYkdMQ29udGV4dCB1c2luZyBjb250ZXh0SWQgJ3dlYmdsMicuIEVycm9yOiAke2Vycn1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wnKSB7XG4gICAgZ2wgPSBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnLCBjYSkgfHwgY2FudmFzLmdldENvbnRleHQoJ2V4cGVyaW1lbnRhbC13ZWJnbCcsIGNhKSBhcyBXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XG4gICAgaWYgKGdsKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbmV3IFdlYkdMQ29udGV4dChnbCwgMSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgTG9nZ2VyLndhcm5pbmcoXG4gICAgICAgICAgICAnR2xDb250ZXh0RmFjdG9yeScsXG4gICAgICAgICAgICBgZmFpbGVkIHRvIGNyZWF0ZSBXZWJHTENvbnRleHQgdXNpbmcgY29udGV4dElkICd3ZWJnbCcgb3IgJ2V4cGVyaW1lbnRhbC13ZWJnbCcuIEVycm9yOiAke2Vycn1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZGVjbGFyZSBsZXQgT2Zmc2NyZWVuQ2FudmFzOiB7bmV3ICh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IEhUTUxDYW52YXNFbGVtZW50fTtcblxuZnVuY3Rpb24gY3JlYXRlQ2FudmFzKCk6IEhUTUxDYW52YXNFbGVtZW50IHtcbiAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdmYWlsZWQgdG8gY3JlYXRlIGNhbnZhczogZG9jdW1lbnQgaXMgbm90IHN1cHBvcnRlZCcpO1xuICB9XG4gIGNvbnN0IGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgY2FudmFzLndpZHRoID0gMTtcbiAgY2FudmFzLmhlaWdodCA9IDE7XG4gIHJldHVybiBjYW52YXM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU9mZnNjcmVlbkNhbnZhcygpOiBIVE1MQ2FudmFzRWxlbWVudCB7XG4gIGlmICh0eXBlb2YgT2Zmc2NyZWVuQ2FudmFzID09PSAndW5kZWZpbmVkJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ZhaWxlZCB0byBjcmVhdGUgb2Zmc2NyZWVuIGNhbnZhczogT2Zmc2NyZWVuQ2FudmFzIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgfVxuICByZXR1cm4gbmV3IE9mZnNjcmVlbkNhbnZhcygxLCAxKTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtlbnZ9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7QmFja2VuZCwgU2Vzc2lvbkhhbmRsZXJ9IGZyb20gJy4uL2JhY2tlbmQnO1xuaW1wb3J0IHtMb2dnZXJ9IGZyb20gJy4uL2luc3RydW1lbnQnO1xuaW1wb3J0IHtTZXNzaW9ufSBmcm9tICcuLi9zZXNzaW9uJztcblxuaW1wb3J0IHtXZWJHTFNlc3Npb25IYW5kbGVyfSBmcm9tICcuL3dlYmdsL3Nlc3Npb24taGFuZGxlcic7XG5pbXBvcnQge1dlYkdMQ29udGV4dH0gZnJvbSAnLi93ZWJnbC93ZWJnbC1jb250ZXh0JztcbmltcG9ydCB7Y3JlYXRlV2ViR0xDb250ZXh0fSBmcm9tICcuL3dlYmdsL3dlYmdsLWNvbnRleHQtZmFjdG9yeSc7XG5cbi8qKlxuICogV2ViR0xCYWNrZW5kIGlzIHRoZSBlbnRyeSBwb2ludCBmb3IgYWxsIFdlYkdMIG9wZWFydGlvbnNcbiAqIFdoZW4gaXQgc3RhcnRzIGl0IGNyZWF0ZWQgdGhlIFdlYkdMUmVuZGVyaW5nQ29udGV4dFxuICogYW5kIG90aGVyIG1haW4gZnJhbWV3b3JrIGNvbXBvbmVudHMgc3VjaCBhcyBQcm9ncmFtIGFuZCBUZXh0dXJlIE1hbmFnZXJzXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJHTEJhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHtcbiAgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQ7XG5cbiAgZ2V0IGNvbnRleHRJZCgpOiAnd2ViZ2wnfCd3ZWJnbDInfHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC5jb250ZXh0SWQ7XG4gIH1cbiAgc2V0IGNvbnRleHRJZCh2YWx1ZTogJ3dlYmdsJ3wnd2ViZ2wyJ3x1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wuY29udGV4dElkID0gdmFsdWU7XG4gIH1cblxuICBnZXQgbWF0bXVsTWF4QmF0Y2hTaXplKCk6IG51bWJlcnx1bmRlZmluZWQge1xuICAgIHJldHVybiBlbnYud2ViZ2wubWF0bXVsTWF4QmF0Y2hTaXplO1xuICB9XG4gIHNldCBtYXRtdWxNYXhCYXRjaFNpemUodmFsdWU6IG51bWJlcnx1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wubWF0bXVsTWF4QmF0Y2hTaXplID0gdmFsdWU7XG4gIH1cblxuICBnZXQgdGV4dHVyZUNhY2hlTW9kZSgpOiAnaW5pdGlhbGl6ZXJPbmx5J3wnZnVsbCd8dW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLnRleHR1cmVDYWNoZU1vZGU7XG4gIH1cbiAgc2V0IHRleHR1cmVDYWNoZU1vZGUodmFsdWU6ICdpbml0aWFsaXplck9ubHknfCdmdWxsJ3x1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wudGV4dHVyZUNhY2hlTW9kZSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IHBhY2soKTogYm9vbGVhbnx1bmRlZmluZWQge1xuICAgIHJldHVybiBlbnYud2ViZ2wucGFjaztcbiAgfVxuICBzZXQgcGFjayh2YWx1ZTogYm9vbGVhbnx1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wucGFjayA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGFzeW5jKCk6IGJvb2xlYW58dW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLmFzeW5jO1xuICB9XG4gIHNldCBhc3luYyh2YWx1ZTogYm9vbGVhbnx1bmRlZmluZWQpIHtcbiAgICBlbnYud2ViZ2wuYXN5bmMgPSB2YWx1ZTtcbiAgfVxuXG4gIGluaXRpYWxpemUoKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuZ2xDb250ZXh0ID0gY3JlYXRlV2ViR0xDb250ZXh0KHRoaXMuY29udGV4dElkKTtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5tYXRtdWxNYXhCYXRjaFNpemUgIT09ICdudW1iZXInKSB7XG4gICAgICAgIHRoaXMubWF0bXVsTWF4QmF0Y2hTaXplID0gMTY7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHRoaXMudGV4dHVyZUNhY2hlTW9kZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhpcy50ZXh0dXJlQ2FjaGVNb2RlID0gJ2Z1bGwnO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB0aGlzLnBhY2sgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aGlzLnBhY2sgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdGhpcy5hc3luYyAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRoaXMuYXN5bmMgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgTG9nZ2VyLnNldFdpdGhFbnYoZW52KTtcblxuICAgICAgaWYgKCFlbnYud2ViZ2wuY29udGV4dCkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZW52LndlYmdsLCAnY29udGV4dCcsIHt2YWx1ZTogdGhpcy5nbENvbnRleHQuZ2x9KTtcbiAgICAgIH1cblxuICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICAgJ1dlYkdMQmFja2VuZCcsXG4gICAgICAgICAgYENyZWF0ZWQgV2ViR0xDb250ZXh0OiAke3R5cGVvZiB0aGlzLmdsQ29udGV4dH0gd2l0aCBtYXRtdWxNYXhCYXRjaFNpemU6ICR7XG4gICAgICAgICAgICAgIHRoaXMubWF0bXVsTWF4QmF0Y2hTaXplfTsgdGV4dHVyZUNhY2hlTW9kZTogJHt0aGlzLnRleHR1cmVDYWNoZU1vZGV9OyBwYWNrOiAke3RoaXMucGFja307IGFzeW5jOiAke1xuICAgICAgICAgICAgICB0aGlzLmFzeW5jfS5gKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIExvZ2dlci53YXJuaW5nKCdXZWJHTEJhY2tlbmQnLCBgVW5hYmxlIHRvIGluaXRpYWxpemUgV2ViR0xCYWNrZW5kLiAke2V9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIGNyZWF0ZVNlc3Npb25IYW5kbGVyKGNvbnRleHQ6IFNlc3Npb24uQ29udGV4dCk6IFNlc3Npb25IYW5kbGVyIHtcbiAgICByZXR1cm4gbmV3IFdlYkdMU2Vzc2lvbkhhbmRsZXIodGhpcywgY29udGV4dCk7XG4gIH1cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmdsQ29udGV4dC5kaXNwb3NlKCk7XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtXZWJHTEJhY2tlbmR9IGZyb20gJy4vYmFja2VuZHMvYmFja2VuZC13ZWJnbCc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3J9IGZyb20gJy4vb3BlcmF0b3JzJztcbmltcG9ydCB7T3BTZXR9IGZyb20gJy4vb3BzZXQnO1xuaW1wb3J0IHtTZXNzaW9ufSBmcm9tICcuL3Nlc3Npb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEluZmVyZW5jZUhhbmRsZXIge1xuICAvKipcbiAgICogZGlzcG9zZSB0aGUgaW5mZXJlbmNlIGhhbmRsZXIuIGl0IHdpbGwgYmUgY2FsbGVkIGFzIHRoZSBsYXN0IHN0ZXAgaW4gU2Vzc2lvbi5ydW4oKVxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNlc3Npb25IYW5kbGVyIHtcbiAgLyoqXG4gICAqIHRyYW5zZm9ybSB0aGUgZ3JhcGggYXQgaW5pdGlhbGl6YXRpb24gdGltZVxuICAgKiBAcGFyYW0gZ3JhcGhUcmFuc2Zvcm1lciB0aGUgZ3JhcGggdHJhbnNmb3JtZXIgdG8gbWFuaXB1bGF0ZSB0aGUgbW9kZWwgZ3JhcGhcbiAgICovXG4gIHRyYW5zZm9ybUdyYXBoPyhncmFwaFRyYW5zZm9ybWVyOiBHcmFwaC5UcmFuc2Zvcm1lcik6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBJbmZlcmVuY2VIYW5kbGVyIHRvIHVzZSBpbiBhIFNlc3Npb24ucnVuKCkgY2FsbFxuICAgKi9cbiAgY3JlYXRlSW5mZXJlbmNlSGFuZGxlcigpOiBJbmZlcmVuY2VIYW5kbGVyO1xuXG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBzZXNzaW9uIGhhbmRsZXIuIGl0IHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBzZXNzaW9uIGlzIGJlaW5nIGRpc3Bvc2VkIGV4cGxpY2l0bHlcbiAgICovXG4gIGRpc3Bvc2UoKTogdm9pZDtcblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIG9wZXJhdG9yIGZyb20gdGhlIG5hbWUgYW5kIG9wc2V0IHZlcnNpb247IGJhY2tlbmQgc3BlY2lmaWNcbiAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgdG8gcmVzb2x2ZVxuICAgKiBAcGFyYW0gb3BzZXRzIGEgbGlzdCBvZiBvcHNldHMgdGhhdCBleHBvcnRlZCBmcm9tIHRoZSBtb2RlbFxuICAgKiBAcGFyYW0gZ3JhcGggdGhlIGNvbXBsZXRlbHkgaW5pdGlhbGl6ZWQgZ3JhcGhcbiAgICovXG4gIHJlc29sdmUobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBncmFwaDogR3JhcGgpOiBPcGVyYXRvcjtcblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgbGV0J3MgdGhlIHNlc3Npb25IYW5kbGVyIGtub3cgdGhhdCB0aGUgZ3JhcGggaW5pdGlhbGl6YXRpb24gaXMgY29tcGxldGVcbiAgICogQHBhcmFtIGdyYXBoIHRoZSBjb21wbGV0ZWx5IGluaXRpYWxpemVkIGdyYXBoXG4gICAqL1xuICBvbkdyYXBoSW5pdGlhbGl6ZWQ/KGdyYXBoOiBHcmFwaCk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBjb3JyZXNwb25kaW5nIGJhY2tlbmRcbiAgICovXG4gIHJlYWRvbmx5IGJhY2tlbmQ6IEJhY2tlbmQ7XG5cbiAgLyoqXG4gICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBzZXNzaW9uIGNvbnRleHRcbiAgICovXG4gIHJlYWRvbmx5IGNvbnRleHQ6IFNlc3Npb24uQ29udGV4dDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCYWNrZW5kIHtcbiAgLyoqXG4gICAqIGluaXRpYWxpemUgdGhlIGJhY2tlbmQuIHdpbGwgYmUgY2FsbGVkIG9ubHkgb25jZSwgd2hlbiB0aGUgZmlyc3QgdGltZSB0aGVcbiAgICogYmFja2VuZCBpdCB0byBiZSB1c2VkXG4gICAqL1xuICBpbml0aWFsaXplKCk6IGJvb2xlYW58UHJvbWlzZTxib29sZWFuPjtcblxuICAvKipcbiAgICogY3JlYXRlIGFuIGluc3RhbmNlIG9mIFNlc3Npb25IYW5kbGVyIHRvIHVzZSBpbiBhIFNlc3Npb24gb2JqZWN0J3MgbGlmZWN5Y2xlXG4gICAqL1xuICBjcmVhdGVTZXNzaW9uSGFuZGxlcihjb250ZXh0OiBTZXNzaW9uLkNvbnRleHQpOiBTZXNzaW9uSGFuZGxlcjtcblxuICAvKipcbiAgICogZGlzcG9zZSB0aGUgYmFja2VuZC4gY3VycmVudGx5IHRoaXMgd2lsbCBub3QgYmUgY2FsbGVkXG4gICAqL1xuICBkaXNwb3NlKCk6IHZvaWQ7XG59XG5cbi8vIGNhY2hlcyBhbGwgaW5pdGlhbGl6ZWQgYmFja2VuZCBpbnN0YW5jZXNcbmNvbnN0IGJhY2tlbmRzQ2FjaGU6IE1hcDxzdHJpbmcsIEJhY2tlbmQ+ID0gbmV3IE1hcCgpO1xuXG5leHBvcnQgY29uc3QgYmFja2VuZDoge1tuYW1lOiBzdHJpbmddOiBCYWNrZW5kfSA9IHtcbiAgd2ViZ2w6IG5ldyBXZWJHTEJhY2tlbmQoKVxufTtcblxuLyoqXG4gKiBSZXNvbHZlIGEgcmVmZXJlbmNlIHRvIHRoZSBiYWNrZW5kLiBJZiBhIGhpbnQgaXMgc3BlY2lmaWVkLCB0aGUgY29ycmVzcG9uZGluZ1xuICogYmFja2VuZCB3aWxsIGJlIHVzZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXNvbHZlQmFja2VuZChoaW50Pzogc3RyaW5nfHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTxCYWNrZW5kPiB7XG4gIGlmICghaGludCkge1xuICAgIHJldHVybiByZXNvbHZlQmFja2VuZChbJ3dlYmdsJ10pO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGhpbnRzID0gdHlwZW9mIGhpbnQgPT09ICdzdHJpbmcnID8gW2hpbnRdIDogaGludDtcblxuICAgIGZvciAoY29uc3QgYmFja2VuZEhpbnQgb2YgaGludHMpIHtcbiAgICAgIGNvbnN0IGNhY2hlID0gYmFja2VuZHNDYWNoZS5nZXQoYmFja2VuZEhpbnQpO1xuICAgICAgaWYgKGNhY2hlKSB7XG4gICAgICAgIHJldHVybiBjYWNoZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmFja2VuZCA9IGF3YWl0IHRyeUxvYWRCYWNrZW5kKGJhY2tlbmRIaW50KTtcbiAgICAgIGlmIChiYWNrZW5kKSB7XG4gICAgICAgIHJldHVybiBiYWNrZW5kO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignbm8gYXZhaWxhYmxlIGJhY2tlbmQgdG8gdXNlJyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRyeUxvYWRCYWNrZW5kKGJhY2tlbmRIaW50OiBzdHJpbmcpOiBQcm9taXNlPEJhY2tlbmR8dW5kZWZpbmVkPiB7XG4gIGNvbnN0IGJhY2tlbmRPYmogPSBiYWNrZW5kO1xuXG4gIGlmICh0eXBlb2YgYmFja2VuZE9ialtiYWNrZW5kSGludF0gIT09ICd1bmRlZmluZWQnICYmIGlzQmFja2VuZChiYWNrZW5kT2JqW2JhY2tlbmRIaW50XSkpIHtcbiAgICBjb25zdCBiYWNrZW5kID0gYmFja2VuZE9ialtiYWNrZW5kSGludF07XG4gICAgbGV0IGluaXQgPSBiYWNrZW5kLmluaXRpYWxpemUoKTtcbiAgICBpZiAodHlwZW9mIGluaXQgPT09ICdvYmplY3QnICYmICd0aGVuJyBpbiBpbml0KSB7XG4gICAgICBpbml0ID0gYXdhaXQgaW5pdDtcbiAgICB9XG4gICAgaWYgKGluaXQpIHtcbiAgICAgIGJhY2tlbmRzQ2FjaGUuc2V0KGJhY2tlbmRIaW50LCBiYWNrZW5kKTtcbiAgICAgIHJldHVybiBiYWNrZW5kO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGlzQmFja2VuZChvYmo6IHVua25vd24pIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgY29uc3QgbyA9IG9iaiBhcyBhbnk7XG5cbiAgLy8gY2hlY2sgaWYgYW4gb2JqZWN0IGlzIGEgQmFja2VuZCBpbnN0YW5jZVxuICBpZiAoXG4gICAgICAnaW5pdGlhbGl6ZScgaW4gbyAmJiB0eXBlb2Ygby5pbml0aWFsaXplID09PSAnZnVuY3Rpb24nICYmICAgICAgICAgICAgICAgICAgICAgIC8vIGluaXRpYWxpemUoKVxuICAgICAgJ2NyZWF0ZVNlc3Npb25IYW5kbGVyJyBpbiBvICYmIHR5cGVvZiBvLmNyZWF0ZVNlc3Npb25IYW5kbGVyID09PSAnZnVuY3Rpb24nICYmICAvLyBjcmVhdGVTZXNzaW9uSGFuZGxlcigpXG4gICAgICAnZGlzcG9zZScgaW4gbyAmJiB0eXBlb2Ygby5kaXNwb3NlID09PSAnZnVuY3Rpb24nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRpc3Bvc2UoKVxuICApIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IHR5cGUgQmFja2VuZFR5cGUgPSBCYWNrZW5kO1xuZXhwb3J0IHR5cGUgU2Vzc2lvbkhhbmRsZXJUeXBlID0gUmV0dXJuVHlwZTxCYWNrZW5kVHlwZVsnY3JlYXRlU2Vzc2lvbkhhbmRsZXInXT47XG5leHBvcnQgdHlwZSBJbmZlcmVuY2VIYW5kbGVyVHlwZSA9IFJldHVyblR5cGU8U2Vzc2lvbkhhbmRsZXJUeXBlWydjcmVhdGVJbmZlcmVuY2VIYW5kbGVyJ10+O1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1Nlc3Npb25IYW5kbGVyfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQge0xvZ2dlciwgUHJvZmlsZXJ9IGZyb20gJy4vaW5zdHJ1bWVudCc7XG5pbXBvcnQge09wZXJhdG9yfSBmcm9tICcuL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi90ZW5zb3InO1xuXG5jbGFzcyBLZXJuZWxPcCB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBvcDogT3BlcmF0b3IsIHB1YmxpYyBub2RlOiBHcmFwaC5Ob2RlKSB7fVxufVxuXG5leHBvcnQgY2xhc3MgRXhlY3V0aW9uUGxhbiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZ3JhcGg6IEdyYXBoLCBvcHM6IE9wZXJhdG9yW10sIHByaXZhdGUgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPikge1xuICAgIHRoaXMuaW5pdGlhbGl6ZShvcHMpO1xuICB9XG5cbiAgaW5pdGlhbGl6ZShvcHM6IE9wZXJhdG9yW10pIHtcbiAgICB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ0V4ZWN1dGlvblBsYW4uaW5pdGlhbGl6ZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGdyYXBoTm9kZXMgPSB0aGlzLmdyYXBoLmdldE5vZGVzKCk7XG4gICAgICBpZiAoZ3JhcGhOb2Rlcy5sZW5ndGggIT09IG9wcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgc2l6ZSBvZiBub2RlcyBhbmQgT1BzIGRvIG5vdCBtYXRjaC4nKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fb3BzID0gb3BzLm1hcCgob3AsIGkpID0+IG5ldyBLZXJuZWxPcChvcCwgZ3JhcGhOb2Rlc1tpXSkpO1xuICAgICAgdGhpcy5yZXNldCgpO1xuXG4gICAgICAvLyBsb29rIGZvciBzdGFydGVyIG5vZGUocylcbiAgICAgIHRoaXMuX3N0YXJ0ZXIgPSBbXTtcbiAgICAgIHRoaXMuX29wcy5mb3JFYWNoKChvcCwgaSkgPT4ge1xuICAgICAgICBsZXQgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICBmb3IgKGNvbnN0IGlucHV0IG9mIG9wLm5vZGUuaW5wdXRzKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAhdGhpcy5fdmFsdWVzW2lucHV0XSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm90IGFuIGluaXRpYWxpemVkIGlucHV0XG4gICAgICAgICAgICAgICYmIHRoaXMuZ3JhcGguZ2V0SW5wdXRJbmRpY2VzKCkuaW5kZXhPZihpbnB1dCkgPT09IC0xICAvLyBub3QgbW9kZWwgaW5wdXRcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJlc29sdmVkID0gZmFsc2U7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc29sdmVkKSB7XG4gICAgICAgICAgdGhpcy5fc3RhcnRlci5wdXNoKGkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHJlc2V0KCkge1xuICAgIHRoaXMuX3ZhbHVlcyA9IHRoaXMuZ3JhcGguZ2V0VmFsdWVzKCkubWFwKGkgPT4gaS50ZW5zb3IpO1xuICB9XG5cbiAgYXN5bmMgZXhlY3V0ZShzZXNzaW9uSGFuZGxlcjogU2Vzc2lvbkhhbmRsZXIsIG1vZGVsSW5wdXRzOiBUZW5zb3JbXSk6IFByb21pc2U8VGVuc29yW10+IHtcbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnc2Vzc2lvbicsICdFeGVjdXRpb25QbGFuLmV4ZWN1dGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyByZXNldCBtZWRpZW0gcmVzdWx0XG4gICAgICB0aGlzLnJlc2V0KCk7XG5cbiAgICAgIC8vIGNyZWF0ZSBpbmZlcmVuY2UgaGFuZGxlclxuICAgICAgY29uc3QgaW5mZXJlbmNlSGFuZGxlciA9IHNlc3Npb25IYW5kbGVyLmNyZWF0ZUluZmVyZW5jZUhhbmRsZXIoKTtcblxuICAgICAgLy8gcG9wdWxhdGUgaW5wdXRzIHZhbHVlXG4gICAgICBjb25zdCBncmFwaElucHV0cyA9IHRoaXMuZ3JhcGguZ2V0SW5wdXRJbmRpY2VzKCk7XG4gICAgICBpZiAobW9kZWxJbnB1dHMubGVuZ3RoICE9PSBncmFwaElucHV0cy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBudW1iZXIgb2YgaW5wdXQgdGVuc29ycyBkb24ndCBtYXRjaCB0aGUgbnVtYmVyIG9mIGlucHV0cyB0byB0aGUgbW9kZWw6IGFjdHVhbDogJHtcbiAgICAgICAgICAgIG1vZGVsSW5wdXRzLmxlbmd0aH0gZXhwZWN0ZWQ6ICR7Z3JhcGhJbnB1dHMubGVuZ3RofWApO1xuICAgICAgfVxuXG4gICAgICBtb2RlbElucHV0cy5mb3JFYWNoKChpbnB1dCwgaSkgPT4ge1xuICAgICAgICBjb25zdCBpbmRleCA9IGdyYXBoSW5wdXRzW2ldO1xuICAgICAgICB0aGlzLl92YWx1ZXNbaW5kZXhdID0gaW5wdXQ7XG4gICAgICB9KTtcblxuICAgICAgLy8gcHJlcGFyZSBydW5uaW5nIHNlcXVlbmNlXG4gICAgICBjb25zdCBzZXF1ZW5jZTogbnVtYmVyW10gPSB0aGlzLl9zdGFydGVyLnNsaWNlKDApO1xuXG4gICAgICAvLyBleGVjdXRpb24gaXRlcmF0aW9uc1xuICAgICAgY29uc3QgZ3JhcGhWYWx1ZXMgPSB0aGlzLmdyYXBoLmdldFZhbHVlcygpO1xuICAgICAgY29uc3QgZ3JhcGhOb2RlcyA9IHRoaXMuZ3JhcGguZ2V0Tm9kZXMoKTtcblxuICAgICAgbGV0IHJlYXIgPSAwO1xuICAgICAgd2hpbGUgKHJlYXIgPCBzZXF1ZW5jZS5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgdGhpc09wSW5kZXggPSBzZXF1ZW5jZVtyZWFyKytdO1xuICAgICAgICBjb25zdCB0aGlzT3AgPSB0aGlzLl9vcHNbdGhpc09wSW5kZXhdO1xuXG4gICAgICAgIC8vIGNoZWNrIGlucHV0XG4gICAgICAgIGNvbnN0IGlucHV0TGlzdCA9IHRoaXNPcC5ub2RlLmlucHV0cy5tYXAoaSA9PiB0aGlzLl92YWx1ZXNbaV0pO1xuICAgICAgICBpZiAoaW5wdXRMaXN0LmluZGV4T2YodW5kZWZpbmVkKSAhPT0gLTEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVzb2x2ZWQgaW5wdXQgZGV0ZWN0ZWQ6IG9wOiAke3RoaXNPcC5ub2RlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcnVuXG4gICAgICAgIGNvbnN0IGlucHV0VGVuc29ycyA9IGlucHV0TGlzdCBhcyBUZW5zb3JbXTtcbiAgICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICAgICAnRXhlY1BsYW4nLFxuICAgICAgICAgICAgYFJ1bmluZyBvcDoke3RoaXNPcC5ub2RlLm5hbWV9ICgke1xuICAgICAgICAgICAgICAgIGlucHV0VGVuc29ycy5tYXAoKHQsIGkpID0+IGAnJHt0aGlzT3Aubm9kZS5pbnB1dHNbaV19JzogJHt0LnR5cGV9WyR7dC5kaW1zLmpvaW4oJywnKX1dYCkuam9pbignLCAnKX0pYCk7XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0TGlzdCA9IGF3YWl0IHRoaXMucHJvZmlsZXIuZXZlbnQoXG4gICAgICAgICAgICAnbm9kZScsIHRoaXNPcC5ub2RlLm5hbWUsIGFzeW5jICgpID0+IHRoaXNPcC5vcC5pbXBsKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0VGVuc29ycywgdGhpc09wLm9wLmNvbnRleHQpKTtcblxuICAgICAgICAvLyBjaGVjayBvdXRwdXRcbiAgICAgICAgaWYgKG91dHB1dExpc3QubGVuZ3RoICE9PSB0aGlzT3Aubm9kZS5vdXRwdXRzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIHNpemUgb2Ygb3V0cHV0IGRvZXMgbm90IG1hdGNoIG1vZGVsIGRlZmluaXRpb24uJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaWxsIHZhbHVlXG4gICAgICAgIG91dHB1dExpc3QuZm9yRWFjaCgob3V0cHV0LCBpKSA9PiB7XG4gICAgICAgICAgY29uc3QgaiA9IHRoaXNPcC5ub2RlLm91dHB1dHNbaV07XG4gICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlc1tqXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXQgWyR7an1dIGFscmVhZHkgaGFzIHZhbHVlOiBvcDoke3RoaXNPcC5ub2RlLm5hbWV9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuX3ZhbHVlc1tqXSA9IG91dHB1dDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gcmVzb2x2ZSBkb3duc3RyZWFtIG5vZGVzXG4gICAgICAgIGNvbnN0IGRvd25zdHJlYW1Ob2RlcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICAgICAgICBvdXRwdXRMaXN0LmZvckVhY2goKF9vdXRwdXQsIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBqID0gdGhpc09wLm5vZGUub3V0cHV0c1tpXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGN1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4IG9mIGdyYXBoVmFsdWVzW2pdLnRvKSB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RG93bnN0cmVhbU5vZGUgPSBncmFwaE5vZGVzW2N1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4XTtcbiAgICAgICAgICAgIGxldCByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGsgb2YgY3VycmVudERvd25zdHJlYW1Ob2RlLmlucHV0cykge1xuICAgICAgICAgICAgICBpZiAoIXRoaXMuX3ZhbHVlc1trXSkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXNvbHZlZCkge1xuICAgICAgICAgICAgICBkb3duc3RyZWFtTm9kZXMuYWRkKGN1cnJlbnREb3duc3RyZWFtTm9kZUluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBzZXF1ZW5jZS5wdXNoKC4uLmRvd25zdHJlYW1Ob2Rlcyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG91dHB1dDogVGVuc29yW10gPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ncmFwaC5nZXRPdXRwdXRJbmRpY2VzKCkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kZXggPSB0aGlzLmdyYXBoLmdldE91dHB1dEluZGljZXMoKVtpXTtcbiAgICAgICAgY29uc3Qgb3V0cHV0VGVuc29yID0gdGhpcy5fdmFsdWVzW291dHB1dEluZGV4XTtcbiAgICAgICAgaWYgKG91dHB1dFRlbnNvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXF1aXJlZCBvdXRwdXQgWyR7b3V0cHV0SW5kZXh9XSBkb2VzIG5vdCBoYXZlIHZhbHVlYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG91dHB1dEluZGV4ID09PSAwKSB7XG4gICAgICAgICAgYXdhaXQgb3V0cHV0VGVuc29yLmdldERhdGEoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG4gICAgICAgICAgb3V0cHV0VGVuc29yLmRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgb3V0cHV0LnB1c2gob3V0cHV0VGVuc29yKTtcbiAgICAgIH1cbiAgICAgIExvZ2dlci52ZXJib3NlKCdFeGVjUGxhbicsICdkaXNwb3Npbmcgb2YgaW5mZXJlbmNlSGFuZGxlcicpO1xuICAgICAgaW5mZXJlbmNlSGFuZGxlci5kaXNwb3NlKCk7XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH0pO1xuICB9XG5cbiAgX3ZhbHVlczogQXJyYXk8VGVuc29yfHVuZGVmaW5lZD47XG4gIF9vcHM6IEtlcm5lbE9wW107XG4gIF9zdGFydGVyOiBudW1iZXJbXTtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IExvbmcgZnJvbSAnbG9uZyc7XG5cbmltcG9ydCB7b25ueHJ1bnRpbWV9IGZyb20gJy4vb3J0LXNjaGVtYS9mbGF0YnVmZmVycy9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7b25ueH0gZnJvbSAnLi9vcnQtc2NoZW1hL3Byb3RvYnVmL29ubngnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4vdGVuc29yJztcbmltcG9ydCB7ZGVjb2RlVXRmOFN0cmluZywgTG9uZ1V0aWx9IGZyb20gJy4vdXRpbCc7XG5cbmltcG9ydCBvcnRGYnMgPSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgQXR0cmlidXRlIHtcbiAgZXhwb3J0IGludGVyZmFjZSBEYXRhVHlwZU1hcCB7XG4gICAgZmxvYXQ6IG51bWJlcjtcbiAgICBpbnQ6IG51bWJlcjtcbiAgICBzdHJpbmc6IHN0cmluZztcbiAgICB0ZW5zb3I6IFRlbnNvcjtcbiAgICBmbG9hdHM6IG51bWJlcltdO1xuICAgIGludHM6IG51bWJlcltdO1xuICAgIHN0cmluZ3M6IHN0cmluZ1tdO1xuICAgIHRlbnNvcnM6IFRlbnNvcltdO1xuICB9XG5cbiAgZXhwb3J0IHR5cGUgRGF0YVR5cGUgPSBrZXlvZiBEYXRhVHlwZU1hcDtcbn1cblxudHlwZSBWYWx1ZVR5cGVzID0gQXR0cmlidXRlLkRhdGFUeXBlTWFwW0F0dHJpYnV0ZS5EYXRhVHlwZV07XG5cbnR5cGUgVmFsdWUgPSBbVmFsdWVUeXBlcywgQXR0cmlidXRlLkRhdGFUeXBlXTtcblxuZXhwb3J0IGNsYXNzIEF0dHJpYnV0ZSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJpYnV0ZXM6IG9ubnguSUF0dHJpYnV0ZVByb3RvW118b3J0RmJzLkF0dHJpYnV0ZVtdfG51bGx8dW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fYXR0cmlidXRlcyA9IG5ldyBNYXAoKTtcbiAgICBpZiAoYXR0cmlidXRlcyAhPT0gbnVsbCAmJiBhdHRyaWJ1dGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGZvciAoY29uc3QgYXR0ciBvZiBhdHRyaWJ1dGVzKSB7XG4gICAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICAgIHRoaXMuX2F0dHJpYnV0ZXMuc2V0KGF0dHIubmFtZSwgW0F0dHJpYnV0ZS5nZXRWYWx1ZShhdHRyKSwgQXR0cmlidXRlLmdldFR5cGUoYXR0cildKTtcbiAgICAgICAgfSBlbHNlIGlmIChhdHRyIGluc3RhbmNlb2Ygb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgICAgICAgIHRoaXMuX2F0dHJpYnV0ZXMuc2V0KGF0dHIubmFtZSgpISwgW0F0dHJpYnV0ZS5nZXRWYWx1ZShhdHRyKSwgQXR0cmlidXRlLmdldFR5cGUoYXR0cildKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX2F0dHJpYnV0ZXMuc2l6ZSA8IGF0dHJpYnV0ZXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZHVwbGljYXRlZCBhdHRyaWJ1dGUgbmFtZXMnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzZXQoa2V5OiBzdHJpbmcsIHR5cGU6IEF0dHJpYnV0ZS5EYXRhVHlwZSwgdmFsdWU6IFZhbHVlVHlwZXMpOiB2b2lkIHtcbiAgICB0aGlzLl9hdHRyaWJ1dGVzLnNldChrZXksIFt2YWx1ZSwgdHlwZV0pO1xuICB9XG4gIGRlbGV0ZShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuX2F0dHJpYnV0ZXMuZGVsZXRlKGtleSk7XG4gIH1cbiAgZ2V0RmxvYXQoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnZmxvYXQnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdmbG9hdCcsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRJbnQoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnaW50J10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnaW50JywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldFN0cmluZyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydzdHJpbmcnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdzdHJpbmcnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0VGVuc29yKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3RlbnNvciddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ3RlbnNvcicsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRGbG9hdHMoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnZmxvYXRzJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnZmxvYXRzJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldEludHMoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsnaW50cyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ2ludHMnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0U3RyaW5ncyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydzdHJpbmdzJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnc3RyaW5ncycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRUZW5zb3JzKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3RlbnNvcnMnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICd0ZW5zb3JzJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0PFYgZXh0ZW5kcyBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbQXR0cmlidXRlLkRhdGFUeXBlXT4oXG4gICAgICBrZXk6IHN0cmluZywgdHlwZTogQXR0cmlidXRlLkRhdGFUeXBlLCBkZWZhdWx0VmFsdWU/OiBWKTogViB7XG4gICAgY29uc3QgdmFsdWVBbmRUeXBlID0gdGhpcy5fYXR0cmlidXRlcy5nZXQoa2V5KTtcbiAgICBpZiAodmFsdWVBbmRUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChkZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXF1aXJlZCBhdHRyaWJ1dGUgbm90IGZvdW5kOiAke2tleX1gKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlQW5kVHlwZVsxXSAhPT0gdHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB0eXBlIG1pc21hdGNoOiBleHBlY3RlZCAke3R5cGV9IGJ1dCBnb3QgJHt2YWx1ZUFuZFR5cGVbMV19YCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZUFuZFR5cGVbMF0gYXMgVjtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFR5cGUoYXR0cjogb25ueC5JQXR0cmlidXRlUHJvdG98b3J0RmJzLkF0dHJpYnV0ZSk6IEF0dHJpYnV0ZS5EYXRhVHlwZSB7XG4gICAgY29uc3QgdHlwZSA9IGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvID8gKGF0dHIpLnR5cGUgOiAoYXR0ciBhcyBvcnRGYnMuQXR0cmlidXRlKS50eXBlKCk7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuICdmbG9hdCc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlQ6XG4gICAgICAgIHJldHVybiAnaW50JztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklORzpcbiAgICAgICAgcmV0dXJuICdzdHJpbmcnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SOlxuICAgICAgICByZXR1cm4gJ3RlbnNvcic7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVFM6XG4gICAgICAgIHJldHVybiAnZmxvYXRzJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVFM6XG4gICAgICAgIHJldHVybiAnaW50cyc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkdTOlxuICAgICAgICByZXR1cm4gJ3N0cmluZ3MnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SUzpcbiAgICAgICAgcmV0dXJuICd0ZW5zb3JzJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgYXR0cmlidXRlIHR5cGUgaXMgbm90IHN1cHBvcnRlZCB5ZXQ6ICR7b25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlW3R5cGVdfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFZhbHVlKGF0dHI6IG9ubnguSUF0dHJpYnV0ZVByb3RvfG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICBjb25zdCBhdHRyVHlwZSA9IGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvID8gYXR0ci50eXBlIDogKGF0dHIgYXMgb3J0RmJzLkF0dHJpYnV0ZSkudHlwZSgpO1xuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkdSQVBIIHx8IGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEhTKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dyYXBoIGF0dHJpYnV0ZSBpcyBub3Qgc3VwcG9ydGVkIHlldCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRWYWx1ZU5vQ2hlY2soYXR0cik7XG5cbiAgICAvLyBjYXN0IExPTkcgdG8gbnVtYmVyXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UICYmIExvbmdVdGlsLmlzTG9uZyh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBMb25nVXRpbC5sb25nVG9OdW1iZXIodmFsdWUgYXMgTG9uZyB8IGZsYXRidWZmZXJzLkxvbmcpO1xuICAgIH1cblxuICAgIC8vIGNhc3QgTE9OR1tdIHRvIG51bWJlcltdXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UUykge1xuICAgICAgY29uc3QgYXJyID0gKHZhbHVlIGFzIEFycmF5PG51bWJlcnxMb25nfGZsYXRidWZmZXJzLkxvbmc+KTtcbiAgICAgIGNvbnN0IG51bWJlclZhbHVlOiBudW1iZXJbXSA9IG5ldyBBcnJheTxudW1iZXI+KGFyci5sZW5ndGgpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBtYXliZUxvbmcgPSBhcnJbaV07XG4gICAgICAgIG51bWJlclZhbHVlW2ldID0gTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG1heWJlTG9uZyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudW1iZXJWYWx1ZTtcbiAgICB9XG5cbiAgICAvLyBjYXN0IG9ubnguVGVuc29yUHJvdG8gdG8gb25ueGpzLlRlbnNvclxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlRFTlNPUikge1xuICAgICAgcmV0dXJuIGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvID8gVGVuc29yLmZyb21Qcm90byh2YWx1ZSBhcyBvbm54LklUZW5zb3JQcm90bykgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVuc29yLmZyb21PcnRUZW5zb3IodmFsdWUgYXMgb3J0RmJzLlRlbnNvcik7XG4gICAgfVxuXG4gICAgLy8gY2FzdCBvbm54LlRlbnNvclByb3RvW10gdG8gb25ueGpzLlRlbnNvcltdXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SUykge1xuICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgIGNvbnN0IHRlbnNvclByb3RvcyA9IHZhbHVlIGFzIG9ubnguSVRlbnNvclByb3RvW107XG4gICAgICAgIHJldHVybiB0ZW5zb3JQcm90b3MubWFwKHZhbHVlID0+IFRlbnNvci5mcm9tUHJvdG8odmFsdWUpKTtcbiAgICAgIH0gZWxzZSBpZiAoYXR0ciBpbnN0YW5jZW9mIG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICAgICAgY29uc3QgdGVuc29yUHJvdG9zID0gdmFsdWUgYXMgb3J0RmJzLlRlbnNvcltdO1xuICAgICAgICByZXR1cm4gdGVuc29yUHJvdG9zLm1hcCh2YWx1ZSA9PiBUZW5zb3IuZnJvbU9ydFRlbnNvcih2YWx1ZSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGNhc3QgVWludDhBcnJheSB0byBzdHJpbmdcbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkcpIHtcbiAgICAgIC8vIHN0cmluZyBpbiBvbm54IGF0dHJpYnV0ZSBpcyBvZiB1aW50OGFycmF5IHR5cGUsIHNvIHdlIG5lZWQgdG8gY29udmVydCBpdCB0byBzdHJpbmcgYmVsb3cuIFdoaWxlIGluIG9ydCBmb3JtYXQsXG4gICAgICAvLyBzdHJpbmcgYXR0cmlidXRlcyBhcmUgcmV0dXJuZWQgYXMgc3RyaW5nLCBzbyBubyBjb252ZXJzaW9uIGlzIG5lZWRlZC5cbiAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICBjb25zdCB1dGY4U3RyaW5nID0gdmFsdWUgYXMgVWludDhBcnJheTtcbiAgICAgICAgcmV0dXJuIGRlY29kZVV0ZjhTdHJpbmcodXRmOFN0cmluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2FzdCBVaW50OEFycmF5W10gdG8gc3RyaW5nW11cbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkdTKSB7XG4gICAgICAvLyBzdHJpbmdzIGluIG9ubnggYXR0cmlidXRlIGlzIHJldHVybmVkIGFzIHVpbnQ4YXJyYXlbXSwgc28gd2UgbmVlZCB0byBjb252ZXJ0IGl0IHRvIHN0cmluZ1tdIGJlbG93LiBXaGlsZSBpbiBvcnRcbiAgICAgIC8vIGZvcm1hdCBzdHJpbmdzIGF0dHJpYnV0ZXMgYXJlIHJldHVybmVkIGFzIHN0cmluZ1tdLCBzbyBubyBjb252ZXJzaW9uIGlzIG5lZWRlZC5cbiAgICAgIGlmIChhdHRyIGluc3RhbmNlb2Ygb25ueC5BdHRyaWJ1dGVQcm90bykge1xuICAgICAgICBjb25zdCB1dGY4U3RyaW5ncyA9IHZhbHVlIGFzIFVpbnQ4QXJyYXlbXTtcbiAgICAgICAgcmV0dXJuIHV0ZjhTdHJpbmdzLm1hcChkZWNvZGVVdGY4U3RyaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWUgYXMgVmFsdWVUeXBlcztcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFZhbHVlTm9DaGVjayhhdHRyOiBvbm54LklBdHRyaWJ1dGVQcm90b3xvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgcmV0dXJuIGF0dHIgaW5zdGFuY2VvZiAob25ueC5BdHRyaWJ1dGVQcm90bykgPyB0aGlzLmdldFZhbHVlTm9DaGVja0Zyb21Pbm54Rm9ybWF0KGF0dHIpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0VmFsdWVOb0NoZWNrRnJvbU9ydEZvcm1hdChhdHRyIGFzIG9ydEZicy5BdHRyaWJ1dGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWVOb0NoZWNrRnJvbU9ubnhGb3JtYXQoYXR0cjogb25ueC5JQXR0cmlidXRlUHJvdG8pIHtcbiAgICBzd2l0Y2ggKGF0dHIudHlwZSEpIHtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkZMT0FUOlxuICAgICAgICByZXR1cm4gYXR0ci5mO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UOlxuICAgICAgICByZXR1cm4gYXR0ci5pO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gYXR0ci5zO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SOlxuICAgICAgICByZXR1cm4gYXR0ci50O1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEg6XG4gICAgICAgIHJldHVybiBhdHRyLmc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5GTE9BVFM6XG4gICAgICAgIHJldHVybiBhdHRyLmZsb2F0cztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVFM6XG4gICAgICAgIHJldHVybiBhdHRyLmludHM7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkdTOlxuICAgICAgICByZXR1cm4gYXR0ci5zdHJpbmdzO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SUzpcbiAgICAgICAgcmV0dXJuIGF0dHIudGVuc29ycztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkdSQVBIUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuZ3JhcGhzO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBhdHRyaWJ1dGUgdHlwZTogJHtvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVbYXR0ci50eXBlIV19YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWVOb0NoZWNrRnJvbU9ydEZvcm1hdChhdHRyOiBvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgc3dpdGNoIChhdHRyLnR5cGUoKSkge1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5GTE9BVDpcbiAgICAgICAgcmV0dXJuIGF0dHIuZigpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5JTlQ6XG4gICAgICAgIHJldHVybiBhdHRyLmkoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gYXR0ci5zKCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLlRFTlNPUjpcbiAgICAgICAgcmV0dXJuIGF0dHIudCgpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5HUkFQSDpcbiAgICAgICAgcmV0dXJuIGF0dHIuZygpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5GTE9BVFM6XG4gICAgICAgIHJldHVybiBhdHRyLmZsb2F0c0FycmF5KCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLklOVFM6IHtcbiAgICAgICAgY29uc3QgaW50cyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHIuaW50c0xlbmd0aCgpOyBpKyspIHtcbiAgICAgICAgICBpbnRzLnB1c2goYXR0ci5pbnRzKGkpISk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGludHM7XG4gICAgICB9XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLlNUUklOR1M6IHtcbiAgICAgICAgY29uc3Qgc3RyaW5ncyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHIuc3RyaW5nc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgICAgICBzdHJpbmdzLnB1c2goYXR0ci5zdHJpbmdzKGkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RyaW5ncztcbiAgICAgIH1cbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuVEVOU09SUzoge1xuICAgICAgICBjb25zdCB0ZW5zb3JzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0ci50ZW5zb3JzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgICAgIHRlbnNvcnMucHVzaChhdHRyLnRlbnNvcnMoaSkhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGVuc29ycztcbiAgICAgIH1cbiAgICAgIC8vIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuR1JBUEhTOlxuICAgICAgLy8gVE9ETzogU3ViZ3JhcGggbm90IHN1cHBvcnRlZCB5ZXQuXG4gICAgICAvLyBjb25zdCBncmFwaHMgPSBbXTtcbiAgICAgIC8vIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0ci5ncmFwaHNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAvLyAgIGdyYXBocy5wdXNoKGF0dHIuZ3JhcGhzKGkpISk7XG4gICAgICAvLyB9XG4gICAgICAvLyByZXR1cm4gZ3JhcGhzO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBhdHRyaWJ1dGUgdHlwZTogJHtvcnRGYnMuQXR0cmlidXRlVHlwZVthdHRyLnR5cGUoKV19YCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF9hdHRyaWJ1dGVzOiBNYXA8c3RyaW5nLCBWYWx1ZT47XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlfSBmcm9tICcuL2F0dHJpYnV0ZSc7XG5pbXBvcnQge29ubnhydW50aW1lfSBmcm9tICcuL29ydC1zY2hlbWEvZmxhdGJ1ZmZlcnMvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQge29ubnh9IGZyb20gJy4vb3J0LXNjaGVtYS9wcm90b2J1Zi9vbm54JztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuL3RlbnNvcic7XG5pbXBvcnQge0xvbmdVdGlsLCBNQVhfQ0xJUCwgTUlOX0NMSVAsIFByb3RvVXRpbH0gZnJvbSAnLi91dGlsJztcblxuaW1wb3J0IG9ydEZicyA9IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnM7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBHcmFwaCB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgU2hhcGUge1xuICAgIHJlYWRvbmx5IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVmFsdWVUeXBlIHtcbiAgICByZWFkb25seSB0ZW5zb3JUeXBlOiBUZW5zb3IuRGF0YVR5cGU7XG4gICAgcmVhZG9ubHkgc2hhcGU6IFNoYXBlO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVmFsdWUge1xuICAgIC8vIHRoZSB0ZW5zb3IgZGF0YS4gZW1wdHkgZm9yIG5vbi1pbml0aWFsaXplZCBpbnB1dHNcbiAgICByZWFkb25seSB0ZW5zb3I/OiBUZW5zb3I7XG5cbiAgICAvLyBpbmRleCB0byB0aGUgTm9kZSB3aGVyZSB0aGUgdmFsdWUgY29tZXMgZnJvbS4gLTEgZm9yIGluaXRpYWxpemVyLlxuICAgIHJlYWRvbmx5IGZyb206IG51bWJlcjtcblxuICAgIC8vIGluZGljZXMgdG8gdGhlIE5vZGVzIHdoZXJlIHRoZSB2YWx1ZXMgZ28gdG8uXG4gICAgcmVhZG9ubHkgdG86IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgLy8gdmFsdWUgdHlwZSBzcGVjaWZpY2F0aW9uLiBlbXB0eSBmb3Igbm9uLWlucHV0IHZhbHVlcy5cbiAgICByZWFkb25seSB0eXBlPzogVmFsdWVUeXBlO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgTm9kZSB7XG4gICAgLy8gbmFtZSBvZiB0aGUgbm9kZVxuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAgIC8vIHRoZSBvcGVyYXRvciB0eXBlXG4gICAgcmVhZG9ubHkgb3BUeXBlOiBzdHJpbmc7XG5cbiAgICAvLyBpbmRpY2VzIHRvIHRoZSBWYWx1ZXMgd2hlcmUgdGhlIGlucHV0cyBjb21lIGZyb20uXG4gICAgcmVhZG9ubHkgaW5wdXRzOiByZWFkb25seSBudW1iZXJbXTtcblxuICAgIC8vIGluZGljZXMgdG8gdGhlIFZhbHVlcyB3aGVyZSB0aGUgb3V0cHVzIGdvIHRvLlxuICAgIHJlYWRvbmx5IG91dHB1dHM6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgLy8gdGhlIGF0dHJpYnV0ZXMgdGhhdCB1c2VkIGJ5IHRoZSBvcGVyYXRvclxuICAgIHJlYWRvbmx5IGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBhIFRyYW5zZm9ybWVyIGlzIGFuIGluc3RhbmNlIHRoYXQgYWxsb3dzIGFsbCBwb3NzaWJsZSB0cmFuc2Zvcm1hdGlvbiBvcGVyYXRpb25zIHRoYXQgYXBwbGllZCB0byBhIGdyYXBoXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFRyYW5zZm9ybWVyIHtcbiAgICByZW1vdmVBbGxJZGVudGl0eU5vZGVzKCk6IHZvaWQ7XG4gICAgcmVtb3ZlQWxsRHJvcG91dE5vZGVzKCk6IHZvaWQ7XG4gICAgZnVzZUNvbnZBY3RpdmF0aW9uTm9kZXMoKTogdm9pZDtcbiAgICAvLyBUT0RPOiBhZGQgZ2VuZXJpYyBmdW5jdGlvbnMgdG8gbWFuaXB1bGF0ZSB0aGUgZ3JhcGhcbiAgfVxuXG4gIC8vIGFuIGluaXRpYWxpemVyIGNhbiB1c2UgdHJhbnNmb3JtZXIgdG8gdHJhbnNmb3JtIHRoZSBncmFwaFxuICBleHBvcnQgaW50ZXJmYWNlIEluaXRpYWxpemVyIHtcbiAgICB0cmFuc2Zvcm1HcmFwaCh0cmFuc2Zvcm1lcjogVHJhbnNmb3JtZXIpOiB2b2lkO1xuICB9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlXG5leHBvcnQgaW50ZXJmYWNlIEdyYXBoIHtcbiAgZ2V0SW5wdXRJbmRpY2VzKCk6IHJlYWRvbmx5IG51bWJlcltdO1xuICBnZXRJbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBnZXRPdXRwdXRJbmRpY2VzKCk6IHJlYWRvbmx5IG51bWJlcltdO1xuICBnZXRPdXRwdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXTtcbiAgZ2V0VmFsdWVzKCk6IHJlYWRvbmx5IEdyYXBoLlZhbHVlW107XG4gIGdldE5vZGVzKCk6IHJlYWRvbmx5IEdyYXBoLk5vZGVbXTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiwgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZVxuZXhwb3J0IGNvbnN0IEdyYXBoID0ge1xuICAvKipcbiAgICogY29uc3RydWN0IGEgZ3JhcGggZnJvbSBhIGdyYXBoIHByb3RvYnVmIHR5cGVcbiAgICovXG4gIGZyb206IChncmFwaFByb3RvOiBvbm54LklHcmFwaFByb3RvfG9ydEZicy5HcmFwaCwgaW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplcikgPT5cbiAgICAgIG5ldyBHcmFwaEltcGwoZ3JhcGhQcm90bywgaW5pdGlhbGl6ZXIpLFxufTtcblxuY2xhc3MgVmFsdWUgaW1wbGVtZW50cyBHcmFwaC5WYWx1ZSB7XG4gIGNvbnN0cnVjdG9yKHZhbHVlSW5mbz86IG9ubnguSVZhbHVlSW5mb1Byb3RvKSB7XG4gICAgdGhpcy5fZnJvbSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl90byA9IFtdO1xuICAgIHRoaXMudGVuc29yID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudHlwZSA9IHVuZGVmaW5lZDtcblxuICAgIGlmICh2YWx1ZUluZm8pIHtcbiAgICAgIHRoaXMudHlwZSA9IFByb3RvVXRpbC50ZW5zb3JWYWx1ZVR5cGVGcm9tUHJvdG8odmFsdWVJbmZvLnR5cGUhLnRlbnNvclR5cGUhKTtcbiAgICB9XG4gIH1cblxuICBfZnJvbT86IG51bWJlcjsgIC8vIC0xIHJlcHJlc2VudCBmcm9tIGluaXRpYWxpemVyXG4gIGdldCBmcm9tKCkge1xuICAgIHJldHVybiB0aGlzLl9mcm9tITtcbiAgfVxuICBfdG86IG51bWJlcltdO1xuICBnZXQgdG8oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RvO1xuICB9XG4gIHR5cGU/OiBHcmFwaC5WYWx1ZVR5cGU7XG4gIHRlbnNvcj86IFRlbnNvcjtcbn1cblxuY2xhc3MgTm9kZSBpbXBsZW1lbnRzIEdyYXBoLk5vZGUge1xuICBjb25zdHJ1Y3Rvcihfbm9kZVByb3RvOiBvbm54LklOb2RlUHJvdG98b3J0RmJzLk5vZGUsIG5hbWU/OiBzdHJpbmcpIHtcbiAgICBpZiAoX25vZGVQcm90byBpbnN0YW5jZW9mIG9ubnguTm9kZVByb3RvKSB7XG4gICAgICB0aGlzLm5hbWUgPSBfbm9kZVByb3RvLm5hbWU7XG4gICAgICB0aGlzLm9wVHlwZSA9IF9ub2RlUHJvdG8ub3BUeXBlO1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZShfbm9kZVByb3RvLmF0dHJpYnV0ZSk7XG4gICAgfSBlbHNlIGlmIChfbm9kZVByb3RvIGluc3RhbmNlb2Ygb3J0RmJzLk5vZGUpIHtcbiAgICAgIHRoaXMubmFtZSA9IG5hbWUgPz8gX25vZGVQcm90by5uYW1lKCkhO1xuICAgICAgdGhpcy5vcFR5cGUgPSBfbm9kZVByb3RvLm9wVHlwZSgpITtcbiAgICAgIHRoaXMuYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGUoUHJvdG9VdGlsLnRlbnNvckF0dHJpYnV0ZXNGcm9tT1JURm9ybWF0KF9ub2RlUHJvdG8pKTtcbiAgICB9XG5cbiAgICB0aGlzLmlucHV0cyA9IFtdO1xuICAgIHRoaXMub3V0cHV0cyA9IFtdO1xuICAgIHRoaXMuZXhlY3V0ZU5vZGUgPSB0cnVlO1xuICB9XG5cbiAgbmFtZTogc3RyaW5nO1xuICBvcFR5cGU6IHN0cmluZztcbiAgaW5wdXRzOiBudW1iZXJbXTtcbiAgb3V0cHV0czogbnVtYmVyW107XG4gIGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZTtcbiAgZXhlY3V0ZU5vZGU6IGJvb2xlYW47XG59XG5cbmNsYXNzIEdyYXBoSW1wbCBpbXBsZW1lbnRzIEdyYXBoLCBHcmFwaC5UcmFuc2Zvcm1lciB7XG4gIHByaXZhdGUgX2FsbERhdGE6IFZhbHVlW107XG5cbiAgcHJpdmF0ZSBfYWxsSW5wdXRJbmRpY2VzOiBudW1iZXJbXTtcbiAgcHJpdmF0ZSBfYWxsSW5wdXROYW1lczogc3RyaW5nW107XG5cbiAgcHJpdmF0ZSBfYWxsT3V0cHV0SW5kaWNlczogbnVtYmVyW107XG4gIHByaXZhdGUgX2FsbE91dHB1dE5hbWVzOiBzdHJpbmdbXTtcblxuICBwcml2YXRlIF9ub2RlczogTm9kZVtdO1xuXG4gIGNvbnN0cnVjdG9yKGdyYXBoOiBvbm54LklHcmFwaFByb3RvfG9ydEZicy5HcmFwaCwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKSB7XG4gICAgaWYgKCFncmFwaCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZ3JhcGggaXMgZW1wdHknKTtcbiAgICB9XG5cbiAgICAvLyBidWlsZCB0aGUgZ3JhcGggLSB3aWxsIHRocm93IGV4Y2VwdGlvbnMgaWYgc29tZXRoaW5nIGZhdGFsIGlzIGRldGVjdGVkXG4gICAgdGhpcy5idWlsZEdyYXBoKGdyYXBoKTtcblxuICAgIC8vIGV4ZWN1dGUgYW55IHRyYW5zZm9ybWF0aW9uIGxvZ2ljIGZvciB0aGUgZ3JhcGggKGlmIGFwcGxpY2FibGUpXG4gICAgdGhpcy50cmFuc2Zvcm1HcmFwaChncmFwaEluaXRpYWxpemVyKTtcblxuICAgIC8vIGNoZWNrIGZvciBjeWNsZXMgYW5kIG90aGVyIGluY29uc2lzdGVuY2llcyAtIHdpbGwgdGhyb3cgZXhjZXB0aW9ucyBpZiBzb21ldGhpbmcgZmF0YWwgaXMgZGV0ZWN0ZWRcbiAgICB0aGlzLmNoZWNrSXNBY3ljbGljKCk7XG4gIH1cblxuICBnZXRJbnB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxJbnB1dEluZGljZXM7XG4gIH1cblxuICBnZXRJbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsSW5wdXROYW1lcztcbiAgfVxuXG4gIGdldE91dHB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzO1xuICB9XG5cbiAgZ2V0T3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxPdXRwdXROYW1lcztcbiAgfVxuXG4gIGdldFZhbHVlcygpOiByZWFkb25seSBHcmFwaC5WYWx1ZVtdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsRGF0YTtcbiAgfVxuXG4gIGdldE5vZGVzKCk6IHJlYWRvbmx5IEdyYXBoLk5vZGVbXSB7XG4gICAgcmV0dXJuIHRoaXMuX25vZGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEdyYXBoKGdyYXBoOiBvbm54LklHcmFwaFByb3RvfG9ydEZicy5HcmFwaCkge1xuICAgIC8vIGJ1aWxkIHRoZSBncmFwaCAtIHdpbGwgdGhyb3cgZXhjZXB0aW9ucyBpZiBzb21ldGhpbmcgZmF0YWwgaXMgZGV0ZWN0ZWRcbiAgICBpZiAoZ3JhcGggaW5zdGFuY2VvZiBvbm54LkdyYXBoUHJvdG8pIHtcbiAgICAgIHRoaXMuYnVpbGRHcmFwaEZyb21Pbm54Rm9ybWF0KGdyYXBoKTtcbiAgICB9IGVsc2UgaWYgKGdyYXBoIGluc3RhbmNlb2Ygb3J0RmJzLkdyYXBoKSB7XG4gICAgICB0aGlzLmJ1aWxkR3JhcGhGcm9tT3J0Rm9ybWF0KGdyYXBoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignR3JhcGggdHlwZSBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIGJ1aWxkR3JhcGhGcm9tT25ueEZvcm1hdChncmFwaDogb25ueC5JR3JhcGhQcm90bykge1xuICAgIGNvbnN0IGRhdGFJbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICB0aGlzLl9hbGxEYXRhID0gW107XG5cbiAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMgPSBbXTtcbiAgICB0aGlzLl9hbGxJbnB1dE5hbWVzID0gW107XG5cbiAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzID0gW107XG4gICAgdGhpcy5fYWxsT3V0cHV0TmFtZXMgPSBbXTtcblxuICAgIHRoaXMuX25vZGVzID0gW107XG5cbiAgICBjb25zdCBub2Rlc0luZGljZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG4gICAgLy8gc2NhbiBhbGwgaW5wdXRzXG4gICAgaWYgKCFncmFwaC5pbnB1dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBpbnB1dCcpO1xuICAgIH1cbiAgICBjb25zdCBpbnB1dFZhbHVlTmFtZXMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGkgb2YgZ3JhcGguaW5wdXQpIHtcbiAgICAgIGlmIChkYXRhSW5kaWNlcy5oYXMoaS5uYW1lISkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIGlucHV0IG5hbWU6ICR7aS5uYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZShpKSkgLSAxO1xuICAgICAgZGF0YUluZGljZXMuc2V0KGkubmFtZSEsIGN1cnJlbnRJbmRleCk7XG4gICAgICBpbnB1dFZhbHVlTmFtZXMucHVzaChpLm5hbWUhKTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBpbml0aWFsaXplcnNcbiAgICBpZiAoIWdyYXBoLmluaXRpYWxpemVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IGluaXRpYWxpemVyJyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgaSBvZiBncmFwaC5pbml0aWFsaXplcikge1xuICAgICAgbGV0IGluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGkubmFtZSEpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBuZXcgVmFsdWUoKTtcbiAgICAgICAgdmFsdWUudHlwZSA9IHtcbiAgICAgICAgICBzaGFwZToge2RpbXM6IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKGkuZGltcyEpfSxcbiAgICAgICAgICB0ZW5zb3JUeXBlOiBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8oaS5kYXRhVHlwZSEpXG4gICAgICAgIH07XG4gICAgICAgIGluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKHZhbHVlKSAtIDE7XG4gICAgICAgIGRhdGFJbmRpY2VzLnNldChpLm5hbWUhLCBpbmRleCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgdGhpcy5fYWxsRGF0YVtpbmRleF0udGVuc29yID0gVGVuc29yLmZyb21Qcm90byhpKTtcbiAgICB9XG5cbiAgICAvLyBmaWx0ZXIgb3V0IGlucHV0IGluZGljZXNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2FsbERhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghdGhpcy5fYWxsRGF0YVtpXS50ZW5zb3IpIHtcbiAgICAgICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzLnB1c2goaSk7XG4gICAgICAgIHRoaXMuX2FsbElucHV0TmFtZXMucHVzaChpbnB1dFZhbHVlTmFtZXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNjYW4gYWxsIG91dHB1dHNcbiAgICBpZiAoIWdyYXBoLm91dHB1dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBvdXRwdXQnKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBpIG9mIGdyYXBoLm91dHB1dCkge1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhpLm5hbWUhKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgb3V0cHV0IG5hbWU6ICR7aS5uYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZShpKSkgLSAxO1xuICAgICAgZGF0YUluZGljZXMuc2V0KGkubmFtZSEsIGN1cnJlbnRJbmRleCk7XG4gICAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLnB1c2goY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzLnB1c2goaS5uYW1lISk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgbm9kZXNcbiAgICBpZiAoIWdyYXBoLm5vZGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogbm9kZScpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG5vZGVQcm90byBvZiBncmFwaC5ub2RlKSB7XG4gICAgICBpZiAoIW5vZGVQcm90by5uYW1lKSB7XG4gICAgICAgIC8vIGFzc2lnbiBhIG5hbWUgdG8gdGhlIG5vZGUgaWYgaXQgZG9lc24ndCBoYXZlIG9uZVxuICAgICAgICBmb3IgKGxldCBwaWNrID0gMDs7IHBpY2srKykge1xuICAgICAgICAgIGNvbnN0IG5hbWUgPSBgdW5uYW1lZF8ke25vZGVQcm90by5vcFR5cGV9XyR7cGlja31gO1xuICAgICAgICAgIGlmICghbm9kZXNJbmRpY2VzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgbm9kZVByb3RvLm5hbWUgPSBuYW1lO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChub2Rlc0luZGljZXMuaGFzKG5vZGVQcm90by5uYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgbm9kZSBuYW1lOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fbm9kZXMucHVzaChuZXcgTm9kZShub2RlUHJvdG8pKSAtIDE7XG4gICAgICBub2Rlc0luZGljZXMuc2V0KG5vZGVQcm90by5uYW1lLCBjdXJyZW50SW5kZXgpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gbm9kZSdzIG91dHB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlW2ldO1xuICAgICAgaWYgKCFub2RlUHJvdG8ub3V0cHV0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBvdXRwdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBub2RlUHJvdG8ub3V0cHV0KSB7XG4gICAgICAgIGxldCBkYXRhSW5kZXggPSBkYXRhSW5kaWNlcy5nZXQob3V0cHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgZGF0YUluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZSgpKSAtIDE7XG4gICAgICAgICAgZGF0YUluZGljZXMuc2V0KG91dHB1dCwgZGF0YUluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLm91dHB1dHMucHVzaChkYXRhSW5kZXgpO1xuXG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbXVsdGlwbGUgbm9kZXMgb3V0cHV0IHRvIG9uZSBkYXRhIHZhbHVlOiAke2RhdGFJbmRleH1gKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSBpO1xuXG4gICAgICAgIC8vIGZvciB0aGUgJ0NvbnN0YW50JyBvcGVyYXRvciwganVzdCBjcmVhdGUgYSBuZXcgZWRnZSBpbiB0aGUgZ3JhcGggY29ycmVzcG9uZGluZyB0byB0aGUgJ291dHB1dCcgb2YgdGhlXG4gICAgICAgIC8vIG9wZXJhdG9yIGFuZCBpZ25vcmUgdGhlIG5vZGUgZnJvbSB0aGUgZ3JhcGhcbiAgICAgICAgaWYgKG5vZGVQcm90by5vcFR5cGUgPT09ICdDb25zdGFudCcpIHtcbiAgICAgICAgICBpZiAoIW5vZGVQcm90by5hdHRyaWJ1dGUgfHwgbm9kZVByb3RvLmF0dHJpYnV0ZS5sZW5ndGggIT09IDEgfHwgIW5vZGVQcm90by5hdHRyaWJ1dGVbMF0udCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGF0dHJpYnV0ZXMgb3IgbWlzc2luZyB0ZW5zb3IgdmFsdWUgaW4gYXR0cmlidXRlcyBmb3IgdGhpcyBDb25zdGFudCBvcGVyYXRvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5vZGVQcm90by5vdXRwdXQgfHwgbm9kZVByb3RvLm91dHB1dC5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBvdXRwdXQgb3IgaW5jb3JyZWN0IG51bWJlciBvZiBvdXRwdXRzIGZvciB0aGlzIENvbnN0YW50IG9wZXJhdG9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5vZGUub3V0cHV0cy5wb3AoKTtcbiAgICAgICAgICBub2RlLmV4ZWN1dGVOb2RlID0gZmFsc2U7XG5cbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSAtMTtcbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0udGVuc29yID0gVGVuc29yLmZyb21Qcm90byhub2RlUHJvdG8uYXR0cmlidXRlWzBdLnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3MgaW5wdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZVtpXTtcblxuICAgICAgaWYgKCFub2RlUHJvdG8uaW5wdXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIGlucHV0IGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBpbnB1dCBvZiBub2RlUHJvdG8uaW5wdXQpIHtcbiAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGlucHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgLy8gaGFuZGxlIGV4Y2VwdGlvbiB3aGVuIG9wc2V0ID4gOSBhbmQgcm9pIC8gc2NhbGVzIG5vdCBnaXZlblxuICAgICAgICAgIGlmIChpbnB1dCA9PT0gJycgJiYgKG5vZGVQcm90by5pbnB1dC5sZW5ndGggPT09IDMgfHwgbm9kZVByb3RvLmlucHV0Lmxlbmd0aCA9PT0gNCkgJiZcbiAgICAgICAgICAgICAgbm9kZVByb3RvLm9wVHlwZSA9PT0gJ1Jlc2l6ZScpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVjb2duaXplZCBpbnB1dCAnJHtpbnB1dH0nIGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUuaW5wdXRzLnB1c2goZGF0YUluZGV4KTtcblxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX3RvLnB1c2goaSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkR3JhcGhGcm9tT3J0Rm9ybWF0KGdyYXBoOiBvcnRGYnMuR3JhcGgpIHtcbiAgICBjb25zdCBkYXRhSW5kaWNlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgdGhpcy5fYWxsRGF0YSA9IFtdO1xuXG4gICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzID0gW107XG4gICAgdGhpcy5fYWxsSW5wdXROYW1lcyA9IFtdO1xuXG4gICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcyA9IFtdO1xuICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzID0gW107XG5cbiAgICB0aGlzLl9ub2RlcyA9IFtdO1xuXG4gICAgY29uc3Qgbm9kZXNJbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuICAgIC8vIHNjYW4gYWxsIGlucHV0c1xuICAgIGNvbnN0IGlucHV0VmFsdWVOYW1lcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JhcGguaW5wdXRzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3QgaW5wdXROYW1lID0gZ3JhcGguaW5wdXRzKGkpO1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhpbnB1dE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBpbnB1dCBuYW1lOiAke2lucHV0TmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIC8vIEZpbmQgdGhlIGlucHV0IHR5cGVJbmZvIGZyb20gbm9kZWFyZ3NcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgZ3JhcGgubm9kZUFyZ3NMZW5ndGgoKTsgaisrKSB7XG4gICAgICAgIGlmIChncmFwaC5ub2RlQXJncyhqKT8ubmFtZSgpID09PSBpbnB1dE5hbWUpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyBWYWx1ZSgpO1xuICAgICAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IGdyYXBoLm5vZGVBcmdzKGopPy50eXBlKCk/LnZhbHVlVHlwZSgpO1xuICAgICAgICAgIGlmICh2YWx1ZVR5cGUgIT09IG9ydEZicy5UeXBlSW5mb1ZhbHVlLnRlbnNvcl90eXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgdmFsdWUgdHlwZSBmb3IgdGhlIG5vZGVBcmcuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHZhbHVlSW5mbyA9IGdyYXBoLm5vZGVBcmdzKGopIS50eXBlKCkhLnZhbHVlKG5ldyBvcnRGYnMuVGVuc29yVHlwZUFuZFNoYXBlKCkpITtcbiAgICAgICAgICBjb25zdCB0eXBlID0gUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKHZhbHVlSW5mby5lbGVtVHlwZSgpKTtcbiAgICAgICAgICBjb25zdCBzaGFwZSA9IHZhbHVlSW5mby5zaGFwZSgpITtcbiAgICAgICAgICBjb25zdCBkaW1zID0gW107XG4gICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBzaGFwZS5kaW1MZW5ndGgoKSE7IGsrKykge1xuICAgICAgICAgICAgZGltcy5wdXNoKExvbmdVdGlsLmxvbmdUb051bWJlcihzaGFwZS5kaW0oaykhLnZhbHVlKCkhLmRpbVZhbHVlKCkhKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhbHVlLnR5cGUgPSB7c2hhcGU6IHtkaW1zfSwgdGVuc29yVHlwZTogdHlwZX07XG4gICAgICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKHZhbHVlKSAtIDE7XG4gICAgICAgICAgZGF0YUluZGljZXMuc2V0KGlucHV0TmFtZSwgY3VycmVudEluZGV4KTtcbiAgICAgICAgICBpbnB1dFZhbHVlTmFtZXMucHVzaChpbnB1dE5hbWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNoZWNrIGluaXRpYWxpemVyc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JhcGguaW5pdGlhbGl6ZXJzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3QgaW5pdGlhbGl6ZXIgPSBncmFwaC5pbml0aWFsaXplcnMoaSkhO1xuICAgICAgbGV0IGluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGluaXRpYWxpemVyLm5hbWUoKSEpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBuZXcgVmFsdWUoKTtcbiAgICAgICAgY29uc3QgZGltcyA9IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbU9SVEZvcm1hdChpbml0aWFsaXplcik7XG4gICAgICAgIGNvbnN0IHR5cGUgPSBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8oaW5pdGlhbGl6ZXIuZGF0YVR5cGUoKSk7XG4gICAgICAgIHZhbHVlLnR5cGUgPSB7c2hhcGU6IHtkaW1zfSwgdGVuc29yVHlwZTogdHlwZX07XG4gICAgICAgIGluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKHZhbHVlKSAtIDE7XG4gICAgICAgIGRhdGFJbmRpY2VzLnNldChpbml0aWFsaXplci5uYW1lKCkhLCBpbmRleCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgdGhpcy5fYWxsRGF0YVtpbmRleF0udGVuc29yID0gVGVuc29yLmZyb21PcnRUZW5zb3IoaW5pdGlhbGl6ZXIpO1xuICAgIH1cblxuICAgIC8vIGZpbHRlciBvdXQgaW5wdXQgaW5kaWNlc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fYWxsRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCF0aGlzLl9hbGxEYXRhW2ldLnRlbnNvcikge1xuICAgICAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMucHVzaChpKTtcbiAgICAgICAgdGhpcy5fYWxsSW5wdXROYW1lcy5wdXNoKGlucHV0VmFsdWVOYW1lc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgb3V0cHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JhcGgub3V0cHV0c0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IG91dHB1dE5hbWUgPSBncmFwaC5vdXRwdXRzKGkpO1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhvdXRwdXROYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgb3V0cHV0IG5hbWU6ICR7b3V0cHV0TmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoKSkgLSAxO1xuICAgICAgZGF0YUluZGljZXMuc2V0KG91dHB1dE5hbWUsIGN1cnJlbnRJbmRleCk7XG4gICAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLnB1c2goY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzLnB1c2gob3V0cHV0TmFtZSk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgbm9kZXNcbiAgICBpZiAoIWdyYXBoLm5vZGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IG5vZGUnKTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5ub2Rlc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVzKGkpO1xuICAgICAgbGV0IG5hbWUgPSBub2RlUHJvdG8hLm5hbWUoKTtcbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICAvLyBhc3NpZ24gYSBuYW1lIHRvIHRoZSBub2RlIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcbiAgICAgICAgZm9yIChsZXQgcGljayA9IDA7OyBwaWNrKyspIHtcbiAgICAgICAgICBuYW1lID0gYHVubmFtZWRfJHtub2RlUHJvdG8hLm9wVHlwZSgpfV8ke3BpY2t9YDtcbiAgICAgICAgICBpZiAoIW5vZGVzSW5kaWNlcy5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIC8vIGFuIHVuaXF1ZSBuYW1lIGlzIGZvdW5kLiBicmVhay5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobm9kZXNJbmRpY2VzLmhhcyhuYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgbm9kZSBuYW1lOiAke25hbWV9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9ub2Rlcy5wdXNoKG5ldyBOb2RlKG5vZGVQcm90byEsIG5hbWUpKSAtIDE7XG4gICAgICBub2Rlc0luZGljZXMuc2V0KG5hbWUsIGN1cnJlbnRJbmRleCk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3Mgb3V0cHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2Rlc1tpXTtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVzKGkpO1xuICAgICAgaWYgKG5vZGVQcm90byA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gbm9kZSBleGlzdHMgYXQgaW5kZXggJHtpfWApO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGVQcm90bz8ub3V0cHV0c0xlbmd0aCgpID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBvdXRwdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG5vZGVQcm90bz8ub3V0cHV0c0xlbmd0aCgpOyBqKyspIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gbm9kZVByb3RvPy5vdXRwdXRzKGopO1xuICAgICAgICBsZXQgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KG91dHB1dCk7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGRhdGFJbmRleCA9IHRoaXMuX2FsbERhdGEucHVzaChuZXcgVmFsdWUoKSkgLSAxO1xuICAgICAgICAgIGRhdGFJbmRpY2VzLnNldChvdXRwdXQsIGRhdGFJbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5vdXRwdXRzLnB1c2goZGF0YUluZGV4KTtcblxuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG11bHRpcGxlIG5vZGVzIG91dHB1dCB0byBvbmUgZGF0YSB2YWx1ZTogJHtkYXRhSW5kZXh9YCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tID0gaTtcblxuICAgICAgICAvLyBmb3IgdGhlICdDb25zdGFudCcgb3BlcmF0b3IsIGp1c3QgY3JlYXRlIGEgbmV3IGVkZ2UgaW4gdGhlIGdyYXBoIGNvcnJlc3BvbmRpbmcgdG8gdGhlICdvdXRwdXQnIG9mIHRoZVxuICAgICAgICAvLyBvcGVyYXRvciBhbmQgaWdub3JlIHRoZSBub2RlIGZyb20gdGhlIGdyYXBoXG4gICAgICAgIGlmIChub2RlUHJvdG8ub3BUeXBlKCkgPT09ICdDb25zdGFudCcpIHtcbiAgICAgICAgICBpZiAobm9kZVByb3RvLmF0dHJpYnV0ZXNMZW5ndGgoKSAhPT0gMSB8fCAhbm9kZVByb3RvLmF0dHJpYnV0ZXMoMCkhLnQoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGF0dHJpYnV0ZXMgb3IgbWlzc2luZyB0ZW5zb3IgdmFsdWUgaW4gYXR0cmlidXRlcyBmb3IgdGhpcyBDb25zdGFudCBvcGVyYXRvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobm9kZVByb3RvLm91dHB1dHNMZW5ndGgoKSAhPT0gMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIG91dHB1dCBvciBpbmNvcnJlY3QgbnVtYmVyIG9mIG91dHB1dHMgZm9yIHRoaXMgQ29uc3RhbnQgb3BlcmF0b3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbm9kZS5vdXRwdXRzLnBvcCgpO1xuICAgICAgICAgIG5vZGUuZXhlY3V0ZU5vZGUgPSBmYWxzZTtcblxuICAgICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS50ZW5zb3IgPSBUZW5zb3IuZnJvbU9ydFRlbnNvcihub2RlUHJvdG8uYXR0cmlidXRlcygwKSEudCgpISk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzY2FuIG5vZGUncyBpbnB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlcyhpKSE7XG5cbiAgICAgIGlmIChub2RlUHJvdG8uaW5wdXRzTGVuZ3RoKCkgPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIGlucHV0IGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBub2RlUHJvdG8uaW5wdXRzTGVuZ3RoKCkhOyBqKyspIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBub2RlUHJvdG8uaW5wdXRzKGopITtcbiAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGlucHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlY29nbml6ZWQgaW5wdXQgJyR7aW5wdXR9JyBmb3Igbm9kZTogJHtub2RlUHJvdG8hLm5hbWUoKX1gKTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLmlucHV0cy5wdXNoKGRhdGFJbmRleCk7XG5cbiAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl90by5wdXNoKGkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tJc0FjeWNsaWMoKSB7XG4gICAgLy8gZ28gdGhyb3VnaCB0aGUgZ3JhcGggYW5kIGNoZWNrIGZvciBjeWNsZXMgb3Igb3RoZXIgZmF0YWwgaW5jb25zaXN0ZW5jaWVzXG4gICAgY29uc3Qgc3RhcnRlcnM6IFNldDxudW1iZXI+ID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzLmZvckVhY2goaSA9PiB7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5fYWxsRGF0YVtpXTtcbiAgICAgIGRhdGEuX3RvLmZvckVhY2goaiA9PiB7XG4gICAgICAgIHN0YXJ0ZXJzLmFkZChqKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gSXRlcmF0aXZlIERGUyB0byBjaGVjayBmb3IgY3ljbGVzXG4gICAgY29uc3Qgbm9kZXNTdGFjayA9IEFycmF5LmZyb20oc3RhcnRlcnMpO1xuICAgIGNvbnN0IG5vZGVzU3RhdGUgPSBuZXcgQXJyYXk8c3RyaW5nPih0aGlzLl9ub2Rlcy5sZW5ndGgpLmZpbGwoJ3doaXRlJyk7XG5cbiAgICB3aGlsZSAobm9kZXNTdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBub2RlSW5kZXggPSBub2Rlc1N0YWNrLnBvcCgpITtcbiAgICAgIC8vIHRoaXMgbm9kZSBoYXMgbm93IGJlZW4gcHJvY2Vzc2VkIGNvbXBsZXRlbHkuIE1hcmsgdGhpcyBub2RlICdibGFjaycgdG8gZGVub3RlIHRoaXMuXG4gICAgICBpZiAobm9kZXNTdGF0ZVtub2RlSW5kZXhdID09PSAnZ3JheScpIHtcbiAgICAgICAgbm9kZXNTdGF0ZVtub2RlSW5kZXhdID0gJ2JsYWNrJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHRoaXMgbm9kZSBpcyB1bmRlciBwcm9jZXNzaW5nIHN0YWdlLiBtYXJrIHRoaXMgbm9kZSAnZ3JheScgdG8gZGVub3RlIHRoaXMuXG4gICAgICAgIG5vZGVzU3RhY2sucHVzaChub2RlSW5kZXgpO1xuICAgICAgICBub2Rlc1N0YXRlW25vZGVJbmRleF0gPSAnZ3JheSc7XG5cbiAgICAgICAgdGhpcy5fbm9kZXNbbm9kZUluZGV4XS5vdXRwdXRzLmZvckVhY2goKG91dGdvaW5nRWRnZUluZGV4KSA9PiB7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2FsbERhdGFbb3V0Z29pbmdFZGdlSW5kZXhdO1xuICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS50ZW5zb3IgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vZGUgb3V0cHV0cyBzaG91bGQgbm90IGJlIGluaXRpYWxpemVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChkYXRhLl9mcm9tICE9PSBub2RlSW5kZXgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZnJvbSBwcm9wZXJ0eSBvZiB0aGUgVmFsdWUgb2JqZWN0IGRvZXNuXFwndCBtYXRjaCBpbmRleCBvZiBOb2RlIGJlaW5nIHByb2Nlc3NlZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkYXRhLl90by5mb3JFYWNoKChkb3duc3RyZWFtTm9kZUluZGV4KSA9PiB7XG4gICAgICAgICAgICAvLyBiYWNrIGVkZ2UgZm91bmQgLSBjeWNsaWNcbiAgICAgICAgICAgIGlmIChub2Rlc1N0YXRlW2Rvd25zdHJlYW1Ob2RlSW5kZXhdID09PSAnZ3JheScpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtb2RlbCBncmFwaCBpcyBjeWNsaWMnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHRyZWUgZWRnZSBmb3VuZCAtIGNvbnRpbnVlIHByb2Nlc3NpbmcgYnkgYWRkaW5nIGl0IHRvIHN0YWNrXG4gICAgICAgICAgICBlbHNlIGlmIChub2Rlc1N0YXRlW2Rvd25zdHJlYW1Ob2RlSW5kZXhdID09PSAnd2hpdGUnKSB7XG4gICAgICAgICAgICAgIG5vZGVzU3RhY2sucHVzaChkb3duc3RyZWFtTm9kZUluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0cmFuc2Zvcm1HcmFwaChncmFwaEluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIpOiB2b2lkIHtcbiAgICAvLyBhcHBseSBjb21tb24gdHJhbnNmb3JtXG4gICAgdGhpcy5yZW1vdmVBbGxJZGVudGl0eU5vZGVzKCk7XG4gICAgdGhpcy5yZW1vdmVBbGxEcm9wb3V0Tm9kZXMoKTtcbiAgICB0aGlzLmZ1c2VDb252QWN0aXZhdGlvbk5vZGVzKCk7XG4gICAgLy8gYXBwbHkgaW5pdGlhbGl6ZXIgc3BlY2lmaWMgdHJhbnNmb3JtXG4gICAgaWYgKGdyYXBoSW5pdGlhbGl6ZXIpIHtcbiAgICAgIGdyYXBoSW5pdGlhbGl6ZXIudHJhbnNmb3JtR3JhcGgodGhpcyk7XG4gICAgfVxuXG4gICAgLy8gZmluYWxpemUgZ3JhcGhcbiAgICB0aGlzLmZpbmFsaXplR3JhcGgoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBmaW5hbGl6ZSB0aGUgZ3JhcGguXG4gICAqXG4gICAqIHRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCBhZnRlciBhbGwgdGhlIHRyYW5zZm9ybWF0aW9uIGNvbXBsZXRlZC5cbiAgICogdGhpcyBmdW5jdGlvbiByZW1vdmVzIGFsbCB1bm5lY2Vzc2FyeSBub2RlcyBhbmQgdmFsdWVzIGZyb20gdGhlIGdyYXBoXG4gICAqL1xuICBmaW5hbGl6ZUdyYXBoKCkge1xuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIC8vIGRlbGV0ZSBhbGwgbm9kZXMgdGhhdCBhcmUgbm90IGJlaW5nIGV4ZWN1dGVkXG4gICAgLy8gVGhlIGdyYXBoIGlzIHJlcHJlc2VudGVkIHVzaW5nIHRoZXNlIHR3byBhcnJheXNcbiAgICAvLyB0aGlzLl9ub2RlcyAtIEFycmF5IGhvbGRpbmcgdGhlIGtlcm5lbHMgdG8gZXhlY3V0ZSAtIGVhY2ggZW50cnkgaXMgYSBrZXJuZWwgcG9pbnRpbmcgdG8gdGhpcy5fYWxsRGF0YVxuICAgIC8vIHRoaXMuX2FsbERhdGEgLSBob2xkIDIgZmllbGRzIC0gdG8gW10gJiBmcm9tIC0gdGhlc2UgZmVpbGVkcyBob2xkIHRoZSBncmFwaCBtYXAgZm9yIGlucHV0cyBhbmQgb3V0cHV0cyBwZXIgbm9kZVxuICAgIC8vIG5ld0luZGljZXMgLSByZW1hcHBpbmcgdGhlIGdyYXBoIGFmdGVyIHJlYWRpbmcgdGhlIGZsYWcgJ2V4ZWN1dGVOb2RlJ1xuICAgIGNvbnN0IG5ld0luZGljZXMgPSBuZXcgQXJyYXk8bnVtYmVyPih0aGlzLl9ub2Rlcy5sZW5ndGgsIDApO1xuICAgIGxldCBub2RlUG9zc2l0aW9uID0gMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIC8vIGdpdmluZyBuZXcgaW5kZXhlcyB0byB0aGUgbm9kZXMgYmFzZWQgb24gZXhlY3V0aW9uIGZsYWdcbiAgICAgIG5ld0luZGljZXNbaV0gPSBub2RlUG9zc2l0aW9uO1xuICAgICAgaWYgKHRoaXMuX25vZGVzW2ldLmV4ZWN1dGVOb2RlKSB7XG4gICAgICAgIGlmIChub2RlUG9zc2l0aW9uICE9PSBpKSB7XG4gICAgICAgICAgdGhpcy5fbm9kZXNbbm9kZVBvc3NpdGlvbl0gPSB0aGlzLl9ub2Rlc1tpXTtcbiAgICAgICAgfVxuICAgICAgICBub2RlUG9zc2l0aW9uKys7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGRlbGV0ZSBhbGwgb3V0cHV0IHZhbHVlc1xuICAgICAgICB0aGlzLl9ub2Rlc1tpXS5vdXRwdXRzLmZvckVhY2goaW5kID0+IHtcbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2luZF0uX2Zyb20gPSAtMjtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZpbmcgdGhlIHVudXNlZCBub2Rlc1xuICAgIHRoaXMuX25vZGVzLnNwbGljZShub2RlUG9zc2l0aW9uLCB0aGlzLl9ub2Rlcy5sZW5ndGggLSBub2RlUG9zc2l0aW9uKTtcblxuICAgIC8vIFVwZGF0aW5nIHRoaXMuX2FsbERhdGEgYWNjb3JkaW5nIHRvIHRoZSBuZXcgdGhpcy5fbm9kZXNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2FsbERhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGN1cnJlbnREYXRhID0gdGhpcy5fYWxsRGF0YVtpXTtcbiAgICAgIGlmIChjdXJyZW50RGF0YS5fZnJvbSAhPT0gdW5kZWZpbmVkICYmIGN1cnJlbnREYXRhLl9mcm9tICE9PSAtMSAmJiBjdXJyZW50RGF0YS5fZnJvbSAhPT0gLTIpIHtcbiAgICAgICAgY3VycmVudERhdGEuX2Zyb20gPSBuZXdJbmRpY2VzW2N1cnJlbnREYXRhLl9mcm9tXTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjdXJyZW50RGF0YS5fdG8ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKGN1cnJlbnREYXRhLl90b1tqXSA+PSAwKSB7XG4gICAgICAgICAgY3VycmVudERhdGEuX3RvW2pdID0gbmV3SW5kaWNlc1tjdXJyZW50RGF0YS5fdG9bal1dO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVHJ5aW5nIHRvIHVwZGF0ZSBhIHJlbW92ZWQgbm9kZScpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgb2Zmc2V0ID0gMDtcbiAgICAvLyBkZWxldGUgYWxsIHZhbHVlcyB0aGF0IGFyZSBub3QgYmVpbmcgcmVmZXJlbmNlZFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fYWxsRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgLy8gaWYgY3VycmVudCB2YWx1ZSBpcyBuZWl0aGVyIGxpbmtlZCB0byBuZXh0IG5vZGUsIG5vciBhbiBvdXRwdXQgdmFsdWUsIHJlbW92ZSBpdC5cbiAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2ldLmZyb20gPT09IC0yICYmIHRoaXMuX2FsbE91dHB1dEluZGljZXMuaW5kZXhPZihpICsgb2Zmc2V0KSA9PT0gLTEpIHtcbiAgICAgICAgb2Zmc2V0Kys7XG4gICAgICAgIHRoaXMuX2FsbERhdGEuc3BsaWNlKGksIDEpO1xuICAgICAgICBpLS07XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKG9mZnNldCA+IDApIHtcbiAgICAgICAgbGV0IGluZCA9IC0xO1xuICAgICAgICAvLyBpZiBjdXJyZW50IHZhbHVlIGlzIG5laXRoZXIgYW4gaW5wdXQgdmFsdWUgbm9yIGFuIGluaXRpYWxpemVyLCBmaW5kIHRoZSBub2RlIGl0J3NcbiAgICAgICAgLy8gY29taW5nIGZyb20gYW5kIHVwZGF0ZSB0aGUgY29ycmVzcG9uZGluZyBub2RlIG91dHB1dFxuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtpXS5mcm9tICE9PSB1bmRlZmluZWQgJiYgdGhpcy5fYWxsRGF0YVtpXS5mcm9tICE9PSAtMSkge1xuICAgICAgICAgIGluZCA9IHRoaXMuX25vZGVzW3RoaXMuX2FsbERhdGFbaV0uZnJvbV0ub3V0cHV0cy5pbmRleE9mKGkgKyBvZmZzZXQpO1xuICAgICAgICAgIGlmIChpbmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9ub2Rlc1t0aGlzLl9hbGxEYXRhW2ldLmZyb21dLm91dHB1dHNbaW5kXSA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGlmIGN1cnJlbnQgdmFsdWUgaXMgYW4gaW5wdXQgdmFsdWUsIHVwZGF0ZSBpdHMgcmVmZXJlbmNlIGluIGlucHV0SW5kaWNlc1xuICAgICAgICAgIGluZCA9IHRoaXMuX2FsbElucHV0SW5kaWNlcy5pbmRleE9mKGkgKyBvZmZzZXQpO1xuICAgICAgICAgIGlmIChpbmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9hbGxJbnB1dEluZGljZXNbaW5kXSA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZmluZCB0aGUgbm9kZSB0aGF0IHRoZSBjdXJyZW50IHZhbHVlIGlzIGxpbmtpbmcgdG8gYW5kIHVwZGF0ZSBpdHMgaW5wdXQgcmVmZXJlbmNlXG4gICAgICAgIHRoaXMuX2FsbERhdGFbaV0udG8uZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICBpbmQgPSB0aGlzLl9ub2Rlc1tub2RlXS5pbnB1dHMuaW5kZXhPZihpICsgb2Zmc2V0KTtcbiAgICAgICAgICBpZiAoaW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fbm9kZXNbbm9kZV0uaW5wdXRzW2luZF0gPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2ldLnRvLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIC8vIGlmIGN1cnJlbnQgdmFsdWUgaXMgYSBncmFwaCBvdXRwdXQsIHVwZGF0ZSBpdHMgcmVmZXJlbmNlIGluIG91dHB1dEluZGljZXNcbiAgICAgICAgICBpbmQgPSB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXNbaW5kXSA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgc3BlY2lmZWQgbm9kZS4gQXNzdW1lIHRoZSBub2RlIGhhcyBvbmUgaW5jb21pbmcgaW5wdXQgYW5kIHRoZSBmaXJzdCBvdXRwdXQgY29ubmVjdGVkIHRvIG90aGVyIG5vZGVzLlxuICAgKiBBbiBpbnB1dCB2YWxpZGF0aW9uIG11c3QgYmUgZG9uZSBiZWZvcmUgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLlxuICAgKiBAcGFyYW0gbm9kZUluZGV4IFRoZSBpbmRleCBvZiBub2RlIHRvIGJlIGRlbGV0ZWRcbiAgICovXG4gIHByaXZhdGUgZGVsZXRlTm9kZShub2RlSW5kZXg6IG51bWJlcikge1xuICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2Rlc1tub2RlSW5kZXhdO1xuICAgIGlmIChub2RlLm91dHB1dHMubGVuZ3RoID4gMSkge1xuICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBub2RlLm91dHB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbbm9kZS5vdXRwdXRzW2ldXS50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb2RlIGRlbGV0aW9uIHdpdGggbW9yZSB0aGFuIG9uZSBvdXRwdXQgY29ubmVjdGVkIHRvIG90aGVyIG5vZGVzIGlzIG5vdCBzdXBwb3J0ZWQuICcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhpcyBub2RlIHdpbCBub3QgYmUgZXhlY3V0ZWRcbiAgICBub2RlLmV4ZWN1dGVOb2RlID0gZmFsc2U7XG4gICAgY29uc3QgaW5wdXRWYWx1ZUluZGV4ID0gbm9kZS5pbnB1dHNbMF07XG4gICAgY29uc3Qgb3V0cHV0VmFsdWVJbmRleCA9IG5vZGUub3V0cHV0c1swXTtcbiAgICBjb25zdCBub2Rlc0NvbnN1bWluZ091dHB1dCA9IHRoaXMuX2FsbERhdGFbb3V0cHV0VmFsdWVJbmRleF0udG87XG5cbiAgICAvLyByZW1vdmUgdGhpcyBub2RlIGZyb20gdGhlIHRvIHByb3BlcnR5IG9mIHRoZSBpbnB1dCBWYWx1ZVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZS5pbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGRlbEluZGV4ID0gdGhpcy5fYWxsRGF0YVtub2RlLmlucHV0c1tpXV0udG8uaW5kZXhPZihub2RlSW5kZXgpO1xuICAgICAgLy8gc2hvdWxkIG5vdCBoYXBwZW5cbiAgICAgIGlmIChkZWxJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgVmFsdWUgb2JqZWN0IGRvZXNuXFwndCBoYXZlIHRoZSBjdXJyZW50IE5vZGUgaW4gaXRcXCdzIFxcJ3RvXFwnIHByb3BlcnR5ICcpO1xuICAgICAgfVxuICAgICAgdGhpcy5fYWxsRGF0YVtub2RlLmlucHV0c1tpXV0udG8uc3BsaWNlKGRlbEluZGV4LCAxKTtcbiAgICB9XG5cbiAgICAvLyBjbGVhciBub2RlIGluZGljZXMgY29uc3VtaW5nIHRoaXMgb3V0cHV0IFZhbHVlXG4gICAgdGhpcy5fYWxsRGF0YVtvdXRwdXRWYWx1ZUluZGV4XS5fdG8gPSBbXTtcblxuICAgIC8vIGlmIHRoZSBvdXRwdXQgb2YgdGhpcyBub2RlIGlzIGEgZ3JhcGggb3V0cHV0LCBhZGp1c3QgdGhlIGluZGV4IGFwcHJvcHJpYXRlbHlcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuX2FsbE91dHB1dEluZGljZXMuaW5kZXhPZihvdXRwdXRWYWx1ZUluZGV4KTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzW2luZGV4XSA9IGlucHV0VmFsdWVJbmRleDtcbiAgICB9XG5cbiAgICAvLyBvdmVycmlkZSB0aGUgaW5wdXRzIGZvciBub2RlcyBjb25zdW1pbmcgdGhpcyBub2RlJ3Mgb3V0cHV0IHdpdGggdGhlIGlucHV0IHRvIHRoaXMgbm9kZVxuICAgIGlmIChub2Rlc0NvbnN1bWluZ091dHB1dCAmJiBub2Rlc0NvbnN1bWluZ091dHB1dC5sZW5ndGggPiAwKSB7XG4gICAgICBmb3IgKGNvbnN0IG5vZGVJbmRleCBvZiBub2Rlc0NvbnN1bWluZ091dHB1dCkge1xuICAgICAgICBjb25zdCByZXBsYWNlSW5kZXggPSB0aGlzLl9ub2Rlc1tub2RlSW5kZXhdLmlucHV0cy5pbmRleE9mKG91dHB1dFZhbHVlSW5kZXgpO1xuICAgICAgICAvLyBzaG91bGQgbm90IGhhcHBlblxuICAgICAgICBpZiAocmVwbGFjZUluZGV4ID09PSAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIE5vZGUgb2JqZWN0IGRvZXNuXFwndCBoYXZlIHRoZSBvdXRwdXQgVmFsdWUgaW4gaXRcXCdzIFxcJ2lucHV0c1xcJyBwcm9wZXJ0eSAnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9ub2Rlc1tub2RlSW5kZXhdLmlucHV0c1tyZXBsYWNlSW5kZXhdID0gaW5wdXRWYWx1ZUluZGV4O1xuICAgICAgICB0aGlzLl9hbGxEYXRhW2lucHV0VmFsdWVJbmRleF0udG8ucHVzaChub2RlSW5kZXgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJlbW92ZUFsbERyb3BvdXROb2RlcygpIHtcbiAgICBsZXQgbm9kZUluZGV4ID0gMDtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5fbm9kZXMpIHtcbiAgICAgIC8vIHdlZWQgb3V0ICdEcm9wb3V0JyBub2RlcyBzbyB0aGF0IG5vIHRpbWUgaXMgd2FzdGVkIGluIGV4ZWN1dGlvblxuICAgICAgaWYgKG5vZGUub3BUeXBlID09PSAnRHJvcG91dCcpIHtcbiAgICAgICAgLy8gdGhlIG5vZGUgc2hvdWxkIGhhdmUgZXhhY3RseSAxIGlucHV0IGFuZCAxIG9yIDIgb3V0cHV0c1xuICAgICAgICBpZiAobm9kZS5pbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEcm9wb3V0IG5vZGVzIHNob3VsZCBvbmx5IGNvbnRhaW4gb25lIGlucHV0LiAnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9kZS5vdXRwdXRzLmxlbmd0aCAhPT0gMSAmJiBub2RlLm91dHB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEcm9wb3V0IG5vZGVzIHNob3VsZCBjb250YWluIGVpdGhlciAxIG9yIDIgb3V0cHV0KHMpJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhlIHNlY29uZCBvdXRwdXQgc2hvdWxkIG5vdCBiZSByZWZlcmVuY2VkIGJ5IGFueSBvdGhlciBub2RlXG4gICAgICAgIGlmIChub2RlLm91dHB1dHMubGVuZ3RoID09PSAyICYmIHRoaXMuX2FsbERhdGFbbm9kZS5vdXRwdXRzWzFdXS5fdG8ubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEcm9wb3V0IG5vZGVzXFwncyBzZWNvbmQgb3V0cHV0IHNob3VsZCBub3QgYmUgcmVmZXJlbmNlZCBieSBvdGhlciBub2RlcycpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGVsZXRlTm9kZShub2RlSW5kZXgpO1xuICAgICAgfVxuICAgICAgbm9kZUluZGV4Kys7XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlQWxsSWRlbnRpdHlOb2RlcygpIHtcbiAgICBsZXQgbm9kZUluZGV4ID0gMDtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5fbm9kZXMpIHtcbiAgICAgIC8vIHdlZWQgb3V0ICdJZGVudGl0eScgbm9kZXMgc28gdGhhdCBubyB0aW1lIGlzIHdhc3RlZCBpbiBleGVjdXRpb25cbiAgICAgIGlmIChub2RlLm9wVHlwZSA9PT0gJ0lkZW50aXR5Jykge1xuICAgICAgICB0aGlzLmRlbGV0ZU5vZGUobm9kZUluZGV4KTtcbiAgICAgIH1cbiAgICAgIG5vZGVJbmRleCsrO1xuICAgIH1cbiAgfVxuXG4gIGlzQWN0aXZhdGlvbihuOiBOb2RlKTogYm9vbGVhbiB7XG4gICAgc3dpdGNoIChuLm9wVHlwZSkge1xuICAgICAgLy8gVE9ETzogYWRkIG90aGVyIGFjdGl2YXRpb24gbWV0aG9kc1xuICAgICAgY2FzZSAnUmVsdSc6XG4gICAgICBjYXNlICdTaWdtb2lkJzpcbiAgICAgIGNhc2UgJ0NsaXAnOlxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBmdXNlQ29udkFjdGl2YXRpb25Ob2RlcygpIHtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5fbm9kZXMpIHtcbiAgICAgIGlmIChub2RlLm9wVHlwZSA9PT0gJ0NvbnYnKSB7XG4gICAgICAgIGNvbnN0IG5leHQgPSB0aGlzLl9hbGxEYXRhW25vZGUub3V0cHV0c1swXV0uX3RvO1xuICAgICAgICBpZiAobmV4dC5sZW5ndGggPT09IDEgJiYgdGhpcy5pc0FjdGl2YXRpb24odGhpcy5fbm9kZXNbbmV4dFswXV0pKSB7XG4gICAgICAgICAgY29uc3QgY2hpbGQgPSB0aGlzLl9ub2Rlc1tuZXh0WzBdXTtcbiAgICAgICAgICBpZiAoY2hpbGQub3BUeXBlID09PSAnQ2xpcCcpIHtcbiAgICAgICAgICAgIGlmIChjaGlsZC5pbnB1dHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnNldChcbiAgICAgICAgICAgICAgICAgICAgJ2FjdGl2YXRpb25fcGFyYW1zJywgJ2Zsb2F0cycsXG4gICAgICAgICAgICAgICAgICAgIFtjaGlsZC5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtaW4nKSwgY2hpbGQuYXR0cmlidXRlcy5nZXRGbG9hdCgnbWF4JyldKTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zZXQoJ2FjdGl2YXRpb25fcGFyYW1zJywgJ2Zsb2F0cycsIFtNSU5fQ0xJUCwgTUFYX0NMSVBdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICBjaGlsZC5pbnB1dHMubGVuZ3RoID49IDMgJiYgdGhpcy5fYWxsRGF0YVtjaGlsZC5pbnB1dHNbMV1dLnRlbnNvciAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICAgdGhpcy5fYWxsRGF0YVtjaGlsZC5pbnB1dHNbMl1dLnRlbnNvciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zZXQoJ2FjdGl2YXRpb25fcGFyYW1zJywgJ2Zsb2F0cycsIFtcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1sxXV0udGVuc29yIS5mbG9hdERhdGFbMF0sIHRoaXMuX2FsbERhdGFbY2hpbGQuaW5wdXRzWzJdXS50ZW5zb3IhLmZsb2F0RGF0YVswXVxuICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIFNraXAgZnVzaW9uIHdpdGggY2xpcCBub2RlIHNpbmNlIGNsaXAgbWluIGFuZCBjbGlwIG1heCBhcmUgbm90IGNvbWluZyBmcm9tIGluaXRpYWxpemVyXG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMuc2V0KCdhY3RpdmF0aW9uJywgJ3N0cmluZycsIChjaGlsZC5vcFR5cGUpKTtcbiAgICAgICAgICB0aGlzLmRlbGV0ZU5vZGUobmV4dFswXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtmbGF0YnVmZmVyc30gZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7T3BTZXR9IGZyb20gJy4vb3BzZXQnO1xuaW1wb3J0IHtvbm54cnVudGltZX0gZnJvbSAnLi9vcnQtc2NoZW1hL2ZsYXRidWZmZXJzL29ydC1nZW5lcmF0ZWQnO1xuaW1wb3J0IHtvbm54fSBmcm9tICcuL29ydC1zY2hlbWEvcHJvdG9idWYvb25ueCc7XG5pbXBvcnQge0xvbmdVdGlsfSBmcm9tICcuL3V0aWwnO1xuXG5pbXBvcnQgb3J0RmJzID0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicztcblxuZXhwb3J0IGNsYXNzIE1vZGVsIHtcbiAgLy8gZW1wdHkgbW9kZWxcbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIGxvYWQoYnVmOiBVaW50OEFycmF5LCBncmFwaEluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIsIGlzT3J0Rm9ybWF0PzogYm9vbGVhbik6IHZvaWQge1xuICAgIGxldCBvbm54RXJyb3I6IEVycm9yfHVuZGVmaW5lZDtcbiAgICBpZiAoIWlzT3J0Rm9ybWF0KSB7XG4gICAgICAvLyBpc09ydEZvcm1hdCA9PT0gZmFsc2UgfHwgaXNPcnRGb3JtYXQgPT09IHVuZGVmaW5lZFxuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5sb2FkRnJvbU9ubnhGb3JtYXQoYnVmLCBncmFwaEluaXRpYWxpemVyKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoaXNPcnRGb3JtYXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgb25ueEVycm9yID0gZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5sb2FkRnJvbU9ydEZvcm1hdChidWYsIGdyYXBoSW5pdGlhbGl6ZXIpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChpc09ydEZvcm1hdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgICAvLyBUcmllZCBib3RoIGZvcm1hdHMgYW5kIGZhaWxlZCAod2hlbiBpc09ydEZvcm1hdCA9PT0gdW5kZWZpbmVkKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbG9hZCBtb2RlbCBhcyBPTk5YIGZvcm1hdDogJHtvbm54RXJyb3J9XFxuYXMgT1JUIGZvcm1hdDogJHtlfWApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbG9hZEZyb21Pbm54Rm9ybWF0KGJ1ZjogVWludDhBcnJheSwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKTogdm9pZCB7XG4gICAgY29uc3QgbW9kZWxQcm90byA9IG9ubnguTW9kZWxQcm90by5kZWNvZGUoYnVmKTtcbiAgICBjb25zdCBpclZlcnNpb24gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIobW9kZWxQcm90by5pclZlcnNpb24pO1xuICAgIGlmIChpclZlcnNpb24gPCAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29ubHkgc3VwcG9ydCBPTk5YIG1vZGVsIHdpdGggSVJfVkVSU0lPTj49MycpO1xuICAgIH1cblxuICAgIHRoaXMuX29wc2V0cyA9XG4gICAgICAgIG1vZGVsUHJvdG8ub3BzZXRJbXBvcnQubWFwKGkgPT4gKHtkb21haW46IGkuZG9tYWluIGFzIHN0cmluZywgdmVyc2lvbjogTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKGkudmVyc2lvbiEpfSkpO1xuXG4gICAgdGhpcy5fZ3JhcGggPSBHcmFwaC5mcm9tKG1vZGVsUHJvdG8uZ3JhcGghLCBncmFwaEluaXRpYWxpemVyKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEZyb21PcnRGb3JtYXQoYnVmOiBVaW50OEFycmF5LCBncmFwaEluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIpOiB2b2lkIHtcbiAgICBjb25zdCBmYiA9IG5ldyBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKGJ1Zik7XG4gICAgY29uc3Qgb3J0TW9kZWwgPSBvcnRGYnMuSW5mZXJlbmNlU2Vzc2lvbi5nZXRSb290QXNJbmZlcmVuY2VTZXNzaW9uKGZiKS5tb2RlbCgpITtcbiAgICBjb25zdCBpclZlcnNpb24gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIob3J0TW9kZWwuaXJWZXJzaW9uKCkpO1xuICAgIGlmIChpclZlcnNpb24gPCAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29ubHkgc3VwcG9ydCBPTk5YIG1vZGVsIHdpdGggSVJfVkVSU0lPTj49MycpO1xuICAgIH1cbiAgICB0aGlzLl9vcHNldHMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9ydE1vZGVsLm9wc2V0SW1wb3J0TGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3Qgb3BzZXRJZCA9IG9ydE1vZGVsLm9wc2V0SW1wb3J0KGkpITtcbiAgICAgIHRoaXMuX29wc2V0cy5wdXNoKHtkb21haW46IG9wc2V0SWQ/LmRvbWFpbigpIGFzIHN0cmluZywgdmVyc2lvbjogTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG9wc2V0SWQudmVyc2lvbigpISl9KTtcbiAgICB9XG5cbiAgICB0aGlzLl9ncmFwaCA9IEdyYXBoLmZyb20ob3J0TW9kZWwuZ3JhcGgoKSEsIGdyYXBoSW5pdGlhbGl6ZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ3JhcGg6IEdyYXBoO1xuICBnZXQgZ3JhcGgoKTogR3JhcGgge1xuICAgIHJldHVybiB0aGlzLl9ncmFwaDtcbiAgfVxuXG4gIHByaXZhdGUgX29wc2V0czogT3BTZXRbXTtcbiAgZ2V0IG9wc2V0cygpOiByZWFkb25seSBPcFNldFtdIHtcbiAgICByZXR1cm4gdGhpcy5fb3BzZXRzO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7cmVhZEZpbGV9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuXG5pbXBvcnQge3Jlc29sdmVCYWNrZW5kLCBTZXNzaW9uSGFuZGxlclR5cGV9IGZyb20gJy4vYmFja2VuZCc7XG5pbXBvcnQge0V4ZWN1dGlvblBsYW59IGZyb20gJy4vZXhlY3V0aW9uLXBsYW4nO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQge1Byb2ZpbGVyfSBmcm9tICcuL2luc3RydW1lbnQnO1xuaW1wb3J0IHtNb2RlbH0gZnJvbSAnLi9tb2RlbCc7XG5pbXBvcnQge09wZXJhdG9yfSBmcm9tICcuL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi90ZW5zb3InO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgU2Vzc2lvbiB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnIHtcbiAgICBiYWNrZW5kSGludD86IHN0cmluZztcbiAgICBwcm9maWxlcj86IFByb2ZpbGVyLkNvbmZpZztcbiAgfVxuXG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29udGV4dCB7XG4gICAgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPjtcbiAgICBncmFwaElucHV0VHlwZXM/OiBUZW5zb3IuRGF0YVR5cGVbXTtcbiAgICBncmFwaElucHV0RGltcz86IEFycmF5PHJlYWRvbmx5IG51bWJlcltdPjtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogU2Vzc2lvbi5Db25maWcgPSB7fSkge1xuICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG4gICAgdGhpcy5iYWNrZW5kSGludCA9IGNvbmZpZy5iYWNrZW5kSGludDtcbiAgICB0aGlzLnByb2ZpbGVyID0gUHJvZmlsZXIuY3JlYXRlKGNvbmZpZy5wcm9maWxlcik7XG4gICAgdGhpcy5jb250ZXh0ID0ge3Byb2ZpbGVyOiB0aGlzLnByb2ZpbGVyLCBncmFwaElucHV0VHlwZXM6IFtdLCBncmFwaElucHV0RGltczogW119O1xuICB9XG5cbiAgZ2V0IGlucHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9tb2RlbC5ncmFwaC5nZXRJbnB1dE5hbWVzKCk7XG4gIH1cbiAgZ2V0IG91dHB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0T3V0cHV0TmFtZXMoKTtcbiAgfVxuXG4gIHN0YXJ0UHJvZmlsaW5nKCkge1xuICAgIHRoaXMucHJvZmlsZXIuc3RhcnQoKTtcbiAgfVxuXG4gIGVuZFByb2ZpbGluZygpIHtcbiAgICB0aGlzLnByb2ZpbGVyLnN0b3AoKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWRNb2RlbCh1cmk6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gIGFzeW5jIGxvYWRNb2RlbChidWZmZXI6IEFycmF5QnVmZmVyLCBieXRlT2Zmc2V0PzogbnVtYmVyLCBsZW5ndGg/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+O1xuICBhc3luYyBsb2FkTW9kZWwoYnVmZmVyOiBVaW50OEFycmF5KTogUHJvbWlzZTx2b2lkPjtcbiAgYXN5bmMgbG9hZE1vZGVsKGFyZzogc3RyaW5nfEFycmF5QnVmZmVyfFVpbnQ4QXJyYXksIGJ5dGVPZmZzZXQ/OiBudW1iZXIsIGxlbmd0aD86IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMucHJvZmlsZXIuZXZlbnQoJ3Nlc3Npb24nLCAnU2Vzc2lvbi5sb2FkTW9kZWwnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyByZXNvbHZlIGJhY2tlbmQgYW5kIHNlc3Npb24gaGFuZGxlclxuICAgICAgY29uc3QgYmFja2VuZCA9IGF3YWl0IHJlc29sdmVCYWNrZW5kKHRoaXMuYmFja2VuZEhpbnQpO1xuICAgICAgdGhpcy5zZXNzaW9uSGFuZGxlciA9IGJhY2tlbmQuY3JlYXRlU2Vzc2lvbkhhbmRsZXIodGhpcy5jb250ZXh0KTtcblxuICAgICAgdGhpcy5fbW9kZWwgPSBuZXcgTW9kZWwoKTtcbiAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zdCBpc09ydEZvcm1hdCA9IGFyZy5lbmRzV2l0aCgnLm9ydCcpO1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHByb2Nlc3MudmVyc2lvbnMgJiYgcHJvY2Vzcy52ZXJzaW9ucy5ub2RlKSB7XG4gICAgICAgICAgLy8gbm9kZVxuICAgICAgICAgIGNvbnN0IGJ1ZiA9IGF3YWl0IHJlYWRGaWxlKGFyZyk7XG4gICAgICAgICAgdGhpcy5pbml0aWFsaXplKGJ1ZiwgaXNPcnRGb3JtYXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGJyb3dzZXJcbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGFyZyk7XG4gICAgICAgICAgY29uc3QgYnVmID0gYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTtcbiAgICAgICAgICB0aGlzLmluaXRpYWxpemUobmV3IFVpbnQ4QXJyYXkoYnVmKSwgaXNPcnRGb3JtYXQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCFBcnJheUJ1ZmZlci5pc1ZpZXcoYXJnKSkge1xuICAgICAgICAvLyBsb2FkIG1vZGVsIGZyb20gQXJyYXlCdWZmZXJcbiAgICAgICAgY29uc3QgYXJyID0gbmV3IFVpbnQ4QXJyYXkoYXJnLCBieXRlT2Zmc2V0IHx8IDAsIGxlbmd0aCB8fCBhcmcuYnl0ZUxlbmd0aCk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZShhcnIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gbG9hZCBtb2RlbCBmcm9tIFVpbnQ4YXJyYXlcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKGFyZyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemUobW9kZWxQcm90b0Jsb2I6IFVpbnQ4QXJyYXksIGlzT3J0Rm9ybWF0PzogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh0aGlzLl9pbml0aWFsaXplZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhbHJlYWR5IGluaXRpYWxpemVkJyk7XG4gICAgfVxuXG4gICAgdGhpcy5wcm9maWxlci5ldmVudCgnc2Vzc2lvbicsICdTZXNzaW9uLmluaXRpYWxpemUnLCAoKSA9PiB7XG4gICAgICAvLyBsb2FkIGdyYXBoXG4gICAgICBjb25zdCBncmFwaEluaXRpYWxpemVyID1cbiAgICAgICAgICB0aGlzLnNlc3Npb25IYW5kbGVyLnRyYW5zZm9ybUdyYXBoID8gdGhpcy5zZXNzaW9uSGFuZGxlciBhcyBHcmFwaC5Jbml0aWFsaXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuX21vZGVsLmxvYWQobW9kZWxQcm90b0Jsb2IsIGdyYXBoSW5pdGlhbGl6ZXIsIGlzT3J0Rm9ybWF0KTtcblxuICAgICAgLy8gZ3JhcGggaXMgY29tcGxldGVseSBpbml0aWFsemllZCBhdCB0aGlzIHN0YWdlICwgbGV0IHRoZSBpbnRlcmVzdGVkIGhhbmRsZXJzIGtub3dcbiAgICAgIGlmICh0aGlzLnNlc3Npb25IYW5kbGVyLm9uR3JhcGhJbml0aWFsaXplZCkge1xuICAgICAgICB0aGlzLnNlc3Npb25IYW5kbGVyLm9uR3JhcGhJbml0aWFsaXplZCh0aGlzLl9tb2RlbC5ncmFwaCk7XG4gICAgICB9XG4gICAgICAvLyBpbml0aWFsaXplIGVhY2ggb3BlcmF0b3IgaW4gdGhlIGdyYXBoXG4gICAgICB0aGlzLmluaXRpYWxpemVPcHModGhpcy5fbW9kZWwuZ3JhcGgpO1xuXG4gICAgICAvLyBpbnN0YW50aWF0ZSBhbiBFeGVjdXRpb25QbGFuIG9iamVjdCB0byBiZSB1c2VkIGJ5IHRoZSBTZXNzaW9uIG9iamVjdFxuICAgICAgdGhpcy5fZXhlY3V0aW9uUGxhbiA9IG5ldyBFeGVjdXRpb25QbGFuKHRoaXMuX21vZGVsLmdyYXBoLCB0aGlzLl9vcHMsIHRoaXMucHJvZmlsZXIpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5faW5pdGlhbGl6ZWQgPSB0cnVlO1xuICB9XG5cbiAgYXN5bmMgcnVuKGlucHV0czogTWFwPHN0cmluZywgVGVuc29yPnxUZW5zb3JbXSk6IFByb21pc2U8TWFwPHN0cmluZywgVGVuc29yPj4ge1xuICAgIGlmICghdGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2Vzc2lvbiBub3QgaW5pdGlhbGl6ZWQgeWV0Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ3Nlc3Npb24nLCAnU2Vzc2lvbi5ydW4nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBpbnB1dFRlbnNvcnMgPSB0aGlzLm5vcm1hbGl6ZUFuZFZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgICAgIGNvbnN0IG91dHB1dFRlbnNvcnMgPSBhd2FpdCB0aGlzLl9leGVjdXRpb25QbGFuLmV4ZWN1dGUodGhpcy5zZXNzaW9uSGFuZGxlciwgaW5wdXRUZW5zb3JzKTtcblxuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlT3V0cHV0KG91dHB1dFRlbnNvcnMpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBub3JtYWxpemVBbmRWYWxpZGF0ZUlucHV0cyhpbnB1dHM6IE1hcDxzdHJpbmcsIFRlbnNvcj58VGVuc29yW10pOiBUZW5zb3JbXSB7XG4gICAgY29uc3QgbW9kZWxJbnB1dE5hbWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0SW5wdXROYW1lcygpO1xuXG4gICAgLy8gbm9ybWFsaXplIGlucHV0c1xuICAgIC8vIGlucHV0czogVGVuc29yW11cbiAgICBpZiAoQXJyYXkuaXNBcnJheShpbnB1dHMpKSB7XG4gICAgICBpZiAoaW5wdXRzLmxlbmd0aCAhPT0gbW9kZWxJbnB1dE5hbWVzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGluY29ycmVjdCBpbnB1dCBhcnJheSBsZW5ndGg6IGV4cGVjdGVkICR7bW9kZWxJbnB1dE5hbWVzLmxlbmd0aH0gYnV0IGdvdCAke2lucHV0cy5sZW5ndGh9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNvbnZlcnQgbWFwIHRvIGFycmF5XG4gICAgLy8gaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+XG4gICAgZWxzZSB7XG4gICAgICBpZiAoaW5wdXRzLnNpemUgIT09IG1vZGVsSW5wdXROYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbmNvcnJlY3QgaW5wdXQgbWFwIHNpemU6IGV4cGVjdGVkICR7bW9kZWxJbnB1dE5hbWVzLmxlbmd0aH0gYnV0IGdvdCAke2lucHV0cy5zaXplfWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzb3J0ZWRJbnB1dHMgPSBuZXcgQXJyYXk8VGVuc29yPihpbnB1dHMuc2l6ZSk7XG4gICAgICBsZXQgc29ydGVkSW5wdXRzSW5kZXggPSAwO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb2RlbElucHV0TmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY29uc3QgdGVuc29yID0gaW5wdXRzLmdldChtb2RlbElucHV0TmFtZXNbaV0pO1xuICAgICAgICBpZiAoIXRlbnNvcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBpbnB1dCB0ZW5zb3IgZm9yOiAnJHtuYW1lfSdgKTtcbiAgICAgICAgfVxuICAgICAgICBzb3J0ZWRJbnB1dHNbc29ydGVkSW5wdXRzSW5kZXgrK10gPSB0ZW5zb3I7XG4gICAgICB9XG5cbiAgICAgIGlucHV0cyA9IHNvcnRlZElucHV0cztcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSBkaW1zIHJlcXVpcmVtZW50c1xuICAgIC8vIEZpcnN0IHNlc3Npb24gcnVuIC0gZ3JhcGggaW5wdXQgZGF0YSBpcyBub3QgY2FjaGVkIGZvciB0aGUgc2Vzc2lvblxuICAgIGlmICghdGhpcy5jb250ZXh0LmdyYXBoSW5wdXRUeXBlcyB8fCB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzLmxlbmd0aCA9PT0gMCB8fCAhdGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zIHx8XG4gICAgICAgIHRoaXMuY29udGV4dC5ncmFwaElucHV0RGltcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnN0IG1vZGVsSW5wdXRJbmRpY2VzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0SW5wdXRJbmRpY2VzKCk7XG4gICAgICBjb25zdCBtb2RlbFZhbHVlcyA9IHRoaXMuX21vZGVsLmdyYXBoLmdldFZhbHVlcygpO1xuXG4gICAgICBjb25zdCBncmFwaElucHV0RGltcyA9IG5ldyBBcnJheTxyZWFkb25seSBudW1iZXJbXT4obW9kZWxJbnB1dEluZGljZXMubGVuZ3RoKTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb2RlbElucHV0SW5kaWNlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICBjb25zdCBncmFwaElucHV0ID0gbW9kZWxWYWx1ZXNbbW9kZWxJbnB1dEluZGljZXNbaV1dO1xuICAgICAgICBncmFwaElucHV0RGltc1tpXSA9IGdyYXBoSW5wdXQudHlwZSEuc2hhcGUuZGltcztcblxuICAgICAgICAvLyBjYWNoZWQgZm9yIHNlY29uZCBhbmQgc3Vic2VxdWVudCBydW5zLlxuICAgICAgICAvLyBTb21lIHBhcnRzIG9mIHRoZSBmcmFtZXdvcmsgd29ya3Mgb24gdGhlIGFzc3VtcHRpb24gdGhhdCB0aGUgZ3JhcGggYW5kIHR5cGVzIGFuZCBzaGFwZXMgYXJlIHN0YXRpY1xuICAgICAgICB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dFR5cGVzIS5wdXNoKGdyYXBoSW5wdXQudHlwZSEudGVuc29yVHlwZSk7XG4gICAgICAgIHRoaXMuY29udGV4dC5ncmFwaElucHV0RGltcyEucHVzaChpbnB1dHNbaV0uZGltcyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMudmFsaWRhdGVJbnB1dFRlbnNvckRpbXMoZ3JhcGhJbnB1dERpbXMsIGlucHV0cywgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gU2Vjb25kIGFuZCBzdWJzZXF1ZW50IHNlc3Npb24gcnVucyAtIGdyYXBoIGlucHV0IGRhdGEgaXMgY2FjaGVkIGZvciB0aGUgc2Vzc2lvblxuICAgIGVsc2Uge1xuICAgICAgdGhpcy52YWxpZGF0ZUlucHV0VGVuc29yRGltcyh0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dERpbXMsIGlucHV0cywgZmFsc2UpO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIHR5cGVzIHJlcXVpcmVtZW50XG4gICAgdGhpcy52YWxpZGF0ZUlucHV0VGVuc29yVHlwZXModGhpcy5jb250ZXh0LmdyYXBoSW5wdXRUeXBlcyEsIGlucHV0cyk7XG5cbiAgICByZXR1cm4gaW5wdXRzO1xuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUlucHV0VGVuc29yVHlwZXMoZ3JhcGhJbnB1dFR5cGVzOiBUZW5zb3IuRGF0YVR5cGVbXSwgZ2l2ZW5JbnB1dHM6IFRlbnNvcltdKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBnaXZlbklucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZXhwZWN0ZWRUeXBlID0gZ3JhcGhJbnB1dFR5cGVzW2ldO1xuICAgICAgY29uc3QgYWN0dWFsVHlwZSA9IGdpdmVuSW5wdXRzW2ldLnR5cGU7XG4gICAgICBpZiAoZXhwZWN0ZWRUeXBlICE9PSBhY3R1YWxUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXQgdGVuc29yWyR7aX1dIGNoZWNrIGZhaWxlZDogZXhwZWN0ZWQgdHlwZSAnJHtleHBlY3RlZFR5cGV9JyBidXQgZ290ICR7YWN0dWFsVHlwZX1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlSW5wdXRUZW5zb3JEaW1zKFxuICAgICAgZ3JhcGhJbnB1dERpbXM6IEFycmF5PHJlYWRvbmx5IG51bWJlcltdPiwgZ2l2ZW5JbnB1dHM6IFRlbnNvcltdLCBub25lRGltU3VwcG9ydGVkOiBib29sZWFuKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBnaXZlbklucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZXhwZWN0ZWREaW1zID0gZ3JhcGhJbnB1dERpbXNbaV07XG4gICAgICBjb25zdCBhY3R1YWxEaW1zID0gZ2l2ZW5JbnB1dHNbaV0uZGltcztcbiAgICAgIGlmICghdGhpcy5jb21wYXJlVGVuc29yRGltcyhleHBlY3RlZERpbXMsIGFjdHVhbERpbXMsIG5vbmVEaW1TdXBwb3J0ZWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXQgdGVuc29yWyR7aX1dIGNoZWNrIGZhaWxlZDogZXhwZWN0ZWQgc2hhcGUgJ1ske2V4cGVjdGVkRGltcy5qb2luKCcsJyl9XScgYnV0IGdvdCBbJHtcbiAgICAgICAgICAgIGFjdHVhbERpbXMuam9pbignLCcpfV1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbXBhcmVUZW5zb3JEaW1zKGV4cGVjdGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10sIGFjdHVhbERpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBub25lRGltU3VwcG9ydGVkOiBib29sZWFuKTpcbiAgICAgIGJvb2xlYW4ge1xuICAgIGlmIChleHBlY3RlZERpbXMubGVuZ3RoICE9PSBhY3R1YWxEaW1zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwZWN0ZWREaW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAoZXhwZWN0ZWREaW1zW2ldICE9PSBhY3R1YWxEaW1zW2ldICYmICghbm9uZURpbVN1cHBvcnRlZCB8fCBleHBlY3RlZERpbXNbaV0gIT09IDApKSB7XG4gICAgICAgIC8vIGRhdGEgc2hhcGUgbWlzLW1hdGNoIEFORCBub3QgYSAnTm9uZScgZGltZW5zaW9uLlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU91dHB1dChvdXRwdXRUZW5zb3JzOiBUZW5zb3JbXSk6IE1hcDxzdHJpbmcsIFRlbnNvcj4ge1xuICAgIGNvbnN0IG1vZGVsT3V0cHV0TmFtZXMgPSB0aGlzLl9tb2RlbC5ncmFwaC5nZXRPdXRwdXROYW1lcygpO1xuICAgIGlmIChvdXRwdXRUZW5zb3JzLmxlbmd0aCAhPT0gbW9kZWxPdXRwdXROYW1lcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0ZWQgbnVtYmVyIG9mIG91dHB1dHMgZG8gbm90IG1hdGNoIG51bWJlciBvZiBnZW5lcmF0ZWQgb3V0cHV0cycpO1xuICAgIH1cblxuICAgIGNvbnN0IG91dHB1dCA9IG5ldyBNYXA8c3RyaW5nLCBUZW5zb3I+KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb2RlbE91dHB1dE5hbWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICBvdXRwdXQuc2V0KG1vZGVsT3V0cHV0TmFtZXNbaV0sIG91dHB1dFRlbnNvcnNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemVPcHMoZ3JhcGg6IEdyYXBoKTogdm9pZCB7XG4gICAgY29uc3Qgbm9kZXMgPSBncmFwaC5nZXROb2RlcygpO1xuICAgIHRoaXMuX29wcyA9IG5ldyBBcnJheShub2Rlcy5sZW5ndGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5fb3BzW2ldID0gdGhpcy5zZXNzaW9uSGFuZGxlci5yZXNvbHZlKG5vZGVzW2ldLCB0aGlzLl9tb2RlbC5vcHNldHMsIGdyYXBoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9tb2RlbDogTW9kZWw7XG4gIHByaXZhdGUgX2luaXRpYWxpemVkOiBib29sZWFuO1xuXG4gIHByaXZhdGUgX29wczogT3BlcmF0b3JbXTtcbiAgcHJpdmF0ZSBfZXhlY3V0aW9uUGxhbjogRXhlY3V0aW9uUGxhbjtcblxuICBwcml2YXRlIGJhY2tlbmRIaW50Pzogc3RyaW5nO1xuXG4gIHByaXZhdGUgc2Vzc2lvbkhhbmRsZXI6IFNlc3Npb25IYW5kbGVyVHlwZTtcbiAgcHJpdmF0ZSBjb250ZXh0OiBTZXNzaW9uLkNvbnRleHQ7XG4gIHByaXZhdGUgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPjtcbn1cbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtJbmZlcmVuY2VTZXNzaW9uLCBJbmZlcmVuY2VTZXNzaW9uSGFuZGxlciwgU2Vzc2lvbkhhbmRsZXIsIFRlbnNvcn0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHtTZXNzaW9ufSBmcm9tICcuL3Nlc3Npb24nO1xuaW1wb3J0IHtUZW5zb3IgYXMgT25ueGpzVGVuc29yfSBmcm9tICcuL3RlbnNvcic7XG5cbmV4cG9ydCBjbGFzcyBPbm54anNTZXNzaW9uSGFuZGxlciBpbXBsZW1lbnRzIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzZXNzaW9uOiBTZXNzaW9uKSB7XG4gICAgdGhpcy5pbnB1dE5hbWVzID0gdGhpcy5zZXNzaW9uLmlucHV0TmFtZXM7XG4gICAgdGhpcy5vdXRwdXROYW1lcyA9IHRoaXMuc2Vzc2lvbi5vdXRwdXROYW1lcztcbiAgfVxuXG4gIGFzeW5jIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB7fVxuICBpbnB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgb3V0cHV0TmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBhc3luYyBydW4oXG4gICAgICBmZWVkczogU2Vzc2lvbkhhbmRsZXIuRmVlZHNUeXBlLCBfZmV0Y2hlczogU2Vzc2lvbkhhbmRsZXIuRmV0Y2hlc1R5cGUsXG4gICAgICBfb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlPiB7XG4gICAgY29uc3QgaW5wdXRNYXAgPSBuZXcgTWFwPHN0cmluZywgT25ueGpzVGVuc29yPigpO1xuICAgIGZvciAoY29uc3QgbmFtZSBpbiBmZWVkcykge1xuICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKGZlZWRzLCBuYW1lKSkge1xuICAgICAgICBjb25zdCBmZWVkID0gZmVlZHNbbmFtZV07XG4gICAgICAgIGlucHV0TWFwLnNldChcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBuZXcgT25ueGpzVGVuc29yKFxuICAgICAgICAgICAgICAgIGZlZWQuZGltcywgZmVlZC50eXBlIGFzIE9ubnhqc1RlbnNvci5EYXRhVHlwZSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgZmVlZC5kYXRhIGFzIE9ubnhqc1RlbnNvci5OdW1iZXJUeXBlKSk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IG91dHB1dE1hcCA9IGF3YWl0IHRoaXMuc2Vzc2lvbi5ydW4oaW5wdXRNYXApO1xuICAgIGNvbnN0IG91dHB1dDogU2Vzc2lvbkhhbmRsZXIuUmV0dXJuVHlwZSA9IHt9O1xuICAgIG91dHB1dE1hcC5mb3JFYWNoKCh0ZW5zb3IsIG5hbWUpID0+IHtcbiAgICAgIG91dHB1dFtuYW1lXSA9IG5ldyBUZW5zb3IodGVuc29yLnR5cGUsIHRlbnNvci5kYXRhLCB0ZW5zb3IuZGltcyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxuICBzdGFydFByb2ZpbGluZygpOiB2b2lkIHtcbiAgICB0aGlzLnNlc3Npb24uc3RhcnRQcm9maWxpbmcoKTtcbiAgfVxuICBlbmRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uLmVuZFByb2ZpbGluZygpO1xuICB9XG59XG4iLCAiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1pbnRlcm5hbC1tb2R1bGVzICovXG5pbXBvcnQge0JhY2tlbmQsIEluZmVyZW5jZVNlc3Npb24sIEluZmVyZW5jZVNlc3Npb25IYW5kbGVyfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQge1Nlc3Npb259IGZyb20gJy4vb25ueGpzL3Nlc3Npb24nO1xuaW1wb3J0IHtPbm54anNTZXNzaW9uSGFuZGxlcn0gZnJvbSAnLi9vbm54anMvc2Vzc2lvbi1oYW5kbGVyLWluZmVyZW5jZSc7XG5cbmNsYXNzIE9ubnhqc0JhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICBhc3luYyBpbml0KCk6IFByb21pc2U8dm9pZD4ge31cblxuICBhc3luYyBjcmVhdGVJbmZlcmVuY2VTZXNzaW9uSGFuZGxlcihwYXRoT3JCdWZmZXI6IHN0cmluZ3xVaW50OEFycmF5LCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6XG4gICAgICBQcm9taXNlPEluZmVyZW5jZVNlc3Npb25IYW5kbGVyPiB7XG4gICAgLy8gTk9URTogU2Vzc2lvbi5Db25maWcoZnJvbSBvbm54LmpzKSBpcyBub3QgY29tcGF0aWJsZSB3aXRoIEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMoZnJvbVxuICAgIC8vIG9ubnhydW50aW1lLWNvbW1vbikuXG4gICAgLy8gICAgICAgSW4gZnV0dXJlIHdlIHNob3VsZCByZW1vdmUgU2Vzc2lvbi5Db25maWcgYW5kIHVzZSBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLlxuICAgIC8vICAgICAgIEN1cnJlbnRseSB3ZSBhbGxvdyB0aGlzIHRvIGhhcHBlbiB0byBtYWtlIHRlc3QgcnVubmVyIHdvcmsuXG4gICAgY29uc3Qgc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKG9wdGlvbnMgYXMgdW5rbm93biBhcyBTZXNzaW9uLkNvbmZpZyk7XG5cbiAgICAvLyB0eXBlc2NyaXB0IGNhbm5vdCBtZXJnZSBtZXRob2Qgb3ZlcnJpZGUgY29ycmVjdGx5IChzbyBmYXIgaW4gNC4yLjMpLiBuZWVkIGlmLWVsc2UgdG8gY2FsbCB0aGUgbWV0aG9kLlxuICAgIGlmICh0eXBlb2YgcGF0aE9yQnVmZmVyID09PSAnc3RyaW5nJykge1xuICAgICAgYXdhaXQgc2Vzc2lvbi5sb2FkTW9kZWwocGF0aE9yQnVmZmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgc2Vzc2lvbi5sb2FkTW9kZWwocGF0aE9yQnVmZmVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE9ubnhqc1Nlc3Npb25IYW5kbGVyKHNlc3Npb24pO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBvbm54anNCYWNrZW5kID0gbmV3IE9ubnhqc0JhY2tlbmQoKTtcbiIsICIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlcywgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAqL1xuLy8gV2UgdXNlIFwicmVxdWlyZVwiIGluc3RlYWQgb2YgXCJpbXBvcnRcIiBoZXJlIGJlY2F1c2UgaW1wb3J0IHN0YXRlbWVudCBtdXN0IGJlIHB1dCBpbiB0b3AgbGV2ZWwuIE91ciBjdXJyZW50IGNvZGUgZG9lc1xuLy8gbm90IGFsbG93IGJ1bmRsZXIgdG8gdHJlZS1zaGFraW5nIGNvZGUgYXMgZXhwZWN0ZWQgYmVjYXVzZSBzb21lIGNvZGVzIGFyZSB0cmVhdGVkIGFzIGhhdmluZyBzaWRlIGVmZmVjdHMuXG4vLyBTbyB3ZSBpbXBvcnQgY29kZSBpbnNpZGUgdGhlIGlmLWNsYXVzZSB0byBhbGxvdyBidW5kbGVyIHJlbW92ZSB0aGUgY29kZSBzYWZlbHkuXG5cbmV4cG9ydCAqIGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5pbXBvcnQgKiBhcyBvcnQgZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcbmV4cG9ydCBkZWZhdWx0IG9ydDtcblxuaW1wb3J0IHtyZWdpc3RlckJhY2tlbmQsIGVudn0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcbmltcG9ydCB7dmVyc2lvbn0gZnJvbSAnLi92ZXJzaW9uJztcblxuaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0VCR0wpIHtcbiAgY29uc3Qgb25ueGpzQmFja2VuZCA9IHJlcXVpcmUoJy4vYmFja2VuZC1vbm54anMnKS5vbm54anNCYWNrZW5kO1xuICByZWdpc3RlckJhY2tlbmQoJ3dlYmdsJywgb25ueGpzQmFja2VuZCwgLTEwKTtcbn1cblxuaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTSkge1xuICBjb25zdCB3YXNtQmFja2VuZCA9IEJVSUxEX0RFRlMuRElTQUJMRV9UUkFJTklORyA/IHJlcXVpcmUoJy4vYmFja2VuZC13YXNtLWluZmVyZW5jZScpLndhc21CYWNrZW5kIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlKCcuL2JhY2tlbmQtd2FzbS10cmFpbmluZycpLndhc21CYWNrZW5kO1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XRUJHUFUpIHtcbiAgICByZWdpc3RlckJhY2tlbmQoJ3dlYmdwdScsIHdhc21CYWNrZW5kLCA1KTtcbiAgICByZWdpc3RlckJhY2tlbmQoJ3dlYm5uJywgd2FzbUJhY2tlbmQsIDUpO1xuICB9XG4gIHJlZ2lzdGVyQmFja2VuZCgnY3B1Jywgd2FzbUJhY2tlbmQsIDEwKTtcbiAgcmVnaXN0ZXJCYWNrZW5kKCd3YXNtJywgd2FzbUJhY2tlbmQsIDEwKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGVudi52ZXJzaW9ucywgJ3dlYicsIHt2YWx1ZTogdmVyc2lvbiwgZW51bWVyYWJsZTogdHJ1ZX0pO1xuIiwgIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vLyBUaGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGJ5IC9qcy9zY3JpcHRzL3VwZGF0ZS12ZXJzaW9uLnRzXG4vLyBEbyBub3QgbW9kaWZ5IGZpbGUgY29udGVudCBtYW51YWxseS5cblxuZXhwb3J0IGNvbnN0IHZlcnNpb24gPSAnMS4xOC4wJztcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxJQWdCTSxVQUNBLDBCQVlPLGlCQXdDUCxnQ0F3Q087QUE3R2I7OztBQWdCQSxJQUFNLFdBQXFDLG9CQUFJLElBQUc7QUFDbEQsSUFBTSwyQkFBcUMsQ0FBQTtBQVlwQyxJQUFNLGtCQUFrQixDQUFDQSxPQUFjQyxVQUFrQixhQUEwQjtBQUN4RixVQUFJQSxZQUFXLE9BQU9BLFNBQVEsU0FBUyxjQUFjLE9BQU9BLFNBQVEsa0NBQWtDLFlBQVk7QUFDaEgsY0FBTSxpQkFBaUIsU0FBUyxJQUFJRCxLQUFJO0FBQ3hDLFlBQUksbUJBQW1CLFFBQVc7QUFDaEMsbUJBQVMsSUFBSUEsT0FBTSxFQUFDLFNBQUFDLFVBQVMsU0FBUSxDQUFDO21CQUM3QixlQUFlLFdBQVcsVUFBVTtBQUU3QzttQkFDUyxlQUFlLGFBQWEsVUFBVTtBQUMvQyxjQUFJLGVBQWUsWUFBWUEsVUFBUztBQUN0QyxrQkFBTSxJQUFJLE1BQU0sNEJBQTRCRCxLQUFJLG9CQUFvQixRQUFRLEVBQUU7OztBQUlsRixZQUFJLFlBQVksR0FBRztBQUNqQixnQkFBTSxJQUFJLHlCQUF5QixRQUFRQSxLQUFJO0FBQy9DLGNBQUksTUFBTSxJQUFJO0FBQ1oscUNBQXlCLE9BQU8sR0FBRyxDQUFDOztBQUd0QyxtQkFBU0UsS0FBSSxHQUFHQSxLQUFJLHlCQUF5QixRQUFRQSxNQUFLO0FBQ3hELGdC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O0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUc7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFJO0FBQUEsUUFBSztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBRztBQUFBLFFBQUs7QUFBQSxRQUFJO0FBQUEsUUFBSTtBQUFBLFFBQUs7QUFBQSxRQUFLO0FBQUEsUUFBSztBQUFBLFFBQUk7QUFBQSxRQUFHO0FBQUEsUUFBSTtBQUFBLFFBQUk7QUFBQSxRQUFL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O0FBQUE7QUFBQSxNQUVyQyxNQUFNLE9BQXNCO0FBQUEsTUFBQztBQUFBLE1BRTdCLE1BQU0sOEJBQThCLGNBQWlDLFNBQ2hDO0FBS25DLGNBQU0sVUFBVSxJQUFJLFFBQVEsT0FBb0M7QUFHaEUsWUFBSSxPQUFPLGlCQUFpQixVQUFVO0FBQ3BDLGdCQUFNLFFBQVEsVUFBVSxZQUFZO0FBQUEsUUFDdEMsT0FBTztBQUNMLGdCQUFNLFFBQVEsVUFBVSxZQUFZO0FBQUEsUUFDdEM7QUFFQSxlQUFPLElBQUkscUJBQXFCLE9BQU87QUFBQSxNQUN6QztBQUFBLElBQ0Y7QUFFTyxJQUFNLGdCQUFnQixJQUFJLGNBQWM7QUFBQTtBQUFBOzs7QUN4Qi9DO0FBQ0E7QUFHQTs7O0FDTk8sSUFBTUMsV0FBVTs7O0FESXZCLElBQU8sY0FBUTtBQUtmLElBQUksTUFBMkI7QUFDN0IsUUFBTUMsaUJBQWdCLDhEQUE0QjtBQUNsRCxrQkFBZ0IsU0FBU0EsZ0JBQWUsR0FBRztBQUM3QztBQUVBLElBQUksT0FBMEI7QUFDNUIsUUFBTSxjQUFjLE9BQThCLEtBQW9DLGNBQ3BDLEtBQW1DO0FBQ3JGLE1BQUksT0FBNEI7QUFDOUIsb0JBQWdCLFVBQVUsYUFBYSxDQUFDO0FBQ3hDLG9CQUFnQixTQUFTLGFBQWEsQ0FBQztBQUFBLEVBQ3pDO0FBQ0Esa0JBQWdCLE9BQU8sYUFBYSxFQUFFO0FBQ3RDLGtCQUFnQixRQUFRLGFBQWEsRUFBRTtBQUN6QztBQUVBLE9BQU8sZUFBZUMsS0FBSSxVQUFVLE9BQU8sRUFBQyxPQUFPQyxVQUFTLFlBQVksS0FBSSxDQUFDOyIsCiAgIm5hbWVzIjogWyJuYW1lIiwgImJhY2tlbmQiLCAiaSIsICJlbnYiLCAiY3JlYXRlQ2FudmFzIiwgIlRlbnNvciIsICJUZW5zb3IiLCAibmFtZSIsICJiYWNrZW5kIiwgIkluZmVyZW5jZVNlc3Npb24iLCAiYmFja2VuZCIsICJUZW5zb3IiLCAibmFtZSIsICJUcmFpbmluZ1Nlc3Npb24iLCAiSW5mZXJlbmNlU2Vzc2lvbiIsICJUZW5zb3IiLCAiVHJhaW5pbmdTZXNzaW9uIiwgImVudiIsICJsb2ciLCAiZW52IiwgIm5hbWUiLCAidmVyc2lvbiIsICJleHBvcnRzIiwgIkd1aWQiLCAiY2FjaGUiLCAiZGl2IiwgImxvZzIiLCAib25ueHJ1bnRpbWUiLCAiZXhwZXJpbWVudGFsIiwgImZicyIsICJBdHRyaWJ1dGVUeXBlIiwgIkRpbWVuc2lvblZhbHVlVHlwZSIsICJUZW5zb3JEYXRhVHlwZSIsICJOb2RlVHlwZSIsICJUeXBlSW5mb1ZhbHVlIiwgIk5vZGUiLCAidmVyc2lvbiIsICJUZW5zb3IiLCAiQXR0cmlidXRlIiwgIkdyYXBoIiwgIk1vZGVsIiwgIkluZmVyZW5jZVNlc3Npb24iLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAicGFyYW1zIiwgIm9mZnNldCIsICJleHBvcnRzIiwgImkiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZXhwb3J0cyIsICJtb2R1bGUiLCAiZXhwb3J0cyIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJzbGljZSIsICJzaXplIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImZyb21OdW1iZXIiLCAidG9OdW1iZXIiLCAiZXhwb3J0cyIsICJCdWZmZXIiLCAibmFtZSIsICJpIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImNyZWF0ZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJjcmVhdGVfYXJyYXkiLCAiY3JlYXRlIiwgImJ1ZmZlciIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJleHBvcnRzIiwgIm1vZHVsZSIsICJzZWxmIiwgImVyciIsICJleHBvcnRzIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImV4cG9ydHMiLCAicmVxdWlyZV9taW5pbWFsIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgImV4cG9ydHMiLCAibW9kdWxlIiwgIm9ubngiLCAiVGVuc29yIiwgIk1hcCIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAic2hhcGUiLCAic3BsaXQiLCAiaW1wb3J0X29ubngiLCAiVGVuc29yIiwgImluaXRfdGVuc29yIiwgImNhY2hlIiwgInZlcnNpb24iLCAibmFtZSIsICJzaGFwZSIsICJzaGFwZSIsICJzaGFwZSIsICJpbml0X3RlbnNvciIsICJzaGFwZSIsICJUZW5zb3IiLCAibmFtZSIsICJuYW1lIiwgIm5hbWUiLCAiYWRkIiwgImFuZCIsICJvciIsICJ4b3IiLCAiZ2xzbCIsICJzaGFkZXJTb3VyY2UiLCAidmFsaWRhdGVJbnB1dHMiLCAic2hpZnQiLCAidmFsaWRhdGVJbnB1dHMiLCAibmFtZSIsICJsb2ciLCAibm90IiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgIm5hbWUiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAic2hhcGUiLCAidmFsaWRhdGVJbnB1dHMiLCAic3VtIiwgInZhbGlkYXRlSW5wdXRzIiwgIm5hbWUiLCAiaW5wdXRzIiwgInZhbGlkYXRlSW5wdXRzIiwgImRpbSIsICJ2YWxpZGF0ZUlucHV0cyIsICJ2YWxpZGF0ZUlucHV0cyIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAic3BsaXQiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHMiLCAidmFsaWRhdGVJbnB1dHNWMTMiLCAiYWRkIiwgImFuZCIsICJsb2ciLCAibm90IiwgIm9yIiwgInhvciIsICJuYW1lIiwgInNoYXBlIiwgInNoYXBlIiwgIm5hbWUiLCAic291cmNlIiwgInBhY2tlZFNhbXBsZXIiLCAidGV4TnVtUiIsICJ0ZXhOdW1DIiwgInRyYW5zcG9zZSIsICJuYW1lIiwgInNoYXBlIiwgImkiLCAibmFtZSIsICJuYW1lIiwgImVudiIsICJuYW1lIiwgInRleHR1cmUiLCAiYmFja2VuZCIsICJ2ZXJzaW9uIiwgImVudiIsICJlbnYiLCAiY2FjaGUiLCAiYmFja2VuZCIsICJpbml0X2JhY2tlbmQiLCAib3V0cHV0IiwgImltcG9ydF9vbm54IiwgIm9ydEZicyIsICJpbml0X3RlbnNvciIsICJUZW5zb3IiLCAidmFsdWUiLCAiaW1wb3J0X29ubngiLCAib3J0RmJzIiwgImluaXRfdGVuc29yIiwgIm5hbWUiLCAiVGVuc29yIiwgInNoYXBlIiwgIm5vZGVJbmRleCIsICJpbXBvcnRfb25ueCIsICJvcnRGYnMiLCAiaW5pdF9iYWNrZW5kIiwgImJhY2tlbmQiLCAiaW5pdF90ZW5zb3IiLCAibmFtZSIsICJUZW5zb3IiLCAidmVyc2lvbiIsICJvbm54anNCYWNrZW5kIiwgImVudiIsICJ2ZXJzaW9uIl0KfQo=